diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
commit | bc95f3669f5e6f63cf0b84fe4922c3c6dd4aa775 (patch) | |
tree | 427fcf2a7287c16d4b5aa6cbf494d59579a6a8b1 /drivers/ata | |
parent | 3d29cdff999c37b3876082278a8134a0642a02cd (diff) | |
parent | dc87c3985e9b442c60994308a96f887579addc39 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/usb/input/Makefile
drivers/usb/input/gtco.c
Diffstat (limited to 'drivers/ata')
71 files changed, 6661 insertions, 3691 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 3747457fee7..365c306c7cf 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -156,10 +156,18 @@ config SATA_INIC162X help This option enables support for Initio 162x Serial ATA. -config SATA_INTEL_COMBINED +config SATA_ACPI bool - depends on IDE=y && !BLK_DEV_IDE_SATA && (SATA_AHCI || ATA_PIIX) + depends on ACPI && PCI default y + help + This option adds support for SATA-related ACPI objects. + These ACPI objects add the ability to retrieve taskfiles + from the ACPI BIOS and write them to the disk controller. + These objects may be related to performance, security, + power management, or other areas. + You can disable this at kernel boot time by using the + option libata.noacpi=1 config PATA_ALI tristate "ALi PATA support (Experimental)" @@ -171,7 +179,7 @@ config PATA_ALI If unsure, say N. config PATA_AMD - tristate "AMD/NVidia PATA support (Experimental)" + tristate "AMD/NVidia PATA support" depends on PCI help This option enables support for the AMD and NVidia PATA @@ -196,6 +204,16 @@ config PATA_ATIIXP If unsure, say N. +config PATA_CMD640_PCI + tristate "CMD640 PCI PATA support (Very Experimental)" + depends on PCI && EXPERIMENTAL + help + This option enables support for the CMD640 PCI IDE + interface chip. Only the primary channel is currently + supported. + + If unsure, say N. + config PATA_CMD64X tristate "CMD64x PATA support (Very Experimental)" depends on PCI&& EXPERIMENTAL @@ -260,7 +278,7 @@ config ATA_GENERIC If unsure, say N. config PATA_HPT366 - tristate "HPT 366/368 PATA support (Very Experimental)" + tristate "HPT 366/368 PATA support (Experimental)" depends on PCI && EXPERIMENTAL help This option enables support for the HPT 366 and 368 @@ -269,7 +287,7 @@ config PATA_HPT366 If unsure, say N. config PATA_HPT37X - tristate "HPT 370/370A/371/372/374/302 PATA support (Very Experimental)" + tristate "HPT 370/370A/371/372/374/302 PATA support (Experimental)" depends on PCI && EXPERIMENTAL help This option enables support for the majority of the later HPT @@ -296,7 +314,7 @@ config PATA_HPT3X3 If unsure, say N. config PATA_ISAPNP - tristate "ISA Plug and Play PATA support (Very Experimental)" + tristate "ISA Plug and Play PATA support (Experimental)" depends on EXPERIMENTAL && ISAPNP help This option enables support for ISA plug & play ATA @@ -305,8 +323,8 @@ config PATA_ISAPNP If unsure, say N. config PATA_IT821X - tristate "IT8211/2 PATA support (Experimental)" - depends on PCI && EXPERIMENTAL + tristate "IT8211/2 PATA support" + depends on PCI help This option enables support for the ITE 8211 and 8212 PATA controllers via the new ATA layer, including RAID @@ -377,10 +395,10 @@ config PATA_MPIIX If unsure, say N. config PATA_OLDPIIX - tristate "Intel PATA old PIIX support (Experimental)" - depends on PCI && EXPERIMENTAL + tristate "Intel PATA old PIIX support" + depends on PCI help - This option enables support for old(?) PIIX PATA support. + This option enables support for early PIIX PATA support. If unsure, say N. @@ -431,7 +449,7 @@ config PATA_PCMCIA If unsure, say N. config PATA_PDC_OLD - tristate "Older Promise PATA controller support (Very Experimental)" + tristate "Older Promise PATA controller support (Experimental)" depends on PCI && EXPERIMENTAL help This option enables support for the Promise 20246, 20262, 20263, @@ -446,7 +464,7 @@ config PATA_QDI Support for QDI 6500 and 6580 PATA controllers on VESA local bus. config PATA_RADISYS - tristate "RADISYS 82600 PATA support (Very experimental)" + tristate "RADISYS 82600 PATA support (Very Experimental)" depends on PCI && EXPERIMENTAL help This option enables support for the RADISYS 82600 @@ -464,7 +482,7 @@ config PATA_RZ1000 If unsure, say N. config PATA_SC1200 - tristate "SC1200 PATA support (Raving Lunatic)" + tristate "SC1200 PATA support (Very Experimental)" depends on PCI && EXPERIMENTAL help This option enables support for the NatSemi/AMD SC1200 SoC @@ -473,8 +491,8 @@ config PATA_SC1200 If unsure, say N. config PATA_SERVERWORKS - tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support (Experimental)" - depends on PCI && EXPERIMENTAL + tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support" + depends on PCI help This option enables support for the Serverworks OSB4/CSB5/CSB6 and HT1000 PATA controllers, via the new ATA layer. @@ -549,6 +567,15 @@ config PATA_IXP4XX_CF If unsure, say N. +config PATA_SCC + tristate "Toshiba's Cell Reference Set IDE support" + depends on PCI && PPC_CELLEB + help + This option enables support for the built-in IDE controller on + Toshiba Cell Reference Board. + + If unsure, say N. + endif endmenu diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index cd096f0c78a..b7055e30265 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_PATA_ALI) += pata_ali.o obj-$(CONFIG_PATA_AMD) += pata_amd.o obj-$(CONFIG_PATA_ARTOP) += pata_artop.o obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o +obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o @@ -59,6 +60,7 @@ obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o obj-$(CONFIG_PATA_SIS) += pata_sis.o obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o +obj-$(CONFIG_PATA_SCC) += pata_scc.o obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o # Should be last but one libata driver obj-$(CONFIG_ATA_GENERIC) += ata_generic.o @@ -66,4 +68,4 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o libata-objs := libata-core.o libata-scsi.o libata-sff.o libata-eh.o - +libata-$(CONFIG_SATA_ACPI) += libata-acpi.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6a3543e0624..34c5534ed64 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -46,7 +46,7 @@ #include <linux/libata.h> #define DRV_NAME "ahci" -#define DRV_VERSION "2.0" +#define DRV_VERSION "2.1" enum { @@ -80,6 +80,7 @@ enum { board_ahci_pi = 1, board_ahci_vt8251 = 2, board_ahci_ign_iferr = 3, + board_ahci_sb600 = 4, /* global controller registers */ HOST_CAP = 0x00, /* host capabilities */ @@ -168,6 +169,11 @@ enum { AHCI_FLAG_NO_NCQ = (1 << 24), AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */ AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */ + AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */ + + AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | + ATA_FLAG_SKIP_D2H_BSY, }; struct ahci_cmd_hdr { @@ -186,8 +192,10 @@ struct ahci_sg { }; struct ahci_host_priv { - u32 cap; /* cache of HOST_CAP register */ - u32 port_map; /* cache of HOST_PORTS_IMPL reg */ + u32 cap; /* cap to use */ + u32 port_map; /* port map to use */ + u32 saved_cap; /* saved initial cap */ + u32 saved_port_map; /* saved initial port_map */ }; struct ahci_port_priv { @@ -198,16 +206,15 @@ struct ahci_port_priv { void *rx_fis; dma_addr_t rx_fis_dma; /* for NCQ spurious interrupt analysis */ - int ncq_saw_spurious_sdb_cnt; unsigned int ncq_saw_d2h:1; unsigned int ncq_saw_dmas:1; + unsigned int ncq_saw_sdb:1; }; static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); -static irqreturn_t ahci_interrupt (int irq, void *dev_instance); static void ahci_irq_clear(struct ata_port *ap); static int ahci_port_start(struct ata_port *ap); static void ahci_port_stop(struct ata_port *ap); @@ -219,10 +226,12 @@ static void ahci_thaw(struct ata_port *ap); static void ahci_error_handler(struct ata_port *ap); static void ahci_vt8251_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); +#ifdef CONFIG_PM static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); static int ahci_port_resume(struct ata_port *ap); static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); static int ahci_pci_device_resume(struct pci_dev *pdev); +#endif static struct scsi_host_template ahci_sht = { .module = THIS_MODULE, @@ -241,8 +250,10 @@ static struct scsi_host_template ahci_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .suspend = ata_scsi_device_suspend, .resume = ata_scsi_device_resume, +#endif }; static const struct ata_port_operations ahci_ops = { @@ -257,7 +268,6 @@ static const struct ata_port_operations ahci_ops = { .qc_prep = ahci_qc_prep, .qc_issue = ahci_qc_issue, - .irq_handler = ahci_interrupt, .irq_clear = ahci_irq_clear, .irq_on = ata_dummy_irq_on, .irq_ack = ata_dummy_irq_ack, @@ -271,8 +281,10 @@ static const struct ata_port_operations ahci_ops = { .error_handler = ahci_error_handler, .post_internal_cmd = ahci_post_internal_cmd, +#ifdef CONFIG_PM .port_suspend = ahci_port_suspend, .port_resume = ahci_port_resume, +#endif .port_start = ahci_port_start, .port_stop = ahci_port_stop, @@ -290,7 +302,6 @@ static const struct ata_port_operations ahci_vt8251_ops = { .qc_prep = ahci_qc_prep, .qc_issue = ahci_qc_issue, - .irq_handler = ahci_interrupt, .irq_clear = ahci_irq_clear, .irq_on = ata_dummy_irq_on, .irq_ack = ata_dummy_irq_ack, @@ -304,8 +315,10 @@ static const struct ata_port_operations ahci_vt8251_ops = { .error_handler = ahci_vt8251_error_handler, .post_internal_cmd = ahci_post_internal_cmd, +#ifdef CONFIG_PM .port_suspend = ahci_port_suspend, .port_resume = ahci_port_resume, +#endif .port_start = ahci_port_start, .port_stop = ahci_port_stop, @@ -314,42 +327,37 @@ static const struct ata_port_operations ahci_vt8251_ops = { static const struct ata_port_info ahci_port_info[] = { /* board_ahci */ { - .sht = &ahci_sht, - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_SKIP_D2H_BSY, + .flags = AHCI_FLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops, }, /* board_ahci_pi */ { - .sht = &ahci_sht, - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI, + .flags = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops, }, /* board_ahci_vt8251 */ { - .sht = &ahci_sht, - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_SKIP_D2H_BSY | - ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ, + .flags = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME | + AHCI_FLAG_NO_NCQ, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_vt8251_ops, }, /* board_ahci_ign_iferr */ { - .sht = &ahci_sht, - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_SKIP_D2H_BSY | - AHCI_FLAG_IGN_IRQ_IF_ERR, + .flags = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR, + .pio_mask = 0x1f, /* pio0-4 */ + .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .port_ops = &ahci_ops, + }, + /* board_ahci_sb600 */ + { + .flags = AHCI_FLAG_COMMON | + AHCI_FLAG_IGN_SERR_INTERNAL, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops, @@ -381,23 +389,21 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292c), board_ahci_pi }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */ { PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */ - /* JMicron */ - { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */ - { PCI_VDEVICE(JMICRON, 0x2361), board_ahci_ign_iferr }, /* JMB361 */ - { PCI_VDEVICE(JMICRON, 0x2363), board_ahci_ign_iferr }, /* JMB363 */ - { PCI_VDEVICE(JMICRON, 0x2365), board_ahci_ign_iferr }, /* JMB365 */ - { PCI_VDEVICE(JMICRON, 0x2366), board_ahci_ign_iferr }, /* JMB366 */ + /* JMicron 360/1/3/5/6, match class to avoid IDE function */ + { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, /* ATI */ - { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */ - { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */ + { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ /* VIA */ { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ + { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */ /* NVIDIA */ { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci }, /* MCP65 */ @@ -439,8 +445,10 @@ static struct pci_driver ahci_pci_driver = { .id_table = ahci_pci_tbl, .probe = ahci_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ahci_pci_device_suspend, .resume = ahci_pci_device_resume, +#endif }; @@ -449,10 +457,100 @@ static inline int ahci_nr_ports(u32 cap) return (cap & 0x1f) + 1; } -static inline void __iomem *ahci_port_base(void __iomem *base, - unsigned int port) +static inline void __iomem *ahci_port_base(struct ata_port *ap) { - return base + 0x100 + (port * 0x80); + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; + + return mmio + 0x100 + (ap->port_no * 0x80); +} + +/** + * ahci_save_initial_config - Save and fixup initial config values + * @pdev: target PCI device + * @pi: associated ATA port info + * @hpriv: host private area to store config values + * + * Some registers containing configuration info might be setup by + * BIOS and might be cleared on reset. This function saves the + * initial values of those registers into @hpriv such that they + * can be restored after controller reset. + * + * If inconsistent, config values are fixed up by this function. + * + * LOCKING: + * None. + */ +static void ahci_save_initial_config(struct pci_dev *pdev, + const struct ata_port_info *pi, + struct ahci_host_priv *hpriv) +{ + void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; + u32 cap, port_map; + int i; + + /* Values prefixed with saved_ are written back to host after + * reset. Values without are used for driver operation. + */ + hpriv->saved_cap = cap = readl(mmio + HOST_CAP); + hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); + + /* fixup zero port_map */ + if (!port_map) { + port_map = (1 << ahci_nr_ports(hpriv->cap)) - 1; + dev_printk(KERN_WARNING, &pdev->dev, + "PORTS_IMPL is zero, forcing 0x%x\n", port_map); + + /* write the fixed up value to the PI register */ + hpriv->saved_port_map = port_map; + } + + /* cross check port_map and cap.n_ports */ + if (pi->flags & AHCI_FLAG_HONOR_PI) { + u32 tmp_port_map = port_map; + int n_ports = ahci_nr_ports(cap); + + for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) { + if (tmp_port_map & (1 << i)) { + n_ports--; + tmp_port_map &= ~(1 << i); + } + } + + /* Whine if inconsistent. No need to update cap. + * port_map is used to determine number of ports. + */ + if (n_ports || tmp_port_map) + dev_printk(KERN_WARNING, &pdev->dev, + "nr_ports (%u) and implemented port map " + "(0x%x) don't match\n", + ahci_nr_ports(cap), port_map); + } else { + /* fabricate port_map from cap.nr_ports */ + port_map = (1 << ahci_nr_ports(cap)) - 1; + } + + /* record values to use during operation */ + hpriv->cap = cap; + hpriv->port_map = port_map; +} + +/** + * ahci_restore_initial_config - Restore initial config + * @host: target ATA host + * + * Restore initial config stored by ahci_save_initial_config(). + * + * LOCKING: + * None. + */ +static void ahci_restore_initial_config(struct ata_host *host) +{ + struct ahci_host_priv *hpriv = host->private_data; + void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; + + writel(hpriv->saved_cap, mmio + HOST_CAP); + writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL); + (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ } static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) @@ -489,8 +587,9 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); } -static void ahci_start_engine(void __iomem *port_mmio) +static void ahci_start_engine(struct ata_port *ap) { + void __iomem *port_mmio = ahci_port_base(ap); u32 tmp; /* start DMA */ @@ -500,8 +599,9 @@ static void ahci_start_engine(void __iomem *port_mmio) readl(port_mmio + PORT_CMD); /* flush */ } -static int ahci_stop_engine(void __iomem *port_mmio) +static int ahci_stop_engine(struct ata_port *ap) { + void __iomem *port_mmio = ahci_port_base(ap); u32 tmp; tmp = readl(port_mmio + PORT_CMD); @@ -523,19 +623,23 @@ static int ahci_stop_engine(void __iomem *port_mmio) return 0; } -static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap, - dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) +static void ahci_start_fis_rx(struct ata_port *ap) { + void __iomem *port_mmio = ahci_port_base(ap); + struct ahci_host_priv *hpriv = ap->host->private_data; + struct ahci_port_priv *pp = ap->private_data; u32 tmp; /* set FIS registers */ - if (cap & HOST_CAP_64) - writel((cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); - writel(cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); + if (hpriv->cap & HOST_CAP_64) + writel((pp->cmd_slot_dma >> 16) >> 16, + port_mmio + PORT_LST_ADDR_HI); + writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); - if (cap & HOST_CAP_64) - writel((rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); - writel(rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); + if (hpriv->cap & HOST_CAP_64) + writel((pp->rx_fis_dma >> 16) >> 16, + port_mmio + PORT_FIS_ADDR_HI); + writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); /* enable FIS reception */ tmp = readl(port_mmio + PORT_CMD); @@ -546,8 +650,9 @@ static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap, readl(port_mmio + PORT_CMD); } -static int ahci_stop_fis_rx(void __iomem *port_mmio) +static int ahci_stop_fis_rx(struct ata_port *ap) { + void __iomem *port_mmio = ahci_port_base(ap); u32 tmp; /* disable FIS reception */ @@ -564,14 +669,16 @@ static int ahci_stop_fis_rx(void __iomem *port_mmio) return 0; } -static void ahci_power_up(void __iomem *port_mmio, u32 cap) +static void ahci_power_up(struct ata_port *ap) { + struct ahci_host_priv *hpriv = ap->host->private_data; + void __iomem *port_mmio = ahci_port_base(ap); u32 cmd; cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; /* spin up device */ - if (cap & HOST_CAP_SSS) { + if (hpriv->cap & HOST_CAP_SSS) { cmd |= PORT_CMD_SPIN_UP; writel(cmd, port_mmio + PORT_CMD); } @@ -580,11 +687,14 @@ static void ahci_power_up(void __iomem *port_mmio, u32 cap) writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); } -static void ahci_power_down(void __iomem *port_mmio, u32 cap) +#ifdef CONFIG_PM +static void ahci_power_down(struct ata_port *ap) { + struct ahci_host_priv *hpriv = ap->host->private_data; + void __iomem *port_mmio = ahci_port_base(ap); u32 cmd, scontrol; - if (!(cap & HOST_CAP_SSS)) + if (!(hpriv->cap & HOST_CAP_SSS)) return; /* put device into listen mode, first set PxSCTL.DET to 0 */ @@ -597,30 +707,30 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap) cmd &= ~PORT_CMD_SPIN_UP; writel(cmd, port_mmio + PORT_CMD); } +#endif -static void ahci_init_port(void __iomem *port_mmio, u32 cap, - dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) +static void ahci_init_port(struct ata_port *ap) { /* enable FIS reception */ - ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma); + ahci_start_fis_rx(ap); /* enable DMA */ - ahci_start_engine(port_mmio); + ahci_start_engine(ap); } -static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg) +static int ahci_deinit_port(struct ata_port *ap, const char **emsg) { int rc; /* disable DMA */ - rc = ahci_stop_engine(port_mmio); + rc = ahci_stop_engine(ap); if (rc) { *emsg = "failed to stop engine"; return rc; } /* disable FIS reception */ - rc = ahci_stop_fis_rx(port_mmio); + rc = ahci_stop_fis_rx(ap); if (rc) { *emsg = "failed stop FIS RX"; return rc; @@ -629,12 +739,11 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg) return 0; } -static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) +static int ahci_reset_controller(struct ata_host *host) { - u32 cap_save, impl_save, tmp; - - cap_save = readl(mmio + HOST_CAP); - impl_save = readl(mmio + HOST_PORTS_IMPL); + struct pci_dev *pdev = to_pci_dev(host->dev); + void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; + u32 tmp; /* global controller reset */ tmp = readl(mmio + HOST_CTL); @@ -650,7 +759,7 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) tmp = readl(mmio + HOST_CTL); if (tmp & HOST_RESET) { - dev_printk(KERN_ERR, &pdev->dev, + dev_printk(KERN_ERR, host->dev, "controller reset failed (0x%x)\n", tmp); return -EIO; } @@ -659,18 +768,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) writel(HOST_AHCI_EN, mmio + HOST_CTL); (void) readl(mmio + HOST_CTL); /* flush */ - /* These write-once registers are normally cleared on reset. - * Restore BIOS values... which we HOPE were present before - * reset. - */ - if (!impl_save) { - impl_save = (1 << ahci_nr_ports(cap_save)) - 1; - dev_printk(KERN_WARNING, &pdev->dev, - "PORTS_IMPL is zero, forcing 0x%x\n", impl_save); - } - writel(cap_save, mmio + HOST_CAP); - writel(impl_save, mmio + HOST_PORTS_IMPL); - (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ + /* some registers might be cleared on reset. restore initial values */ + ahci_restore_initial_config(host); if (pdev->vendor == PCI_VENDOR_ID_INTEL) { u16 tmp16; @@ -684,23 +783,23 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) return 0; } -static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, - int n_ports, unsigned int port_flags, - struct ahci_host_priv *hpriv) +static void ahci_init_controller(struct ata_host *host) { + struct pci_dev *pdev = to_pci_dev(host->dev); + void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; int i, rc; u32 tmp; - for (i = 0; i < n_ports; i++) { - void __iomem *port_mmio = ahci_port_base(mmio, i); + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + void __iomem *port_mmio = ahci_port_base(ap); const char *emsg = NULL; - if ((port_flags & AHCI_FLAG_HONOR_PI) && - !(hpriv->port_map & (1 << i))) + if (ata_port_is_dummy(ap)) continue; /* make sure port is not active */ - rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); + rc = ahci_deinit_port(ap, &emsg); if (rc) dev_printk(KERN_WARNING, &pdev->dev, "%s (%d)\n", emsg, rc); @@ -728,7 +827,7 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, static unsigned int ahci_dev_classify(struct ata_port *ap) { - void __iomem *port_mmio = ap->ioaddr.cmd_addr; + void __iomem *port_mmio = ahci_port_base(ap); struct ata_taskfile tf; u32 tmp; @@ -778,8 +877,7 @@ static int ahci_clo(struct ata_port *ap) static int ahci_softreset(struct ata_port *ap, unsigned int *class) { struct ahci_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); + void __iomem *port_mmio = ahci_port_base(ap); const u32 cmd_fis_len = 5; /* five dwords */ const char *reason = NULL; struct ata_taskfile tf; @@ -796,7 +894,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) } /* prepare for SRST (AHCI-1.1 10.4.1) */ - rc = ahci_stop_engine(port_mmio); + rc = ahci_stop_engine(ap); if (rc) { reason = "failed to stop engine"; goto fail_restart; @@ -816,7 +914,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) } /* restart engine */ - ahci_start_engine(port_mmio); + ahci_start_engine(ap); ata_tf_init(ap->device, &tf); fis = pp->cmd_tbl; @@ -875,7 +973,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) return 0; fail_restart: - ahci_start_engine(port_mmio); + ahci_start_engine(ap); fail: ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); return rc; @@ -886,13 +984,11 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) struct ahci_port_priv *pp = ap->private_data; u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; struct ata_taskfile tf; - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); int rc; DPRINTK("ENTER\n"); - ahci_stop_engine(port_mmio); + ahci_stop_engine(ap); /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(ap->device, &tf); @@ -901,7 +997,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) rc = sata_std_hardreset(ap, class); - ahci_start_engine(port_mmio); + ahci_start_engine(ap); if (rc == 0 && ata_port_online(ap)) *class = ahci_dev_classify(ap); @@ -914,20 +1010,18 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class) { - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); int rc; DPRINTK("ENTER\n"); - ahci_stop_engine(port_mmio); + ahci_stop_engine(ap); rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context)); /* vt8251 needs SError cleared for the port to operate */ ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR)); - ahci_start_engine(port_mmio); + ahci_start_engine(ap); DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); @@ -939,7 +1033,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class) static void ahci_postreset(struct ata_port *ap, unsigned int *class) { - void __iomem *port_mmio = ap->ioaddr.cmd_addr; + void __iomem *port_mmio = ahci_port_base(ap); u32 new_tmp, tmp; ata_std_postreset(ap, class); @@ -1057,8 +1151,11 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR) irq_stat &= ~PORT_IRQ_IF_ERR; - if (irq_stat & PORT_IRQ_TF_ERR) + if (irq_stat & PORT_IRQ_TF_ERR) { err_mask |= AC_ERR_DEV; + if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL) + serror &= ~SERR_INTERNAL; + } if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { err_mask |= AC_ERR_HOST_BUS; @@ -1104,8 +1201,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) static void ahci_host_intr(struct ata_port *ap) { - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); + void __iomem *port_mmio = ap->ioaddr.cmd_addr; struct ata_eh_info *ehi = &ap->eh_info; struct ahci_port_priv *pp = ap->private_data; u32 status, qc_active; @@ -1160,23 +1256,32 @@ static void ahci_host_intr(struct ata_port *ap) known_irq = 1; } - if (status & PORT_IRQ_SDB_FIS && - pp->ncq_saw_spurious_sdb_cnt < 10) { - /* SDB FIS containing spurious completions might be - * dangerous, we need to know more about them. Print - * more of it. - */ + if (status & PORT_IRQ_SDB_FIS) { const __le32 *f = pp->rx_fis + RX_FIS_SDB; - ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " - "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", + if (le32_to_cpu(f[1])) { + /* SDB FIS containing spurious completions + * might be dangerous, whine and fail commands + * with HSM violation. EH will turn off NCQ + * after several such failures. + */ + ata_ehi_push_desc(ehi, + "spurious completions during NCQ " + "issue=0x%x SAct=0x%x FIS=%08x:%08x", readl(port_mmio + PORT_CMD_ISSUE), readl(port_mmio + PORT_SCR_ACT), - le32_to_cpu(f[0]), le32_to_cpu(f[1]), - pp->ncq_saw_spurious_sdb_cnt < 10 ? - "" : ", shutting up"); - - pp->ncq_saw_spurious_sdb_cnt++; + le32_to_cpu(f[0]), le32_to_cpu(f[1])); + ehi->err_mask |= AC_ERR_HSM; + ehi->action |= ATA_EH_SOFTRESET; + ata_port_freeze(ap); + } else { + if (!pp->ncq_saw_sdb) + ata_port_printk(ap, KERN_INFO, + "spurious SDB FIS %08x:%08x during NCQ, " + "this message won't be printed again\n", + le32_to_cpu(f[0]), le32_to_cpu(f[1])); + pp->ncq_saw_sdb = 1; + } known_irq = 1; } @@ -1247,7 +1352,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void __iomem *port_mmio = ap->ioaddr.cmd_addr; + void __iomem *port_mmio = ahci_port_base(ap); if (qc->tf.protocol == ATA_PROT_NCQ) writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); @@ -1259,8 +1364,7 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) static void ahci_freeze(struct ata_port *ap) { - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); + void __iomem *port_mmio = ahci_port_base(ap); /* turn IRQ off */ writel(0, port_mmio + PORT_IRQ_MASK); @@ -1269,7 +1373,7 @@ static void ahci_freeze(struct ata_port *ap) static void ahci_thaw(struct ata_port *ap) { void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); + void __iomem *port_mmio = ahci_port_base(ap); u32 tmp; /* clear IRQ */ @@ -1283,13 +1387,10 @@ static void ahci_thaw(struct ata_port *ap) static void ahci_error_handler(struct ata_port *ap) { - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - if (!(ap->pflags & ATA_PFLAG_FROZEN)) { /* restart engine */ - ahci_stop_engine(port_mmio); - ahci_start_engine(port_mmio); + ahci_stop_engine(ap); + ahci_start_engine(ap); } /* perform recovery */ @@ -1299,13 +1400,10 @@ static void ahci_error_handler(struct ata_port *ap) static void ahci_vt8251_error_handler(struct ata_port *ap) { - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - if (!(ap->pflags & ATA_PFLAG_FROZEN)) { /* restart engine */ - ahci_stop_engine(port_mmio); - ahci_start_engine(port_mmio); + ahci_stop_engine(ap); + ahci_start_engine(ap); } /* perform recovery */ @@ -1316,35 +1414,26 @@ static void ahci_vt8251_error_handler(struct ata_port *ap) static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - if (qc->flags & ATA_QCFLAG_FAILED) - qc->err_mask |= AC_ERR_OTHER; - - if (qc->err_mask) { + if (qc->flags & ATA_QCFLAG_FAILED) { /* make DMA engine forget about the failed command */ - ahci_stop_engine(port_mmio); - ahci_start_engine(port_mmio); + ahci_stop_engine(ap); + ahci_start_engine(ap); } } +#ifdef CONFIG_PM static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) { - struct ahci_host_priv *hpriv = ap->host->private_data; - struct ahci_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); const char *emsg = NULL; int rc; - rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); + rc = ahci_deinit_port(ap, &emsg); if (rc == 0) - ahci_power_down(port_mmio, hpriv->cap); + ahci_power_down(ap); else { ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc); - ahci_init_port(port_mmio, hpriv->cap, - pp->cmd_slot_dma, pp->rx_fis_dma); + ahci_init_port(ap); } return rc; @@ -1352,13 +1441,8 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) static int ahci_port_resume(struct ata_port *ap) { - struct ahci_port_priv *pp = ap->private_data; - struct ahci_host_priv *hpriv = ap->host->private_data; - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - - ahci_power_up(port_mmio, hpriv->cap); - ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); + ahci_power_up(ap); + ahci_init_port(ap); return 0; } @@ -1386,8 +1470,6 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) static int ahci_pci_device_resume(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); - struct ahci_host_priv *hpriv = host->private_data; - void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; int rc; rc = ata_pci_device_do_resume(pdev); @@ -1395,26 +1477,23 @@ static int ahci_pci_device_resume(struct pci_dev *pdev) return rc; if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - rc = ahci_reset_controller(mmio, pdev); + rc = ahci_reset_controller(host); if (rc) return rc; - ahci_init_controller(mmio, pdev, host->n_ports, - host->ports[0]->flags, hpriv); + ahci_init_controller(host); } ata_host_resume(host); return 0; } +#endif static int ahci_port_start(struct ata_port *ap) { struct device *dev = ap->host->dev; - struct ahci_host_priv *hpriv = ap->host->private_data; struct ahci_port_priv *pp; - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); void *mem; dma_addr_t mem_dma; int rc; @@ -1462,85 +1541,29 @@ static int ahci_port_start(struct ata_port *ap) ap->private_data = pp; /* power up port */ - ahci_power_up(port_mmio, hpriv->cap); + ahci_power_up(ap); /* initialize port */ - ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); + ahci_init_port(ap); return 0; } static void ahci_port_stop(struct ata_port *ap) { - struct ahci_host_priv *hpriv = ap->host->private_data; - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); const char *emsg = NULL; int rc; /* de-initialize port */ - rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); + rc = ahci_deinit_port(ap, &emsg); if (rc) ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc); } -static void ahci_setup_port(struct ata_ioports *port, void __iomem *base, - unsigned int port_idx) -{ - VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx); - base = ahci_port_base(base, port_idx); - VPRINTK("base now==0x%lx\n", base); - - port->cmd_addr = base; - port->scr_addr = base + PORT_SCR; - - VPRINTK("EXIT\n"); -} - -static int ahci_host_init(struct ata_probe_ent *probe_ent) +static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) { - struct ahci_host_priv *hpriv = probe_ent->private_data; - struct pci_dev *pdev = to_pci_dev(probe_ent->dev); - void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR]; - unsigned int i, cap_n_ports, using_dac; int rc; - rc = ahci_reset_controller(mmio, pdev); - if (rc) - return rc; - - hpriv->cap = readl(mmio + HOST_CAP); - hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); - cap_n_ports = ahci_nr_ports(hpriv->cap); - - VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n", - hpriv->cap, hpriv->port_map, cap_n_ports); - - if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) { - unsigned int n_ports = cap_n_ports; - u32 port_map = hpriv->port_map; - int max_port = 0; - - for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) { - if (port_map & (1 << i)) { - n_ports--; - port_map &= ~(1 << i); - max_port = i; - } else - probe_ent->dummy_port_mask |= 1 << i; - } - - if (n_ports || port_map) - dev_printk(KERN_WARNING, &pdev->dev, - "nr_ports (%u) and implemented port map " - "(0x%x) don't match\n", - cap_n_ports, hpriv->port_map); - - probe_ent->n_ports = max_port + 1; - } else - probe_ent->n_ports = cap_n_ports; - - using_dac = hpriv->cap & HOST_CAP_64; if (using_dac && !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); @@ -1566,23 +1589,14 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) return rc; } } - - for (i = 0; i < probe_ent->n_ports; i++) - ahci_setup_port(&probe_ent->port[i], mmio, i); - - ahci_init_controller(mmio, pdev, probe_ent->n_ports, - probe_ent->port_flags, hpriv); - - pci_set_master(pdev); - return 0; } -static void ahci_print_info(struct ata_probe_ent *probe_ent) +static void ahci_print_info(struct ata_host *host) { - struct ahci_host_priv *hpriv = probe_ent->private_data; - struct pci_dev *pdev = to_pci_dev(probe_ent->dev); - void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR]; + struct ahci_host_priv *hpriv = host->private_data; + struct pci_dev *pdev = to_pci_dev(host->dev); + void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; u32 vers, cap, impl, speed; const char *speed_s; u16 cc; @@ -1652,11 +1666,12 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent) static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - unsigned int board_idx = (unsigned int) ent->driver_data; + struct ata_port_info pi = ahci_port_info[ent->driver_data]; + const struct ata_port_info *ppi[] = { &pi, NULL }; struct device *dev = &pdev->dev; - struct ata_probe_ent *probe_ent; struct ahci_host_priv *hpriv; - int rc; + struct ata_host *host; + int i, rc; VPRINTK("ENTER\n"); @@ -1665,13 +1680,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - if (pdev->vendor == PCI_VENDOR_ID_JMICRON) { - /* Function 1 is the PATA controller except on the 368, where - we are not AHCI anyway */ - if (PCI_FUNC(pdev->devfn)) - return -ENODEV; - } - + /* acquire resources */ rc = pcim_enable_device(pdev); if (rc) return rc; @@ -1685,44 +1694,49 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (pci_enable_msi(pdev)) pci_intx(pdev, 1); - probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) - return -ENOMEM; - - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) return -ENOMEM; - probe_ent->sht = ahci_port_info[board_idx].sht; - probe_ent->port_flags = ahci_port_info[board_idx].flags; - probe_ent->pio_mask = ahci_port_info[board_idx].pio_mask; - probe_ent->udma_mask = ahci_port_info[board_idx].udma_mask; - probe_ent->port_ops = ahci_port_info[board_idx].port_ops; + /* save initial config */ + ahci_save_initial_config(pdev, &pi, hpriv); - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->iomap = pcim_iomap_table(pdev); - probe_ent->private_data = hpriv; + /* prepare host */ + if (!(pi.flags & AHCI_FLAG_NO_NCQ) && (hpriv->cap & HOST_CAP_NCQ)) + pi.flags |= ATA_FLAG_NCQ; + + host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map)); + if (!host) + return -ENOMEM; + host->iomap = pcim_iomap_table(pdev); + host->private_data = hpriv; + + for (i = 0; i < host->n_ports; i++) { + if (hpriv->port_map & (1 << i)) { + struct ata_port *ap = host->ports[i]; + void __iomem *port_mmio = ahci_port_base(ap); + + ap->ioaddr.cmd_addr = port_mmio; + ap->ioaddr.scr_addr = port_mmio + PORT_SCR; + } else + host->ports[i]->ops = &ata_dummy_port_ops; + } /* initialize adapter */ - rc = ahci_host_init(probe_ent); + rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); if (rc) return rc; - if (!(probe_ent->port_flags & AHCI_FLAG_NO_NCQ) && - (hpriv->cap & HOST_CAP_NCQ)) - probe_ent->port_flags |= ATA_FLAG_NCQ; - - ahci_print_info(probe_ent); + rc = ahci_reset_controller(host); + if (rc) + return rc; - if (!ata_device_add(probe_ent)) - return -ENODEV; + ahci_init_controller(host); + ahci_print_info(host); - devm_kfree(dev, probe_ent); - return 0; + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED, + &ahci_sht); } static int __init ahci_init(void) diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index be66ea08da5..92a491ddd03 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -26,42 +26,13 @@ #include <linux/libata.h> #define DRV_NAME "ata_generic" -#define DRV_VERSION "0.2.10" +#define DRV_VERSION "0.2.11" /* * A generic parallel ATA driver using libata */ /** - * generic_pre_reset - probe begin - * @ap: ATA port - * - * Set up cable type and use generic probe init - */ - -static int generic_pre_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA80; - return ata_std_prereset(ap); -} - - -/** - * generic_error_handler - Probe specified port on PATA host controller - * @ap: Port to probe - * @classes: - * - * LOCKING: - * None (inherited from caller). - */ - - -static void generic_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, generic_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} - -/** * generic_set_mode - mode setting * @ap: interface to set up * @unused: returned device on error @@ -90,10 +61,10 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) /* We do need the right mode information for DMA or PIO and this comes from the current configuration flags */ if (dma_enabled & (1 << (5 + i))) { - dev->xfer_mode = XFER_MW_DMA_0; - dev->xfer_shift = ATA_SHIFT_MWDMA; + ata_id_to_dma_mode(dev, XFER_MW_DMA_0); dev->flags &= ~ATA_DFLAG_PIO; } else { + ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); dev->xfer_mode = XFER_PIO_0; dev->xfer_shift = ATA_SHIFT_PIO; dev->flags |= ATA_DFLAG_PIO; @@ -119,8 +90,10 @@ static struct scsi_host_template generic_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations generic_port_ops = { @@ -142,8 +115,9 @@ static struct ata_port_operations generic_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = generic_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_unknown, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -230,8 +204,10 @@ static struct pci_driver ata_generic_pci_driver = { .id_table = ata_generic, .probe = ata_generic_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init ata_generic_init(void) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 4d716c7347e..55d306a3e53 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -93,7 +93,7 @@ #include <linux/libata.h> #define DRV_NAME "ata_piix" -#define DRV_VERSION "2.00ac7" +#define DRV_VERSION "2.11" enum { PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ @@ -155,11 +155,11 @@ struct piix_host_priv { static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void piix_pata_error_handler(struct ata_port *ap); -static void ich_pata_error_handler(struct ata_port *ap); static void piix_sata_error_handler(struct ata_port *ap); static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev); +static int ich_pata_cable_detect(struct ata_port *ap); static unsigned int in_module_init = 1; @@ -169,8 +169,6 @@ static const struct pci_device_id piix_pci_tbl[] = { /* Intel PIIX4 for the 430TX/440BX/MX chipset: UDMA 33 */ /* Also PIIX4E (fn3 rev 2) and PIIX4M (fn3 rev 3) */ { 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 }, - { 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, - { 0x8086, 0x25a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, /* Intel PIIX4 */ { 0x8086, 0x7199, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 }, /* Intel PIIX4 */ @@ -255,8 +253,10 @@ static struct pci_driver piix_pci_driver = { .id_table = piix_pci_tbl, .probe = piix_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static struct scsi_host_template piix_sht = { @@ -275,8 +275,10 @@ static struct scsi_host_template piix_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static const struct ata_port_operations piix_pata_ops = { @@ -303,6 +305,7 @@ static const struct ata_port_operations piix_pata_ops = { .thaw = ata_bmdma_thaw, .error_handler = piix_pata_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -334,8 +337,9 @@ static const struct ata_port_operations ich_pata_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = ich_pata_error_handler, + .error_handler = piix_pata_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ich_pata_cable_detect, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -578,12 +582,13 @@ static const struct ich_laptop ich_laptop[] = { /* devid, subvendor, subdev */ { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */ { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ + { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ /* end marker */ { 0, } }; /** - * piix_pata_cbl_detect - Probe host controller cable detect info + * ich_pata_cable_detect - Probe host controller cable detect info * @ap: Port for which cable detect info is desired * * Read 80c cable indicator from ATA PCI device's PCI config @@ -593,23 +598,18 @@ static const struct ich_laptop ich_laptop[] = { * None (inherited from caller). */ -static void ich_pata_cbl_detect(struct ata_port *ap) +static int ich_pata_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); const struct ich_laptop *lap = &ich_laptop[0]; u8 tmp, mask; - /* no 80c support in host controller? */ - if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0) - goto cbl40; - /* Check for specials - Acer Aspire 5602WLMi */ while (lap->device) { if (lap->device == pdev->device && lap->subvendor == pdev->subsystem_vendor && lap->subdevice == pdev->subsystem_device) { - ap->cbl = ATA_CBL_PATA40_SHORT; - return; + return ATA_CBL_PATA40_SHORT; } lap++; } @@ -618,20 +618,14 @@ static void ich_pata_cbl_detect(struct ata_port *ap) mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; pci_read_config_byte(pdev, PIIX_IOCFG, &tmp); if ((tmp & mask) == 0) - goto cbl40; - - ap->cbl = ATA_CBL_PATA80; - return; - -cbl40: - ap->cbl = ATA_CBL_PATA40; + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; } /** * piix_pata_prereset - prereset for PATA host controller * @ap: Target port * - * * LOCKING: * None (inherited from caller). */ @@ -641,8 +635,6 @@ static int piix_pata_prereset(struct ata_port *ap) if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) return -ENOENT; - - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -653,35 +645,6 @@ static void piix_pata_error_handler(struct ata_port *ap) } -/** - * ich_pata_prereset - prereset for PATA host controller - * @ap: Target port - * - * - * LOCKING: - * None (inherited from caller). - */ -static int ich_pata_prereset(struct ata_port *ap) -{ - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - - if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) { - ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n"); - ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; - return 0; - } - - ich_pata_cbl_detect(ap); - - return ata_std_prereset(ap); -} - -static void ich_pata_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, ich_pata_prereset, ata_std_softreset, NULL, - ata_std_postreset); -} - static void piix_sata_error_handler(struct ata_port *ap) { ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL, diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c new file mode 100644 index 00000000000..03a0acff6cf --- /dev/null +++ b/drivers/ata/libata-acpi.c @@ -0,0 +1,709 @@ +/* + * libata-acpi.c + * Provides ACPI support for PATA/SATA. + * + * Copyright (C) 2006 Intel Corp. + * Copyright (C) 2006 Randy Dunlap + */ + +#include <linux/ata.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/acpi.h> +#include <linux/libata.h> +#include <linux/pci.h> +#include "libata.h" + +#include <acpi/acpi_bus.h> +#include <acpi/acnames.h> +#include <acpi/acnamesp.h> +#include <acpi/acparser.h> +#include <acpi/acexcep.h> +#include <acpi/acmacros.h> +#include <acpi/actypes.h> + +#define SATA_ROOT_PORT(x) (((x) >> 16) & 0xffff) +#define SATA_PORT_NUMBER(x) ((x) & 0xffff) /* or NO_PORT_MULT */ +#define NO_PORT_MULT 0xffff +#define SATA_ADR_RSVD 0xffffffff + +#define REGS_PER_GTF 7 +struct taskfile_array { + u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ +}; + +/* + * Helper - belongs in the PCI layer somewhere eventually + */ +static int is_pci_dev(struct device *dev) +{ + return (dev->bus == &pci_bus_type); +} + +/** + * sata_get_dev_handle - finds acpi_handle and PCI device.function + * @dev: device to locate + * @handle: returned acpi_handle for @dev + * @pcidevfn: return PCI device.func for @dev + * + * This function is somewhat SATA-specific. Or at least the + * PATA & SATA versions of this function are different, + * so it's not entirely generic code. + * + * Returns 0 on success, <0 on error. + */ +static int sata_get_dev_handle(struct device *dev, acpi_handle *handle, + acpi_integer *pcidevfn) +{ + struct pci_dev *pci_dev; + acpi_integer addr; + + if (!is_pci_dev(dev)) + return -ENODEV; + + pci_dev = to_pci_dev(dev); /* NOTE: PCI-specific */ + /* Please refer to the ACPI spec for the syntax of _ADR. */ + addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); + *pcidevfn = addr; + *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr); + if (!*handle) + return -ENODEV; + return 0; +} + +/** + * pata_get_dev_handle - finds acpi_handle and PCI device.function + * @dev: device to locate + * @handle: returned acpi_handle for @dev + * @pcidevfn: return PCI device.func for @dev + * + * The PATA and SATA versions of this function are different. + * + * Returns 0 on success, <0 on error. + */ +static int pata_get_dev_handle(struct device *dev, acpi_handle *handle, + acpi_integer *pcidevfn) +{ + unsigned int bus, devnum, func; + acpi_integer addr; + acpi_handle dev_handle, parent_handle; + struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER, + .pointer = NULL}; + acpi_status status; + struct acpi_device_info *dinfo = NULL; + int ret = -ENODEV; + struct pci_dev *pdev; + + if (!is_pci_dev(dev)) + return -ENODEV; + + pdev = to_pci_dev(dev); + + bus = pdev->bus->number; + devnum = PCI_SLOT(pdev->devfn); + func = PCI_FUNC(pdev->devfn); + + dev_handle = DEVICE_ACPI_HANDLE(dev); + parent_handle = DEVICE_ACPI_HANDLE(dev->parent); + + status = acpi_get_object_info(parent_handle, &buffer); + if (ACPI_FAILURE(status)) + goto err; + + dinfo = buffer.pointer; + if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && + dinfo->address == bus) { + /* ACPI spec for _ADR for PCI bus: */ + addr = (acpi_integer)(devnum << 16 | func); + *pcidevfn = addr; + *handle = dev_handle; + } else { + goto err; + } + + if (!*handle) + goto err; + ret = 0; +err: + kfree(dinfo); + return ret; +} + +struct walk_info { /* can be trimmed some */ + struct device *dev; + struct acpi_device *adev; + acpi_handle handle; + acpi_integer pcidevfn; + unsigned int drivenum; + acpi_handle obj_handle; + struct ata_port *ataport; + struct ata_device *atadev; + u32 sata_adr; + int status; + char basepath[ACPI_PATHNAME_MAX]; + int basepath_len; +}; + +static acpi_status get_devices(acpi_handle handle, + u32 level, void *context, void **return_value) +{ + acpi_status status; + struct walk_info *winfo = context; + struct acpi_buffer namebuf = {ACPI_ALLOCATE_BUFFER, NULL}; + char *pathname; + struct acpi_buffer buffer; + struct acpi_device_info *dinfo; + + status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf); + if (status) + goto ret; + pathname = namebuf.pointer; + + buffer.length = ACPI_ALLOCATE_BUFFER; + buffer.pointer = NULL; + status = acpi_get_object_info(handle, &buffer); + if (ACPI_FAILURE(status)) + goto out2; + + dinfo = buffer.pointer; + + /* find full device path name for pcidevfn */ + if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && + dinfo->address == winfo->pcidevfn) { + if (ata_msg_probe(winfo->ataport)) + ata_dev_printk(winfo->atadev, KERN_DEBUG, + ":%s: matches pcidevfn (0x%llx)\n", + pathname, winfo->pcidevfn); + strlcpy(winfo->basepath, pathname, + sizeof(winfo->basepath)); + winfo->basepath_len = strlen(pathname); + goto out; + } + + /* if basepath is not yet known, ignore this object */ + if (!winfo->basepath_len) + goto out; + + /* if this object is in scope of basepath, maybe use it */ + if (strncmp(pathname, winfo->basepath, + winfo->basepath_len) == 0) { + if (!(dinfo->valid & ACPI_VALID_ADR)) + goto out; + if (ata_msg_probe(winfo->ataport)) + ata_dev_printk(winfo->atadev, KERN_DEBUG, + "GOT ONE: (%s) root_port = 0x%llx," + " port_num = 0x%llx\n", pathname, + SATA_ROOT_PORT(dinfo->address), + SATA_PORT_NUMBER(dinfo->address)); + /* heuristics: */ + if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT) + if (ata_msg_probe(winfo->ataport)) + ata_dev_printk(winfo->atadev, + KERN_DEBUG, "warning: don't" + " know how to handle SATA port" + " multiplier\n"); + if (SATA_ROOT_PORT(dinfo->address) == + winfo->ataport->port_no && + SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) { + if (ata_msg_probe(winfo->ataport)) + ata_dev_printk(winfo->atadev, + KERN_DEBUG, + "THIS ^^^^^ is the requested" + " SATA drive (handle = 0x%p)\n", + handle); + winfo->sata_adr = dinfo->address; + winfo->obj_handle = handle; + } + } +out: + kfree(dinfo); +out2: + kfree(pathname); + +ret: + return status; +} + +/* Get the SATA drive _ADR object. */ +static int get_sata_adr(struct device *dev, acpi_handle handle, + acpi_integer pcidevfn, unsigned int drive, + struct ata_port *ap, + struct ata_device *atadev, u32 *dev_adr) +{ + acpi_status status; + struct walk_info *winfo; + int err = -ENOMEM; + + winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL); + if (!winfo) + goto out; + + winfo->dev = dev; + winfo->atadev = atadev; + winfo->ataport = ap; + if (acpi_bus_get_device(handle, &winfo->adev) < 0) + if (ata_msg_probe(ap)) + ata_dev_printk(winfo->atadev, KERN_DEBUG, + "acpi_bus_get_device failed\n"); + winfo->handle = handle; + winfo->pcidevfn = pcidevfn; + winfo->drivenum = drive; + + status = acpi_get_devices(NULL, get_devices, winfo, NULL); + if (ACPI_FAILURE(status)) { + if (ata_msg_probe(ap)) + ata_dev_printk(winfo->atadev, KERN_DEBUG, + "%s: acpi_get_devices failed\n", + __FUNCTION__); + err = -ENODEV; + } else { + *dev_adr = winfo->sata_adr; + atadev->obj_handle = winfo->obj_handle; + err = 0; + } + kfree(winfo); +out: + return err; +} + +/** + * do_drive_get_GTF - get the drive bootup default taskfile settings + * @ap: the ata_port for the drive + * @ix: target ata_device (drive) index + * @gtf_length: number of bytes of _GTF data returned at @gtf_address + * @gtf_address: buffer containing _GTF taskfile arrays + * + * This applies to both PATA and SATA drives. + * + * The _GTF method has no input parameters. + * It returns a variable number of register set values (registers + * hex 1F1..1F7, taskfiles). + * The <variable number> is not known in advance, so have ACPI-CA + * allocate the buffer as needed and return it, then free it later. + * + * The returned @gtf_length and @gtf_address are only valid if the + * function return value is 0. + */ +static int do_drive_get_GTF(struct ata_port *ap, int ix, + unsigned int *gtf_length, unsigned long *gtf_address, + unsigned long *obj_loc) +{ + acpi_status status; + acpi_handle dev_handle = NULL; + acpi_handle chan_handle, drive_handle; + acpi_integer pcidevfn = 0; + u32 dev_adr; + struct acpi_buffer output; + union acpi_object *out_obj; + struct device *dev = ap->host->dev; + struct ata_device *atadev = &ap->device[ix]; + int err = -ENODEV; + + *gtf_length = 0; + *gtf_address = 0UL; + *obj_loc = 0UL; + + if (libata_noacpi) + return 0; + + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n", + __FUNCTION__, ap->port_no); + + if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, "%s: ERR: " + "ata_dev_present: %d, PORT_DISABLED: %lu\n", + __FUNCTION__, ata_dev_enabled(atadev), + ap->flags & ATA_FLAG_DISABLED); + goto out; + } + + /* Don't continue if device has no _ADR method. + * _GTF is intended for known motherboard devices. */ + if (!(ap->cbl == ATA_CBL_SATA)) { + err = pata_get_dev_handle(dev, &dev_handle, &pcidevfn); + if (err < 0) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, + "%s: pata_get_dev_handle failed (%d)\n", + __FUNCTION__, err); + goto out; + } + } else { + err = sata_get_dev_handle(dev, &dev_handle, &pcidevfn); + if (err < 0) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, + "%s: sata_get_dev_handle failed (%d\n", + __FUNCTION__, err); + goto out; + } + } + + /* Get this drive's _ADR info. if not already known. */ + if (!atadev->obj_handle) { + if (!(ap->cbl == ATA_CBL_SATA)) { + /* get child objects of dev_handle == channel objects, + * + _their_ children == drive objects */ + /* channel is ap->port_no */ + chan_handle = acpi_get_child(dev_handle, + ap->port_no); + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, + "%s: chan adr=%d: chan_handle=0x%p\n", + __FUNCTION__, ap->port_no, + chan_handle); + if (!chan_handle) { + err = -ENODEV; + goto out; + } + /* TBD: could also check ACPI object VALID bits */ + drive_handle = acpi_get_child(chan_handle, ix); + if (!drive_handle) { + err = -ENODEV; + goto out; + } + dev_adr = ix; + atadev->obj_handle = drive_handle; + } else { /* for SATA mode */ + dev_adr = SATA_ADR_RSVD; + err = get_sata_adr(dev, dev_handle, pcidevfn, 0, + ap, atadev, &dev_adr); + } + if (err < 0 || dev_adr == SATA_ADR_RSVD || + !atadev->obj_handle) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, + "%s: get_sata/pata_adr failed: " + "err=%d, dev_adr=%u, obj_handle=0x%p\n", + __FUNCTION__, err, dev_adr, + atadev->obj_handle); + goto out; + } + } + + /* Setting up output buffer */ + output.length = ACPI_ALLOCATE_BUFFER; + output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ + + /* _GTF has no input parameters */ + err = -EIO; + status = acpi_evaluate_object(atadev->obj_handle, "_GTF", + NULL, &output); + if (ACPI_FAILURE(status)) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, + "%s: Run _GTF error: status = 0x%x\n", + __FUNCTION__, status); + goto out; + } + + if (!output.length || !output.pointer) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: " + "length or ptr is NULL (0x%llx, 0x%p)\n", + __FUNCTION__, + (unsigned long long)output.length, + output.pointer); + kfree(output.pointer); + goto out; + } + + out_obj = output.pointer; + if (out_obj->type != ACPI_TYPE_BUFFER) { + kfree(output.pointer); + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: " + "error: expected object type of " + " ACPI_TYPE_BUFFER, got 0x%x\n", + __FUNCTION__, out_obj->type); + err = -ENOENT; + goto out; + } + + if (!out_obj->buffer.length || !out_obj->buffer.pointer || + out_obj->buffer.length % REGS_PER_GTF) { + if (ata_msg_drv(ap)) + ata_dev_printk(atadev, KERN_ERR, + "%s: unexpected GTF length (%d) or addr (0x%p)\n", + __FUNCTION__, out_obj->buffer.length, + out_obj->buffer.pointer); + err = -ENOENT; + goto out; + } + + *gtf_length = out_obj->buffer.length; + *gtf_address = (unsigned long)out_obj->buffer.pointer; + *obj_loc = (unsigned long)out_obj; + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, "%s: returning " + "gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n", + __FUNCTION__, *gtf_length, *gtf_address, *obj_loc); + err = 0; +out: + return err; +} + +/** + * taskfile_load_raw - send taskfile registers to host controller + * @ap: Port to which output is sent + * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) + * + * Outputs ATA taskfile to standard ATA host controller using MMIO + * or PIO as indicated by the ATA_FLAG_MMIO flag. + * Writes the control, feature, nsect, lbal, lbam, and lbah registers. + * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, + * hob_lbal, hob_lbam, and hob_lbah. + * + * This function waits for idle (!BUSY and !DRQ) after writing + * registers. If the control register has a new value, this + * function also waits for idle after writing control and before + * writing the remaining registers. + * + * LOCKING: TBD: + * Inherited from caller. + */ +static void taskfile_load_raw(struct ata_port *ap, + struct ata_device *atadev, + const struct taskfile_array *gtf) +{ + struct ata_taskfile tf; + unsigned int err; + + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: " + "%02x %02x %02x %02x %02x %02x %02x\n", + __FUNCTION__, + gtf->tfa[0], gtf->tfa[1], gtf->tfa[2], + gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]); + + if ((gtf->tfa[0] == 0) && (gtf->tfa[1] == 0) && (gtf->tfa[2] == 0) + && (gtf->tfa[3] == 0) && (gtf->tfa[4] == 0) && (gtf->tfa[5] == 0) + && (gtf->tfa[6] == 0)) + return; + + ata_tf_init(atadev, &tf); + + /* convert gtf to tf */ + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */ + tf.protocol = atadev->class == ATA_DEV_ATAPI ? + ATA_PROT_ATAPI_NODATA : ATA_PROT_NODATA; + tf.feature = gtf->tfa[0]; /* 0x1f1 */ + tf.nsect = gtf->tfa[1]; /* 0x1f2 */ + tf.lbal = gtf->tfa[2]; /* 0x1f3 */ + tf.lbam = gtf->tfa[3]; /* 0x1f4 */ + tf.lbah = gtf->tfa[4]; /* 0x1f5 */ + tf.device = gtf->tfa[5]; /* 0x1f6 */ + tf.command = gtf->tfa[6]; /* 0x1f7 */ + + err = ata_exec_internal(atadev, &tf, NULL, DMA_NONE, NULL, 0); + if (err && ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_ERR, + "%s: ata_exec_internal failed: %u\n", + __FUNCTION__, err); +} + +/** + * do_drive_set_taskfiles - write the drive taskfile settings from _GTF + * @ap: the ata_port for the drive + * @atadev: target ata_device + * @gtf_length: total number of bytes of _GTF taskfiles + * @gtf_address: location of _GTF taskfile arrays + * + * This applies to both PATA and SATA drives. + * + * Write {gtf_address, length gtf_length} in groups of + * REGS_PER_GTF bytes. + */ +static int do_drive_set_taskfiles(struct ata_port *ap, + struct ata_device *atadev, unsigned int gtf_length, + unsigned long gtf_address) +{ + int err = -ENODEV; + int gtf_count = gtf_length / REGS_PER_GTF; + int ix; + struct taskfile_array *gtf; + + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n", + __FUNCTION__, ap->port_no); + + if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA)) + return 0; + + if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) + goto out; + if (!gtf_count) /* shouldn't be here */ + goto out; + + if (gtf_length % REGS_PER_GTF) { + if (ata_msg_drv(ap)) + ata_dev_printk(atadev, KERN_ERR, + "%s: unexpected GTF length (%d)\n", + __FUNCTION__, gtf_length); + goto out; + } + + for (ix = 0; ix < gtf_count; ix++) { + gtf = (struct taskfile_array *) + (gtf_address + ix * REGS_PER_GTF); + + /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ + taskfile_load_raw(ap, atadev, gtf); + } + + err = 0; +out: + return err; +} + +/** + * ata_acpi_exec_tfs - get then write drive taskfile settings + * @ap: the ata_port for the drive + * + * This applies to both PATA and SATA drives. + */ +int ata_acpi_exec_tfs(struct ata_port *ap) +{ + int ix; + int ret =0; + unsigned int gtf_length; + unsigned long gtf_address; + unsigned long obj_loc; + + if (libata_noacpi) + return 0; + /* + * TBD - implement PATA support. For now, + * we should not run GTF on PATA devices since some + * PATA require execution of GTM/STM before GTF. + */ + if (!(ap->cbl == ATA_CBL_SATA)) + return 0; + + for (ix = 0; ix < ATA_MAX_DEVICES; ix++) { + if (!ata_dev_enabled(&ap->device[ix])) + continue; + + ret = do_drive_get_GTF(ap, ix, + >f_length, >f_address, &obj_loc); + if (ret < 0) { + if (ata_msg_probe(ap)) + ata_port_printk(ap, KERN_DEBUG, + "%s: get_GTF error (%d)\n", + __FUNCTION__, ret); + break; + } + + ret = do_drive_set_taskfiles(ap, &ap->device[ix], + gtf_length, gtf_address); + kfree((void *)obj_loc); + if (ret < 0) { + if (ata_msg_probe(ap)) + ata_port_printk(ap, KERN_DEBUG, + "%s: set_taskfiles error (%d)\n", + __FUNCTION__, ret); + break; + } + } + + return ret; +} + +/** + * ata_acpi_push_id - send Identify data to drive + * @ap: the ata_port for the drive + * @ix: drive index + * + * _SDD ACPI object: for SATA mode only + * Must be after Identify (Packet) Device -- uses its data + * ATM this function never returns a failure. It is an optional + * method and if it fails for whatever reason, we should still + * just keep going. + */ +int ata_acpi_push_id(struct ata_port *ap, unsigned int ix) +{ + acpi_handle handle; + acpi_integer pcidevfn; + int err; + struct device *dev = ap->host->dev; + struct ata_device *atadev = &ap->device[ix]; + u32 dev_adr; + acpi_status status; + struct acpi_object_list input; + union acpi_object in_params[1]; + + if (libata_noacpi) + return 0; + + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, "%s: ix = %d, port#: %d\n", + __FUNCTION__, ix, ap->port_no); + + /* Don't continue if not a SATA device. */ + if (!(ap->cbl == ATA_CBL_SATA)) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, + "%s: Not a SATA device\n", __FUNCTION__); + goto out; + } + + /* Don't continue if device has no _ADR method. + * _SDD is intended for known motherboard devices. */ + err = sata_get_dev_handle(dev, &handle, &pcidevfn); + if (err < 0) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, + "%s: sata_get_dev_handle failed (%d\n", + __FUNCTION__, err); + goto out; + } + + /* Get this drive's _ADR info, if not already known */ + if (!atadev->obj_handle) { + dev_adr = SATA_ADR_RSVD; + err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev, + &dev_adr); + if (err < 0 || dev_adr == SATA_ADR_RSVD || + !atadev->obj_handle) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, + "%s: get_sata_adr failed: " + "err=%d, dev_adr=%u, obj_handle=0x%p\n", + __FUNCTION__, err, dev_adr, + atadev->obj_handle); + goto out; + } + } + + /* Give the drive Identify data to the drive via the _SDD method */ + /* _SDD: set up input parameters */ + input.count = 1; + input.pointer = in_params; + in_params[0].type = ACPI_TYPE_BUFFER; + in_params[0].buffer.length = sizeof(atadev->id[0]) * ATA_ID_WORDS; + in_params[0].buffer.pointer = (u8 *)atadev->id; + /* Output buffer: _SDD has no output */ + + /* It's OK for _SDD to be missing too. */ + swap_buf_le16(atadev->id, ATA_ID_WORDS); + status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL); + swap_buf_le16(atadev->id, ATA_ID_WORDS); + + err = ACPI_FAILURE(status) ? -EIO : 0; + if (err < 0) { + if (ata_msg_probe(ap)) + ata_dev_printk(atadev, KERN_DEBUG, + "%s _SDD error: status = 0x%x\n", + __FUNCTION__, status); + } + + /* always return success */ +out: + return 0; +} + + diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2cf8251728d..ca67484af1e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -59,7 +59,7 @@ #include "libata.h" -#define DRV_VERSION "2.10" /* must be exactly four chars */ +#define DRV_VERSION "2.20" /* must be exactly four chars */ /* debounce timing parameters in msecs { interval, duration, timeout } */ @@ -72,7 +72,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, static unsigned int ata_dev_set_xfermode(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev); -static unsigned int ata_unique_id = 1; +unsigned int ata_print_id = 1; static struct workqueue_struct *ata_wq; struct workqueue_struct *ata_aux_wq; @@ -89,10 +89,18 @@ int libata_fua = 0; module_param_named(fua, libata_fua, int, 0444); MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); +static int ata_ignore_hpa = 0; +module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644); +MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)"); + static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ; module_param(ata_probe_timeout, int, 0444); MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); +int libata_noacpi = 1; +module_param_named(noacpi, libata_noacpi, int, 0444); +MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set"); + MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); @@ -311,9 +319,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf->flags |= tf_flags; - if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | - ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ && - likely(tag != ATA_TAG_INTERNAL)) { + if (ata_ncq_enabled(dev) && likely(tag != ATA_TAG_INTERNAL)) { /* yay, NCQ */ if (!lba_48_ok(block, n_block)) return -ERANGE; @@ -596,6 +602,8 @@ void ata_dev_disable(struct ata_device *dev) { if (ata_dev_enabled(dev) && ata_msg_drv(dev->ap)) { ata_dev_printk(dev, KERN_WARNING, "disabled\n"); + ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | + ATA_DNXFER_QUIET); dev->class++; } } @@ -704,7 +712,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) * Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE. */ -static unsigned int +unsigned int ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err) { struct ata_taskfile tf; @@ -804,6 +812,205 @@ void ata_id_c_string(const u16 *id, unsigned char *s, *p = '\0'; } +static u64 ata_tf_to_lba48(struct ata_taskfile *tf) +{ + u64 sectors = 0; + + sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40; + sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32; + sectors |= (tf->hob_lbal & 0xff) << 24; + sectors |= (tf->lbah & 0xff) << 16; + sectors |= (tf->lbam & 0xff) << 8; + sectors |= (tf->lbal & 0xff); + + return ++sectors; +} + +static u64 ata_tf_to_lba(struct ata_taskfile *tf) +{ + u64 sectors = 0; + + sectors |= (tf->device & 0x0f) << 24; + sectors |= (tf->lbah & 0xff) << 16; + sectors |= (tf->lbam & 0xff) << 8; + sectors |= (tf->lbal & 0xff); + + return ++sectors; +} + +/** + * ata_read_native_max_address_ext - LBA48 native max query + * @dev: Device to query + * + * Perform an LBA48 size query upon the device in question. Return the + * actual LBA48 size or zero if the command fails. + */ + +static u64 ata_read_native_max_address_ext(struct ata_device *dev) +{ + unsigned int err; + struct ata_taskfile tf; + + ata_tf_init(dev, &tf); + + tf.command = ATA_CMD_READ_NATIVE_MAX_EXT; + tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR; + tf.protocol |= ATA_PROT_NODATA; + tf.device |= 0x40; + + err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); + if (err) + return 0; + + return ata_tf_to_lba48(&tf); +} + +/** + * ata_read_native_max_address - LBA28 native max query + * @dev: Device to query + * + * Performa an LBA28 size query upon the device in question. Return the + * actual LBA28 size or zero if the command fails. + */ + +static u64 ata_read_native_max_address(struct ata_device *dev) +{ + unsigned int err; + struct ata_taskfile tf; + + ata_tf_init(dev, &tf); + + tf.command = ATA_CMD_READ_NATIVE_MAX; + tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; + tf.protocol |= ATA_PROT_NODATA; + tf.device |= 0x40; + + err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); + if (err) + return 0; + + return ata_tf_to_lba(&tf); +} + +/** + * ata_set_native_max_address_ext - LBA48 native max set + * @dev: Device to query + * + * Perform an LBA48 size set max upon the device in question. Return the + * actual LBA48 size or zero if the command fails. + */ + +static u64 ata_set_native_max_address_ext(struct ata_device *dev, u64 new_sectors) +{ + unsigned int err; + struct ata_taskfile tf; + + new_sectors--; + + ata_tf_init(dev, &tf); + + tf.command = ATA_CMD_SET_MAX_EXT; + tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR; + tf.protocol |= ATA_PROT_NODATA; + tf.device |= 0x40; + + tf.lbal = (new_sectors >> 0) & 0xff; + tf.lbam = (new_sectors >> 8) & 0xff; + tf.lbah = (new_sectors >> 16) & 0xff; + + tf.hob_lbal = (new_sectors >> 24) & 0xff; + tf.hob_lbam = (new_sectors >> 32) & 0xff; + tf.hob_lbah = (new_sectors >> 40) & 0xff; + + err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); + if (err) + return 0; + + return ata_tf_to_lba48(&tf); +} + +/** + * ata_set_native_max_address - LBA28 native max set + * @dev: Device to query + * + * Perform an LBA28 size set max upon the device in question. Return the + * actual LBA28 size or zero if the command fails. + */ + +static u64 ata_set_native_max_address(struct ata_device *dev, u64 new_sectors) +{ + unsigned int err; + struct ata_taskfile tf; + + new_sectors--; + + ata_tf_init(dev, &tf); + + tf.command = ATA_CMD_SET_MAX; + tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; + tf.protocol |= ATA_PROT_NODATA; + + tf.lbal = (new_sectors >> 0) & 0xff; + tf.lbam = (new_sectors >> 8) & 0xff; + tf.lbah = (new_sectors >> 16) & 0xff; + tf.device |= ((new_sectors >> 24) & 0x0f) | 0x40; + + err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); + if (err) + return 0; + + return ata_tf_to_lba(&tf); +} + +/** + * ata_hpa_resize - Resize a device with an HPA set + * @dev: Device to resize + * + * Read the size of an LBA28 or LBA48 disk with HPA features and resize + * it if required to the full size of the media. The caller must check + * the drive has the HPA feature set enabled. + */ + +static u64 ata_hpa_resize(struct ata_device *dev) +{ + u64 sectors = dev->n_sectors; + u64 hpa_sectors; + + if (ata_id_has_lba48(dev->id)) + hpa_sectors = ata_read_native_max_address_ext(dev); + else + hpa_sectors = ata_read_native_max_address(dev); + + /* if no hpa, both should be equal */ + ata_dev_printk(dev, KERN_INFO, "%s 1: sectors = %lld, " + "hpa_sectors = %lld\n", + __FUNCTION__, (long long)sectors, (long long)hpa_sectors); + + if (hpa_sectors > sectors) { + ata_dev_printk(dev, KERN_INFO, + "Host Protected Area detected:\n" + "\tcurrent size: %lld sectors\n" + "\tnative size: %lld sectors\n", + (long long)sectors, (long long)hpa_sectors); + + if (ata_ignore_hpa) { + if (ata_id_has_lba48(dev->id)) + hpa_sectors = ata_set_native_max_address_ext(dev, hpa_sectors); + else + hpa_sectors = ata_set_native_max_address(dev, + hpa_sectors); + + if (hpa_sectors) { + ata_dev_printk(dev, KERN_INFO, "native size " + "increased to %lld sectors\n", + (long long)hpa_sectors); + return hpa_sectors; + } + } + } + return sectors; +} + static u64 ata_id_n_sectors(const u16 *id) { if (ata_id_has_lba(id)) { @@ -820,6 +1027,48 @@ static u64 ata_id_n_sectors(const u16 *id) } /** + * ata_id_to_dma_mode - Identify DMA mode from id block + * @dev: device to identify + * @unknown: mode to assume if we cannot tell + * + * Set up the timing values for the device based upon the identify + * reported values for the DMA mode. This function is used by drivers + * which rely upon firmware configured modes, but wish to report the + * mode correctly when possible. + * + * In addition we emit similarly formatted messages to the default + * ata_dev_set_mode handler, in order to provide consistency of + * presentation. + */ + +void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown) +{ + unsigned int mask; + u8 mode; + + /* Pack the DMA modes */ + mask = ((dev->id[63] >> 8) << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA; + if (dev->id[53] & 0x04) + mask |= ((dev->id[88] >> 8) << ATA_SHIFT_UDMA) & ATA_MASK_UDMA; + + /* Select the mode in use */ + mode = ata_xfer_mask2mode(mask); + + if (mode != 0) { + ata_dev_printk(dev, KERN_INFO, "configured for %s\n", + ata_mode_string(mask)); + } else { + /* SWDMA perhaps ? */ + mode = unknown; + ata_dev_printk(dev, KERN_INFO, "configured for DMA\n"); + } + + /* Configure the device reporting */ + dev->xfer_mode = mode; + dev->xfer_shift = ata_xfer_mode2shift(mode); +} + +/** * ata_noop_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate * @device: ATA device (numbered from zero) to select @@ -887,8 +1136,8 @@ void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep) { if (ata_msg_probe(ap)) - ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, ata%u: " - "device %u, wait %u\n", ap->id, device, wait); + ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, " + "device %u, wait %u\n", device, wait); if (wait) ata_wait_idle(ap); @@ -1224,12 +1473,16 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, if (ap->ops->post_internal_cmd) ap->ops->post_internal_cmd(qc); - if ((qc->flags & ATA_QCFLAG_FAILED) && !qc->err_mask) { - if (ata_msg_warn(ap)) - ata_dev_printk(dev, KERN_WARNING, - "zero err_mask for failed " - "internal command, assuming AC_ERR_OTHER\n"); - qc->err_mask |= AC_ERR_OTHER; + /* perform minimal error analysis */ + if (qc->flags & ATA_QCFLAG_FAILED) { + if (qc->result_tf.command & (ATA_ERR | ATA_DF)) + qc->err_mask |= AC_ERR_DEV; + + if (!qc->err_mask) + qc->err_mask |= AC_ERR_OTHER; + + if (qc->err_mask & ~AC_ERR_OTHER) + qc->err_mask &= ~AC_ERR_OTHER; } /* finish up */ @@ -1333,30 +1586,44 @@ unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd) * Check if the current speed of the device requires IORDY. Used * by various controllers for chip configuration. */ - + unsigned int ata_pio_need_iordy(const struct ata_device *adev) { - int pio; - int speed = adev->pio_mode - XFER_PIO_0; - - if (speed < 2) + /* Controller doesn't support IORDY. Probably a pointless check + as the caller should know this */ + if (adev->ap->flags & ATA_FLAG_NO_IORDY) return 0; - if (speed > 2) + /* PIO3 and higher it is mandatory */ + if (adev->pio_mode > XFER_PIO_2) + return 1; + /* We turn it on when possible */ + if (ata_id_has_iordy(adev->id)) return 1; + return 0; +} +/** + * ata_pio_mask_no_iordy - Return the non IORDY mask + * @adev: ATA device + * + * Compute the highest mode possible if we are not using iordy. Return + * -1 if no iordy mode is available. + */ + +static u32 ata_pio_mask_no_iordy(const struct ata_device *adev) +{ /* If we have no drive specific rule, then PIO 2 is non IORDY */ - if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE */ - pio = adev->id[ATA_ID_EIDE_PIO]; + u16 pio = adev->id[ATA_ID_EIDE_PIO]; /* Is the speed faster than the drive allows non IORDY ? */ if (pio) { /* This is cycle times not frequency - watch the logic! */ if (pio > 240) /* PIO2 is 240nS per cycle */ - return 1; - return 0; + return 3 << ATA_SHIFT_PIO; + return 7 << ATA_SHIFT_PIO; } } - return 0; + return 3 << ATA_SHIFT_PIO; } /** @@ -1385,14 +1652,13 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, struct ata_taskfile tf; unsigned int err_mask = 0; const char *reason; + int tried_spinup = 0; int rc; if (ata_msg_ctl(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", - __FUNCTION__, ap->id, dev->devno); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ - retry: ata_tf_init(dev, &tf); @@ -1426,7 +1692,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, if (err_mask) { if (err_mask & AC_ERR_NODEV_HINT) { DPRINTK("ata%u.%d: NODEV after polling detection\n", - ap->id, dev->devno); + ap->print_id, dev->devno); return -ENOENT; } @@ -1449,6 +1715,32 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, goto err_out; } + if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) { + tried_spinup = 1; + /* + * Drive powered-up in standby mode, and requires a specific + * SET_FEATURES spin-up subcommand before it will accept + * anything other than the original IDENTIFY command. + */ + ata_tf_init(dev, &tf); + tf.command = ATA_CMD_SET_FEATURES; + tf.feature = SETFEATURES_SPINUP; + tf.protocol = ATA_PROT_NODATA; + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); + if (err_mask) { + rc = -EIO; + reason = "SPINUP failed"; + goto err_out; + } + /* + * If the drive initially returned incomplete IDENTIFY info, + * we now must reissue the IDENTIFY command. + */ + if (id[2] == 0x37c8) + goto retry; + } + if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) { /* * The exact sequence expected by certain pre-ATA4 drives is: @@ -1515,20 +1807,6 @@ static void ata_dev_config_ncq(struct ata_device *dev, snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth); } -static void ata_set_port_max_cmd_len(struct ata_port *ap) -{ - int i; - - if (ap->scsi_host) { - unsigned int len = 0; - - for (i = 0; i < ATA_MAX_DEVICES; i++) - len = max(len, ap->device[i].cdb_len); - - ap->scsi_host->max_cmd_len = len; - } -} - /** * ata_dev_configure - Configure the specified ATA/ATAPI device * @dev: Target device to configure @@ -1554,15 +1832,23 @@ int ata_dev_configure(struct ata_device *dev) int rc; if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { - ata_dev_printk(dev, KERN_INFO, - "%s: ENTER/EXIT (host %u, dev %u) -- nodev\n", - __FUNCTION__, ap->id, dev->devno); + ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n", + __FUNCTION__); return 0; } if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", - __FUNCTION__, ap->id, dev->devno); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); + + /* set _SDD */ + rc = ata_acpi_push_id(ap, dev->devno); + if (rc) { + ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n", + rc); + } + + /* retrieve and execute the ATA task file of _GTF */ + ata_acpi_exec_tfs(ap); /* print device capabilities */ if (ata_msg_probe(ap)) @@ -1596,14 +1882,16 @@ int ata_dev_configure(struct ata_device *dev) if (dev->class == ATA_DEV_ATA) { if (ata_id_is_cfa(id)) { if (id[162] & 1) /* CPRM may make this media unusable */ - ata_dev_printk(dev, KERN_WARNING, "ata%u: device %u supports DRM functions and may not be fully accessable.\n", - ap->id, dev->devno); + ata_dev_printk(dev, KERN_WARNING, + "supports DRM functions and may " + "not be fully accessable.\n"); snprintf(revbuf, 7, "CFA"); } else snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); dev->n_sectors = ata_id_n_sectors(id); + dev->n_sectors_boot = dev->n_sectors; /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */ ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV, @@ -1630,6 +1918,9 @@ int ata_dev_configure(struct ata_device *dev) dev->flags |= ATA_DFLAG_FLUSH_EXT; } + if (ata_id_hpa_enabled(dev->id)) + dev->n_sectors = ata_hpa_resize(dev); + /* config NCQ */ ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc)); @@ -1665,7 +1956,7 @@ int ata_dev_configure(struct ata_device *dev) "%s: %s, %s, max %s\n", revbuf, modelbuf, fwrevbuf, ata_mode_string(xfer_mask)); - ata_dev_printk(dev, KERN_INFO, + ata_dev_printk(dev, KERN_INFO, "%Lu sectors, multi %u, CHS %u/%u/%u\n", (unsigned long long)dev->n_sectors, dev->multi_count, dev->cylinders, @@ -1719,8 +2010,6 @@ int ata_dev_configure(struct ata_device *dev) } } - ata_set_port_max_cmd_len(ap); - /* limit bridge transfers to udma5, 200 sectors */ if (ata_dev_knobble(dev)) { if (ata_msg_drv(ap) && print_info) @@ -1730,8 +2019,16 @@ int ata_dev_configure(struct ata_device *dev) dev->max_sectors = ATA_MAX_SECTORS; } + if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128) + dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, + dev->max_sectors); + + /* limit ATAPI DMA to R/W commands only */ + if (ata_device_blacklisted(dev) & ATA_HORKAGE_DMA_RW_ONLY) + dev->horkage |= ATA_HORKAGE_DMA_RW_ONLY; + if (ap->ops->dev_config) - ap->ops->dev_config(ap, dev); + ap->ops->dev_config(dev); if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", @@ -1746,6 +2043,56 @@ err_out_nosup: } /** + * ata_cable_40wire - return 40 wire cable type + * @ap: port + * + * Helper method for drivers which want to hardwire 40 wire cable + * detection. + */ + +int ata_cable_40wire(struct ata_port *ap) +{ + return ATA_CBL_PATA40; +} + +/** + * ata_cable_80wire - return 80 wire cable type + * @ap: port + * + * Helper method for drivers which want to hardwire 80 wire cable + * detection. + */ + +int ata_cable_80wire(struct ata_port *ap) +{ + return ATA_CBL_PATA80; +} + +/** + * ata_cable_unknown - return unknown PATA cable. + * @ap: port + * + * Helper method for drivers which have no PATA cable detection. + */ + +int ata_cable_unknown(struct ata_port *ap) +{ + return ATA_CBL_PATA_UNK; +} + +/** + * ata_cable_sata - return SATA cable type + * @ap: port + * + * Helper method for drivers which have SATA cables + */ + +int ata_cable_sata(struct ata_port *ap) +{ + return ATA_CBL_SATA; +} + +/** * ata_bus_probe - Reset and probe ATA bus * @ap: Bus to probe * @@ -1764,7 +2111,7 @@ int ata_bus_probe(struct ata_port *ap) { unsigned int classes[ATA_MAX_DEVICES]; int tries[ATA_MAX_DEVICES]; - int i, rc, down_xfermask; + int i, rc; struct ata_device *dev; ata_port_probe(ap); @@ -1773,8 +2120,6 @@ int ata_bus_probe(struct ata_port *ap) tries[i] = ATA_PROBE_MAX_TRIES; retry: - down_xfermask = 0; - /* reset and determine device classes */ ap->ops->phy_reset(ap); @@ -1798,8 +2143,11 @@ int ata_bus_probe(struct ata_port *ap) for (i = 0; i < ATA_MAX_DEVICES; i++) ap->device[i].pio_mode = XFER_PIO_0; - /* read IDENTIFY page and configure devices */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { + /* read IDENTIFY page and configure devices. We have to do the identify + specific sequence bass-ackwards so that PDIAG- is released by + the slave device */ + + for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) { dev = &ap->device[i]; if (tries[i]) @@ -1812,6 +2160,19 @@ int ata_bus_probe(struct ata_port *ap) dev->id); if (rc) goto fail; + } + + /* Now ask for the cable type as PDIAG- should have been released */ + if (ap->ops->cable_detect) + ap->cbl = ap->ops->cable_detect(ap); + + /* After the identify sequence we can now set up the devices. We do + this in the normal order so that the user doesn't get confused */ + + for(i = 0; i < ATA_MAX_DEVICES; i++) { + dev = &ap->device[i]; + if (!ata_dev_enabled(dev)) + continue; ap->eh_context.i.flags |= ATA_EHI_PRINTINFO; rc = ata_dev_configure(dev); @@ -1822,10 +2183,8 @@ int ata_bus_probe(struct ata_port *ap) /* configure transfer mode */ rc = ata_set_mode(ap, &dev); - if (rc) { - down_xfermask = 1; + if (rc) goto fail; - } for (i = 0; i < ATA_MAX_DEVICES; i++) if (ata_dev_enabled(&ap->device[i])) @@ -1837,25 +2196,29 @@ int ata_bus_probe(struct ata_port *ap) return -ENODEV; fail: + tries[dev->devno]--; + switch (rc) { case -EINVAL: - case -ENODEV: + /* eeek, something went very wrong, give up */ tries[dev->devno] = 0; break; + + case -ENODEV: + /* give it just one more chance */ + tries[dev->devno] = min(tries[dev->devno], 1); case -EIO: - sata_down_spd_limit(ap); - /* fall through */ - default: - tries[dev->devno]--; - if (down_xfermask && - ata_down_xfermask_limit(dev, tries[dev->devno] == 1)) - tries[dev->devno] = 0; + if (tries[dev->devno] == 1) { + /* This is the last chance, better to slow + * down than lose it. + */ + sata_down_spd_limit(ap); + ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); + } } - if (!tries[dev->devno]) { - ata_down_xfermask_limit(dev, 1); + if (!tries[dev->devno]) ata_dev_disable(dev); - } goto retry; } @@ -1885,7 +2248,7 @@ void ata_port_probe(struct ata_port *ap) * LOCKING: * None. */ -static void sata_print_link_status(struct ata_port *ap) +void sata_print_link_status(struct ata_port *ap) { u32 sstatus, scontrol, tmp; @@ -2279,6 +2642,12 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, t->active += (t->cycle - (t->active + t->recover)) / 2; t->recover = t->cycle - t->active; } + + /* In a few cases quantisation may produce enough errors to + leave t->cycle too low for the sum of active and recovery + if so we must correct this */ + if (t->active + t->recover > t->cycle) + t->cycle = t->active + t->recover; return 0; } @@ -2286,7 +2655,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, /** * ata_down_xfermask_limit - adjust dev xfer masks downward * @dev: Device to adjust xfer masks - * @force_pio0: Force PIO0 + * @sel: ATA_DNXFER_* selector * * Adjust xfer masks of @dev downward. Note that this function * does not apply the change. Invoking ata_set_mode() afterwards @@ -2298,37 +2667,78 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, * RETURNS: * 0 on success, negative errno on failure */ -int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0) +int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel) { - unsigned long xfer_mask; - int highbit; + char buf[32]; + unsigned int orig_mask, xfer_mask; + unsigned int pio_mask, mwdma_mask, udma_mask; + int quiet, highbit; - xfer_mask = ata_pack_xfermask(dev->pio_mask, dev->mwdma_mask, - dev->udma_mask); + quiet = !!(sel & ATA_DNXFER_QUIET); + sel &= ~ATA_DNXFER_QUIET; - if (!xfer_mask) - goto fail; - /* don't gear down to MWDMA from UDMA, go directly to PIO */ - if (xfer_mask & ATA_MASK_UDMA) - xfer_mask &= ~ATA_MASK_MWDMA; + xfer_mask = orig_mask = ata_pack_xfermask(dev->pio_mask, + dev->mwdma_mask, + dev->udma_mask); + ata_unpack_xfermask(xfer_mask, &pio_mask, &mwdma_mask, &udma_mask); - highbit = fls(xfer_mask) - 1; - xfer_mask &= ~(1 << highbit); - if (force_pio0) - xfer_mask &= 1 << ATA_SHIFT_PIO; - if (!xfer_mask) - goto fail; + switch (sel) { + case ATA_DNXFER_PIO: + highbit = fls(pio_mask) - 1; + pio_mask &= ~(1 << highbit); + break; + + case ATA_DNXFER_DMA: + if (udma_mask) { + highbit = fls(udma_mask) - 1; + udma_mask &= ~(1 << highbit); + if (!udma_mask) + return -ENOENT; + } else if (mwdma_mask) { + highbit = fls(mwdma_mask) - 1; + mwdma_mask &= ~(1 << highbit); + if (!mwdma_mask) + return -ENOENT; + } + break; + + case ATA_DNXFER_40C: + udma_mask &= ATA_UDMA_MASK_40C; + break; + + case ATA_DNXFER_FORCE_PIO0: + pio_mask &= 1; + case ATA_DNXFER_FORCE_PIO: + mwdma_mask = 0; + udma_mask = 0; + break; + + default: + BUG(); + } + + xfer_mask &= ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask); + + if (!(xfer_mask & ATA_MASK_PIO) || xfer_mask == orig_mask) + return -ENOENT; + + if (!quiet) { + if (xfer_mask & (ATA_MASK_MWDMA | ATA_MASK_UDMA)) + snprintf(buf, sizeof(buf), "%s:%s", + ata_mode_string(xfer_mask), + ata_mode_string(xfer_mask & ATA_MASK_PIO)); + else + snprintf(buf, sizeof(buf), "%s", + ata_mode_string(xfer_mask)); + + ata_dev_printk(dev, KERN_WARNING, + "limiting speed to %s\n", buf); + } ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, &dev->udma_mask); - ata_dev_printk(dev, KERN_WARNING, "limiting speed to %s\n", - ata_mode_string(xfer_mask)); - return 0; - - fail: - return -EINVAL; } static int ata_dev_set_mode(struct ata_device *dev) @@ -2367,12 +2777,13 @@ static int ata_dev_set_mode(struct ata_device *dev) } /** - * ata_set_mode - Program timings and issue SET FEATURES - XFER + * ata_do_set_mode - Program timings and issue SET FEATURES - XFER * @ap: port on which timings will be programmed * @r_failed_dev: out paramter for failed device * - * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If - * ata_set_mode() fails, pointer to the failing device is + * Standard implementation of the function used to tune and set + * ATA device disk transfer mode (PIO3, UDMA6, etc.). If + * ata_dev_set_mode() fails, pointer to the failing device is * returned in @r_failed_dev. * * LOCKING: @@ -2381,14 +2792,12 @@ static int ata_dev_set_mode(struct ata_device *dev) * RETURNS: * 0 on success, negative errno otherwise */ -int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) + +int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) { struct ata_device *dev; int i, rc = 0, used_dma = 0, found = 0; - /* has private set_mode? */ - if (ap->ops->set_mode) - return ap->ops->set_mode(ap, r_failed_dev); /* step 1: calculate xfer_mask */ for (i = 0; i < ATA_MAX_DEVICES; i++) { @@ -2461,12 +2870,11 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) * host channels are not permitted to do so. */ if (used_dma && (ap->host->flags & ATA_HOST_SIMPLEX)) - ap->host->simplex_claimed = 1; + ap->host->simplex_claimed = ap; /* step5: chip specific finalisation */ if (ap->ops->post_set_mode) ap->ops->post_set_mode(ap); - out: if (rc) *r_failed_dev = dev; @@ -2474,6 +2882,29 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) } /** + * ata_set_mode - Program timings and issue SET FEATURES - XFER + * @ap: port on which timings will be programmed + * @r_failed_dev: out paramter for failed device + * + * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If + * ata_set_mode() fails, pointer to the failing device is + * returned in @r_failed_dev. + * + * LOCKING: + * PCI/etc. bus probe sem. + * + * RETURNS: + * 0 on success, negative errno otherwise + */ +int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) +{ + /* has private set_mode? */ + if (ap->ops->set_mode) + return ap->ops->set_mode(ap, r_failed_dev); + return ata_do_set_mode(ap, r_failed_dev); +} + +/** * ata_tf_to_host - issue ATA taskfile to host controller * @ap: port to which command is being issued * @tf: ATA taskfile register set @@ -2595,7 +3026,7 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, { struct ata_ioports *ioaddr = &ap->ioaddr; - DPRINTK("ata%u: bus reset via SRST\n", ap->id); + DPRINTK("ata%u: bus reset via SRST\n", ap->print_id); /* software reset. causes dev0 to be selected */ iowrite8(ap->ctl, ioaddr->ctl_addr); @@ -2655,7 +3086,7 @@ void ata_bus_reset(struct ata_port *ap) u8 err; unsigned int dev0, dev1 = 0, devmask = 0; - DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); + DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no); /* determine if device 0/1 are present */ if (ap->flags & ATA_FLAG_SATA_RESET) @@ -3154,6 +3585,11 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, "%llu != %llu\n", (unsigned long long)dev->n_sectors, (unsigned long long)new_n_sectors); + /* Are we the boot time size - if so we appear to be the + same disk at this point and our HPA got reapplied */ + if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors + && ata_id_hpa_enabled(new_id)) + return 1; return 0; } @@ -3242,16 +3678,30 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "WPI CDD-820", NULL, ATA_HORKAGE_NODMA }, { "SAMSUNG CD-ROM SC-148C", NULL, ATA_HORKAGE_NODMA }, { "SAMSUNG CD-ROM SC", NULL, ATA_HORKAGE_NODMA }, - { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA }, { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA }, { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, { "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA }, + /* Weird ATAPI devices */ + { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 | + ATA_HORKAGE_DMA_RW_ONLY }, + /* Devices we expect to fail diagnostics */ /* Devices where NCQ should be avoided */ /* NCQ is slow */ { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ }, + /* http://thread.gmane.org/gmane.linux.ide/14907 */ + { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ }, + /* NCQ is broken */ + { "Maxtor 6L250S0", "BANC1G10", ATA_HORKAGE_NONCQ }, + /* NCQ hard hangs device under heavier load, needs hard power cycle */ + { "Maxtor 6B250S0", "BANC1B70", ATA_HORKAGE_NONCQ }, + /* Blacklist entries taken from Silicon Image 3124/3132 + Windows driver .inf file - also several Linux problem reports */ + { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, + { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, + { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, /* Devices with NCQ limits */ @@ -3314,19 +3764,7 @@ static void ata_dev_xfermask(struct ata_device *dev) xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, ap->udma_mask); - /* Apply cable rule here. Don't apply it early because when - * we handle hot plug the cable type can itself change. - */ - if (ap->cbl == ATA_CBL_PATA40) - xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); - /* Apply drive side cable rule. Unknown or 80 pin cables reported - * host side are checked drive side as well. Cases where we know a - * 40wire cable is used safely for 80 are not checked here. - */ - if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80)) - xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); - - + /* drive modes available */ xfer_mask &= ata_pack_xfermask(dev->pio_mask, dev->mwdma_mask, dev->udma_mask); xfer_mask &= ata_id_xfermask(dev->id); @@ -3348,14 +3786,37 @@ static void ata_dev_xfermask(struct ata_device *dev) "device is on DMA blacklist, disabling DMA\n"); } - if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed) { + if ((host->flags & ATA_HOST_SIMPLEX) && + host->simplex_claimed && host->simplex_claimed != ap) { xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by " "other device, disabling DMA\n"); } + if (ap->flags & ATA_FLAG_NO_IORDY) + xfer_mask &= ata_pio_mask_no_iordy(dev); + if (ap->ops->mode_filter) - xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask); + xfer_mask = ap->ops->mode_filter(dev, xfer_mask); + + /* Apply cable rule here. Don't apply it early because when + * we handle hot plug the cable type can itself change. + * Check this last so that we know if the transfer rate was + * solely limited by the cable. + * Unknown or 80 wire cables reported host side are checked + * drive side as well. Cases where we know a 40wire cable + * is used safely for 80 are not checked here. + */ + if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) + /* UDMA/44 or higher would be available */ + if((ap->cbl == ATA_CBL_PATA40) || + (ata_drive_40wire(dev->id) && + (ap->cbl == ATA_CBL_PATA_UNK || + ap->cbl == ATA_CBL_PATA80))) { + ata_dev_printk(dev, KERN_WARNING, + "limited to UDMA/33 due to 40-wire cable\n"); + xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); + } ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, &dev->udma_mask); @@ -3562,6 +4023,26 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; int rc = 0; /* Assume ATAPI DMA is OK by default */ + /* some drives can only do ATAPI DMA on read/write */ + if (unlikely(qc->dev->horkage & ATA_HORKAGE_DMA_RW_ONLY)) { + struct scsi_cmnd *cmd = qc->scsicmd; + u8 *scsicmd = cmd->cmnd; + + switch (scsicmd[0]) { + case READ_10: + case WRITE_10: + case READ_12: + case WRITE_12: + case READ_6: + case WRITE_6: + /* atapi dma maybe ok */ + break; + default: + /* turn off atapi dma */ + return 1; + } + } + if (ap->ops->check_atapi_dma) rc = ap->ops->check_atapi_dma(qc); @@ -3725,7 +4206,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) struct scatterlist *lsg = &sg[qc->n_elem - 1]; int n_elem, pre_n_elem, dir, trim_sg = 0; - VPRINTK("ENTER, ata%u\n", ap->id); + VPRINTK("ENTER, ata%u\n", ap->print_id); WARN_ON(!(qc->flags & ATA_QCFLAG_SG)); /* we must lengthen transfers to end on a 32-bit boundary */ @@ -3874,10 +4355,10 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, /** - * ata_pio_sector - Transfer ATA_SECT_SIZE (512 bytes) of data. + * ata_pio_sector - Transfer a sector of data. * @qc: Command on going * - * Transfer ATA_SECT_SIZE of data from/to the ATA device. + * Transfer qc->sect_size bytes of data from/to the ATA device. * * LOCKING: * Inherited from caller. @@ -3892,7 +4373,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) unsigned int offset; unsigned char *buf; - if (qc->curbytes == qc->nbytes - ATA_SECT_SIZE) + if (qc->curbytes == qc->nbytes - qc->sect_size) ap->hsm_task_state = HSM_ST_LAST; page = sg[qc->cursg].page; @@ -3912,17 +4393,17 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) buf = kmap_atomic(page, KM_IRQ0); /* do the actual data transfer */ - ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write); + ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write); kunmap_atomic(buf, KM_IRQ0); local_irq_restore(flags); } else { buf = page_address(page); - ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write); + ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write); } - qc->curbytes += ATA_SECT_SIZE; - qc->cursg_ofs += ATA_SECT_SIZE; + qc->curbytes += qc->sect_size; + qc->cursg_ofs += qc->sect_size; if (qc->cursg_ofs == (&sg[qc->cursg])->length) { qc->cursg++; @@ -3931,10 +4412,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) } /** - * ata_pio_sectors - Transfer one or many 512-byte sectors. + * ata_pio_sectors - Transfer one or many sectors. * @qc: Command on going * - * Transfer one or many ATA_SECT_SIZE of data from/to the + * Transfer one or many sectors of data from/to the * ATA device for the DRQ request. * * LOCKING: @@ -3949,7 +4430,7 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc) WARN_ON(qc->dev->multi_count == 0); - nsect = min((qc->nbytes - qc->curbytes) / ATA_SECT_SIZE, + nsect = min((qc->nbytes - qc->curbytes) / qc->sect_size, qc->dev->multi_count); while (nsect--) ata_pio_sector(qc); @@ -4126,7 +4607,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) if (do_write != i_write) goto err_out; - VPRINTK("ata%u: xfering %d bytes\n", ap->id, bytes); + VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes); __atapi_pio_bytes(qc, bytes); @@ -4243,7 +4724,7 @@ int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, fsm_start: DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n", - ap->id, qc->tf.protocol, ap->hsm_task_state, status); + ap->print_id, qc->tf.protocol, ap->hsm_task_state, status); switch (ap->hsm_task_state) { case HSM_ST_FIRST: @@ -4276,8 +4757,8 @@ fsm_start: * let the EH abort the command or reset the device. */ if (unlikely(status & (ATA_ERR | ATA_DF))) { - printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n", - ap->id, status); + ata_port_printk(ap, KERN_WARNING, "DRQ=1 with device " + "error, dev_stat 0x%X\n", status); qc->err_mask |= AC_ERR_HSM; ap->hsm_task_state = HSM_ST_ERR; goto fsm_start; @@ -4334,8 +4815,9 @@ fsm_start: * let the EH abort the command or reset the device. */ if (unlikely(status & (ATA_ERR | ATA_DF))) { - printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n", - ap->id, status); + ata_port_printk(ap, KERN_WARNING, "DRQ=1 with " + "device error, dev_stat 0x%X\n", + status); qc->err_mask |= AC_ERR_HSM; ap->hsm_task_state = HSM_ST_ERR; goto fsm_start; @@ -4421,7 +4903,7 @@ fsm_start: /* no more data to transfer */ DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n", - ap->id, qc->dev->devno, status); + ap->print_id, qc->dev->devno, status); WARN_ON(qc->err_mask); @@ -4604,8 +5086,8 @@ static void fill_result_tf(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - ap->ops->tf_read(ap, &qc->result_tf); qc->result_tf.flags = qc->tf.flags; + ap->ops->tf_read(ap, &qc->result_tf); } /** @@ -4963,7 +5445,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, u8 status, host_stat = 0; VPRINTK("ata%u: protocol %d task_state %d\n", - ap->id, qc->tf.protocol, ap->hsm_task_state); + ap->print_id, qc->tf.protocol, ap->hsm_task_state); /* Check whether we are expecting interrupt in this state */ switch (ap->hsm_task_state) { @@ -4984,7 +5466,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap, qc->tf.protocol == ATA_PROT_ATAPI_DMA) { /* check status of DMA engine */ host_stat = ap->ops->bmdma_status(ap); - VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat); + VPRINTK("ata%u: host_stat 0x%X\n", + ap->print_id, host_stat); /* if it's not our irq... */ if (!(host_stat & ATA_DMA_INTR)) @@ -5245,6 +5728,7 @@ int ata_flush_cache(struct ata_device *dev) return 0; } +#ifdef CONFIG_PM static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg, unsigned int action, unsigned int ehi_flags, int wait) @@ -5360,6 +5844,7 @@ void ata_host_resume(struct ata_host *host) ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0); host->dev->power.power_state = PMSG_ON; } +#endif /** * ata_port_start - Set port up for dma. @@ -5425,42 +5910,35 @@ void ata_dev_init(struct ata_device *dev) } /** - * ata_port_init - Initialize an ata_port structure - * @ap: Structure to initialize - * @host: Collection of hosts to which @ap belongs - * @ent: Probe information provided by low-level driver - * @port_no: Port number associated with this ata_port + * ata_port_alloc - allocate and initialize basic ATA port resources + * @host: ATA host this allocated port belongs to + * + * Allocate and initialize basic ATA port resources. * - * Initialize a new ata_port structure. + * RETURNS: + * Allocate ATA port on success, NULL on failure. * * LOCKING: - * Inherited from caller. + * Inherited from calling layer (may sleep). */ -void ata_port_init(struct ata_port *ap, struct ata_host *host, - const struct ata_probe_ent *ent, unsigned int port_no) +struct ata_port *ata_port_alloc(struct ata_host *host) { + struct ata_port *ap; unsigned int i; + DPRINTK("ENTER\n"); + + ap = kzalloc(sizeof(*ap), GFP_KERNEL); + if (!ap) + return NULL; + ap->lock = &host->lock; ap->flags = ATA_FLAG_DISABLED; - ap->id = ata_unique_id++; + ap->print_id = -1; ap->ctl = ATA_DEVCTL_OBS; ap->host = host; - ap->dev = ent->dev; - ap->port_no = port_no; - if (port_no == 1 && ent->pinfo2) { - ap->pio_mask = ent->pinfo2->pio_mask; - ap->mwdma_mask = ent->pinfo2->mwdma_mask; - ap->udma_mask = ent->pinfo2->udma_mask; - ap->flags |= ent->pinfo2->flags; - ap->ops = ent->pinfo2->port_ops; - } else { - ap->pio_mask = ent->pio_mask; - ap->mwdma_mask = ent->mwdma_mask; - ap->udma_mask = ent->udma_mask; - ap->flags |= ent->port_flags; - ap->ops = ent->port_ops; - } + ap->dev = host->dev; + ap->hw_sata_spd_limit = UINT_MAX; ap->active_tag = ATA_TAG_POISON; ap->last_ctl = 0xFF; @@ -5480,10 +5958,7 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host, INIT_LIST_HEAD(&ap->eh_done_q); init_waitqueue_head(&ap->eh_wait_q); - /* set cable type */ ap->cbl = ATA_CBL_NONE; - if (ap->flags & ATA_FLAG_SATA) - ap->cbl = ATA_CBL_SATA; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; @@ -5496,94 +5971,209 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host, ap->stats.unhandled_irq = 1; ap->stats.idle_irq = 1; #endif + return ap; +} + +static void ata_host_release(struct device *gendev, void *res) +{ + struct ata_host *host = dev_get_drvdata(gendev); + int i; + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + + if (!ap) + continue; + + if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop) + ap->ops->port_stop(ap); + } + + if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop) + host->ops->host_stop(host); + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + + if (!ap) + continue; + + if (ap->scsi_host) + scsi_host_put(ap->scsi_host); - memcpy(&ap->ioaddr, &ent->port[port_no], sizeof(struct ata_ioports)); + kfree(ap); + host->ports[i] = NULL; + } + + dev_set_drvdata(gendev, NULL); } /** - * ata_port_init_shost - Initialize SCSI host associated with ATA port - * @ap: ATA port to initialize SCSI host for - * @shost: SCSI host associated with @ap + * ata_host_alloc - allocate and init basic ATA host resources + * @dev: generic device this host is associated with + * @max_ports: maximum number of ATA ports associated with this host + * + * Allocate and initialize basic ATA host resources. LLD calls + * this function to allocate a host, initializes it fully and + * attaches it using ata_host_register(). + * + * @max_ports ports are allocated and host->n_ports is + * initialized to @max_ports. The caller is allowed to decrease + * host->n_ports before calling ata_host_register(). The unused + * ports will be automatically freed on registration. * - * Initialize SCSI host @shost associated with ATA port @ap. + * RETURNS: + * Allocate ATA host on success, NULL on failure. * * LOCKING: - * Inherited from caller. + * Inherited from calling layer (may sleep). */ -static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost) +struct ata_host *ata_host_alloc(struct device *dev, int max_ports) { - ap->scsi_host = shost; + struct ata_host *host; + size_t sz; + int i; + + DPRINTK("ENTER\n"); + + if (!devres_open_group(dev, NULL, GFP_KERNEL)) + return NULL; + + /* alloc a container for our list of ATA ports (buses) */ + sz = sizeof(struct ata_host) + (max_ports + 1) * sizeof(void *); + /* alloc a container for our list of ATA ports (buses) */ + host = devres_alloc(ata_host_release, sz, GFP_KERNEL); + if (!host) + goto err_out; + + devres_add(dev, host); + dev_set_drvdata(dev, host); + + spin_lock_init(&host->lock); + host->dev = dev; + host->n_ports = max_ports; + + /* allocate ports bound to this host */ + for (i = 0; i < max_ports; i++) { + struct ata_port *ap; + + ap = ata_port_alloc(host); + if (!ap) + goto err_out; + + ap->port_no = i; + host->ports[i] = ap; + } - shost->unique_id = ap->id; - shost->max_id = 16; - shost->max_lun = 1; - shost->max_channel = 1; - shost->max_cmd_len = 12; + devres_remove_group(dev, NULL); + return host; + + err_out: + devres_release_group(dev, NULL); + return NULL; } /** - * ata_port_add - Attach low-level ATA driver to system - * @ent: Information provided by low-level driver - * @host: Collections of ports to which we add - * @port_no: Port number associated with this host + * ata_host_alloc_pinfo - alloc host and init with port_info array + * @dev: generic device this host is associated with + * @ppi: array of ATA port_info to initialize host with + * @n_ports: number of ATA ports attached to this host * - * Attach low-level ATA driver to system. - * - * LOCKING: - * PCI/etc. bus probe sem. + * Allocate ATA host and initialize with info from @ppi. If NULL + * terminated, @ppi may contain fewer entries than @n_ports. The + * last entry will be used for the remaining ports. * * RETURNS: - * New ata_port on success, for NULL on error. + * Allocate ATA host on success, NULL on failure. + * + * LOCKING: + * Inherited from calling layer (may sleep). */ -static struct ata_port * ata_port_add(const struct ata_probe_ent *ent, - struct ata_host *host, - unsigned int port_no) +struct ata_host *ata_host_alloc_pinfo(struct device *dev, + const struct ata_port_info * const * ppi, + int n_ports) { - struct Scsi_Host *shost; - struct ata_port *ap; - - DPRINTK("ENTER\n"); + const struct ata_port_info *pi; + struct ata_host *host; + int i, j; - if (!ent->port_ops->error_handler && - !(ent->port_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { - printk(KERN_ERR "ata%u: no reset mechanism available\n", - port_no); + host = ata_host_alloc(dev, n_ports); + if (!host) return NULL; - } - shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); - if (!shost) - return NULL; + for (i = 0, j = 0, pi = NULL; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; - shost->transportt = &ata_scsi_transport_template; + if (ppi[j]) + pi = ppi[j++]; - ap = ata_shost_to_port(shost); + ap->pio_mask = pi->pio_mask; + ap->mwdma_mask = pi->mwdma_mask; + ap->udma_mask = pi->udma_mask; + ap->flags |= pi->flags; + ap->ops = pi->port_ops; - ata_port_init(ap, host, ent, port_no); - ata_port_init_shost(ap, shost); + if (!host->ops && (pi->port_ops != &ata_dummy_port_ops)) + host->ops = pi->port_ops; + if (!host->private_data && pi->private_data) + host->private_data = pi->private_data; + } - return ap; + return host; } -static void ata_host_release(struct device *gendev, void *res) +/** + * ata_host_start - start and freeze ports of an ATA host + * @host: ATA host to start ports for + * + * Start and then freeze ports of @host. Started status is + * recorded in host->flags, so this function can be called + * multiple times. Ports are guaranteed to get started only + * once. If host->ops isn't initialized yet, its set to the + * first non-dummy port ops. + * + * LOCKING: + * Inherited from calling layer (may sleep). + * + * RETURNS: + * 0 if all ports are started successfully, -errno otherwise. + */ +int ata_host_start(struct ata_host *host) { - struct ata_host *host = dev_get_drvdata(gendev); - int i; + int i, rc; + + if (host->flags & ATA_HOST_STARTED) + return 0; for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; - if (!ap) - continue; + if (!host->ops && !ata_port_is_dummy(ap)) + host->ops = ap->ops; - if (ap->ops->port_stop) - ap->ops->port_stop(ap); + if (ap->ops->port_start) { + rc = ap->ops->port_start(ap); + if (rc) { + ata_port_printk(ap, KERN_ERR, "failed to " + "start port (errno=%d)\n", rc); + goto err_out; + } + } - scsi_host_put(ap->scsi_host); + ata_eh_freeze_port(ap); } - if (host->ops->host_stop) - host->ops->host_stop(host); + host->flags |= ATA_HOST_STARTED; + return 0; + + err_out: + while (--i >= 0) { + struct ata_port *ap = host->ports[i]; + + if (ap->ops->port_stop) + ap->ops->port_stop(ap); + } + return rc; } /** @@ -5597,7 +6187,7 @@ static void ata_host_release(struct device *gendev, void *res) * PCI/etc. bus probe sem. * */ - +/* KILLME - the only user left is ipr */ void ata_host_init(struct ata_host *host, struct device *dev, unsigned long flags, const struct ata_port_operations *ops) { @@ -5608,155 +6198,95 @@ void ata_host_init(struct ata_host *host, struct device *dev, } /** - * ata_device_add - Register hardware device with ATA and SCSI layers - * @ent: Probe information describing hardware device to be registered - * - * This function processes the information provided in the probe - * information struct @ent, allocates the necessary ATA and SCSI - * host information structures, initializes them, and registers - * everything with requisite kernel subsystems. + * ata_host_register - register initialized ATA host + * @host: ATA host to register + * @sht: template for SCSI host * - * This function requests irqs, probes the ATA bus, and probes - * the SCSI bus. + * Register initialized ATA host. @host is allocated using + * ata_host_alloc() and fully initialized by LLD. This function + * starts ports, registers @host with ATA and SCSI layers and + * probe registered devices. * * LOCKING: - * PCI/etc. bus probe sem. + * Inherited from calling layer (may sleep). * * RETURNS: - * Number of ports registered. Zero on error (no ports registered). + * 0 on success, -errno otherwise. */ -int ata_device_add(const struct ata_probe_ent *ent) +int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) { - unsigned int i; - struct device *dev = ent->dev; - struct ata_host *host; - int rc; - - DPRINTK("ENTER\n"); + int i, rc; - if (ent->irq == 0) { - dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n"); - return 0; + /* host must have been started */ + if (!(host->flags & ATA_HOST_STARTED)) { + dev_printk(KERN_ERR, host->dev, + "BUG: trying to register unstarted host\n"); + WARN_ON(1); + return -EINVAL; } - if (!devres_open_group(dev, ata_device_add, GFP_KERNEL)) - return 0; + /* Blow away unused ports. This happens when LLD can't + * determine the exact number of ports to allocate at + * allocation time. + */ + for (i = host->n_ports; host->ports[i]; i++) + kfree(host->ports[i]); - /* alloc a container for our list of ATA ports (buses) */ - host = devres_alloc(ata_host_release, sizeof(struct ata_host) + - (ent->n_ports * sizeof(void *)), GFP_KERNEL); - if (!host) - goto err_out; - devres_add(dev, host); - dev_set_drvdata(dev, host); + /* give ports names and add SCSI hosts */ + for (i = 0; i < host->n_ports; i++) + host->ports[i]->print_id = ata_print_id++; - ata_host_init(host, dev, ent->_host_flags, ent->port_ops); - host->n_ports = ent->n_ports; - host->irq = ent->irq; - host->irq2 = ent->irq2; - host->iomap = ent->iomap; - host->private_data = ent->private_data; + rc = ata_scsi_add_hosts(host, sht); + if (rc) + return rc; - /* register each port bound to this device */ + /* set cable, sata_spd_limit and report */ for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap; - unsigned long xfer_mode_mask; - int irq_line = ent->irq; - - ap = ata_port_add(ent, host, i); - host->ports[i] = ap; - if (!ap) - goto err_out; + struct ata_port *ap = host->ports[i]; + int irq_line; + u32 scontrol; + unsigned long xfer_mask; - /* dummy? */ - if (ent->dummy_port_mask & (1 << i)) { - ata_port_printk(ap, KERN_INFO, "DUMMY\n"); - ap->ops = &ata_dummy_port_ops; - continue; - } + /* set SATA cable type if still unset */ + if (ap->cbl == ATA_CBL_NONE && (ap->flags & ATA_FLAG_SATA)) + ap->cbl = ATA_CBL_SATA; - /* start port */ - rc = ap->ops->port_start(ap); - if (rc) { - host->ports[i] = NULL; - scsi_host_put(ap->scsi_host); - goto err_out; + /* init sata_spd_limit to the current value */ + if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { + int spd = (scontrol >> 4) & 0xf; + ap->hw_sata_spd_limit &= (1 << spd) - 1; } + ap->sata_spd_limit = ap->hw_sata_spd_limit; - /* Report the secondary IRQ for second channel legacy */ - if (i == 1 && ent->irq2) - irq_line = ent->irq2; + /* report the secondary IRQ for second channel legacy */ + irq_line = host->irq; + if (i == 1 && host->irq2) + irq_line = host->irq2; - xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | - (ap->mwdma_mask << ATA_SHIFT_MWDMA) | - (ap->pio_mask << ATA_SHIFT_PIO); + xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, + ap->udma_mask); /* print per-port info to dmesg */ - ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p " - "ctl 0x%p bmdma 0x%p irq %d\n", - ap->flags & ATA_FLAG_SATA ? 'S' : 'P', - ata_mode_string(xfer_mode_mask), - ap->ioaddr.cmd_addr, - ap->ioaddr.ctl_addr, - ap->ioaddr.bmdma_addr, - irq_line); - - /* freeze port before requesting IRQ */ - ata_eh_freeze_port(ap); - } - - /* obtain irq, that may be shared between channels */ - rc = devm_request_irq(dev, ent->irq, ent->port_ops->irq_handler, - ent->irq_flags, DRV_NAME, host); - if (rc) { - dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", - ent->irq, rc); - goto err_out; - } - - /* do we have a second IRQ for the other channel, eg legacy mode */ - if (ent->irq2) { - /* We will get weird core code crashes later if this is true - so trap it now */ - BUG_ON(ent->irq == ent->irq2); - - rc = devm_request_irq(dev, ent->irq2, - ent->port_ops->irq_handler, ent->irq_flags, - DRV_NAME, host); - if (rc) { - dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", - ent->irq2, rc); - goto err_out; - } + if (!ata_port_is_dummy(ap)) + ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p " + "ctl 0x%p bmdma 0x%p irq %d\n", + ap->cbl == ATA_CBL_SATA ? 'S' : 'P', + ata_mode_string(xfer_mask), + ap->ioaddr.cmd_addr, + ap->ioaddr.ctl_addr, + ap->ioaddr.bmdma_addr, + irq_line); + else + ata_port_printk(ap, KERN_INFO, "DUMMY\n"); } - /* resource acquisition complete */ - devres_remove_group(dev, ata_device_add); - /* perform each probe synchronously */ DPRINTK("probe begin\n"); for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; - u32 scontrol; int rc; - /* init sata_spd_limit to the current value */ - if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { - int spd = (scontrol >> 4) & 0xf; - ap->hw_sata_spd_limit &= (1 << spd) - 1; - } - ap->sata_spd_limit = ap->hw_sata_spd_limit; - - rc = scsi_add_host(ap->scsi_host, dev); - if (rc) { - ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n"); - /* FIXME: do something useful here */ - /* FIXME: handle unconditional calls to - * scsi_scan_host and ata_host_remove, below, - * at the very least - */ - } - + /* probe */ if (ap->ops->error_handler) { struct ata_eh_info *ehi = &ap->eh_info; unsigned long flags; @@ -5778,9 +6308,9 @@ int ata_device_add(const struct ata_probe_ent *ent) /* wait for EH to finish */ ata_port_wait_eh(ap); } else { - DPRINTK("ata%u: bus probe begin\n", ap->id); + DPRINTK("ata%u: bus probe begin\n", ap->print_id); rc = ata_bus_probe(ap); - DPRINTK("ata%u: bus probe end\n", ap->id); + DPRINTK("ata%u: bus probe end\n", ap->print_id); if (rc) { /* FIXME: do something useful here? @@ -5801,17 +6331,52 @@ int ata_device_add(const struct ata_probe_ent *ent) ata_scsi_scan_host(ap); } - VPRINTK("EXIT, returning %u\n", ent->n_ports); - return ent->n_ports; /* success */ - - err_out: - devres_release_group(dev, ata_device_add); - dev_set_drvdata(dev, NULL); - VPRINTK("EXIT, returning %d\n", rc); return 0; } /** + * ata_host_activate - start host, request IRQ and register it + * @host: target ATA host + * @irq: IRQ to request + * @irq_handler: irq_handler used when requesting IRQ + * @irq_flags: irq_flags used when requesting IRQ + * @sht: scsi_host_template to use when registering the host + * + * After allocating an ATA host and initializing it, most libata + * LLDs perform three steps to activate the host - start host, + * request IRQ and register it. This helper takes necessasry + * arguments and performs the three steps in one go. + * + * LOCKING: + * Inherited from calling layer (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int ata_host_activate(struct ata_host *host, int irq, + irq_handler_t irq_handler, unsigned long irq_flags, + struct scsi_host_template *sht) +{ + int rc; + + rc = ata_host_start(host); + if (rc) + return rc; + + rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags, + dev_driver_string(host->dev), host); + if (rc) + return rc; + + rc = ata_host_register(host, sht); + /* if failed, just free the IRQ and leave ports alone */ + if (rc) + devm_free_irq(host->dev, irq, host); + + return rc; +} + +/** * ata_port_detach - Detach ATA port in prepration of device removal * @ap: ATA port to be detached * @@ -5886,36 +6451,6 @@ void ata_host_detach(struct ata_host *host) ata_port_detach(host->ports[i]); } -struct ata_probe_ent * -ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) -{ - struct ata_probe_ent *probe_ent; - - /* XXX - the following if can go away once all LLDs are managed */ - if (!list_empty(&dev->devres_head)) - probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); - else - probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); - if (!probe_ent) { - printk(KERN_ERR DRV_NAME "(%s): out of memory\n", - kobject_name(&(dev->kobj))); - return NULL; - } - - INIT_LIST_HEAD(&probe_ent->node); - probe_ent->dev = dev; - - probe_ent->sht = port->sht; - probe_ent->port_flags = port->flags; - probe_ent->pio_mask = port->pio_mask; - probe_ent->mwdma_mask = port->mwdma_mask; - probe_ent->udma_mask = port->udma_mask; - probe_ent->port_ops = port->port_ops; - probe_ent->private_data = port->private_data; - - return probe_ent; -} - /** * ata_std_ports - initialize ioaddr with standard port offsets. * @ioaddr: IO address structure to be initialized @@ -5998,14 +6533,14 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) return (tmp == bits->val) ? 1 : 0; } +#ifdef CONFIG_PM void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) { pci_save_state(pdev); + pci_disable_device(pdev); - if (mesg.event == PM_EVENT_SUSPEND) { - pci_disable_device(pdev); + if (mesg.event == PM_EVENT_SUSPEND) pci_set_power_state(pdev, PCI_D3hot); - } } int ata_pci_device_do_resume(struct pci_dev *pdev) @@ -6050,6 +6585,8 @@ int ata_pci_device_resume(struct pci_dev *pdev) ata_host_resume(host); return rc; } +#endif /* CONFIG_PM */ + #endif /* CONFIG_PCI */ @@ -6179,6 +6716,10 @@ const struct ata_port_operations ata_dummy_port_ops = { .port_stop = ata_dummy_noret, }; +const struct ata_port_info ata_dummy_port_info = { + .port_ops = &ata_dummy_port_ops, +}; + /* * libata is essentially a library of internal helper functions for * low-level ATA host controller drivers. As such, the API/ABI is @@ -6190,10 +6731,15 @@ EXPORT_SYMBOL_GPL(sata_deb_timing_normal); EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); EXPORT_SYMBOL_GPL(sata_deb_timing_long); EXPORT_SYMBOL_GPL(ata_dummy_port_ops); +EXPORT_SYMBOL_GPL(ata_dummy_port_info); EXPORT_SYMBOL_GPL(ata_std_bios_param); EXPORT_SYMBOL_GPL(ata_std_ports); EXPORT_SYMBOL_GPL(ata_host_init); -EXPORT_SYMBOL_GPL(ata_device_add); +EXPORT_SYMBOL_GPL(ata_host_alloc); +EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); +EXPORT_SYMBOL_GPL(ata_host_start); +EXPORT_SYMBOL_GPL(ata_host_register); +EXPORT_SYMBOL_GPL(ata_host_activate); EXPORT_SYMBOL_GPL(ata_host_detach); EXPORT_SYMBOL_GPL(ata_sg_init); EXPORT_SYMBOL_GPL(ata_sg_init_one); @@ -6205,6 +6751,7 @@ EXPORT_SYMBOL_GPL(ata_tf_load); EXPORT_SYMBOL_GPL(ata_tf_read); EXPORT_SYMBOL_GPL(ata_noop_dev_select); EXPORT_SYMBOL_GPL(ata_std_dev_select); +EXPORT_SYMBOL_GPL(sata_print_link_status); EXPORT_SYMBOL_GPL(ata_tf_to_fis); EXPORT_SYMBOL_GPL(ata_tf_from_fis); EXPORT_SYMBOL_GPL(ata_check_status); @@ -6212,6 +6759,7 @@ EXPORT_SYMBOL_GPL(ata_altstatus); EXPORT_SYMBOL_GPL(ata_exec_command); EXPORT_SYMBOL_GPL(ata_port_start); EXPORT_SYMBOL_GPL(ata_interrupt); +EXPORT_SYMBOL_GPL(ata_do_set_mode); EXPORT_SYMBOL_GPL(ata_data_xfer); EXPORT_SYMBOL_GPL(ata_data_xfer_noirq); EXPORT_SYMBOL_GPL(ata_qc_prep); @@ -6227,6 +6775,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_drive_eh); EXPORT_SYMBOL_GPL(ata_bmdma_error_handler); EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd); EXPORT_SYMBOL_GPL(ata_port_probe); +EXPORT_SYMBOL_GPL(ata_dev_disable); EXPORT_SYMBOL_GPL(sata_set_spd); EXPORT_SYMBOL_GPL(sata_phy_debounce); EXPORT_SYMBOL_GPL(sata_phy_resume); @@ -6257,10 +6806,13 @@ EXPORT_SYMBOL_GPL(sata_scr_write); EXPORT_SYMBOL_GPL(sata_scr_write_flush); EXPORT_SYMBOL_GPL(ata_port_online); EXPORT_SYMBOL_GPL(ata_port_offline); +#ifdef CONFIG_PM EXPORT_SYMBOL_GPL(ata_host_suspend); EXPORT_SYMBOL_GPL(ata_host_resume); +#endif /* CONFIG_PM */ EXPORT_SYMBOL_GPL(ata_id_string); EXPORT_SYMBOL_GPL(ata_id_c_string); +EXPORT_SYMBOL_GPL(ata_id_to_dma_mode); EXPORT_SYMBOL_GPL(ata_device_blacklisted); EXPORT_SYMBOL_GPL(ata_scsi_simulate); @@ -6270,19 +6822,24 @@ EXPORT_SYMBOL_GPL(ata_timing_merge); #ifdef CONFIG_PCI EXPORT_SYMBOL_GPL(pci_test_config_bits); -EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); +EXPORT_SYMBOL_GPL(ata_pci_init_native_host); +EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host); EXPORT_SYMBOL_GPL(ata_pci_init_one); EXPORT_SYMBOL_GPL(ata_pci_remove_one); +#ifdef CONFIG_PM EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend); EXPORT_SYMBOL_GPL(ata_pci_device_do_resume); EXPORT_SYMBOL_GPL(ata_pci_device_suspend); EXPORT_SYMBOL_GPL(ata_pci_device_resume); +#endif /* CONFIG_PM */ EXPORT_SYMBOL_GPL(ata_pci_default_filter); EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); #endif /* CONFIG_PCI */ +#ifdef CONFIG_PM EXPORT_SYMBOL_GPL(ata_scsi_device_suspend); EXPORT_SYMBOL_GPL(ata_scsi_device_resume); +#endif /* CONFIG_PM */ EXPORT_SYMBOL_GPL(ata_eng_timeout); EXPORT_SYMBOL_GPL(ata_port_schedule_eh); @@ -6297,3 +6854,9 @@ EXPORT_SYMBOL_GPL(ata_irq_on); EXPORT_SYMBOL_GPL(ata_dummy_irq_on); EXPORT_SYMBOL_GPL(ata_irq_ack); EXPORT_SYMBOL_GPL(ata_dummy_irq_ack); +EXPORT_SYMBOL_GPL(ata_dev_try_classify); + +EXPORT_SYMBOL_GPL(ata_cable_40wire); +EXPORT_SYMBOL_GPL(ata_cable_80wire); +EXPORT_SYMBOL_GPL(ata_cable_unknown); +EXPORT_SYMBOL_GPL(ata_cable_sata); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 52c85af7fe9..2bff9adcacf 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -44,10 +44,41 @@ #include "libata.h" +enum { + ATA_EH_SPDN_NCQ_OFF = (1 << 0), + ATA_EH_SPDN_SPEED_DOWN = (1 << 1), + ATA_EH_SPDN_FALLBACK_TO_PIO = (1 << 2), +}; + static void __ata_port_freeze(struct ata_port *ap); static void ata_eh_finish(struct ata_port *ap); +#ifdef CONFIG_PM static void ata_eh_handle_port_suspend(struct ata_port *ap); static void ata_eh_handle_port_resume(struct ata_port *ap); +static int ata_eh_suspend(struct ata_port *ap, + struct ata_device **r_failed_dev); +static void ata_eh_prep_resume(struct ata_port *ap); +static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev); +#else /* CONFIG_PM */ +static void ata_eh_handle_port_suspend(struct ata_port *ap) +{ } + +static void ata_eh_handle_port_resume(struct ata_port *ap) +{ } + +static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) +{ + return 0; +} + +static void ata_eh_prep_resume(struct ata_port *ap) +{ } + +static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev) +{ + return 0; +} +#endif /* CONFIG_PM */ static void ata_ering_record(struct ata_ering *ering, int is_io, unsigned int err_mask) @@ -65,12 +96,9 @@ static void ata_ering_record(struct ata_ering *ering, int is_io, ent->timestamp = get_jiffies_64(); } -static struct ata_ering_entry * ata_ering_top(struct ata_ering *ering) +static void ata_ering_clear(struct ata_ering *ering) { - struct ata_ering_entry *ent = &ering->ring[ering->cursor]; - if (!ent->err_mask) - return NULL; - return ent; + memset(ering, 0, sizeof(*ering)); } static int ata_ering_map(struct ata_ering *ering, @@ -585,7 +613,7 @@ static void __ata_port_freeze(struct ata_port *ap) ap->pflags |= ATA_PFLAG_FROZEN; - DPRINTK("ata%u port frozen\n", ap->id); + DPRINTK("ata%u port frozen\n", ap->print_id); } /** @@ -658,7 +686,7 @@ void ata_eh_thaw_port(struct ata_port *ap) spin_unlock_irqrestore(ap->lock, flags); - DPRINTK("ata%u port thawed\n", ap->id); + DPRINTK("ata%u port thawed\n", ap->print_id); } static void ata_eh_scsidone(struct scsi_cmnd *scmd) @@ -954,26 +982,27 @@ static int ata_eh_read_log_10h(struct ata_device *dev, * RETURNS: * 0 on success, AC_ERR_* mask on failure */ -static unsigned int atapi_eh_request_sense(struct ata_device *dev, - unsigned char *sense_buf) +static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc) { + struct ata_device *dev = qc->dev; + unsigned char *sense_buf = qc->scsicmd->sense_buffer; struct ata_port *ap = dev->ap; struct ata_taskfile tf; u8 cdb[ATAPI_CDB_LEN]; DPRINTK("ATAPI request sense\n"); - ata_tf_init(dev, &tf); - /* FIXME: is this needed? */ memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE); - /* XXX: why tf_read here? */ - ap->ops->tf_read(ap, &tf); - - /* fill these in, for the case where they are -not- overwritten */ + /* initialize sense_buf with the error register, + * for the case where they are -not- overwritten + */ sense_buf[0] = 0x70; - sense_buf[2] = tf.feature >> 4; + sense_buf[2] = qc->result_tf.feature >> 4; + + /* some devices time out if garbage left in tf */ + ata_tf_init(dev, &tf); memset(cdb, 0, ATAPI_CDB_LEN); cdb[0] = REQUEST_SENSE; @@ -1027,7 +1056,7 @@ static void ata_eh_analyze_serror(struct ata_port *ap) } if (serror & SERR_INTERNAL) { err_mask |= AC_ERR_SYSTEM; - action |= ATA_EH_SOFTRESET; + action |= ATA_EH_HARDRESET; } if (serror & (SERR_PHYRDY_CHG | SERR_DEV_XCHG)) ata_ehi_hotplugged(&ehc->i); @@ -1122,7 +1151,9 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, return ATA_EH_SOFTRESET; } - if (!(qc->err_mask & AC_ERR_DEV)) + if (stat & (ATA_ERR | ATA_DF)) + qc->err_mask |= AC_ERR_DEV; + else return 0; switch (qc->dev->class) { @@ -1137,8 +1168,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, case ATA_DEV_ATAPI: if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) { - tmp = atapi_eh_request_sense(qc->dev, - qc->scsicmd->sense_buffer); + tmp = atapi_eh_request_sense(qc); if (!tmp) { /* ATA_QCFLAG_SENSE_VALID is used to * tell atapi_qc_complete() that sense @@ -1159,87 +1189,99 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, return action; } -static int ata_eh_categorize_ering_entry(struct ata_ering_entry *ent) +static int ata_eh_categorize_error(int is_io, unsigned int err_mask) { - if (ent->err_mask & (AC_ERR_ATA_BUS | AC_ERR_TIMEOUT)) + if (err_mask & AC_ERR_ATA_BUS) return 1; - if (ent->is_io) { - if (ent->err_mask & AC_ERR_HSM) - return 1; - if ((ent->err_mask & - (AC_ERR_DEV|AC_ERR_MEDIA|AC_ERR_INVALID)) == AC_ERR_DEV) + if (err_mask & AC_ERR_TIMEOUT) + return 2; + + if (is_io) { + if (err_mask & AC_ERR_HSM) return 2; + if ((err_mask & + (AC_ERR_DEV|AC_ERR_MEDIA|AC_ERR_INVALID)) == AC_ERR_DEV) + return 3; } return 0; } -struct speed_down_needed_arg { +struct speed_down_verdict_arg { u64 since; - int nr_errors[3]; + int nr_errors[4]; }; -static int speed_down_needed_cb(struct ata_ering_entry *ent, void *void_arg) +static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg) { - struct speed_down_needed_arg *arg = void_arg; + struct speed_down_verdict_arg *arg = void_arg; + int cat = ata_eh_categorize_error(ent->is_io, ent->err_mask); if (ent->timestamp < arg->since) return -1; - arg->nr_errors[ata_eh_categorize_ering_entry(ent)]++; + arg->nr_errors[cat]++; return 0; } /** - * ata_eh_speed_down_needed - Determine wheter speed down is necessary + * ata_eh_speed_down_verdict - Determine speed down verdict * @dev: Device of interest * * This function examines error ring of @dev and determines - * whether speed down is necessary. Speed down is necessary if - * there have been more than 3 of Cat-1 errors or 10 of Cat-2 - * errors during last 15 minutes. + * whether NCQ needs to be turned off, transfer speed should be + * stepped down, or falling back to PIO is necessary. + * + * Cat-1 is ATA_BUS error for any command. * - * Cat-1 errors are ATA_BUS, TIMEOUT for any command and HSM - * violation for known supported commands. + * Cat-2 is TIMEOUT for any command or HSM violation for known + * supported commands. * - * Cat-2 errors are unclassified DEV error for known supported + * Cat-3 is is unclassified DEV error for known supported * command. * + * NCQ needs to be turned off if there have been more than 3 + * Cat-2 + Cat-3 errors during last 10 minutes. + * + * Speed down is necessary if there have been more than 3 Cat-1 + + * Cat-2 errors or 10 Cat-3 errors during last 10 minutes. + * + * Falling back to PIO mode is necessary if there have been more + * than 10 Cat-1 + Cat-2 + Cat-3 errors during last 5 minutes. + * * LOCKING: * Inherited from caller. * * RETURNS: - * 1 if speed down is necessary, 0 otherwise + * OR of ATA_EH_SPDN_* flags. */ -static int ata_eh_speed_down_needed(struct ata_device *dev) +static unsigned int ata_eh_speed_down_verdict(struct ata_device *dev) { - const u64 interval = 15LLU * 60 * HZ; - static const int err_limits[3] = { -1, 3, 10 }; - struct speed_down_needed_arg arg; - struct ata_ering_entry *ent; - int err_cat; - u64 j64; + const u64 j5mins = 5LLU * 60 * HZ, j10mins = 10LLU * 60 * HZ; + u64 j64 = get_jiffies_64(); + struct speed_down_verdict_arg arg; + unsigned int verdict = 0; - ent = ata_ering_top(&dev->ering); - if (!ent) - return 0; + /* scan past 10 mins of error history */ + memset(&arg, 0, sizeof(arg)); + arg.since = j64 - min(j64, j10mins); + ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg); - err_cat = ata_eh_categorize_ering_entry(ent); - if (err_cat == 0) - return 0; + if (arg.nr_errors[2] + arg.nr_errors[3] > 3) + verdict |= ATA_EH_SPDN_NCQ_OFF; + if (arg.nr_errors[1] + arg.nr_errors[2] > 3 || arg.nr_errors[3] > 10) + verdict |= ATA_EH_SPDN_SPEED_DOWN; + /* scan past 3 mins of error history */ memset(&arg, 0, sizeof(arg)); + arg.since = j64 - min(j64, j5mins); + ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg); - j64 = get_jiffies_64(); - if (j64 >= interval) - arg.since = j64 - interval; - else - arg.since = 0; - - ata_ering_map(&dev->ering, speed_down_needed_cb, &arg); + if (arg.nr_errors[1] + arg.nr_errors[2] + arg.nr_errors[3] > 10) + verdict |= ATA_EH_SPDN_FALLBACK_TO_PIO; - return arg.nr_errors[err_cat] > err_limits[err_cat]; + return verdict; } /** @@ -1257,31 +1299,80 @@ static int ata_eh_speed_down_needed(struct ata_device *dev) * Kernel thread context (may sleep). * * RETURNS: - * 0 on success, -errno otherwise + * Determined recovery action. */ -static int ata_eh_speed_down(struct ata_device *dev, int is_io, - unsigned int err_mask) +static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io, + unsigned int err_mask) { - if (!err_mask) + unsigned int verdict; + unsigned int action = 0; + + /* don't bother if Cat-0 error */ + if (ata_eh_categorize_error(is_io, err_mask) == 0) return 0; /* record error and determine whether speed down is necessary */ ata_ering_record(&dev->ering, is_io, err_mask); + verdict = ata_eh_speed_down_verdict(dev); - if (!ata_eh_speed_down_needed(dev)) - return 0; + /* turn off NCQ? */ + if ((verdict & ATA_EH_SPDN_NCQ_OFF) && + (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ | + ATA_DFLAG_NCQ_OFF)) == ATA_DFLAG_NCQ) { + dev->flags |= ATA_DFLAG_NCQ_OFF; + ata_dev_printk(dev, KERN_WARNING, + "NCQ disabled due to excessive errors\n"); + goto done; + } + + /* speed down? */ + if (verdict & ATA_EH_SPDN_SPEED_DOWN) { + /* speed down SATA link speed if possible */ + if (sata_down_spd_limit(dev->ap) == 0) { + action |= ATA_EH_HARDRESET; + goto done; + } - /* speed down SATA link speed if possible */ - if (sata_down_spd_limit(dev->ap) == 0) - return ATA_EH_HARDRESET; + /* lower transfer mode */ + if (dev->spdn_cnt < 2) { + static const int dma_dnxfer_sel[] = + { ATA_DNXFER_DMA, ATA_DNXFER_40C }; + static const int pio_dnxfer_sel[] = + { ATA_DNXFER_PIO, ATA_DNXFER_FORCE_PIO0 }; + int sel; - /* lower transfer mode */ - if (ata_down_xfermask_limit(dev, 0) == 0) - return ATA_EH_SOFTRESET; + if (dev->xfer_shift != ATA_SHIFT_PIO) + sel = dma_dnxfer_sel[dev->spdn_cnt]; + else + sel = pio_dnxfer_sel[dev->spdn_cnt]; + + dev->spdn_cnt++; + + if (ata_down_xfermask_limit(dev, sel) == 0) { + action |= ATA_EH_SOFTRESET; + goto done; + } + } + } + + /* Fall back to PIO? Slowing down to PIO is meaningless for + * SATA. Consider it only for PATA. + */ + if ((verdict & ATA_EH_SPDN_FALLBACK_TO_PIO) && (dev->spdn_cnt >= 2) && + (dev->ap->cbl != ATA_CBL_SATA) && + (dev->xfer_shift != ATA_SHIFT_PIO)) { + if (ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO) == 0) { + dev->spdn_cnt = 0; + action |= ATA_EH_SOFTRESET; + goto done; + } + } - ata_dev_printk(dev, KERN_ERR, - "speed down requested but no transfer mode left\n"); return 0; + done: + /* device has been slowed down, blow error history */ + ata_ering_clear(&dev->ering); + return action; } /** @@ -1536,8 +1627,14 @@ static int ata_eh_reset(struct ata_port *ap, int classify, rc = prereset(ap); if (rc) { if (rc == -ENOENT) { - ata_port_printk(ap, KERN_DEBUG, "port disabled. ignoring.\n"); + ata_port_printk(ap, KERN_DEBUG, + "port disabled. ignoring.\n"); ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; + + for (i = 0; i < ATA_MAX_DEVICES; i++) + classes[i] = ATA_DEV_NONE; + + rc = 0; } else ata_port_printk(ap, KERN_ERR, "prereset failed (errno=%d)\n", rc); @@ -1574,7 +1671,10 @@ static int ata_eh_reset(struct ata_port *ap, int classify, reset == softreset ? "soft" : "hard"); /* mark that this EH session started with reset */ - ehc->i.flags |= ATA_EHI_DID_RESET; + if (reset == hardreset) + ehc->i.flags |= ATA_EHI_DID_HARDRESET; + else + ehc->i.flags |= ATA_EHI_DID_SOFTRESET; rc = ata_do_reset(ap, reset, classes); @@ -1648,12 +1748,17 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, { struct ata_eh_context *ehc = &ap->eh_context; struct ata_device *dev; + unsigned int new_mask = 0; unsigned long flags; int i, rc = 0; DPRINTK("ENTER\n"); - for (i = 0; i < ATA_MAX_DEVICES; i++) { + /* For PATA drive side cable detection to work, IDENTIFY must + * be done backwards such that PDIAG- is released by the slave + * device before the master device is identified. + */ + for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) { unsigned int action, readid_flags = 0; dev = &ap->device[i]; @@ -1665,13 +1770,13 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) { if (ata_port_offline(ap)) { rc = -EIO; - break; + goto err; } ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE); rc = ata_dev_revalidate(dev, readid_flags); if (rc) - break; + goto err; ata_eh_done(ap, dev, ATA_EH_REVALIDATE); @@ -1689,43 +1794,61 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, rc = ata_dev_read_id(dev, &dev->class, readid_flags, dev->id); - if (rc == 0) { - ehc->i.flags |= ATA_EHI_PRINTINFO; - rc = ata_dev_configure(dev); - ehc->i.flags &= ~ATA_EHI_PRINTINFO; - } else if (rc == -ENOENT) { + switch (rc) { + case 0: + new_mask |= 1 << i; + break; + case -ENOENT: /* IDENTIFY was issued to non-existent * device. No need to reset. Just * thaw and kill the device. */ ata_eh_thaw_port(ap); dev->class = ATA_DEV_UNKNOWN; - rc = 0; - } - - if (rc) { - dev->class = ATA_DEV_UNKNOWN; break; + default: + dev->class = ATA_DEV_UNKNOWN; + goto err; } + } + } - if (ata_dev_enabled(dev)) { - spin_lock_irqsave(ap->lock, flags); - ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; - spin_unlock_irqrestore(ap->lock, flags); + /* PDIAG- should have been released, ask cable type if post-reset */ + if ((ehc->i.flags & ATA_EHI_DID_RESET) && ap->ops->cable_detect) + ap->cbl = ap->ops->cable_detect(ap); - /* new device discovered, configure xfermode */ - ehc->i.flags |= ATA_EHI_SETMODE; - } - } + /* Configure new devices forward such that user doesn't see + * device detection messages backwards. + */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + dev = &ap->device[i]; + + if (!(new_mask & (1 << i))) + continue; + + ehc->i.flags |= ATA_EHI_PRINTINFO; + rc = ata_dev_configure(dev); + ehc->i.flags &= ~ATA_EHI_PRINTINFO; + if (rc) + goto err; + + spin_lock_irqsave(ap->lock, flags); + ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; + spin_unlock_irqrestore(ap->lock, flags); + + /* new device discovered, configure xfermode */ + ehc->i.flags |= ATA_EHI_SETMODE; } - if (rc) - *r_failed_dev = dev; + return 0; - DPRINTK("EXIT\n"); + err: + *r_failed_dev = dev; + DPRINTK("EXIT rc=%d\n", rc); return rc; } +#ifdef CONFIG_PM /** * ata_eh_suspend - handle suspend EH action * @ap: target host port @@ -1883,6 +2006,7 @@ static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev) DPRINTK("EXIT\n"); return 0; } +#endif /* CONFIG_PM */ static int ata_port_nr_enabled(struct ata_port *ap) { @@ -1964,7 +2088,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, { struct ata_eh_context *ehc = &ap->eh_context; struct ata_device *dev; - int down_xfermask, i, rc; + int i, rc; DPRINTK("ENTER\n"); @@ -1993,7 +2117,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, } retry: - down_xfermask = 0; rc = 0; /* if UNLOADING, finish immediately */ @@ -2038,10 +2161,8 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, /* configure transfer mode if necessary */ if (ehc->i.flags & ATA_EHI_SETMODE) { rc = ata_set_mode(ap, &dev); - if (rc) { - down_xfermask = 1; + if (rc) goto dev_fail; - } ehc->i.flags &= ~ATA_EHI_SETMODE; } @@ -2053,20 +2174,27 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, goto out; dev_fail: + ehc->tries[dev->devno]--; + switch (rc) { - case -ENODEV: - /* device missing, schedule probing */ - ehc->i.probe_mask |= (1 << dev->devno); case -EINVAL: + /* eeek, something went very wrong, give up */ ehc->tries[dev->devno] = 0; break; + + case -ENODEV: + /* device missing or wrong IDENTIFY data, schedule probing */ + ehc->i.probe_mask |= (1 << dev->devno); + /* give it just one more chance */ + ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); case -EIO: - sata_down_spd_limit(ap); - default: - ehc->tries[dev->devno]--; - if (down_xfermask && - ata_down_xfermask_limit(dev, ehc->tries[dev->devno] == 1)) - ehc->tries[dev->devno] = 0; + if (ehc->tries[dev->devno] == 1) { + /* This is the last chance, better to slow + * down than lose it. + */ + sata_down_spd_limit(ap); + ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); + } } if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) { @@ -2181,6 +2309,7 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_eh_finish(ap); } +#ifdef CONFIG_PM /** * ata_eh_handle_port_suspend - perform port suspend operation * @ap: port to suspend @@ -2296,3 +2425,4 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) } spin_unlock_irqrestore(ap->lock, flags); } +#endif /* CONFIG_PM */ diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0009818a430..9afba2ba489 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -104,7 +104,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { * libata transport template. libata doesn't do real transport stuff. * It just needs the eh_timed_out hook. */ -struct scsi_transport_template ata_scsi_transport_template = { +static struct scsi_transport_template ata_scsi_transport_template = { .eh_strategy_handler = ata_scsi_error, .eh_timed_out = ata_scsi_timed_out, .user_scan = ata_scsi_user_scan, @@ -333,6 +333,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) scsi_cmd[8] = args[3]; scsi_cmd[10] = args[4]; scsi_cmd[12] = args[5]; + scsi_cmd[13] = args[6] & 0x4f; scsi_cmd[14] = args[0]; /* Good values for timeout and retries? Values below @@ -509,6 +510,7 @@ static void ata_dump_status(unsigned id, struct ata_taskfile *tf) } } +#ifdef CONFIG_PM /** * ata_scsi_device_suspend - suspend ATA device associated with sdev * @sdev: the SCSI device to suspend @@ -633,6 +635,7 @@ int ata_scsi_device_resume(struct scsi_device *sdev) sdev->sdev_gendev.power.power_state = PMSG_ON; return 0; } +#endif /* CONFIG_PM */ /** * ata_to_sense_error - convert ATA error to SCSI error @@ -781,7 +784,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) */ if (qc->err_mask || tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->id, tf->command, tf->feature, + ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, &sb[1], &sb[2], &sb[3], verbose); sb[1] &= 0x0f; } @@ -854,7 +857,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) */ if (qc->err_mask || tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->id, tf->command, tf->feature, + ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, &sb[1], &sb[2], &sb[3], verbose); sb[1] &= 0x0f; } @@ -986,29 +989,32 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_device *dev; unsigned long flags; - int max_depth; - if (queue_depth < 1) + if (queue_depth < 1 || queue_depth == sdev->queue_depth) return sdev->queue_depth; dev = ata_scsi_find_dev(ap, sdev); if (!dev || !ata_dev_enabled(dev)) return sdev->queue_depth; - max_depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); - max_depth = min(ATA_MAX_QUEUE - 1, max_depth); - if (queue_depth > max_depth) - queue_depth = max_depth; - - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth); - + /* NCQ enabled? */ spin_lock_irqsave(ap->lock, flags); - if (queue_depth > 1) - dev->flags &= ~ATA_DFLAG_NCQ_OFF; - else + dev->flags &= ~ATA_DFLAG_NCQ_OFF; + if (queue_depth == 1 || !ata_ncq_enabled(dev)) { dev->flags |= ATA_DFLAG_NCQ_OFF; + queue_depth = 1; + } spin_unlock_irqrestore(ap->lock, flags); + /* limit and apply queue depth */ + queue_depth = min(queue_depth, sdev->host->can_queue); + queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); + queue_depth = min(queue_depth, ATA_MAX_QUEUE - 1); + + if (sdev->queue_depth == queue_depth) + return -EINVAL; + + scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth); return queue_depth; } @@ -1469,7 +1475,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) } if (need_sense && !ap->ops->error_handler) - ata_dump_status(ap->id, &qc->result_tf); + ata_dump_status(ap->print_id, &qc->result_tf); qc->scsidone(cmd); @@ -1495,11 +1501,9 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) static int ata_scmd_need_defer(struct ata_device *dev, int is_io) { struct ata_port *ap = dev->ap; + int is_ncq = is_io && ata_ncq_enabled(dev); - if (!(dev->flags & ATA_DFLAG_NCQ)) - return 0; - - if (is_io) { + if (is_ncq) { if (!ata_tag_valid(ap->active_tag)) return 0; } else { @@ -2674,6 +2678,18 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) tf->device = qc->dev->devno ? tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; + /* READ/WRITE LONG use a non-standard sect_size */ + qc->sect_size = ATA_SECT_SIZE; + switch (tf->command) { + case ATA_CMD_READ_LONG: + case ATA_CMD_READ_LONG_ONCE: + case ATA_CMD_WRITE_LONG: + case ATA_CMD_WRITE_LONG_ONCE: + if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1) + goto invalid_fld; + qc->sect_size = scmd->request_bufflen; + } + /* * Filter SET_FEATURES - XFER MODE command -- otherwise, * SET_FEATURES - XFER MODE must be preceded/succeeded @@ -2774,7 +2790,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, u8 *scsicmd = cmd->cmnd; DPRINTK("CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - ap->id, + ap->print_id, scsidev->channel, scsidev->id, scsidev->lun, scsicmd[0], scsicmd[1], scsicmd[2], scsicmd[3], scsicmd[4], scsicmd[5], scsicmd[6], scsicmd[7], @@ -2788,8 +2804,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, { int rc = 0; - if (unlikely(!scmd->cmd_len)) { - ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n"); + if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) { + DPRINTK("bad CDB len=%u, max=%u\n", + scmd->cmd_len, dev->cdb_len); scmd->result = DID_ERROR << 16; done(scmd); return 0; @@ -2944,6 +2961,48 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, } } +int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) +{ + int i, rc; + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + struct Scsi_Host *shost; + + rc = -ENOMEM; + shost = scsi_host_alloc(sht, sizeof(struct ata_port *)); + if (!shost) + goto err_alloc; + + *(struct ata_port **)&shost->hostdata[0] = ap; + ap->scsi_host = shost; + + shost->transportt = &ata_scsi_transport_template; + shost->unique_id = ap->print_id; + shost->max_id = 16; + shost->max_lun = 1; + shost->max_channel = 1; + shost->max_cmd_len = 16; + + rc = scsi_add_host(ap->scsi_host, ap->host->dev); + if (rc) + goto err_add; + } + + return 0; + + err_add: + scsi_host_put(host->ports[i]->scsi_host); + err_alloc: + while (--i >= 0) { + struct Scsi_Host *shost = host->ports[i]->scsi_host; + + scsi_remove_host(shost); + scsi_host_put(shost); + } + return rc; +} + void ata_scsi_scan_host(struct ata_port *ap) { unsigned int i; @@ -3220,21 +3279,21 @@ struct ata_port *ata_sas_port_alloc(struct ata_host *host, struct ata_port_info *port_info, struct Scsi_Host *shost) { - struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL); - struct ata_probe_ent *ent; + struct ata_port *ap; + ap = ata_port_alloc(host); if (!ap) return NULL; - ent = ata_probe_ent_alloc(host->dev, port_info); - if (!ent) { - kfree(ap); - return NULL; - } - - ata_port_init(ap, host, ent, 0); + ap->port_no = 0; ap->lock = shost->host_lock; - kfree(ent); + ap->pio_mask = port_info->pio_mask; + ap->mwdma_mask = port_info->mwdma_mask; + ap->udma_mask = port_info->udma_mask; + ap->flags |= port_info->flags; + ap->ops = port_info->port_ops; + ap->cbl = ATA_CBL_SATA; + return ap; } EXPORT_SYMBOL_GPL(ata_sas_port_alloc); @@ -3290,8 +3349,10 @@ int ata_sas_port_init(struct ata_port *ap) { int rc = ap->ops->port_start(ap); - if (!rc) + if (!rc) { + ap->print_id = ata_print_id++; rc = ata_bus_probe(ap); + } return rc; } diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 16bc3e35bdd..d211db6b35a 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -175,7 +175,7 @@ void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) */ void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) { - DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); iowrite8(tf->command, ap->ioaddr.command_addr); ata_pause(ap); @@ -521,173 +521,404 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) static int ata_resources_present(struct pci_dev *pdev, int port) { int i; - + /* Check the PCI resources for this channel are enabled */ port = port * 2; for (i = 0; i < 2; i ++) { if (pci_resource_start(pdev, port + i) == 0 || - pci_resource_len(pdev, port + i) == 0) - return 0; + pci_resource_len(pdev, port + i) == 0) + return 0; } return 1; } - + /** - * ata_pci_init_native_mode - Initialize native-mode driver - * @pdev: pci device to be initialized - * @port: array[2] of pointers to port info structures. - * @ports: bitmap of ports present - * - * Utility function which allocates and initializes an - * ata_probe_ent structure for a standard dual-port - * PIO-based IDE controller. The returned ata_probe_ent - * structure can be passed to ata_device_add(). The returned - * ata_probe_ent structure should then be freed with kfree(). - * - * The caller need only pass the address of the primary port, the - * secondary will be deduced automatically. If the device has non - * standard secondary port mappings this function can be called twice, - * once for each interface. + * ata_pci_init_bmdma - acquire PCI BMDMA resources and init ATA host + * @host: target ATA host + * + * Acquire PCI BMDMA resources and initialize @host accordingly. + * + * LOCKING: + * Inherited from calling layer (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. */ +static int ata_pci_init_bmdma(struct ata_host *host) +{ + struct device *gdev = host->dev; + struct pci_dev *pdev = to_pci_dev(gdev); + int i, rc; + + /* TODO: If we get no DMA mask we should fall back to PIO */ + rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + return rc; + rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + return rc; + + /* request and iomap DMA region */ + rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME); + if (rc) { + dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n"); + return -ENOMEM; + } + host->iomap = pcim_iomap_table(pdev); -struct ata_probe_ent * -ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports) + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + void __iomem *bmdma = host->iomap[4] + 8 * i; + + if (ata_port_is_dummy(ap)) + continue; + + ap->ioaddr.bmdma_addr = bmdma; + if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) && + (ioread8(bmdma + 2) & 0x80)) + host->flags |= ATA_HOST_SIMPLEX; + } + + return 0; +} + +/** + * ata_pci_init_native_host - acquire native ATA resources and init host + * @host: target ATA host + * @port_mask: ports to consider + * + * Acquire native PCI ATA resources for @host and initialize + * @host accordoingly. + * + * LOCKING: + * Inherited from calling layer (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask) { - struct ata_probe_ent *probe_ent; - int i, p = 0; - void __iomem * const *iomap; - - /* iomap BARs */ - for (i = 0; i < 4; i++) { - if (pcim_iomap(pdev, i, 0) == NULL) { - dev_printk(KERN_ERR, &pdev->dev, - "failed to iomap PCI BAR %d\n", i); - return NULL; + struct device *gdev = host->dev; + struct pci_dev *pdev = to_pci_dev(gdev); + int i, rc; + + /* Discard disabled ports. Some controllers show their unused + * channels this way. Disabled ports are made dummy. + */ + for (i = 0; i < 2; i++) { + if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) { + host->ports[i]->ops = &ata_dummy_port_ops; + port_mask &= ~(1 << i); } } - pcim_iomap(pdev, 4, 0); /* may fail */ - iomap = pcim_iomap_table(pdev); - - /* alloc and init probe_ent */ - probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); - if (!probe_ent) - return NULL; - - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - - /* Discard disabled ports. Some controllers show their - unused channels this way */ - if (ata_resources_present(pdev, 0) == 0) - ports &= ~ATA_PORT_PRIMARY; - if (ata_resources_present(pdev, 1) == 0) - ports &= ~ATA_PORT_SECONDARY; - - if (ports & ATA_PORT_PRIMARY) { - probe_ent->port[p].cmd_addr = iomap[0]; - probe_ent->port[p].altstatus_addr = - probe_ent->port[p].ctl_addr = (void __iomem *) - ((unsigned long)iomap[1] | ATA_PCI_CTL_OFS); - if (iomap[4]) { - if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && - (ioread8(iomap[4] + 2) & 0x80)) - probe_ent->_host_flags |= ATA_HOST_SIMPLEX; - probe_ent->port[p].bmdma_addr = iomap[4]; - } - ata_std_ports(&probe_ent->port[p]); - p++; + if (!port_mask) { + dev_printk(KERN_ERR, gdev, "no available port\n"); + return -ENODEV; } - if (ports & ATA_PORT_SECONDARY) { - probe_ent->port[p].cmd_addr = iomap[2]; - probe_ent->port[p].altstatus_addr = - probe_ent->port[p].ctl_addr = (void __iomem *) - ((unsigned long)iomap[3] | ATA_PCI_CTL_OFS); - if (iomap[4]) { - if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && - (ioread8(iomap[4] + 10) & 0x80)) - probe_ent->_host_flags |= ATA_HOST_SIMPLEX; - probe_ent->port[p].bmdma_addr = iomap[4] + 8; + /* request, iomap BARs and init port addresses accordingly */ + for (i = 0; i < 2; i++) { + struct ata_port *ap = host->ports[i]; + int base = i * 2; + void __iomem * const *iomap; + + if (!(port_mask & (1 << i))) + continue; + + rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME); + if (rc) { + dev_printk(KERN_ERR, gdev, "failed to request/iomap " + "BARs for port %d (errno=%d)\n", i, rc); + if (rc == -EBUSY) + pcim_pin_device(pdev); + return rc; } - ata_std_ports(&probe_ent->port[p]); - probe_ent->pinfo2 = port[1]; - p++; + host->iomap = iomap = pcim_iomap_table(pdev); + + ap->ioaddr.cmd_addr = iomap[base]; + ap->ioaddr.altstatus_addr = + ap->ioaddr.ctl_addr = (void __iomem *) + ((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS); + ata_std_ports(&ap->ioaddr); + } + + return 0; +} + +/** + * ata_pci_prepare_native_host - helper to prepare native PCI ATA host + * @pdev: target PCI device + * @ppi: array of port_info + * @n_ports: number of ports to allocate + * @r_host: out argument for the initialized ATA host + * + * Helper to allocate ATA host for @pdev, acquire all native PCI + * resources and initialize it accordingly in one go. + * + * LOCKING: + * Inherited from calling layer (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int ata_pci_prepare_native_host(struct pci_dev *pdev, + const struct ata_port_info * const * ppi, + int n_ports, struct ata_host **r_host) +{ + struct ata_host *host; + unsigned int port_mask; + int rc; + + if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) + return -ENOMEM; + + host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2); + if (!host) { + dev_printk(KERN_ERR, &pdev->dev, + "failed to allocate ATA host\n"); + rc = -ENOMEM; + goto err_out; } - probe_ent->n_ports = p; - return probe_ent; + port_mask = ATA_PORT_PRIMARY; + if (n_ports > 1) + port_mask |= ATA_PORT_SECONDARY; + + rc = ata_pci_init_native_host(host, port_mask); + if (rc) + goto err_out; + + /* init DMA related stuff */ + rc = ata_pci_init_bmdma(host); + if (rc) + goto err_bmdma; + + devres_remove_group(&pdev->dev, NULL); + *r_host = host; + return 0; + + err_bmdma: + /* This is necessary because PCI and iomap resources are + * merged and releasing the top group won't release the + * acquired resources if some of those have been acquired + * before entering this function. + */ + pcim_iounmap_regions(pdev, 0xf); + err_out: + devres_release_group(&pdev->dev, NULL); + return rc; } -static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, - struct ata_port_info **port, int port_mask) +struct ata_legacy_devres { + unsigned int mask; + unsigned long cmd_port[2]; + void __iomem * cmd_addr[2]; + void __iomem * ctl_addr[2]; + unsigned int irq[2]; + void * irq_dev_id[2]; +}; + +static void ata_legacy_free_irqs(struct ata_legacy_devres *legacy_dr) { - struct ata_probe_ent *probe_ent; - void __iomem *iomap[5] = { }, *bmdma; - - if (port_mask & ATA_PORT_PRIMARY) { - iomap[0] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CMD, 8); - iomap[1] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CTL, 1); - if (!iomap[0] || !iomap[1]) - return NULL; + int i; + + for (i = 0; i < 2; i++) { + if (!legacy_dr->irq[i]) + continue; + + free_irq(legacy_dr->irq[i], legacy_dr->irq_dev_id[i]); + legacy_dr->irq[i] = 0; + legacy_dr->irq_dev_id[i] = NULL; } +} - if (port_mask & ATA_PORT_SECONDARY) { - iomap[2] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CMD, 8); - iomap[3] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CTL, 1); - if (!iomap[2] || !iomap[3]) - return NULL; +static void ata_legacy_release(struct device *gdev, void *res) +{ + struct ata_legacy_devres *this = res; + int i; + + ata_legacy_free_irqs(this); + + for (i = 0; i < 2; i++) { + if (this->cmd_addr[i]) + ioport_unmap(this->cmd_addr[i]); + if (this->ctl_addr[i]) + ioport_unmap(this->ctl_addr[i]); + if (this->cmd_port[i]) + release_region(this->cmd_port[i], 8); } +} - bmdma = pcim_iomap(pdev, 4, 16); /* may fail */ - - /* alloc and init probe_ent */ - probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); - if (!probe_ent) - return NULL; - - probe_ent->n_ports = 2; - probe_ent->irq_flags = IRQF_SHARED; - - if (port_mask & ATA_PORT_PRIMARY) { - probe_ent->irq = ATA_PRIMARY_IRQ(pdev); - probe_ent->port[0].cmd_addr = iomap[0]; - probe_ent->port[0].altstatus_addr = - probe_ent->port[0].ctl_addr = iomap[1]; - if (bmdma) { - probe_ent->port[0].bmdma_addr = bmdma; - if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) && - (ioread8(bmdma + 2) & 0x80)) - probe_ent->_host_flags |= ATA_HOST_SIMPLEX; - } - ata_std_ports(&probe_ent->port[0]); - } else - probe_ent->dummy_port_mask |= ATA_PORT_PRIMARY; +static int ata_init_legacy_port(struct ata_port *ap, + struct ata_legacy_devres *legacy_dr) +{ + struct ata_host *host = ap->host; + int port_no = ap->port_no; + unsigned long cmd_port, ctl_port; + + if (port_no == 0) { + cmd_port = ATA_PRIMARY_CMD; + ctl_port = ATA_PRIMARY_CTL; + } else { + cmd_port = ATA_SECONDARY_CMD; + ctl_port = ATA_SECONDARY_CTL; + } + + /* request cmd_port */ + if (request_region(cmd_port, 8, "libata")) + legacy_dr->cmd_port[port_no] = cmd_port; + else { + dev_printk(KERN_WARNING, host->dev, + "0x%0lX IDE port busy\n", cmd_port); + return -EBUSY; + } - if (port_mask & ATA_PORT_SECONDARY) { - if (probe_ent->irq) - probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev); + /* iomap cmd and ctl ports */ + legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8); + legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1); + if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) + return -ENOMEM; + + /* init IO addresses */ + ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no]; + ap->ioaddr.altstatus_addr = legacy_dr->ctl_addr[port_no]; + ap->ioaddr.ctl_addr = legacy_dr->ctl_addr[port_no]; + ata_std_ports(&ap->ioaddr); + + return 0; +} + +/** + * ata_init_legacy_host - acquire legacy ATA resources and init ATA host + * @host: target ATA host + * @legacy_mask: out parameter, mask indicating ports is in legacy mode + * @was_busy: out parameter, indicates whether any port was busy + * + * Acquire legacy ATA resources for ports. + * + * LOCKING: + * Inherited from calling layer (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +static int ata_init_legacy_host(struct ata_host *host, + unsigned int *legacy_mask, int *was_busy) +{ + struct device *gdev = host->dev; + struct ata_legacy_devres *legacy_dr; + int i, rc; + + if (!devres_open_group(gdev, NULL, GFP_KERNEL)) + return -ENOMEM; + + rc = -ENOMEM; + legacy_dr = devres_alloc(ata_legacy_release, sizeof(*legacy_dr), + GFP_KERNEL); + if (!legacy_dr) + goto err_out; + devres_add(gdev, legacy_dr); + + for (i = 0; i < 2; i++) { + *legacy_mask &= ~(1 << i); + rc = ata_init_legacy_port(host->ports[i], legacy_dr); + if (rc == 0) + legacy_dr->mask |= 1 << i; + else if (rc == -EBUSY) + (*was_busy)++; + } + + if (!legacy_dr->mask) + return -EBUSY; + + for (i = 0; i < 2; i++) + if (!(legacy_dr->mask & (1 << i))) + host->ports[i]->ops = &ata_dummy_port_ops; + + *legacy_mask |= legacy_dr->mask; + + devres_remove_group(gdev, NULL); + return 0; + + err_out: + devres_release_group(gdev, NULL); + return rc; +} + +/** + * ata_request_legacy_irqs - request legacy ATA IRQs + * @host: target ATA host + * @handler: array of IRQ handlers + * @irq_flags: array of IRQ flags + * @dev_id: array of IRQ dev_ids + * + * Request legacy IRQs for non-dummy legacy ports in @host. All + * IRQ parameters are passed as array to allow ports to have + * separate IRQ handlers. + * + * LOCKING: + * Inherited from calling layer (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +static int ata_request_legacy_irqs(struct ata_host *host, + irq_handler_t const *handler, + const unsigned int *irq_flags, + void * const *dev_id) +{ + struct device *gdev = host->dev; + struct ata_legacy_devres *legacy_dr; + int i, rc; + + legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL); + BUG_ON(!legacy_dr); + + for (i = 0; i < host->n_ports; i++) { + unsigned int irq; + + /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */ + if (i == 0) + irq = ATA_PRIMARY_IRQ(to_pci_dev(gdev)); else - probe_ent->irq = ATA_SECONDARY_IRQ(pdev); - probe_ent->port[1].cmd_addr = iomap[2]; - probe_ent->port[1].altstatus_addr = - probe_ent->port[1].ctl_addr = iomap[3]; - if (bmdma) { - probe_ent->port[1].bmdma_addr = bmdma + 8; - if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) && - (ioread8(bmdma + 10) & 0x80)) - probe_ent->_host_flags |= ATA_HOST_SIMPLEX; + irq = ATA_SECONDARY_IRQ(to_pci_dev(gdev)); + + if (!(legacy_dr->mask & (1 << i))) + continue; + + if (!handler[i]) { + dev_printk(KERN_ERR, gdev, + "NULL handler specified for port %d\n", i); + rc = -EINVAL; + goto err_out; + } + + rc = request_irq(irq, handler[i], irq_flags[i], DRV_NAME, + dev_id[i]); + if (rc) { + dev_printk(KERN_ERR, gdev, + "irq %u request failed (errno=%d)\n", irq, rc); + goto err_out; } - ata_std_ports(&probe_ent->port[1]); - /* FIXME: could be pointing to stack area; must copy */ - probe_ent->pinfo2 = port[1]; - } else - probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY; + /* record irq allocation in legacy_dr */ + legacy_dr->irq[i] = irq; + legacy_dr->irq_dev_id[i] = dev_id[i]; - return probe_ent; -} + /* only used to print info */ + if (i == 0) + host->irq = irq; + else + host->irq2 = irq; + } + return 0; + + err_out: + ata_legacy_free_irqs(legacy_dr); + return rc; +} /** * ata_pci_init_one - Initialize/register PCI IDE host controller @@ -718,8 +949,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, unsigned int n_ports) { struct device *dev = &pdev->dev; - struct ata_probe_ent *probe_ent = NULL; - struct ata_port_info *port[2]; + struct ata_host *host = NULL; + const struct ata_port_info *port[2]; u8 mask; unsigned int legacy_mode = 0; int rc; @@ -732,10 +963,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, BUG_ON(n_ports < 1 || n_ports > 2); port[0] = port_info[0]; - if (n_ports > 1) - port[1] = port_info[1]; - else - port[1] = port[0]; + port[1] = (n_ports > 1) ? port_info[1] : NULL; /* FIXME: Really for ATA it isn't safe because the device may be multi-purpose and we want to leave it alone if it was already @@ -743,7 +971,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, Checking dev->is_enabled is insufficient as this is not set at boot for the primary video which is BIOS enabled - */ + */ rc = pcim_enable_device(pdev); if (rc) @@ -769,96 +997,68 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, #endif } + /* alloc and init host */ + host = ata_host_alloc_pinfo(dev, port, n_ports); + if (!host) { + dev_printk(KERN_ERR, &pdev->dev, + "failed to allocate ATA host\n"); + rc = -ENOMEM; + goto err_out; + } + if (!legacy_mode) { - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) { - pcim_pin_device(pdev); + unsigned int port_mask; + + port_mask = ATA_PORT_PRIMARY; + if (n_ports > 1) + port_mask |= ATA_PORT_SECONDARY; + + rc = ata_pci_init_native_host(host, port_mask); + if (rc) goto err_out; - } } else { - /* Deal with combined mode hack. This side of the logic all - goes away once the combined mode hack is killed in 2.6.21 */ - if (!devm_request_region(dev, ATA_PRIMARY_CMD, 8, "libata")) { - struct resource *conflict, res; - res.start = ATA_PRIMARY_CMD; - res.end = ATA_PRIMARY_CMD + 8 - 1; - conflict = ____request_resource(&ioport_resource, &res); - while (conflict->child) - conflict = ____request_resource(conflict, &res); - if (!strcmp(conflict->name, "libata")) - legacy_mode |= ATA_PORT_PRIMARY; - else { - pcim_pin_device(pdev); - printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \ - "ata: conflict with %s\n", - ATA_PRIMARY_CMD, - conflict->name); - } - } else - legacy_mode |= ATA_PORT_PRIMARY; - - if (!devm_request_region(dev, ATA_SECONDARY_CMD, 8, "libata")) { - struct resource *conflict, res; - res.start = ATA_SECONDARY_CMD; - res.end = ATA_SECONDARY_CMD + 8 - 1; - conflict = ____request_resource(&ioport_resource, &res); - while (conflict->child) - conflict = ____request_resource(conflict, &res); - if (!strcmp(conflict->name, "libata")) - legacy_mode |= ATA_PORT_SECONDARY; - else { - pcim_pin_device(pdev); - printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \ - "ata: conflict with %s\n", - ATA_SECONDARY_CMD, - conflict->name); - } - } else - legacy_mode |= ATA_PORT_SECONDARY; - - if (legacy_mode & ATA_PORT_PRIMARY) - pci_request_region(pdev, 1, DRV_NAME); - if (legacy_mode & ATA_PORT_SECONDARY) - pci_request_region(pdev, 3, DRV_NAME); - /* If there is a DMA resource, allocate it */ - pci_request_region(pdev, 4, DRV_NAME); - } + int was_busy = 0; - /* we have legacy mode, but all ports are unavailable */ - if (legacy_mode == (1 << 3)) { - rc = -EBUSY; - goto err_out; + rc = ata_init_legacy_host(host, &legacy_mode, &was_busy); + if (was_busy) + pcim_pin_device(pdev); + if (rc) + goto err_out; + + /* request respective PCI regions, may fail */ + rc = pci_request_region(pdev, 1, DRV_NAME); + rc = pci_request_region(pdev, 3, DRV_NAME); } - /* TODO: If we get no DMA mask we should fall back to PIO */ - rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - goto err_out; - rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); + /* init BMDMA, may fail */ + ata_pci_init_bmdma(host); + pci_set_master(pdev); + + /* start host and request IRQ */ + rc = ata_host_start(host); if (rc) goto err_out; - if (legacy_mode) { - probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode); - } else { - if (n_ports == 2) - probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); - else - probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); + if (!legacy_mode) + rc = devm_request_irq(dev, pdev->irq, + port_info[0]->port_ops->irq_handler, + IRQF_SHARED, DRV_NAME, host); + else { + irq_handler_t handler[2] = { host->ops->irq_handler, + host->ops->irq_handler }; + unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED }; + void *dev_id[2] = { host, host }; + + rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id); } - if (!probe_ent) { - rc = -ENOMEM; + if (rc) goto err_out; - } - - pci_set_master(pdev); - if (!ata_device_add(probe_ent)) { - rc = -ENODEV; + /* register */ + rc = ata_host_register(host, port_info[0]->sht); + if (rc) goto err_out; - } - devm_kfree(dev, probe_ent); devres_remove_group(dev, NULL); return 0; @@ -893,12 +1093,12 @@ int ata_pci_clear_simplex(struct pci_dev *pdev) return 0; } -unsigned long ata_pci_default_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long xfer_mask) +unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer_mask) { /* Filter out DMA modes if the device has been configured by the BIOS as PIO only */ - if (ap->ioaddr.bmdma_addr == 0) + if (adev->ap->ioaddr.bmdma_addr == 0) xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); return xfer_mask; } diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 06ccf230e3c..5f4d40cd328 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -41,12 +41,23 @@ struct ata_scsi_args { enum { /* flags for ata_dev_read_id() */ ATA_READID_POSTRESET = (1 << 0), /* reading ID after reset */ + + /* selector for ata_down_xfermask_limit() */ + ATA_DNXFER_PIO = 0, /* speed down PIO */ + ATA_DNXFER_DMA = 1, /* speed down DMA */ + ATA_DNXFER_40C = 2, /* apply 40c cable limit */ + ATA_DNXFER_FORCE_PIO = 3, /* force PIO */ + ATA_DNXFER_FORCE_PIO0 = 4, /* force PIO0 */ + + ATA_DNXFER_QUIET = (1 << 31), }; +extern unsigned int ata_print_id; extern struct workqueue_struct *ata_aux_wq; extern int atapi_enabled; extern int atapi_dmadir; extern int libata_fua; +extern int libata_noacpi; extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, u64 block, u32 n_block, unsigned int tf_flags, @@ -68,7 +79,7 @@ extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags); extern int ata_dev_configure(struct ata_device *dev); extern int sata_down_spd_limit(struct ata_port *ap); extern int sata_set_spd_needed(struct ata_port *ap); -extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0); +extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev); extern void ata_sg_clean(struct ata_queued_cmd *qc); extern void ata_qc_free(struct ata_queued_cmd *qc); @@ -82,15 +93,26 @@ extern int ata_flush_cache(struct ata_device *dev); extern void ata_dev_init(struct ata_device *dev); extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); -extern void ata_port_init(struct ata_port *ap, struct ata_host *host, - const struct ata_probe_ent *ent, unsigned int port_no); -extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev, - const struct ata_port_info *port); +extern struct ata_port *ata_port_alloc(struct ata_host *host); +/* libata-acpi.c */ +#ifdef CONFIG_SATA_ACPI +extern int ata_acpi_exec_tfs(struct ata_port *ap); +extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix); +#else +static inline int ata_acpi_exec_tfs(struct ata_port *ap) +{ + return 0; +} +static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix) +{ + return 0; +} +#endif /* libata-scsi.c */ -extern struct scsi_transport_template ata_scsi_transport_template; - +extern int ata_scsi_add_hosts(struct ata_host *host, + struct scsi_host_template *sht); extern void ata_scsi_scan_host(struct ata_port *ap); extern int ata_scsi_offline_dev(struct ata_device *dev); extern void ata_scsi_hotplug(struct work_struct *work); @@ -135,7 +157,5 @@ extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc); /* libata-sff.c */ extern u8 ata_irq_on(struct ata_port *ap); -/* pata_sis.c */ -extern struct ata_port_info sis_info133; #endif /* __LIBATA_H__ */ diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index ab44d18850f..d40edebb510 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -34,7 +34,7 @@ #include <linux/dmi.h> #define DRV_NAME "pata_ali" -#define DRV_VERSION "0.7.2" +#define DRV_VERSION "0.7.4" /* * Cable special cases @@ -90,59 +90,6 @@ static int ali_c2_cable_detect(struct ata_port *ap) } /** - * ali_early_error_handler - reset for eary chip - * @ap: ATA port - * - * Handle the reset callback for the later chips with cable detect - */ - -static int ali_c2_pre_reset(struct ata_port *ap) -{ - ap->cbl = ali_c2_cable_detect(ap); - return ata_std_prereset(ap); -} - -static void ali_c2_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, ali_c2_pre_reset, - ata_std_softreset, NULL, - ata_std_postreset); -} - -/** - * ali_early_cable_detect - cable detection - * @ap: ATA port - * - * Perform cable detection for older chipsets. This turns out to be - * rather easy to implement - */ - -static int ali_early_cable_detect(struct ata_port *ap) -{ - return ATA_CBL_PATA40; -} - -/** - * ali_early_probe_init - reset for early chip - * @ap: ATA port - * - * Handle the reset callback for the early (pre cable detect) chips. - */ - -static int ali_early_pre_reset(struct ata_port *ap) -{ - ap->cbl = ali_early_cable_detect(ap); - return ata_std_prereset(ap); -} - -static void ali_early_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, ali_early_pre_reset, - ata_std_softreset, NULL, - ata_std_postreset); -} - -/** * ali_20_filter - filter for earlier ALI DMA * @ap: ALi ATA port * @adev: attached device @@ -151,7 +98,7 @@ static void ali_early_error_handler(struct ata_port *ap) * fix that later on. Also ensure we do not do UDMA on WDC drives */ -static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask) +static unsigned long ali_20_filter(struct ata_device *adev, unsigned long mask) { char model_num[ATA_ID_PROD_LEN + 1]; /* No DMA on anything but a disk for now */ @@ -160,7 +107,7 @@ static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num)); if (strstr(model_num, "WDC")) return mask &= ~ATA_MASK_UDMA; - return ata_pci_default_filter(ap, adev, mask); + return ata_pci_default_filter(adev, mask); } /** @@ -314,7 +261,6 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev) /** * ali_lock_sectors - Keep older devices to 255 sector mode - * @ap: ATA port * @adev: Device * * Called during the bus probe for each device that is found. We use @@ -324,7 +270,7 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev) * slower PIO methods */ -static void ali_lock_sectors(struct ata_port *ap, struct ata_device *adev) +static void ali_lock_sectors(struct ata_device *adev) { adev->max_sectors = 255; } @@ -345,8 +291,10 @@ static struct scsi_host_template ali_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; /* @@ -364,8 +312,9 @@ static struct ata_port_operations ali_early_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = ali_early_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -400,8 +349,9 @@ static struct ata_port_operations ali_20_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = ali_early_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -438,8 +388,9 @@ static struct ata_port_operations ali_c2_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = ali_c2_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ali_c2_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -475,8 +426,9 @@ static struct ata_port_operations ali_c5_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = ali_c2_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ali_c2_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -667,11 +619,13 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ata_pci_init_one(pdev, port_info, 2); } +#ifdef CONFIG_PM static int ali_reinit_one(struct pci_dev *pdev) { ali_init_chipset(pdev); return ata_pci_device_resume(pdev); } +#endif static const struct pci_device_id ali[] = { { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), }, @@ -685,8 +639,10 @@ static struct pci_driver ali_pci_driver = { .id_table = ali, .probe = ali_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ali_reinit_one, +#endif }; static int __init ali_init(void) diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 619e44b0403..536ee892ab7 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -25,7 +25,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_amd" -#define DRV_VERSION "0.2.7" +#define DRV_VERSION "0.3.8" /** * timing_setup - shared timing computation and load @@ -119,32 +119,25 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse } /** - * amd_probe_init - cable detection + * amd_probe_init - perform reset handling * @ap: ATA port * - * Perform cable detection. The BIOS stores this in PCI config - * space for us. + * Reset sequence checking enable bits to see which ports are + * active. */ static int amd_pre_reset(struct ata_port *ap) { - static const u32 bitmask[2] = {0x03, 0xC0}; static const struct pci_bits amd_enable_bits[] = { { 0x40, 1, 0x02, 0x02 }, { 0x40, 1, 0x01, 0x01 } }; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u8 ata66; if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) return -ENOENT; - pci_read_config_byte(pdev, 0x42, &ata66); - if (ata66 & bitmask[ap->port_no]) - ap->cbl = ATA_CBL_PATA80; - else - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -156,28 +149,16 @@ static void amd_error_handler(struct ata_port *ap) ata_std_postreset); } -static int amd_early_pre_reset(struct ata_port *ap) +static int amd_cable_detect(struct ata_port *ap) { + static const u32 bitmask[2] = {0x03, 0x0C}; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - static struct pci_bits amd_enable_bits[] = { - { 0x40, 1, 0x02, 0x02 }, - { 0x40, 1, 0x01, 0x01 } - }; - - if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) - return -ENOENT; - - /* No host side cable detection */ - ap->cbl = ATA_CBL_PATA80; - return ata_std_prereset(ap); - -} + u8 ata66; -static void amd_early_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, amd_early_pre_reset, - ata_std_softreset, NULL, - ata_std_postreset); + pci_read_config_byte(pdev, 0x42, &ata66); + if (ata66 & bitmask[ap->port_no]) + return ATA_CBL_PATA80; + return ATA_CBL_PATA40; } /** @@ -247,31 +228,16 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev) */ static int nv_pre_reset(struct ata_port *ap) { - static const u8 bitmask[2] = {0x03, 0xC0}; static const struct pci_bits nv_enable_bits[] = { { 0x50, 1, 0x02, 0x02 }, { 0x50, 1, 0x01, 0x01 } }; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u8 ata66; - u16 udma; if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no])) return -ENOENT; - pci_read_config_byte(pdev, 0x52, &ata66); - if (ata66 & bitmask[ap->port_no]) - ap->cbl = ATA_CBL_PATA80; - else - ap->cbl = ATA_CBL_PATA40; - - /* We now have to double check because the Nvidia boxes BIOS - doesn't always set the cable bits but does set mode bits */ - - pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma); - if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400) - ap->cbl = ATA_CBL_PATA80; return ata_std_prereset(ap); } @@ -281,6 +247,29 @@ static void nv_error_handler(struct ata_port *ap) ata_std_softreset, NULL, ata_std_postreset); } + +static int nv_cable_detect(struct ata_port *ap) +{ + static const u8 bitmask[2] = {0x03, 0x0C}; + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u8 ata66; + u16 udma; + int cbl; + + pci_read_config_byte(pdev, 0x52, &ata66); + if (ata66 & bitmask[ap->port_no]) + cbl = ATA_CBL_PATA80; + else + cbl = ATA_CBL_PATA40; + + /* We now have to double check because the Nvidia boxes BIOS + doesn't always set the cable bits but does set mode bits */ + pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma); + if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400) + cbl = ATA_CBL_PATA80; + return cbl; +} + /** * nv100_set_piomode - set initial PIO mode data * @ap: ATA interface @@ -334,8 +323,10 @@ static struct scsi_host_template amd_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations amd33_port_ops = { @@ -351,8 +342,9 @@ static struct ata_port_operations amd33_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = amd_early_error_handler, + .error_handler = amd_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -385,8 +377,9 @@ static struct ata_port_operations amd66_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = amd_early_error_handler, + .error_handler = amd_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_unknown, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -421,6 +414,7 @@ static struct ata_port_operations amd100_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = amd_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_unknown, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -455,6 +449,7 @@ static struct ata_port_operations amd133_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = amd_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = amd_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -489,6 +484,7 @@ static struct ata_port_operations nv100_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = nv_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = nv_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -523,6 +519,7 @@ static struct ata_port_operations nv133_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = nv_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = nv_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -663,6 +660,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ata_pci_init_one(pdev, port_info, 2); } +#ifdef CONFIG_PM static int amd_reinit_one(struct pci_dev *pdev) { if (pdev->vendor == PCI_VENDOR_ID_AMD) { @@ -679,6 +677,7 @@ static int amd_reinit_one(struct pci_dev *pdev) } return ata_pci_device_resume(pdev); } +#endif static const struct pci_device_id amd[] = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_COBRA_7401), 0 }, @@ -708,8 +707,10 @@ static struct pci_driver amd_pci_driver = { .id_table = amd, .probe = amd_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = amd_reinit_one, +#endif }; static int __init amd_init(void) diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 21c30282717..00e9ec342db 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -49,8 +49,6 @@ static int artop6210_pre_reset(struct ata_port *ap) if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) return -ENOENT; - - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -85,18 +83,28 @@ static int artop6260_pre_reset(struct ata_port *ap) }; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u8 tmp; /* Odd numbered device ids are the units with enable bits (the -R cards) */ if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) return -ENOENT; + return ata_std_prereset(ap); +} +/** + * artop6260_cable_detect - identify cable type + * @ap: Port + * + * Identify the cable type for the ARTOp interface in question + */ + +static int artop6260_cable_detect(struct ata_port *ap) +{ + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u8 tmp; pci_read_config_byte(pdev, 0x49, &tmp); if (tmp & (1 << ap->port_no)) - ap->cbl = ATA_CBL_PATA40; - else - ap->cbl = ATA_CBL_PATA80; - return ata_std_prereset(ap); + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; } /** @@ -225,7 +233,7 @@ static void artop6260_set_piomode(struct ata_port *ap, struct ata_device *adev) /** * artop6210_set_dmamode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring - * @adev: um + * @adev: Device whose timings we are configuring * * Set DMA mode for device, in host controller PCI config space. * @@ -333,6 +341,7 @@ static const struct ata_port_operations artop6210_ops = { .thaw = ata_bmdma_thaw, .error_handler = artop6210_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -366,6 +375,7 @@ static const struct ata_port_operations artop6260_ops = { .thaw = ata_bmdma_thaw, .error_handler = artop6260_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = artop6260_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index c3eb40c91c8..39c871a3dda 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -22,7 +22,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_atiixp" -#define DRV_VERSION "0.4.4" +#define DRV_VERSION "0.4.5" enum { ATIIXP_IDE_PIO_TIMING = 0x40, @@ -35,23 +35,15 @@ enum { static int atiixp_pre_reset(struct ata_port *ap) { - struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const struct pci_bits atiixp_enable_bits[] = { { 0x48, 1, 0x01, 0x00 }, { 0x48, 1, 0x08, 0x00 } }; - u8 udma; + struct pci_dev *pdev = to_pci_dev(ap->host->dev); if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no])) return -ENOENT; - /* Hack from drivers/ide/pci. Really we want to know how to do the - raw detection not play follow the bios mode guess */ - pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); - if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40) - ap->cbl = ATA_CBL_PATA80; - else - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -60,6 +52,19 @@ static void atiixp_error_handler(struct ata_port *ap) ata_bmdma_drive_eh(ap, atiixp_pre_reset, ata_std_softreset, NULL, ata_std_postreset); } +static int atiixp_cable_detect(struct ata_port *ap) +{ + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u8 udma; + + /* Hack from drivers/ide/pci. Really we want to know how to do the + raw detection not play follow the bios mode guess */ + pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); + if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40) + return ATA_CBL_PATA80; + return ATA_CBL_PATA40; +} + /** * atiixp_set_pio_timing - set initial PIO mode data * @ap: ATA interface @@ -224,8 +229,10 @@ static struct scsi_host_template atiixp_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations atiixp_port_ops = { @@ -243,6 +250,7 @@ static struct ata_port_operations atiixp_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = atiixp_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = atiixp_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = atiixp_bmdma_start, @@ -290,8 +298,10 @@ static struct pci_driver atiixp_pci_driver = { .id_table = atiixp, .probe = atiixp_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .resume = ata_pci_device_resume, .suspend = ata_pci_device_suspend, +#endif }; static int __init atiixp_init(void) diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c new file mode 100644 index 00000000000..2105985a801 --- /dev/null +++ b/drivers/ata/pata_cmd640.c @@ -0,0 +1,312 @@ +/* + * pata_cmd640.c - CMD640 PCI PATA for new ATA layer + * (C) 2007 Red Hat Inc + * Alan Cox <alan@redhat.com> + * + * Based upon + * linux/drivers/ide/pci/cmd640.c Version 1.02 Sep 01, 1996 + * + * Copyright (C) 1995-1996 Linus Torvalds & authors (see driver) + * + * This drives only the PCI version of the controller. If you have a + * VLB one then we have enough docs to support it but you can write + * your own code. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/blkdev.h> +#include <linux/delay.h> +#include <scsi/scsi_host.h> +#include <linux/libata.h> + +#define DRV_NAME "pata_cmd640" +#define DRV_VERSION "0.0.5" + +struct cmd640_reg { + int last; + u8 reg58[ATA_MAX_DEVICES]; +}; + +enum { + CFR = 0x50, + CNTRL = 0x51, + CMDTIM = 0x52, + ARTIM0 = 0x53, + DRWTIM0 = 0x54, + ARTIM23 = 0x57, + DRWTIM23 = 0x58, + BRST = 0x59 +}; + +/** + * cmd640_set_piomode - set initial PIO mode data + * @ap: ATA port + * @adev: ATA device + * + * Called to do the PIO mode setup. + */ + +static void cmd640_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + struct cmd640_reg *timing = ap->private_data; + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + struct ata_timing t; + const unsigned long T = 1000000 / 33; + const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 }; + u8 reg; + int arttim = ARTIM0 + 2 * adev->devno; + struct ata_device *pair = ata_dev_pair(adev); + + if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) { + printk(KERN_ERR DRV_NAME ": mode computation failed.\n"); + return; + } + + /* The second channel has shared timings and the setup timing is + messy to switch to merge it for worst case */ + if (ap->port_no && pair) { + struct ata_timing p; + ata_timing_compute(pair, pair->pio_mode, &p, T, 1); + ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP); + } + + /* Make the timings fit */ + if (t.recover > 16) { + t.active += t.recover - 16; + t.recover = 16; + } + if (t.active > 16) + t.active = 16; + + /* Now convert the clocks into values we can actually stuff into + the chip */ + + if (t.recover > 1) + t.recover--; /* 640B only */ + else + t.recover = 15; + + if (t.setup > 4) + t.setup = 0xC0; + else + t.setup = setup_data[t.setup]; + + if (ap->port_no == 0) { + t.active &= 0x0F; /* 0 = 16 */ + + /* Load setup timing */ + pci_read_config_byte(pdev, arttim, ®); + reg &= 0x3F; + reg |= t.setup; + pci_write_config_byte(pdev, arttim, reg); + + /* Load active/recovery */ + pci_write_config_byte(pdev, arttim + 1, (t.active << 4) | t.recover); + } else { + /* Save the shared timings for channel, they will be loaded + by qc_issue_prot. Reloading the setup time is expensive + so we keep a merged one loaded */ + pci_read_config_byte(pdev, ARTIM23, ®); + reg &= 0x3F; + reg |= t.setup; + pci_write_config_byte(pdev, ARTIM23, reg); + timing->reg58[adev->devno] = (t.active << 4) | t.recover; + } +} + + +/** + * cmd640_qc_issue_prot - command preparation hook + * @qc: Command to be issued + * + * Channel 1 has shared timings. We must reprogram the + * clock each drive 2/3 switch we do. + */ + +static unsigned int cmd640_qc_issue_prot(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ata_device *adev = qc->dev; + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + struct cmd640_reg *timing = ap->private_data; + + if (ap->port_no != 0 && adev->devno != timing->last) { + pci_write_config_byte(pdev, DRWTIM23, timing->reg58[adev->devno]); + timing->last = adev->devno; + } + return ata_qc_issue_prot(qc); +} + +/** + * cmd640_port_start - port setup + * @ap: ATA port being set up + * + * The CMD640 needs to maintain private data structures so we + * allocate space here. + */ + +static int cmd640_port_start(struct ata_port *ap) +{ + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + struct cmd640_reg *timing; + + int ret = ata_port_start(ap); + if (ret < 0) + return ret; + + timing = devm_kzalloc(&pdev->dev, sizeof(struct cmd640_reg), GFP_KERNEL); + if (timing == NULL) + return -ENOMEM; + timing->last = -1; /* Force a load */ + ap->private_data = timing; + return ret; +} + +static struct scsi_host_template cmd640_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .ioctl = ata_scsi_ioctl, + .queuecommand = ata_scsi_queuecmd, + .can_queue = ATA_DEF_QUEUE, + .this_id = ATA_SHT_THIS_ID, + .sg_tablesize = LIBATA_MAX_PRD, + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, + .emulated = ATA_SHT_EMULATED, + .use_clustering = ATA_SHT_USE_CLUSTERING, + .proc_name = DRV_NAME, + .dma_boundary = ATA_DMA_BOUNDARY, + .slave_configure = ata_scsi_slave_config, + .slave_destroy = ata_scsi_slave_destroy, + .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM + .resume = ata_scsi_device_resume, + .suspend = ata_scsi_device_suspend, +#endif +}; + +static struct ata_port_operations cmd640_port_ops = { + .port_disable = ata_port_disable, + .set_piomode = cmd640_set_piomode, + .mode_filter = ata_pci_default_filter, + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, + + .bmdma_setup = ata_bmdma_setup, + .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, + + .qc_prep = ata_qc_prep, + .qc_issue = cmd640_qc_issue_prot, + + /* In theory this is not needed once we kill the prefetcher */ + .data_xfer = ata_data_xfer_noirq, + + .irq_handler = ata_interrupt, + .irq_clear = ata_bmdma_irq_clear, + .irq_on = ata_irq_on, + .irq_ack = ata_irq_ack, + + .port_start = cmd640_port_start, +}; + +static void cmd640_hardware_init(struct pci_dev *pdev) +{ + u8 r; + u8 ctrl; + + /* CMD640 detected, commiserations */ + pci_write_config_byte(pdev, 0x5B, 0x00); + /* Get version info */ + pci_read_config_byte(pdev, CFR, &r); + /* PIO0 command cycles */ + pci_write_config_byte(pdev, CMDTIM, 0); + /* 512 byte bursts (sector) */ + pci_write_config_byte(pdev, BRST, 0x40); + /* + * A reporter a long time ago + * Had problems with the data fifo + * So don't run the risk + * Of putting crap on the disk + * For its better just to go slow + */ + /* Do channel 0 */ + pci_read_config_byte(pdev, CNTRL, &ctrl); + pci_write_config_byte(pdev, CNTRL, ctrl | 0xC0); + /* Ditto for channel 1 */ + pci_read_config_byte(pdev, ARTIM23, &ctrl); + ctrl |= 0x0C; + pci_write_config_byte(pdev, ARTIM23, ctrl); +} + +static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id) +{ + static struct ata_port_info info = { + .sht = &cmd640_sht, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .pio_mask = 0x1f, + .port_ops = &cmd640_port_ops + }; + + static struct ata_port_info *port_info[2] = { &info, &info }; + + cmd640_hardware_init(pdev); + return ata_pci_init_one(pdev, port_info, 2); +} + +static int cmd640_reinit_one(struct pci_dev *pdev) +{ + cmd640_hardware_init(pdev); +#ifdef CONFIG_PM + return ata_pci_device_resume(pdev); +#else + return 0; +#endif +} + +static const struct pci_device_id cmd640[] = { + { PCI_VDEVICE(CMD, 0x640), 0 }, + { }, +}; + +static struct pci_driver cmd640_pci_driver = { + .name = DRV_NAME, + .id_table = cmd640, + .probe = cmd640_init_one, + .remove = ata_pci_remove_one, +#ifdef CONFIG_PM + .suspend = ata_pci_device_suspend, +#endif + .resume = cmd640_reinit_one, +}; + +static int __init cmd640_init(void) +{ + return pci_register_driver(&cmd640_pci_driver); +} + +static void __exit cmd640_exit(void) +{ + pci_unregister_driver(&cmd640_pci_driver); +} + +MODULE_AUTHOR("Alan Cox"); +MODULE_DESCRIPTION("low-level driver for CMD640 PATA controllers"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, cmd640); +MODULE_VERSION(DRV_VERSION); + +module_init(cmd640_init); +module_exit(cmd640_exit); diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index da098282b5f..3989cc577fc 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -1,5 +1,5 @@ /* - * pata_cmd64x.c - ATI PATA for new ATA layer + * pata_cmd64x.c - CMD64x PATA for new ATA layer * (C) 2005 Red Hat Inc * Alan Cox <alan@redhat.com> * @@ -75,13 +75,7 @@ enum { DTPR1 = 0x7C }; -static int cmd64x_pre_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA40; - return ata_std_prereset(ap); -} - -static int cmd648_pre_reset(struct ata_port *ap) +static int cmd648_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 r; @@ -89,21 +83,8 @@ static int cmd648_pre_reset(struct ata_port *ap) /* Check cable detect bits */ pci_read_config_byte(pdev, BMIDECSR, &r); if (r & (1 << ap->port_no)) - ap->cbl = ATA_CBL_PATA80; - else - ap->cbl = ATA_CBL_PATA40; - - return ata_std_prereset(ap); -} - -static void cmd64x_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, cmd64x_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} - -static void cmd648_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, cmd648_pre_reset, ata_std_softreset, NULL, ata_std_postreset); + return ATA_CBL_PATA80; + return ATA_CBL_PATA40; } /** @@ -285,8 +266,10 @@ static struct scsi_host_template cmd64x_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations cmd64x_port_ops = { @@ -302,8 +285,9 @@ static struct ata_port_operations cmd64x_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = cmd64x_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -336,8 +320,9 @@ static struct ata_port_operations cmd646r1_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = cmd64x_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -370,8 +355,9 @@ static struct ata_port_operations cmd648_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = cmd648_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = cmd648_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -479,6 +465,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ata_pci_init_one(pdev, port_info, 2); } +#ifdef CONFIG_PM static int cmd64x_reinit_one(struct pci_dev *pdev) { u8 mrdmode; @@ -492,6 +479,7 @@ static int cmd64x_reinit_one(struct pci_dev *pdev) #endif return ata_pci_device_resume(pdev); } +#endif static const struct pci_device_id cmd64x[] = { { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 }, @@ -507,8 +495,10 @@ static struct pci_driver cmd64x_pci_driver = { .id_table = cmd64x, .probe = cmd64x_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = cmd64x_reinit_one, +#endif }; static int __init cmd64x_init(void) diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 1ce8fcfd782..79bef0d1fad 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -41,7 +41,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_cs5520" -#define DRV_VERSION "0.6.3" +#define DRV_VERSION "0.6.4" struct pio_clocks { @@ -139,18 +139,6 @@ static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev) cs5520_set_timings(ap, adev, adev->pio_mode); } - -static int cs5520_pre_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA40; - return ata_std_prereset(ap); -} - -static void cs5520_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, cs5520_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} - static struct scsi_host_template cs5520_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -167,8 +155,10 @@ static struct scsi_host_template cs5520_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations cs5520_port_ops = { @@ -184,8 +174,9 @@ static struct ata_port_operations cs5520_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = cs5520_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -195,7 +186,6 @@ static struct ata_port_operations cs5520_port_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_data_xfer, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -203,91 +193,104 @@ static struct ata_port_operations cs5520_port_ops = { .port_start = ata_port_start, }; -static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id) +static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { + struct ata_port_info pi = { + .flags = ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, + .port_ops = &cs5520_port_ops, + }; + const struct ata_port_info *ppi[2]; u8 pcicfg; void *iomap[5]; - static struct ata_probe_ent probe[2]; - int ports = 0; + struct ata_host *host; + struct ata_ioports *ioaddr; + int i, rc; /* IDE port enable bits */ - pci_read_config_byte(dev, 0x60, &pcicfg); + pci_read_config_byte(pdev, 0x60, &pcicfg); /* Check if the ATA ports are enabled */ if ((pcicfg & 3) == 0) return -ENODEV; + ppi[0] = ppi[1] = &ata_dummy_port_info; + if (pcicfg & 1) + ppi[0] = π + if (pcicfg & 2) + ppi[1] = π + if ((pcicfg & 0x40) == 0) { - printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n"); - pci_write_config_byte(dev, 0x60, pcicfg | 0x40); + dev_printk(KERN_WARNING, &pdev->dev, + "DMA mode disabled. Enabling.\n"); + pci_write_config_byte(pdev, 0x60, pcicfg | 0x40); } + pi.mwdma_mask = id->driver_data; + + host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2); + if (!host) + return -ENOMEM; + /* Perform set up for DMA */ - if (pci_enable_device_bars(dev, 1<<2)) { + if (pci_enable_device_bars(pdev, 1<<2)) { printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); return -ENODEV; } - pci_set_master(dev); - if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { + + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n"); return -ENODEV; } - if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) { + if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n"); return -ENODEV; } - /* Map IO ports */ - iomap[0] = devm_ioport_map(&dev->dev, 0x1F0, 8); - iomap[1] = devm_ioport_map(&dev->dev, 0x3F6, 1); - iomap[2] = devm_ioport_map(&dev->dev, 0x170, 8); - iomap[3] = devm_ioport_map(&dev->dev, 0x376, 1); - iomap[4] = pcim_iomap(dev, 2, 0); + /* Map IO ports and initialize host accordingly */ + iomap[0] = devm_ioport_map(&pdev->dev, 0x1F0, 8); + iomap[1] = devm_ioport_map(&pdev->dev, 0x3F6, 1); + iomap[2] = devm_ioport_map(&pdev->dev, 0x170, 8); + iomap[3] = devm_ioport_map(&pdev->dev, 0x376, 1); + iomap[4] = pcim_iomap(pdev, 2, 0); if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4]) return -ENOMEM; - /* We have to do our own plumbing as the PCI setup for this - chipset is non-standard so we can't punt to the libata code */ - - INIT_LIST_HEAD(&probe[0].node); - probe[0].dev = pci_dev_to_dev(dev); - probe[0].port_ops = &cs5520_port_ops; - probe[0].sht = &cs5520_sht; - probe[0].pio_mask = 0x1F; - probe[0].mwdma_mask = id->driver_data; - probe[0].irq = 14; - probe[0].irq_flags = 0; - probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST; - probe[0].n_ports = 1; - probe[0].port[0].cmd_addr = iomap[0]; - probe[0].port[0].ctl_addr = iomap[1]; - probe[0].port[0].altstatus_addr = iomap[1]; - probe[0].port[0].bmdma_addr = iomap[4]; - - /* The secondary lurks at different addresses but is otherwise - the same beastie */ - - probe[1] = probe[0]; - INIT_LIST_HEAD(&probe[1].node); - probe[1].irq = 15; - probe[1].port[0].cmd_addr = iomap[2]; - probe[1].port[0].ctl_addr = iomap[3]; - probe[1].port[0].altstatus_addr = iomap[3]; - probe[1].port[0].bmdma_addr = iomap[4] + 8; - - /* Let libata fill in the port details */ - ata_std_ports(&probe[0].port[0]); - ata_std_ports(&probe[1].port[0]); - - /* Now add the ports that are active */ - if (pcicfg & 1) - ports += ata_device_add(&probe[0]); - if (pcicfg & 2) - ports += ata_device_add(&probe[1]); - if (ports) - return 0; - return -ENODEV; + ioaddr = &host->ports[0]->ioaddr; + ioaddr->cmd_addr = iomap[0]; + ioaddr->ctl_addr = iomap[1]; + ioaddr->altstatus_addr = iomap[1]; + ioaddr->bmdma_addr = iomap[4]; + ata_std_ports(ioaddr); + + ioaddr = &host->ports[1]->ioaddr; + ioaddr->cmd_addr = iomap[2]; + ioaddr->ctl_addr = iomap[3]; + ioaddr->altstatus_addr = iomap[3]; + ioaddr->bmdma_addr = iomap[4] + 8; + ata_std_ports(ioaddr); + + /* activate the host */ + pci_set_master(pdev); + rc = ata_host_start(host); + if (rc) + return rc; + + for (i = 0; i < 2; i++) { + static const int irq[] = { 14, 15 }; + struct ata_port *ap = host->ports[0]; + + if (ata_port_is_dummy(ap)) + continue; + + rc = devm_request_irq(&pdev->dev, irq[ap->port_no], + ata_interrupt, 0, DRV_NAME, host); + if (rc) + return rc; + } + + return ata_host_register(host, &cs5520_sht); } /** @@ -306,9 +309,9 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev) struct ata_host *host = dev_get_drvdata(dev); ata_host_detach(host); - dev_set_drvdata(dev, NULL); } +#ifdef CONFIG_PM /** * cs5520_reinit_one - device resume * @pdev: PCI device @@ -325,6 +328,31 @@ static int cs5520_reinit_one(struct pci_dev *pdev) pci_write_config_byte(pdev, 0x60, pcicfg | 0x40); return ata_pci_device_resume(pdev); } + +/** + * cs5520_pci_device_suspend - device suspend + * @pdev: PCI device + * + * We have to cut and waste bits from the standard method because + * the 5520 is a bit odd and not just a pure ATA device. As a result + * we must not disable it. The needed code is short and this avoids + * chip specific mess in the core code. + */ + +static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + int rc = 0; + + rc = ata_host_suspend(host, mesg); + if (rc) + return rc; + + pci_save_state(pdev); + return 0; +} +#endif /* CONFIG_PM */ + /* For now keep DMA off. We can set it for all but A rev CS5510 once the core ATA code can handle it */ @@ -340,8 +368,10 @@ static struct pci_driver cs5520_pci_driver = { .id_table = pata_cs5520, .probe = cs5520_init_one, .remove = cs5520_remove_one, - .suspend = ata_pci_device_suspend, +#ifdef CONFIG_PM + .suspend = cs5520_pci_device_suspend, .resume = cs5520_reinit_one, +#endif }; static int __init cs5520_init(void) diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index 3d7b7d87ec6..29642d5ee18 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c @@ -35,7 +35,7 @@ #include <linux/dmi.h> #define DRV_NAME "pata_cs5530" -#define DRV_VERSION "0.7.1" +#define DRV_VERSION "0.7.2" static void __iomem *cs5530_port_base(struct ata_port *ap) { @@ -160,18 +160,6 @@ static unsigned int cs5530_qc_issue_prot(struct ata_queued_cmd *qc) return ata_qc_issue_prot(qc); } -static int cs5530_pre_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA40; - return ata_std_prereset(ap); -} - -static void cs5530_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, cs5530_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} - - static struct scsi_host_template cs5530_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -188,8 +176,10 @@ static struct scsi_host_template cs5530_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations cs5530_port_ops = { @@ -211,8 +201,9 @@ static struct ata_port_operations cs5530_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = cs5530_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = cs5530_qc_issue_prot, @@ -376,6 +367,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ata_pci_init_one(pdev, port_info, 2); } +#ifdef CONFIG_PM static int cs5530_reinit_one(struct pci_dev *pdev) { /* If we fail on resume we are doomed */ @@ -383,6 +375,7 @@ static int cs5530_reinit_one(struct pci_dev *pdev) BUG(); return ata_pci_device_resume(pdev); } +#endif /* CONFIG_PM */ static const struct pci_device_id cs5530[] = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), }, @@ -395,8 +388,10 @@ static struct pci_driver cs5530_pci_driver = { .id_table = cs5530, .probe = cs5530_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = cs5530_reinit_one, +#endif }; static int __init cs5530_init(void) diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index 17bc693cc51..08cccc9c659 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c @@ -70,36 +70,23 @@ #define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL)==0x00009172 ) /** - * cs5535_pre_reset - detect cable type + * cs5535_cable_detect - detect cable type * @ap: Port to detect on * * Perform cable detection for ATA66 capable cable. Return a libata * cable type. */ -static int cs5535_pre_reset(struct ata_port *ap) +static int cs5535_cable_detect(struct ata_port *ap) { u8 cable; struct pci_dev *pdev = to_pci_dev(ap->host->dev); pci_read_config_byte(pdev, CS5535_CABLE_DETECT, &cable); if (cable & 1) - ap->cbl = ATA_CBL_PATA80; + return ATA_CBL_PATA80; else - ap->cbl = ATA_CBL_PATA40; - return ata_std_prereset(ap); -} - -/** - * cs5535_error_handler - reset/probe - * @ap: Port to reset - * - * Reset and configure a port - */ - -static void cs5535_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, cs5535_pre_reset, ata_std_softreset, NULL, ata_std_postreset); + return ATA_CBL_PATA40; } /** @@ -185,8 +172,10 @@ static struct scsi_host_template cs5535_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations cs5535_port_ops = { @@ -203,8 +192,9 @@ static struct ata_port_operations cs5535_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = cs5535_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = cs5535_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -270,8 +260,10 @@ static struct pci_driver cs5535_pci_driver = { .id_table = cs5535, .probe = cs5535_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init cs5535_init(void) diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index 63f48f08763..6ec049c3b1d 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c @@ -41,17 +41,6 @@ enum { CY82_INDEX_TIMEOUT = 0x32 }; -static int cy82c693_pre_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA40; - return ata_std_prereset(ap); -} - -static void cy82c693_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, cy82c693_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} - /** * cy82c693_set_piomode - set initial PIO mode data * @ap: ATA interface @@ -136,8 +125,10 @@ static struct scsi_host_template cy82c693_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations cy82c693_port_ops = { @@ -154,8 +145,9 @@ static struct ata_port_operations cy82c693_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = cy82c693_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -206,8 +198,10 @@ static struct pci_driver cy82c693_pci_driver = { .id_table = cy82c693, .probe = cy82c693_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init cy82c693_init(void) diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index c19b6a8a7dc..a3216850bba 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c @@ -22,10 +22,10 @@ #include <linux/ata.h> #define DRV_NAME "pata_efar" -#define DRV_VERSION "0.4.3" +#define DRV_VERSION "0.4.4" /** - * efar_pre_reset - check for 40/80 pin + * efar_pre_reset - Enable bits * @ap: Port * * Perform cable detection for the EFAR ATA interface. This is @@ -38,18 +38,11 @@ static int efar_pre_reset(struct ata_port *ap) { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ { 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */ }; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u8 tmp; if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no])) return -ENOENT; - pci_read_config_byte(pdev, 0x47, &tmp); - if (tmp & (2 >> ap->port_no)) - ap->cbl = ATA_CBL_PATA40; - else - ap->cbl = ATA_CBL_PATA80; return ata_std_prereset(ap); } @@ -67,6 +60,25 @@ static void efar_error_handler(struct ata_port *ap) } /** + * efar_cable_detect - check for 40/80 pin + * @ap: Port + * + * Perform cable detection for the EFAR ATA interface. This is + * different to the PIIX arrangement + */ + +static int efar_cable_detect(struct ata_port *ap) +{ + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u8 tmp; + + pci_read_config_byte(pdev, 0x47, &tmp); + if (tmp & (2 >> ap->port_no)) + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; +} + +/** * efar_set_piomode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring * @adev: um @@ -234,8 +246,10 @@ static struct scsi_host_template efar_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static const struct ata_port_operations efar_ops = { @@ -254,6 +268,7 @@ static const struct ata_port_operations efar_ops = { .thaw = ata_bmdma_thaw, .error_handler = efar_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = efar_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -317,8 +332,10 @@ static struct pci_driver efar_pci_driver = { .id_table = efar_pci_tbl, .probe = efar_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init efar_init(void) diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 27d724b5eea..93cfa6d300a 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -27,7 +27,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.5.3" +#define DRV_VERSION "0.6.1" struct hpt_clock { u8 xfer_speed; @@ -169,13 +169,12 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, cons /** * hpt366_filter - mode selection filter - * @ap: ATA interface * @adev: ATA device * * Block UDMA on devices that cause trouble with this controller. */ -static unsigned long hpt366_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask) +static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask) { if (adev->class == ATA_DEV_ATA) { if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) @@ -185,7 +184,7 @@ static unsigned long hpt366_filter(const struct ata_port *ap, struct ata_device if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4)) mask &= ~(0x0F << ATA_SHIFT_UDMA); } - return ata_pci_default_filter(ap, adev, mask); + return ata_pci_default_filter(adev, mask); } /** @@ -210,24 +209,28 @@ static u32 hpt36x_find_mode(struct ata_port *ap, int speed) return 0xffffffffU; /* silence compiler warning */ } +static int hpt36x_cable_detect(struct ata_port *ap) +{ + u8 ata66; + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + + pci_read_config_byte(pdev, 0x5A, &ata66); + if (ata66 & (1 << ap->port_no)) + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; +} + static int hpt36x_pre_reset(struct ata_port *ap) { static const struct pci_bits hpt36x_enable_bits[] = { { 0x50, 1, 0x04, 0x04 }, { 0x54, 1, 0x04, 0x04 } }; - - u8 ata66; struct pci_dev *pdev = to_pci_dev(ap->host->dev); if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no])) return -ENOENT; - pci_read_config_byte(pdev, 0x5A, &ata66); - if (ata66 & (1 << ap->port_no)) - ap->cbl = ATA_CBL_PATA40; - else - ap->cbl = ATA_CBL_PATA80; return ata_std_prereset(ap); } @@ -328,8 +331,10 @@ static struct scsi_host_template hpt36x_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; /* @@ -352,6 +357,7 @@ static struct ata_port_operations hpt366_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = hpt36x_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = hpt36x_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -457,12 +463,13 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) return ata_pci_init_one(dev, port_info, 2); } +#ifdef CONFIG_PM static int hpt36x_reinit_one(struct pci_dev *dev) { hpt36x_init_chipset(dev); return ata_pci_device_resume(dev); } - +#endif static const struct pci_device_id hpt36x[] = { { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, @@ -474,8 +481,10 @@ static struct pci_driver hpt36x_pci_driver = { .id_table = hpt36x, .probe = hpt36x_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = hpt36x_reinit_one, +#endif }; static int __init hpt36x_init(void) diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 4ffc392052c..41d83129634 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -8,6 +8,7 @@ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc + * Portions Copyright (C) 2005-2006 MontaVista Software, Inc. * * TODO * PLL mode @@ -25,7 +26,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.5.2" +#define DRV_VERSION "0.6.5" struct hpt_clock { u8 xfer_speed; @@ -61,201 +62,75 @@ struct hpt_chip { * 31 FIFO enable. */ -/* from highpoint documentation. these are old values */ -static const struct hpt_clock hpt370_timings_33[] = { -/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */ - { XFER_UDMA_5, 0x16454e31 }, - { XFER_UDMA_4, 0x16454e31 }, - { XFER_UDMA_3, 0x166d4e31 }, - { XFER_UDMA_2, 0x16494e31 }, - { XFER_UDMA_1, 0x164d4e31 }, - { XFER_UDMA_0, 0x16514e31 }, - - { XFER_MW_DMA_2, 0x26514e21 }, - { XFER_MW_DMA_1, 0x26514e33 }, - { XFER_MW_DMA_0, 0x26514e97 }, - - { XFER_PIO_4, 0x06514e21 }, - { XFER_PIO_3, 0x06514e22 }, - { XFER_PIO_2, 0x06514e33 }, - { XFER_PIO_1, 0x06914e43 }, - { XFER_PIO_0, 0x06914e57 }, - { 0, 0x06514e57 } +static struct hpt_clock hpt37x_timings_33[] = { + { XFER_UDMA_6, 0x12446231 }, /* 0x12646231 ?? */ + { XFER_UDMA_5, 0x12446231 }, + { XFER_UDMA_4, 0x12446231 }, + { XFER_UDMA_3, 0x126c6231 }, + { XFER_UDMA_2, 0x12486231 }, + { XFER_UDMA_1, 0x124c6233 }, + { XFER_UDMA_0, 0x12506297 }, + + { XFER_MW_DMA_2, 0x22406c31 }, + { XFER_MW_DMA_1, 0x22406c33 }, + { XFER_MW_DMA_0, 0x22406c97 }, + + { XFER_PIO_4, 0x06414e31 }, + { XFER_PIO_3, 0x06414e42 }, + { XFER_PIO_2, 0x06414e53 }, + { XFER_PIO_1, 0x06814e93 }, + { XFER_PIO_0, 0x06814ea7 } }; -static const struct hpt_clock hpt370_timings_66[] = { - { XFER_UDMA_5, 0x14846231 }, - { XFER_UDMA_4, 0x14886231 }, - { XFER_UDMA_3, 0x148c6231 }, - { XFER_UDMA_2, 0x148c6231 }, - { XFER_UDMA_1, 0x14906231 }, - { XFER_UDMA_0, 0x14986231 }, - - { XFER_MW_DMA_2, 0x26514e21 }, - { XFER_MW_DMA_1, 0x26514e33 }, - { XFER_MW_DMA_0, 0x26514e97 }, - - { XFER_PIO_4, 0x06514e21 }, - { XFER_PIO_3, 0x06514e22 }, - { XFER_PIO_2, 0x06514e33 }, - { XFER_PIO_1, 0x06914e43 }, - { XFER_PIO_0, 0x06914e57 }, - { 0, 0x06514e57 } +static struct hpt_clock hpt37x_timings_50[] = { + { XFER_UDMA_6, 0x12848242 }, + { XFER_UDMA_5, 0x12848242 }, + { XFER_UDMA_4, 0x12ac8242 }, + { XFER_UDMA_3, 0x128c8242 }, + { XFER_UDMA_2, 0x120c8242 }, + { XFER_UDMA_1, 0x12148254 }, + { XFER_UDMA_0, 0x121882ea }, + + { XFER_MW_DMA_2, 0x22808242 }, + { XFER_MW_DMA_1, 0x22808254 }, + { XFER_MW_DMA_0, 0x228082ea }, + + { XFER_PIO_4, 0x0a81f442 }, + { XFER_PIO_3, 0x0a81f443 }, + { XFER_PIO_2, 0x0a81f454 }, + { XFER_PIO_1, 0x0ac1f465 }, + { XFER_PIO_0, 0x0ac1f48a } }; -/* these are the current (4 sep 2001) timings from highpoint */ -static const struct hpt_clock hpt370a_timings_33[] = { - { XFER_UDMA_5, 0x12446231 }, - { XFER_UDMA_4, 0x12446231 }, - { XFER_UDMA_3, 0x126c6231 }, - { XFER_UDMA_2, 0x12486231 }, - { XFER_UDMA_1, 0x124c6233 }, - { XFER_UDMA_0, 0x12506297 }, - - { XFER_MW_DMA_2, 0x22406c31 }, - { XFER_MW_DMA_1, 0x22406c33 }, - { XFER_MW_DMA_0, 0x22406c97 }, - - { XFER_PIO_4, 0x06414e31 }, - { XFER_PIO_3, 0x06414e42 }, - { XFER_PIO_2, 0x06414e53 }, - { XFER_PIO_1, 0x06814e93 }, - { XFER_PIO_0, 0x06814ea7 }, - { 0, 0x06814ea7 } +static struct hpt_clock hpt37x_timings_66[] = { + { XFER_UDMA_6, 0x1c869c62 }, + { XFER_UDMA_5, 0x1cae9c62 }, /* 0x1c8a9c62 */ + { XFER_UDMA_4, 0x1c8a9c62 }, + { XFER_UDMA_3, 0x1c8e9c62 }, + { XFER_UDMA_2, 0x1c929c62 }, + { XFER_UDMA_1, 0x1c9a9c62 }, + { XFER_UDMA_0, 0x1c829c62 }, + + { XFER_MW_DMA_2, 0x2c829c62 }, + { XFER_MW_DMA_1, 0x2c829c66 }, + { XFER_MW_DMA_0, 0x2c829d2e }, + + { XFER_PIO_4, 0x0c829c62 }, + { XFER_PIO_3, 0x0c829c84 }, + { XFER_PIO_2, 0x0c829ca6 }, + { XFER_PIO_1, 0x0d029d26 }, + { XFER_PIO_0, 0x0d029d5e } }; -/* 2x 33MHz timings */ -static const struct hpt_clock hpt370a_timings_66[] = { - { XFER_UDMA_5, 0x1488e673 }, - { XFER_UDMA_4, 0x1488e673 }, - { XFER_UDMA_3, 0x1498e673 }, - { XFER_UDMA_2, 0x1490e673 }, - { XFER_UDMA_1, 0x1498e677 }, - { XFER_UDMA_0, 0x14a0e73f }, - - { XFER_MW_DMA_2, 0x2480fa73 }, - { XFER_MW_DMA_1, 0x2480fa77 }, - { XFER_MW_DMA_0, 0x2480fb3f }, - - { XFER_PIO_4, 0x0c82be73 }, - { XFER_PIO_3, 0x0c82be95 }, - { XFER_PIO_2, 0x0c82beb7 }, - { XFER_PIO_1, 0x0d02bf37 }, - { XFER_PIO_0, 0x0d02bf5f }, - { 0, 0x0d02bf5f } -}; - -static const struct hpt_clock hpt370a_timings_50[] = { - { XFER_UDMA_5, 0x12848242 }, - { XFER_UDMA_4, 0x12ac8242 }, - { XFER_UDMA_3, 0x128c8242 }, - { XFER_UDMA_2, 0x120c8242 }, - { XFER_UDMA_1, 0x12148254 }, - { XFER_UDMA_0, 0x121882ea }, - - { XFER_MW_DMA_2, 0x22808242 }, - { XFER_MW_DMA_1, 0x22808254 }, - { XFER_MW_DMA_0, 0x228082ea }, - - { XFER_PIO_4, 0x0a81f442 }, - { XFER_PIO_3, 0x0a81f443 }, - { XFER_PIO_2, 0x0a81f454 }, - { XFER_PIO_1, 0x0ac1f465 }, - { XFER_PIO_0, 0x0ac1f48a }, - { 0, 0x0ac1f48a } -}; - -static const struct hpt_clock hpt372_timings_33[] = { - { XFER_UDMA_6, 0x1c81dc62 }, - { XFER_UDMA_5, 0x1c6ddc62 }, - { XFER_UDMA_4, 0x1c8ddc62 }, - { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */ - { XFER_UDMA_2, 0x1c91dc62 }, - { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */ - { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */ - - { XFER_MW_DMA_2, 0x2c829262 }, - { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */ - { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */ - - { XFER_PIO_4, 0x0c829c62 }, - { XFER_PIO_3, 0x0c829c84 }, - { XFER_PIO_2, 0x0c829ca6 }, - { XFER_PIO_1, 0x0d029d26 }, - { XFER_PIO_0, 0x0d029d5e }, - { 0, 0x0d029d5e } -}; - -static const struct hpt_clock hpt372_timings_50[] = { - { XFER_UDMA_5, 0x12848242 }, - { XFER_UDMA_4, 0x12ac8242 }, - { XFER_UDMA_3, 0x128c8242 }, - { XFER_UDMA_2, 0x120c8242 }, - { XFER_UDMA_1, 0x12148254 }, - { XFER_UDMA_0, 0x121882ea }, - - { XFER_MW_DMA_2, 0x22808242 }, - { XFER_MW_DMA_1, 0x22808254 }, - { XFER_MW_DMA_0, 0x228082ea }, - - { XFER_PIO_4, 0x0a81f442 }, - { XFER_PIO_3, 0x0a81f443 }, - { XFER_PIO_2, 0x0a81f454 }, - { XFER_PIO_1, 0x0ac1f465 }, - { XFER_PIO_0, 0x0ac1f48a }, - { 0, 0x0a81f443 } -}; - -static const struct hpt_clock hpt372_timings_66[] = { - { XFER_UDMA_6, 0x1c869c62 }, - { XFER_UDMA_5, 0x1cae9c62 }, - { XFER_UDMA_4, 0x1c8a9c62 }, - { XFER_UDMA_3, 0x1c8e9c62 }, - { XFER_UDMA_2, 0x1c929c62 }, - { XFER_UDMA_1, 0x1c9a9c62 }, - { XFER_UDMA_0, 0x1c829c62 }, - - { XFER_MW_DMA_2, 0x2c829c62 }, - { XFER_MW_DMA_1, 0x2c829c66 }, - { XFER_MW_DMA_0, 0x2c829d2e }, - - { XFER_PIO_4, 0x0c829c62 }, - { XFER_PIO_3, 0x0c829c84 }, - { XFER_PIO_2, 0x0c829ca6 }, - { XFER_PIO_1, 0x0d029d26 }, - { XFER_PIO_0, 0x0d029d5e }, - { 0, 0x0d029d26 } -}; - -static const struct hpt_clock hpt374_timings_33[] = { - { XFER_UDMA_6, 0x12808242 }, - { XFER_UDMA_5, 0x12848242 }, - { XFER_UDMA_4, 0x12ac8242 }, - { XFER_UDMA_3, 0x128c8242 }, - { XFER_UDMA_2, 0x120c8242 }, - { XFER_UDMA_1, 0x12148254 }, - { XFER_UDMA_0, 0x121882ea }, - - { XFER_MW_DMA_2, 0x22808242 }, - { XFER_MW_DMA_1, 0x22808254 }, - { XFER_MW_DMA_0, 0x228082ea }, - - { XFER_PIO_4, 0x0a81f442 }, - { XFER_PIO_3, 0x0a81f443 }, - { XFER_PIO_2, 0x0a81f454 }, - { XFER_PIO_1, 0x0ac1f465 }, - { XFER_PIO_0, 0x0ac1f48a }, - { 0, 0x06814e93 } -}; static const struct hpt_chip hpt370 = { "HPT370", 48, { - hpt370_timings_33, + hpt37x_timings_33, NULL, NULL, - hpt370_timings_66 + NULL } }; @@ -263,10 +138,10 @@ static const struct hpt_chip hpt370a = { "HPT370A", 48, { - hpt370a_timings_33, + hpt37x_timings_33, NULL, - hpt370a_timings_50, - hpt370a_timings_66 + hpt37x_timings_50, + NULL } }; @@ -274,10 +149,10 @@ static const struct hpt_chip hpt372 = { "HPT372", 55, { - hpt372_timings_33, + hpt37x_timings_33, NULL, - hpt372_timings_50, - hpt372_timings_66 + hpt37x_timings_50, + hpt37x_timings_66 } }; @@ -285,10 +160,10 @@ static const struct hpt_chip hpt302 = { "HPT302", 66, { - hpt372_timings_33, + hpt37x_timings_33, NULL, - hpt372_timings_50, - hpt372_timings_66 + hpt37x_timings_50, + hpt37x_timings_66 } }; @@ -296,10 +171,10 @@ static const struct hpt_chip hpt371 = { "HPT371", 66, { - hpt372_timings_33, + hpt37x_timings_33, NULL, - hpt372_timings_50, - hpt372_timings_66 + hpt37x_timings_50, + hpt37x_timings_66 } }; @@ -307,10 +182,10 @@ static const struct hpt_chip hpt372a = { "HPT372A", 66, { - hpt372_timings_33, + hpt37x_timings_33, NULL, - hpt372_timings_50, - hpt372_timings_66 + hpt37x_timings_50, + hpt37x_timings_66 } }; @@ -318,7 +193,7 @@ static const struct hpt_chip hpt374 = { "HPT374", 48, { - hpt374_timings_33, + hpt37x_timings_33, NULL, NULL, NULL @@ -397,13 +272,12 @@ static const char *bad_ata100_5[] = { /** * hpt370_filter - mode selection filter - * @ap: ATA interface * @adev: ATA device * * Block UDMA on devices that cause trouble with this controller. */ -static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask) +static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask) { if (adev->class == ATA_DEV_ATA) { if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) @@ -411,24 +285,23 @@ static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) mask &= ~(0x1F << ATA_SHIFT_UDMA); } - return ata_pci_default_filter(ap, adev, mask); + return ata_pci_default_filter(adev, mask); } /** * hpt370a_filter - mode selection filter - * @ap: ATA interface * @adev: ATA device * * Block UDMA on devices that cause trouble with this controller. */ -static unsigned long hpt370a_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask) +static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask) { if (adev->class != ATA_DEV_ATA) { if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) mask &= ~ (0x1F << ATA_SHIFT_UDMA); } - return ata_pci_default_filter(ap, adev, mask); + return ata_pci_default_filter(adev, mask); } /** @@ -462,8 +335,7 @@ static int hpt37x_pre_reset(struct ata_port *ap) ap->cbl = ATA_CBL_PATA80; /* Reset the state machine */ - pci_write_config_byte(pdev, 0x50, 0x37); - pci_write_config_byte(pdev, 0x54, 0x37); + pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(100); return ata_std_prereset(ap); @@ -513,8 +385,7 @@ static int hpt374_pre_reset(struct ata_port *ap) ap->cbl = ATA_CBL_PATA80; /* Reset the state machine */ - pci_write_config_byte(pdev, 0x50, 0x37); - pci_write_config_byte(pdev, 0x54, 0x37); + pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(100); return ata_std_prereset(ap); @@ -1032,6 +903,24 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x3f, .port_ops = &hpt370a_port_ops }; + /* HPT370 - UDMA100 */ + static struct ata_port_info info_hpt370_33 = { + .sht = &hpt37x_sht, + .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = 0x0f, + .port_ops = &hpt370_port_ops + }; + /* HPT370A - UDMA100 */ + static struct ata_port_info info_hpt370a_33 = { + .sht = &hpt37x_sht, + .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = 0x0f, + .port_ops = &hpt370a_port_ops + }; /* HPT371, 372 and friends - UDMA133 */ static struct ata_port_info info_hpt372 = { .sht = &hpt37x_sht, @@ -1067,7 +956,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) u8 irqmask; u32 class_rev; + u8 mcr1; u32 freq; + int prefer_dpll = 1; + + unsigned long iobase = pci_resource_start(dev, 4); const struct hpt_chip *chip_table; int clock_slot; @@ -1088,10 +981,12 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) case 3: port = &info_hpt370; chip_table = &hpt370; + prefer_dpll = 0; break; case 4: port = &info_hpt370a; chip_table = &hpt370a; + prefer_dpll = 0; break; case 5: port = &info_hpt372; @@ -1119,8 +1014,16 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) chip_table = &hpt302; break; case PCI_DEVICE_ID_TTI_HPT371: + if (class_rev > 1) + return -ENODEV; port = &info_hpt372; chip_table = &hpt371; + /* Single channel device, master is not present + but the BIOS (or us for non x86) must mark it + absent */ + pci_read_config_byte(dev, 0x50, &mcr1); + mcr1 &= ~0x04; + pci_write_config_byte(dev, 0x50, mcr1); break; case PCI_DEVICE_ID_TTI_HPT374: chip_table = &hpt374; @@ -1150,8 +1053,18 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) */ pci_write_config_byte(dev, 0x5b, 0x23); + + /* + * HighPoint does this for HPT372A. + * NOTE: This register is only writeable via I/O space. + */ + if (chip_table == &hpt372a) + outb(0x0e, iobase + 0x9c); - pci_read_config_dword(dev, 0x70, &freq); + /* Some devices do not let this value be accessed via PCI space + according to the old driver */ + + freq = inl(iobase + 0x90); if ((freq >> 12) != 0xABCDE) { int i; u8 sr; @@ -1162,7 +1075,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* This is the process the HPT371 BIOS is reported to use */ for(i = 0; i < 128; i++) { pci_read_config_byte(dev, 0x78, &sr); - total += sr; + total += sr & 0x1FF; udelay(15); } freq = total / 128; @@ -1173,15 +1086,27 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) * Turn the frequency check into a band and then find a timing * table to match it. */ - + clock_slot = hpt37x_clock_slot(freq, chip_table->base); - if (chip_table->clocks[clock_slot] == NULL) { + if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) { /* * We need to try PLL mode instead + * + * For non UDMA133 capable devices we should + * use a 50MHz DPLL by choice */ - unsigned int f_low = (MHz[clock_slot] * chip_table->base) / 192; - unsigned int f_high = f_low + 2; + unsigned int f_low, f_high; int adjust; + + clock_slot = 2; + if (port->udma_mask & 0xE0) + clock_slot = 3; + + f_low = (MHz[clock_slot] * chip_table->base) / 192; + f_high = f_low + 2; + + /* Select the DPLL clock. */ + pci_write_config_byte(dev, 0x5b, 0x21); for(adjust = 0; adjust < 8; adjust++) { if (hpt37x_calibrate_dpll(dev)) @@ -1197,25 +1122,27 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); return -ENODEV; } - /* Check if this works for all cases */ - port->private_data = (void *)hpt370_timings_66; + if (clock_slot == 3) + port->private_data = (void *)hpt37x_timings_66; + else + port->private_data = (void *)hpt37x_timings_50; printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]); } else { port->private_data = (void *)chip_table->clocks[clock_slot]; /* - * Perform a final fixup. The 371 and 372 clock determines - * if UDMA133 is available. - */ - - if (clock_slot == 2 && chip_table == &hpt372) { /* 50Mhz */ - printk(KERN_WARNING "pata_hpt37x: No UDMA133 support available with 50MHz bus clock.\n"); - if (port == &info_hpt372) - port = &info_hpt372_50; - else BUG(); - } + * Perform a final fixup. Note that we will have used the + * DPLL on the HPT372 which means we don't have to worry + * about lack of UDMA133 support on lower clocks + */ + + if (clock_slot < 2 && port == &info_hpt370) + port = &info_hpt370_33; + if (clock_slot < 2 && port == &info_hpt370a) + port = &info_hpt370a_33; printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]); } + port_info[0] = port_info[1] = port; /* Now kick off ATA set up */ return ata_pci_init_one(dev, port_info, 2); diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 65f2e180e7f..6a34521b9e0 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -8,10 +8,10 @@ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc + * Portions Copyright (C) 2005-2006 MontaVista Software, Inc. * * * TODO - * 371N * Work out best PLL policy */ @@ -25,7 +25,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.2" +#define DRV_VERSION "0.3.3" enum { HPT_PCI_FAST = (1 << 31), @@ -115,14 +115,13 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) } /** - * hpt3x2n_pre_reset - reset the hpt3x2n bus - * @ap: ATA port to reset + * hpt3x2n_cable_detect - Detect the cable type + * @ap: ATA port to detect on * - * Perform the initial reset handling for the 3x2n series controllers. - * Reset the hardware and state machine, obtain the cable type. + * Return the cable type attached to this port */ -static int hpt3xn_pre_reset(struct ata_port *ap) +static int hpt3x2n_cable_detect(struct ata_port *ap) { u8 scr2, ata66; struct pci_dev *pdev = to_pci_dev(ap->host->dev); @@ -135,15 +134,26 @@ static int hpt3xn_pre_reset(struct ata_port *ap) pci_write_config_byte(pdev, 0x5B, scr2); if (ata66 & (1 << ap->port_no)) - ap->cbl = ATA_CBL_PATA40; + return ATA_CBL_PATA40; else - ap->cbl = ATA_CBL_PATA80; + return ATA_CBL_PATA80; +} + +/** + * hpt3x2n_pre_reset - reset the hpt3x2n bus + * @ap: ATA port to reset + * @deadline: deadline jiffies for the operation + * + * Perform the initial reset handling for the 3x2n series controllers. + * Reset the hardware and state machine, + */ +static int hpt3xn_pre_reset(struct ata_port *ap) +{ + struct pci_dev *pdev = to_pci_dev(ap->host->dev); /* Reset the state machine */ - pci_write_config_byte(pdev, 0x50, 0x37); - pci_write_config_byte(pdev, 0x54, 0x37); + pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(100); - return ata_std_prereset(ap); } @@ -364,6 +374,7 @@ static struct ata_port_operations hpt3x2n_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = hpt3x2n_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = hpt3x2n_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -422,8 +433,9 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) { unsigned long freq; u32 fcnt; + unsigned long iobase = pci_resource_start(pdev, 4); - pci_read_config_dword(pdev, 0x70/*CHECKME*/, &fcnt); + fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */ if ((fcnt >> 12) != 0xABCDE) { printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n"); return 33; /* Not BIOS set */ @@ -492,6 +504,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) unsigned int pci_mhz; unsigned int f_low, f_high; int adjust; + unsigned long iobase = pci_resource_start(dev, 4); pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xFF; @@ -501,6 +514,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (class_rev < 6) return -ENODEV; break; + case PCI_DEVICE_ID_TTI_HPT371: + if (class_rev < 2) + return -ENODEV; + /* 371N if rev > 1 */ + break; case PCI_DEVICE_ID_TTI_HPT372: /* 372N if rev >= 1*/ if (class_rev == 0) @@ -528,6 +546,19 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) irqmask &= ~0x10; pci_write_config_byte(dev, 0x5a, irqmask); + /* + * HPT371 chips physically have only one channel, the secondary one, + * but the primary channel registers do exist! Go figure... + * So, we manually disable the non-existing channel here + * (if the BIOS hasn't done this already). + */ + if (dev->device == PCI_DEVICE_ID_TTI_HPT371) { + u8 mcr1; + pci_read_config_byte(dev, 0x50, &mcr1); + mcr1 &= ~0x04; + pci_write_config_byte(dev, 0x50, mcr1); + } + /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or 50 for UDMA100. Right now we always use 66 */ @@ -546,14 +577,24 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) break; pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); } - if (adjust == 8) - printk(KERN_WARNING "hpt3xn: DPLL did not stabilize.\n"); + if (adjust == 8) { + printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n"); + return -ENODEV; + } /* Set our private data up. We only need a few flags so we use it directly */ port->private_data = NULL; - if (pci_mhz > 60) + if (pci_mhz > 60) { port->private_data = (void *)PCI66; + /* + * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in + * the MISC. register to stretch the UltraDMA Tss timing. + * NOTE: This register is only writeable via I/O space. + */ + if (dev->device == PCI_DEVICE_ID_TTI_HPT371) + outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); + } /* Now kick off ATA set up */ port_info[0] = port_info[1] = port; @@ -562,6 +603,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) static const struct pci_device_id hpt3x2n[] = { { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, + { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), }, { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), }, { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), }, { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), }, diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index 483ce7c12c9..ac28ec8c50a 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c @@ -25,25 +25,6 @@ #define DRV_NAME "pata_hpt3x3" #define DRV_VERSION "0.4.2" -static int hpt3x3_probe_init(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA40; - return ata_std_prereset(ap); -} - -/** - * hpt3x3_probe_reset - reset the hpt3x3 bus - * @ap: ATA port to reset - * - * Perform the housekeeping when doing an ATA bus reeset. We just - * need to force the cable type. - */ - -static void hpt3x3_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, hpt3x3_probe_init, ata_std_softreset, NULL, ata_std_postreset); -} - /** * hpt3x3_set_piomode - PIO setup * @ap: ATA interface @@ -119,8 +100,10 @@ static struct scsi_host_template hpt3x3_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations hpt3x3_port_ops = { @@ -137,8 +120,9 @@ static struct ata_port_operations hpt3x3_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = hpt3x3_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -206,11 +190,13 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id) return ata_pci_init_one(dev, port_info, 2); } +#ifdef CONFIG_PM static int hpt3x3_reinit_one(struct pci_dev *dev) { hpt3x3_init_chipset(dev); return ata_pci_device_resume(dev); } +#endif static const struct pci_device_id hpt3x3[] = { { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), }, @@ -223,8 +209,10 @@ static struct pci_driver hpt3x3_pci_driver = { .id_table = hpt3x3, .probe = hpt3x3_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = hpt3x3_reinit_one, +#endif }; static int __init hpt3x3_init(void) diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index 1bf5ec18b2e..d042efdfbac 100644 --- a/drivers/ata/pata_isapnp.c +++ b/drivers/ata/pata_isapnp.c @@ -17,7 +17,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_isapnp" -#define DRV_VERSION "0.1.5" +#define DRV_VERSION "0.2.0" static struct scsi_host_template isapnp_sht = { .module = THIS_MODULE, @@ -49,13 +49,13 @@ static struct ata_port_operations isapnp_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .data_xfer = ata_data_xfer, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -74,8 +74,10 @@ static struct ata_port_operations isapnp_port_ops = { static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id) { - struct ata_probe_ent ae; + struct ata_host *host; + struct ata_port *ap; void __iomem *cmd_addr, *ctl_addr; + int rc; if (pnp_port_valid(idev, 0) == 0) return -ENODEV; @@ -84,34 +86,36 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev if (pnp_irq_valid(idev, 0) == 0) return -ENODEV; + /* allocate host */ + host = ata_host_alloc(&idev->dev, 1); + if (!host) + return -ENOMEM; + + /* acquire resources and fill host */ cmd_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 0), 8); if (!cmd_addr) return -ENOMEM; - memset(&ae, 0, sizeof(struct ata_probe_ent)); - INIT_LIST_HEAD(&ae.node); - ae.dev = &idev->dev; - ae.port_ops = &isapnp_port_ops; - ae.sht = &isapnp_sht; - ae.n_ports = 1; - ae.pio_mask = 1; /* ISA so PIO 0 cycles */ - ae.irq = pnp_irq(idev, 0); - ae.irq_flags = 0; - ae.port_flags = ATA_FLAG_SLAVE_POSS; - ae.port[0].cmd_addr = cmd_addr; + ap = host->ports[0]; + + ap->ops = &isapnp_port_ops; + ap->pio_mask = 1; + ap->flags |= ATA_FLAG_SLAVE_POSS; + + ap->ioaddr.cmd_addr = cmd_addr; if (pnp_port_valid(idev, 1) == 0) { ctl_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 1), 1); - ae.port[0].altstatus_addr = ctl_addr; - ae.port[0].ctl_addr = ctl_addr; - ae.port_flags |= ATA_FLAG_SRST; + ap->ioaddr.altstatus_addr = ctl_addr; + ap->ioaddr.ctl_addr = ctl_addr; } - ata_std_ports(&ae.port[0]); - if (ata_device_add(&ae) == 0) - return -ENODEV; - return 0; + ata_std_ports(&ap->ioaddr); + + /* activate */ + return ata_host_activate(host, pnp_irq(idev, 0), ata_interrupt, 0, + &isapnp_sht); } /** @@ -128,7 +132,6 @@ static void isapnp_remove_one(struct pnp_dev *idev) struct ata_host *host = dev_get_drvdata(dev); ata_host_detach(host); - dev_set_drvdata(dev, NULL); } static struct pnp_device_id isapnp_devices[] = { diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c index 7eac869dfcd..011306ef833 100644 --- a/drivers/ata/pata_it8213.c +++ b/drivers/ata/pata_it8213.c @@ -25,8 +25,8 @@ * it8213_pre_reset - check for 40/80 pin * @ap: Port * - * Perform cable detection for the 8213 ATA interface. This is - * different to the PIIX arrangement + * Filter out ports by the enable bits before doing the normal reset + * and probe. */ static int it8213_pre_reset(struct ata_port *ap) @@ -34,23 +34,14 @@ static int it8213_pre_reset(struct ata_port *ap) static const struct pci_bits it8213_enable_bits[] = { { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ }; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u8 tmp; - if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no])) return -ENOENT; - - pci_read_config_byte(pdev, 0x42, &tmp); - if (tmp & 2) /* The initial docs are incorrect */ - ap->cbl = ATA_CBL_PATA40; - else - ap->cbl = ATA_CBL_PATA80; return ata_std_prereset(ap); } /** - * it8213_probe_reset - Probe specified port on PATA host controller + * it8213_error_handler - Probe specified port on PATA host controller * @ap: Port to probe * * LOCKING: @@ -63,9 +54,27 @@ static void it8213_error_handler(struct ata_port *ap) } /** + * it8213_cable_detect - check for 40/80 pin + * @ap: Port + * + * Perform cable detection for the 8213 ATA interface. This is + * different to the PIIX arrangement + */ + +static int it8213_cable_detect(struct ata_port *ap) +{ + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u8 tmp; + pci_read_config_byte(pdev, 0x42, &tmp); + if (tmp & 2) /* The initial docs are incorrect */ + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; +} + +/** * it8213_set_piomode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring - * @adev: um + * @adev: Device whose timings we are configuring * * Set PIO mode for device, in host controller PCI config space. * @@ -246,8 +255,10 @@ static struct scsi_host_template it8213_sht = { .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static const struct ata_port_operations it8213_ops = { @@ -266,6 +277,7 @@ static const struct ata_port_operations it8213_ops = { .thaw = ata_bmdma_thaw, .error_handler = it8213_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = it8213_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -330,8 +342,10 @@ static struct pci_driver it8213_pci_driver = { .id_table = it8213_pci_tbl, .probe = it8213_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init it8213_init(void) diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 73394c75be4..f1f8cec8c22 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -80,7 +80,7 @@ #define DRV_NAME "pata_it821x" -#define DRV_VERSION "0.3.3" +#define DRV_VERSION "0.3.6" struct it821x_dev { @@ -113,31 +113,6 @@ struct it821x_dev static int it8212_noraid; /** - * it821x_pre_reset - probe - * @ap: ATA port - * - * Set the cable type - */ - -static int it821x_pre_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA80; - return ata_std_prereset(ap); -} - -/** - * it821x_error_handler - probe/reset - * @ap: ATA port - * - * Set the cable type and trigger a probe - */ - -static void it821x_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, it821x_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} - -/** * it821x_program - program the PIO/MWDMA registers * @ap: ATA port * @adev: Device to program @@ -503,10 +478,12 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused /* We do need the right mode information for DMA or PIO and this comes from the current configuration flags */ if (dma_enabled & (1 << (5 + i))) { + ata_dev_printk(dev, KERN_INFO, "configured for DMA\n"); dev->xfer_mode = XFER_MW_DMA_0; dev->xfer_shift = ATA_SHIFT_MWDMA; dev->flags &= ~ATA_DFLAG_PIO; } else { + ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); dev->xfer_mode = XFER_PIO_0; dev->xfer_shift = ATA_SHIFT_PIO; dev->flags |= ATA_DFLAG_PIO; @@ -518,7 +495,6 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused /** * it821x_dev_config - Called each device identify - * @ap: ATA port * @adev: Device that has just been identified * * Perform the initial setup needed for each device that is chip @@ -529,7 +505,7 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused * basically we need to filter commands for this chip. */ -static void it821x_dev_config(struct ata_port *ap, struct ata_device *adev) +static void it821x_dev_config(struct ata_device *adev) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; @@ -644,8 +620,10 @@ static struct scsi_host_template it821x_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations it821x_smart_port_ops = { @@ -663,8 +641,9 @@ static struct ata_port_operations it821x_smart_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = it821x_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_unknown, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -699,8 +678,9 @@ static struct ata_port_operations it821x_passthru_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = it821x_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_unknown, .bmdma_setup = ata_bmdma_setup, .bmdma_start = it821x_passthru_bmdma_start, @@ -778,6 +758,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ata_pci_init_one(pdev, port_info, 2); } +#ifdef CONFIG_PM static int it821x_reinit_one(struct pci_dev *pdev) { /* Resume - turn raid back off if need be */ @@ -785,6 +766,7 @@ static int it821x_reinit_one(struct pci_dev *pdev) it821x_disable_raid(pdev); return ata_pci_device_resume(pdev); } +#endif static const struct pci_device_id it821x[] = { { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), }, @@ -798,8 +780,10 @@ static struct pci_driver it821x_pci_driver = { .id_table = it821x, .probe = it821x_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = it821x_reinit_one, +#endif }; static int __init it821x_init(void) diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 3222ac7b945..420c343e571 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -23,15 +23,16 @@ #include <scsi/scsi_host.h> #define DRV_NAME "pata_ixp4xx_cf" -#define DRV_VERSION "0.1.1ac1" +#define DRV_VERSION "0.1.2" -static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev) +static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error) { int i; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_enabled(dev)) { + if (ata_dev_ready(dev)) { + ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n"); dev->pio_mode = XFER_PIO_0; dev->xfer_mode = XFER_PIO_0; dev->xfer_shift = ATA_SHIFT_PIO; @@ -128,8 +129,8 @@ static struct ata_port_operations ixp4xx_port_ops = { .qc_issue = ata_qc_issue_prot, .eng_timeout = ata_eng_timeout, .data_xfer = ixp4xx_mmio_data_xfer, + .cable_detect = ata_cable_40wire, - .irq_handler = ata_interrupt, .irq_clear = ixp4xx_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -172,12 +173,12 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr, static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) { - int ret; unsigned int irq; struct resource *cs0, *cs1; - struct ata_probe_ent ae; - + struct ata_host *host; + struct ata_port *ap; struct ixp4xx_pata_data *data = pdev->dev.platform_data; + int rc; cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -185,6 +186,12 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) if (!cs0 || !cs1) return -EINVAL; + /* allocate host */ + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + return -ENOMEM; + + /* acquire resources and fill host */ pdev->dev.coherent_dma_mask = DMA_32BIT_MASK; data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000); @@ -192,38 +199,28 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq) - set_irq_type(irq, IRQT_HIGH); + set_irq_type(irq, IRQT_RISING); /* Setup expansion bus chip selects */ *data->cs0_cfg = data->cs0_bits; *data->cs1_cfg = data->cs1_bits; - memset(&ae, 0, sizeof(struct ata_probe_ent)); - INIT_LIST_HEAD(&ae.node); + ap = host->ports[0]; - ae.dev = &pdev->dev; - ae.port_ops = &ixp4xx_port_ops; - ae.sht = &ixp4xx_sht; - ae.n_ports = 1; - ae.pio_mask = 0x1f; /* PIO4 */ - ae.irq = irq; - ae.irq_flags = 0; - ae.port_flags = ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY - | ATA_FLAG_NO_ATAPI | ATA_FLAG_SRST; + ap->ops = &ixp4xx_port_ops; + ap->pio_mask = 0x1f; /* PIO4 */ + ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI; /* run in polling mode if no irq has been assigned */ if (!irq) - ae.port_flags |= ATA_FLAG_PIO_POLLING; + ap->flags |= ATA_FLAG_PIO_POLLING; - ixp4xx_setup_port(&ae.port[0], data); + ixp4xx_setup_port(&ap->ioaddr, data); dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); - ret = ata_device_add(&ae); - if (ret == 0) - return -ENODEV; - - return 0; + /* activate host */ + return ata_host_activate(host, irq, ata_interrupt, 0, &ixp4xx_sht); } static __devexit int ixp4xx_pata_remove(struct platform_device *dev) @@ -231,7 +228,6 @@ static __devexit int ixp4xx_pata_remove(struct platform_device *dev) struct ata_host *host = platform_get_drvdata(dev); ata_host_detach(host); - platform_set_drvdata(dev, NULL); return 0; } diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 7a635dd326f..43763c99ea0 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -137,6 +137,10 @@ static struct scsi_host_template jmicron_sht = { .slave_destroy = ata_scsi_slave_destroy, /* Use standard CHS mapping rules */ .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM + .suspend = ata_scsi_device_suspend, + .resume = ata_scsi_device_resume, +#endif }; static const struct ata_port_operations jmicron_ops = { @@ -202,49 +206,20 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i }; struct ata_port_info *port_info[2] = { &info, &info }; - u32 reg; - - /* PATA controller is fn 1, AHCI is fn 0 */ - if (id->driver_data != 368 && PCI_FUNC(pdev->devfn) != 1) - return -ENODEV; - - /* The 365/66 have two PATA channels, redirect the second */ - if (id->driver_data == 365 || id->driver_data == 366) { - pci_read_config_dword(pdev, 0x80, ®); - reg |= (1 << 24); /* IDE1 to PATA IDE secondary */ - pci_write_config_dword(pdev, 0x80, reg); - } - return ata_pci_init_one(pdev, port_info, 2); } -static int jmicron_reinit_one(struct pci_dev *pdev) -{ - u32 reg; - - switch(pdev->device) { - case PCI_DEVICE_ID_JMICRON_JMB368: - break; - case PCI_DEVICE_ID_JMICRON_JMB365: - case PCI_DEVICE_ID_JMICRON_JMB366: - /* Restore mapping or disks swap and boy does it get ugly */ - pci_read_config_dword(pdev, 0x80, ®); - reg |= (1 << 24); /* IDE1 to PATA IDE secondary */ - pci_write_config_dword(pdev, 0x80, reg); - /* Fall through */ - default: - /* Make sure AHCI is turned back on */ - pci_write_config_byte(pdev, 0x41, 0xa1); - } - return ata_pci_device_resume(pdev); -} - static const struct pci_device_id jmicron_pci_tbl[] = { - { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361}, - { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363}, - { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 365}, - { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 366}, - { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 368}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, + PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 361 }, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, + PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 363 }, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, + PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 365 }, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, + PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 366 }, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, + PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 368 }, { } /* terminate list */ }; @@ -254,8 +229,10 @@ static struct pci_driver jmicron_pci_driver = { .id_table = jmicron_pci_tbl, .probe = jmicron_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, - .resume = jmicron_reinit_one, + .resume = ata_pci_device_resume, +#endif }; static int __init jmicron_init(void) diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 98c1fee4b30..707099291e0 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -64,12 +64,12 @@ #include <linux/platform_device.h> #define DRV_NAME "pata_legacy" -#define DRV_VERSION "0.5.3" +#define DRV_VERSION "0.5.4" #define NR_HOST 6 static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; -static int legacy_irq[NR_HOST] = { 15, 14, 11, 10, 8, 12 }; +static int legacy_irq[NR_HOST] = { 14, 15, 11, 10, 8, 12 }; struct legacy_data { unsigned long timing; @@ -162,6 +162,7 @@ static struct ata_port_operations simple_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -185,8 +186,12 @@ static struct ata_port_operations legacy_port_ops = { .check_status = ata_check_status, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .cable_detect = ata_cable_40wire, + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -298,7 +303,11 @@ static struct ata_port_operations pdc20230_port_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -350,7 +359,11 @@ static struct ata_port_operations ht6560a_port_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -413,7 +426,11 @@ static struct ata_port_operations ht6560b_port_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -531,7 +548,11 @@ static struct ata_port_operations opti82c611a_port_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -661,7 +682,11 @@ static struct ata_port_operations opti82c46x_port_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = opti82c46x_qc_issue_prot, @@ -691,7 +716,8 @@ static struct ata_port_operations opti82c46x_port_ops = { static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl, int irq) { struct legacy_data *ld = &legacy_data[nr_legacy_host]; - struct ata_probe_ent ae; + struct ata_host *host; + struct ata_port *ap; struct platform_device *pdev; struct ata_port_operations *ops = &legacy_port_ops; void __iomem *io_addr, *ctrl_addr; @@ -773,24 +799,23 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl if (ops == &legacy_port_ops && (autospeed & mask)) ops = &simple_port_ops; - memset(&ae, 0, sizeof(struct ata_probe_ent)); - INIT_LIST_HEAD(&ae.node); - ae.dev = &pdev->dev; - ae.port_ops = ops; - ae.sht = &legacy_sht; - ae.n_ports = 1; - ae.pio_mask = pio_modes; - ae.irq = irq; - ae.irq_flags = 0; - ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST|iordy; - ae.port[0].cmd_addr = io_addr; - ae.port[0].altstatus_addr = ctrl_addr; - ae.port[0].ctl_addr = ctrl_addr; - ata_std_ports(&ae.port[0]); - ae.private_data = ld; - - ret = -ENODEV; - if (!ata_device_add(&ae)) + ret = -ENOMEM; + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + goto fail; + ap = host->ports[0]; + + ap->ops = ops; + ap->pio_mask = pio_modes; + ap->flags |= ATA_FLAG_SLAVE_POSS | iordy; + ap->ioaddr.cmd_addr = io_addr; + ap->ioaddr.altstatus_addr = ctrl_addr; + ap->ioaddr.ctl_addr = ctrl_addr; + ata_std_ports(&ap->ioaddr); + ap->private_data = ld; + + ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht); + if (ret) goto fail; legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev); diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index 13a70ac6f1d..d9b94a1b695 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -20,7 +20,7 @@ #include <linux/ata.h> #define DRV_NAME "pata_marvell" -#define DRV_VERSION "0.1.1" +#define DRV_VERSION "0.1.4" /** * marvell_pre_reset - check for 40/80 pin @@ -52,22 +52,23 @@ static int marvell_pre_reset(struct ata_port *ap) if ((pdev->device == 0x6145) && (ap->port_no == 0) && (!(devices & 0x10))) /* PATA enable ? */ return -ENOENT; + return ata_std_prereset(ap); +} +static int marvell_cable_detect(struct ata_port *ap) +{ /* Cable type */ switch(ap->port_no) { case 0: if (ioread8(ap->ioaddr.bmdma_addr + 1) & 1) - ap->cbl = ATA_CBL_PATA40; - else - ap->cbl = ATA_CBL_PATA80; - break; - + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; case 1: /* Legacy SATA port */ - ap->cbl = ATA_CBL_SATA; - break; + return ATA_CBL_SATA; } - return ata_std_prereset(ap); + BUG(); + return 0; /* Our BUG macro needs the right markup */ } /** @@ -103,8 +104,10 @@ static struct scsi_host_template marvell_sht = { .slave_destroy = ata_scsi_slave_destroy, /* Use standard CHS mapping rules */ .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static const struct ata_port_operations marvell_ops = { @@ -121,6 +124,7 @@ static const struct ata_port_operations marvell_ops = { .thaw = ata_bmdma_thaw, .error_handler = marvell_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = marvell_cable_detect, /* BMDMA handling is PCI ATA format, use helpers */ .bmdma_setup = ata_bmdma_setup, @@ -199,8 +203,10 @@ static struct pci_driver marvell_pci_driver = { .id_table = marvell_pci_tbl, .probe = marvell_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init marvell_init(void) diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 29e1809e5ec..9587a89f968 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -24,7 +24,7 @@ #define DRV_NAME "mpc52xx_ata" -#define DRV_VERSION "0.1.0" +#define DRV_VERSION "0.1.0ac2" /* Private structures used by the driver */ @@ -280,6 +280,10 @@ static struct scsi_host_template mpc52xx_ata_sht = { .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM + .suspend = ata_scsi_device_suspend, + .resume = ata_scsi_device_resume, +#endif }; static struct ata_port_operations mpc52xx_ata_port_ops = { @@ -293,39 +297,38 @@ static struct ata_port_operations mpc52xx_ata_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, .error_handler = mpc52xx_ata_error_handler, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .data_xfer = ata_data_xfer, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, .port_start = ata_port_start, }; -static struct ata_probe_ent mpc52xx_ata_probe_ent = { - .port_ops = &mpc52xx_ata_port_ops, - .sht = &mpc52xx_ata_sht, - .n_ports = 1, - .pio_mask = 0x1f, /* Up to PIO4 */ - .mwdma_mask = 0x00, /* No MWDMA */ - .udma_mask = 0x00, /* No UDMA */ - .port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, - .irq_flags = 0, -}; - static int __devinit mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv) { - struct ata_probe_ent *ae = &mpc52xx_ata_probe_ent; - struct ata_ioports *aio = &ae->port[0]; - int rv; - - INIT_LIST_HEAD(&ae->node); - ae->dev = dev; - ae->irq = priv->ata_irq; - - aio->cmd_addr = 0; /* Don't have a classic reg block */ + struct ata_host *host; + struct ata_port *ap; + struct ata_ioports *aio; + int rc; + + host = ata_host_alloc(dev, 1); + if (!host) + return -ENOMEM; + + ap = host->ports[0]; + ap->flags |= ATA_FLAG_SLAVE_POSS; + ap->pio_mask = 0x1f; /* Up to PIO4 */ + ap->mwdma_mask = 0x00; /* No MWDMA */ + ap->udma_mask = 0x00; /* No UDMA */ + ap->ops = &mpc52xx_ata_port_ops; + host->private_data = priv; + + aio = &ap->ioaddr; + aio->cmd_addr = NULL; /* Don't have a classic reg block */ aio->altstatus_addr = &priv->ata_regs->tf_control; aio->ctl_addr = &priv->ata_regs->tf_control; aio->data_addr = &priv->ata_regs->tf_data; @@ -339,11 +342,9 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv) aio->status_addr = &priv->ata_regs->tf_command; aio->command_addr = &priv->ata_regs->tf_command; - ae->private_data = priv; - - rv = ata_device_add(ae); - - return rv ? 0 : -EINVAL; + /* activate host */ + return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0, + &mpc52xx_ata_sht); } static struct mpc52xx_ata_priv * diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c index f2e7115f7ab..987c5fafab0 100644 --- a/drivers/ata/pata_mpiix.c +++ b/drivers/ata/pata_mpiix.c @@ -35,7 +35,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_mpiix" -#define DRV_VERSION "0.7.5" +#define DRV_VERSION "0.7.6" enum { IDETIM = 0x6C, /* IDE control register */ @@ -53,7 +53,6 @@ static int mpiix_pre_reset(struct ata_port *ap) if (!pci_test_config_bits(pdev, &mpiix_enable_bits)) return -ENOENT; - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -165,8 +164,10 @@ static struct scsi_host_template mpiix_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations mpiix_port_ops = { @@ -183,12 +184,12 @@ static struct ata_port_operations mpiix_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = mpiix_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = mpiix_qc_issue_prot, .data_xfer = ata_data_xfer, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -199,8 +200,9 @@ static struct ata_port_operations mpiix_port_ops = { static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id) { /* Single threaded by the PCI probe logic */ - static struct ata_probe_ent probe; static int printed_version; + struct ata_host *host; + struct ata_port *ap; void __iomem *cmd_addr, *ctl_addr; u16 idetim; int irq; @@ -208,6 +210,10 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (!printed_version++) dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); + host = ata_host_alloc(&dev->dev, 1); + if (!host) + return -ENOMEM; + /* MPIIX has many functions which can be turned on or off according to other devices present. Make sure IDE is enabled before we try and use it */ @@ -236,27 +242,21 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id) without BARs set fools the setup. #2 If you pci_disable_device the MPIIX your box goes castors up */ - INIT_LIST_HEAD(&probe.node); - probe.dev = pci_dev_to_dev(dev); - probe.port_ops = &mpiix_port_ops; - probe.sht = &mpiix_sht; - probe.pio_mask = 0x1F; - probe.irq_flags = IRQF_SHARED; - probe.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; - probe.n_ports = 1; + ap = host->ports[0]; + ap->ops = &mpiix_port_ops; + ap->pio_mask = 0x1F; + ap->flags |= ATA_FLAG_SLAVE_POSS; - probe.irq = irq; - probe.port[0].cmd_addr = cmd_addr; - probe.port[0].ctl_addr = ctl_addr; - probe.port[0].altstatus_addr = ctl_addr; + ap->ioaddr.cmd_addr = cmd_addr; + ap->ioaddr.ctl_addr = ctl_addr; + ap->ioaddr.altstatus_addr = ctl_addr; /* Let libata fill in the port details */ - ata_std_ports(&probe.port[0]); + ata_std_ports(&ap->ioaddr); - /* Now add the port that is active */ - if (ata_device_add(&probe)) - return 0; - return -ENODEV; + /* activate host */ + return ata_host_activate(host, irq, ata_interrupt, IRQF_SHARED, + &mpiix_sht); } static const struct pci_device_id mpiix[] = { @@ -270,8 +270,10 @@ static struct pci_driver mpiix_pci_driver = { .id_table = mpiix, .probe = mpiix_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init mpiix_init(void) diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index e8393e19be4..dbba5b77d79 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c @@ -16,33 +16,7 @@ #include <linux/ata.h> #define DRV_NAME "pata_netcell" -#define DRV_VERSION "0.1.6" - -/** - * netcell_probe_init - check for 40/80 pin - * @ap: Port - * - * Cables are handled by the RAID controller. Report 80 pin. - */ - -static int netcell_pre_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA80; - return ata_std_prereset(ap); -} - -/** - * netcell_probe_reset - Probe specified port on PATA host controller - * @ap: Port to probe - * - * LOCKING: - * None (inherited from caller). - */ - -static void netcell_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, netcell_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} +#define DRV_VERSION "0.1.7" /* No PIO or DMA methods needed for this device */ @@ -63,8 +37,10 @@ static struct scsi_host_template netcell_sht = { .slave_destroy = ata_scsi_slave_destroy, /* Use standard CHS mapping rules */ .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static const struct ata_port_operations netcell_ops = { @@ -79,8 +55,9 @@ static const struct ata_port_operations netcell_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = netcell_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_80wire, /* BMDMA handling is PCI ATA format, use helpers */ .bmdma_setup = ata_bmdma_setup, @@ -153,8 +130,10 @@ static struct pci_driver netcell_pci_driver = { .id_table = netcell_pci_tbl, .probe = netcell_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init netcell_init(void) diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index 3d1fa487c48..078aeda9cf8 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c @@ -28,13 +28,13 @@ #include <linux/libata.h> #define DRV_NAME "pata_ns87410" -#define DRV_VERSION "0.4.3" +#define DRV_VERSION "0.4.6" /** * ns87410_pre_reset - probe begin * @ap: ATA port * - * Set up cable type and use generic probe init + * Check enabled ports */ static int ns87410_pre_reset(struct ata_port *ap) @@ -47,7 +47,6 @@ static int ns87410_pre_reset(struct ata_port *ap) if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no])) return -ENOENT; - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -157,8 +156,10 @@ static struct scsi_host_template ns87410_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations ns87410_port_ops = { @@ -175,6 +176,7 @@ static struct ata_port_operations ns87410_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ns87410_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ns87410_qc_issue_prot, @@ -212,8 +214,10 @@ static struct pci_driver ns87410_pci_driver = { .id_table = ns87410, .probe = ns87410_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init ns87410_init(void) diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index 45215aa05e7..dea4690340d 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c @@ -25,7 +25,7 @@ #include <linux/ata.h> #define DRV_NAME "pata_oldpiix" -#define DRV_VERSION "0.5.3" +#define DRV_VERSION "0.5.5" /** * oldpiix_pre_reset - probe begin @@ -44,7 +44,6 @@ static int oldpiix_pre_reset(struct ata_port *ap) if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no])) return -ENOENT; - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -65,7 +64,7 @@ static void oldpiix_pata_error_handler(struct ata_port *ap) /** * oldpiix_set_piomode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring - * @adev: um + * @adev: Device whose timings we are configuring * * Set PIO mode for device, in host controller PCI config space. * @@ -209,10 +208,9 @@ static unsigned int oldpiix_qc_issue_prot(struct ata_queued_cmd *qc) struct ata_device *adev = qc->dev; if (adev != ap->private_data) { + oldpiix_set_piomode(ap, adev); if (adev->dma_mode) oldpiix_set_dmamode(ap, adev); - else if (adev->pio_mode) - oldpiix_set_piomode(ap, adev); } return ata_qc_issue_prot(qc); } @@ -234,8 +232,10 @@ static struct scsi_host_template oldpiix_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static const struct ata_port_operations oldpiix_pata_ops = { @@ -254,6 +254,7 @@ static const struct ata_port_operations oldpiix_pata_ops = { .thaw = ata_bmdma_thaw, .error_handler = oldpiix_pata_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -317,8 +318,10 @@ static struct pci_driver oldpiix_pci_driver = { .id_table = oldpiix_pci_tbl, .probe = oldpiix_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init oldpiix_init(void) diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c index da1aa148b37..13b63e21838 100644 --- a/drivers/ata/pata_opti.c +++ b/drivers/ata/pata_opti.c @@ -34,7 +34,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_opti" -#define DRV_VERSION "0.2.7" +#define DRV_VERSION "0.2.9" enum { READ_REG = 0, /* index of Read cycle timing register */ @@ -61,8 +61,6 @@ static int opti_pre_reset(struct ata_port *ap) if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no])) return -ENOENT; - - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -179,8 +177,10 @@ static struct scsi_host_template opti_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations opti_port_ops = { @@ -196,6 +196,7 @@ static struct ata_port_operations opti_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = opti_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -244,8 +245,10 @@ static struct pci_driver opti_pci_driver = { .id_table = opti, .probe = opti_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init opti_init(void) diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index d80b36e209c..b70e04c144d 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c @@ -33,7 +33,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_optidma" -#define DRV_VERSION "0.2.3" +#define DRV_VERSION "0.3.2" enum { READ_REG = 0, /* index of Read cycle timing register */ @@ -62,7 +62,6 @@ static int optidma_pre_reset(struct ata_port *ap) if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits)) return -ENOENT; - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -115,7 +114,7 @@ static void optidma_lock(struct ata_port *ap) } /** - * optidma_set_mode - set mode data + * optidma_mode_setup - set mode data * @ap: ATA interface * @adev: ATA device * @mode: Mode to set @@ -128,7 +127,7 @@ static void optidma_lock(struct ata_port *ap) * IRQ here we depend on the host set locking to avoid catastrophe. */ -static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode) +static void optidma_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode) { struct ata_device *pair = ata_dev_pair(adev); int pio = adev->pio_mode - XFER_PIO_0; @@ -202,7 +201,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo } /** - * optiplus_set_mode - DMA setup for Firestar Plus + * optiplus_mode_setup - DMA setup for Firestar Plus * @ap: ATA port * @adev: device * @mode: desired mode @@ -213,7 +212,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo * one */ -static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode) +static void optiplus_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 udcfg; @@ -225,7 +224,7 @@ static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 m pci_read_config_byte(pdev, 0x44, &udcfg); if (mode <= XFER_UDMA_0) { udcfg &= ~(1 << unit); - optidma_set_mode(ap, adev, adev->dma_mode); + optidma_mode_setup(ap, adev, adev->dma_mode); } else { udcfg |= (1 << unit); if (ap->port_no) { @@ -253,7 +252,7 @@ static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 m static void optidma_set_pio_mode(struct ata_port *ap, struct ata_device *adev) { - optidma_set_mode(ap, adev, adev->pio_mode); + optidma_mode_setup(ap, adev, adev->pio_mode); } /** @@ -268,7 +267,7 @@ static void optidma_set_pio_mode(struct ata_port *ap, struct ata_device *adev) static void optidma_set_dma_mode(struct ata_port *ap, struct ata_device *adev) { - optidma_set_mode(ap, adev, adev->dma_mode); + optidma_mode_setup(ap, adev, adev->dma_mode); } /** @@ -283,7 +282,7 @@ static void optidma_set_dma_mode(struct ata_port *ap, struct ata_device *adev) static void optiplus_set_pio_mode(struct ata_port *ap, struct ata_device *adev) { - optiplus_set_mode(ap, adev, adev->pio_mode); + optiplus_mode_setup(ap, adev, adev->pio_mode); } /** @@ -298,7 +297,7 @@ static void optiplus_set_pio_mode(struct ata_port *ap, struct ata_device *adev) static void optiplus_set_dma_mode(struct ata_port *ap, struct ata_device *adev) { - optiplus_set_mode(ap, adev, adev->dma_mode); + optiplus_mode_setup(ap, adev, adev->dma_mode); } /** @@ -322,26 +321,29 @@ static u8 optidma_make_bits43(struct ata_device *adev) } /** - * optidma_post_set_mode - finalize PCI setup + * optidma_set_mode - mode setup * @ap: port to set up * - * Finalise the configuration by writing the nibble of extra bits - * of data into the chip. + * Use the standard setup to tune the chipset and then finalise the + * configuration by writing the nibble of extra bits of data into + * the chip. */ -static void optidma_post_set_mode(struct ata_port *ap) +static int optidma_set_mode(struct ata_port *ap, struct ata_device **r_failed) { u8 r; int nybble = 4 * ap->port_no; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - - pci_read_config_byte(pdev, 0x43, &r); - - r &= (0x0F << nybble); - r |= (optidma_make_bits43(&ap->device[0]) + - (optidma_make_bits43(&ap->device[0]) << 2)) << nybble; - - pci_write_config_byte(pdev, 0x43, r); + int rc = ata_do_set_mode(ap, r_failed); + if (rc == 0) { + pci_read_config_byte(pdev, 0x43, &r); + + r &= (0x0F << nybble); + r |= (optidma_make_bits43(&ap->device[0]) + + (optidma_make_bits43(&ap->device[0]) << 2)) << nybble; + pci_write_config_byte(pdev, 0x43, r); + } + return rc; } static struct scsi_host_template optidma_sht = { @@ -360,8 +362,10 @@ static struct scsi_host_template optidma_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations optidma_port_ops = { @@ -379,7 +383,8 @@ static struct ata_port_operations optidma_port_ops = { .thaw = ata_bmdma_thaw, .post_internal_cmd = ata_bmdma_post_internal_cmd, .error_handler = optidma_error_handler, - .post_set_mode = optidma_post_set_mode, + .set_mode = optidma_set_mode, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -414,7 +419,8 @@ static struct ata_port_operations optiplus_port_ops = { .thaw = ata_bmdma_thaw, .post_internal_cmd = ata_bmdma_post_internal_cmd, .error_handler = optidma_error_handler, - .post_set_mode = optidma_post_set_mode, + .set_mode = optidma_set_mode, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -524,8 +530,10 @@ static struct pci_driver optidma_pci_driver = { .id_table = optidma, .probe = optidma_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init optidma_init(void) diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 36468ec6454..75dc84797ff 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -42,7 +42,7 @@ #define DRV_NAME "pata_pcmcia" -#define DRV_VERSION "0.2.11" +#define DRV_VERSION "0.3.1" /* * Private data structure to glue stuff together @@ -54,6 +54,39 @@ struct ata_pcmcia_info { dev_node_t node; }; +/** + * pcmcia_set_mode - PCMCIA specific mode setup + * @ap: Port + * @r_failed_dev: Return pointer for failed device + * + * Perform the tuning and setup of the devices and timings, which + * for PCMCIA is the same as any other controller. We wrap it however + * as we need to spot hardware with incorrect or missing master/slave + * decode, which alas is embarrassingly common in the PC world + */ + +static int pcmcia_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) +{ + struct ata_device *master = &ap->device[0]; + struct ata_device *slave = &ap->device[1]; + + if (!ata_dev_enabled(master) || !ata_dev_enabled(slave)) + return ata_do_set_mode(ap, r_failed_dev); + + if (memcmp(master->id + ATA_ID_FW_REV, slave->id + ATA_ID_FW_REV, + ATA_ID_FW_REV_LEN + ATA_ID_PROD_LEN) == 0) + { + /* Suspicious match, but could be two cards from + the same vendor - check serial */ + if (memcmp(master->id + ATA_ID_SERNO, slave->id + ATA_ID_SERNO, + ATA_ID_SERNO_LEN) == 0 && master->id[ATA_ID_SERNO] >> 8) { + ata_dev_printk(slave, KERN_WARNING, "is a ghost device, ignoring.\n"); + ata_dev_disable(slave); + } + } + return ata_do_set_mode(ap, r_failed_dev); +} + static struct scsi_host_template pcmcia_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -73,6 +106,7 @@ static struct scsi_host_template pcmcia_sht = { }; static struct ata_port_operations pcmcia_port_ops = { + .set_mode = pcmcia_set_mode, .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, @@ -84,13 +118,13 @@ static struct ata_port_operations pcmcia_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .data_xfer = ata_data_xfer_noirq, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -111,7 +145,8 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) static int pcmcia_init_one(struct pcmcia_device *pdev) { - struct ata_probe_ent ae; + struct ata_host *host; + struct ata_port *ap; struct ata_pcmcia_info *info; tuple_t tuple; struct { @@ -255,24 +290,24 @@ next_entry: * Having done the PCMCIA plumbing the ATA side is relatively * sane. */ - - memset(&ae, 0, sizeof(struct ata_probe_ent)); - INIT_LIST_HEAD(&ae.node); - ae.dev = &pdev->dev; - ae.port_ops = &pcmcia_port_ops; - ae.sht = &pcmcia_sht; - ae.n_ports = 1; - ae.pio_mask = 1; /* ISA so PIO 0 cycles */ - ae.irq = pdev->irq.AssignedIRQ; - ae.irq_flags = IRQF_SHARED; - ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; - ae.port[0].cmd_addr = io_addr; - ae.port[0].altstatus_addr = ctl_addr; - ae.port[0].ctl_addr = ctl_addr; - ata_std_ports(&ae.port[0]); - - ret = -ENODEV; - if (ata_device_add(&ae) == 0) + ret = -ENOMEM; + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + goto failed; + ap = host->ports[0]; + + ap->ops = &pcmcia_port_ops; + ap->pio_mask = 1; /* ISA so PIO 0 cycles */ + ap->flags |= ATA_FLAG_SLAVE_POSS; + ap->ioaddr.cmd_addr = io_addr; + ap->ioaddr.altstatus_addr = ctl_addr; + ap->ioaddr.ctl_addr = ctl_addr; + ata_std_ports(&ap->ioaddr); + + /* activate */ + ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_interrupt, + IRQF_SHARED, &pcmcia_sht); + if (ret) goto failed; info->ndev = 1; @@ -308,7 +343,6 @@ static void pcmcia_remove_one(struct pcmcia_device *pdev) if (info->ndev) { struct ata_host *host = dev_get_drvdata(dev); ata_host_detach(host); - dev_set_drvdata(dev, NULL); } info->ndev = 0; pdev->priv = NULL; @@ -320,14 +354,17 @@ static void pcmcia_remove_one(struct pcmcia_device *pdev) static struct pcmcia_device_id pcmcia_devices[] = { PCMCIA_DEVICE_FUNC_ID(4), PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */ + PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */ + PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */ PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), - PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), + PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */ PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001), - PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */ + PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0100), /* Viking CFA */ + PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar, Viking CFA */ PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74), PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9), diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 61537873d28..a61cbc11068 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -35,7 +35,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_pdc2027x" -#define DRV_VERSION "0.74-ac5" +#define DRV_VERSION "0.9" #undef PDC_DEBUG #ifdef PDC_DEBUG @@ -66,8 +66,10 @@ static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *e static void pdc2027x_error_handler(struct ata_port *ap); static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev); static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev); -static void pdc2027x_post_set_mode(struct ata_port *ap); static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc); +static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask); +static int pdc2027x_cable_detect(struct ata_port *ap); +static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed); /* * ATA Timing Tables based on 133MHz controller clock. @@ -146,6 +148,7 @@ static struct scsi_host_template pdc2027x_sht = { static struct ata_port_operations pdc2027x_pata100_ops = { .port_disable = ata_port_disable, + .mode_filter = ata_pci_default_filter, .tf_load = ata_tf_load, .tf_read = ata_tf_read, @@ -166,8 +169,8 @@ static struct ata_port_operations pdc2027x_pata100_ops = { .thaw = ata_bmdma_thaw, .error_handler = pdc2027x_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = pdc2027x_cable_detect, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -179,7 +182,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = { .port_disable = ata_port_disable, .set_piomode = pdc2027x_set_piomode, .set_dmamode = pdc2027x_set_dmamode, - .post_set_mode = pdc2027x_post_set_mode, + .set_mode = pdc2027x_set_mode, + .mode_filter = pdc2027x_mode_filter, .tf_load = ata_tf_load, .tf_read = ata_tf_read, @@ -200,8 +204,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = { .thaw = ata_bmdma_thaw, .error_handler = pdc2027x_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = pdc2027x_cable_detect, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -212,7 +216,6 @@ static struct ata_port_operations pdc2027x_pata133_ops = { static struct ata_port_info pdc2027x_port_info[] = { /* PDC_UDMA_100 */ { - .sht = &pdc2027x_sht, .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO, .pio_mask = 0x1f, /* pio0-4 */ @@ -222,7 +225,6 @@ static struct ata_port_info pdc2027x_port_info[] = { }, /* PDC_UDMA_133 */ { - .sht = &pdc2027x_sht, .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO, .pio_mask = 0x1f, /* pio0-4 */ @@ -261,7 +263,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade } /** - * pdc2027x_pata_cbl_detect - Probe host controller cable detect info + * pdc2027x_pata_cable_detect - Probe host controller cable detect info * @ap: Port for which cable detect info is desired * * Read 80c cable indicator from Promise extended register. @@ -270,7 +272,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade * LOCKING: * None (inherited from caller). */ -static void pdc2027x_cbl_detect(struct ata_port *ap) +static int pdc2027x_cable_detect(struct ata_port *ap) { u32 cgcr; @@ -281,13 +283,10 @@ static void pdc2027x_cbl_detect(struct ata_port *ap) PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no); - ap->cbl = ATA_CBL_PATA80; - return; - + return ATA_CBL_PATA80; cbl40: printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no); - ap->cbl = ATA_CBL_PATA40; - ap->udma_mask &= ATA_UDMA_MASK_40C; + return ATA_CBL_PATA40; } /** @@ -314,7 +313,6 @@ static int pdc2027x_prereset(struct ata_port *ap) /* Check whether port enabled */ if (!pdc2027x_port_enabled(ap)) return -ENOENT; - pdc2027x_cbl_detect(ap); return ata_std_prereset(ap); } @@ -334,6 +332,32 @@ static void pdc2027x_error_handler(struct ata_port *ap) } /** + * pdc2720x_mode_filter - mode selection filter + * @adev: ATA device + * @mask: list of modes proposed + * + * Block UDMA on devices that cause trouble with this controller. + */ + +static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask) +{ + unsigned char model_num[ATA_ID_PROD_LEN + 1]; + struct ata_device *pair = ata_dev_pair(adev); + + if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL) + return ata_pci_default_filter(adev, mask); + + /* Check for slave of a Maxtor at UDMA6 */ + ata_id_c_string(pair->id, model_num, ATA_ID_PROD, + ATA_ID_PROD_LEN + 1); + /* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */ + if(strstr(model_num, "Maxtor") == 0 && pair->dma_mode == XFER_UDMA_6) + mask &= ~ (1 << (6 + ATA_SHIFT_UDMA)); + + return ata_pci_default_filter(adev, mask); +} + +/** * pdc2027x_set_piomode - Initialize host controller PATA PIO timings * @ap: Port to configure * @adev: um @@ -444,17 +468,22 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev) } /** - * pdc2027x_post_set_mode - Set the timing registers back to correct values. + * pdc2027x_set_mode - Set the timing registers back to correct values. * @ap: Port to configure + * @r_failed: Returned device for failure * * The pdc2027x hardware will look at "SET FEATURES" and change the timing registers * automatically. The values set by the hardware might be incorrect, under 133Mhz PLL. * This function overwrites the possibly incorrect values set by the hardware to be correct. */ -static void pdc2027x_post_set_mode(struct ata_port *ap) +static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed) { int i; + i = ata_do_set_mode(ap, r_failed); + if (i < 0) + return i; + for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; @@ -476,6 +505,7 @@ static void pdc2027x_post_set_mode(struct ata_port *ap) } } } + return 0; } /** @@ -521,12 +551,12 @@ static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc) /** * pdc_read_counter - Read the ctr counter - * @probe_ent: for the port address + * @host: target ATA host */ -static long pdc_read_counter(struct ata_probe_ent *probe_ent) +static long pdc_read_counter(struct ata_host *host) { - void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR]; + void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR]; long counter; int retry = 1; u32 bccrl, bccrh, bccrlv, bccrhv; @@ -564,12 +594,12 @@ retry: * adjust_pll - Adjust the PLL input clock in Hz. * * @pdc_controller: controller specific information - * @probe_ent: For the port address + * @host: target ATA host * @pll_clock: The input of PLL in HZ */ -static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsigned int board_idx) +static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int board_idx) { - void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR]; + void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR]; u16 pll_ctl; long pll_clock_khz = pll_clock / 1000; long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ; @@ -649,19 +679,19 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi /** * detect_pll_input_clock - Detect the PLL input clock in Hz. - * @probe_ent: for the port address + * @host: target ATA host * Ex. 16949000 on 33MHz PCI bus for pdc20275. * Half of the PCI clock. */ -static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent) +static long pdc_detect_pll_input_clock(struct ata_host *host) { - void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR]; + void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR]; u32 scr; long start_count, end_count; long pll_clock; /* Read current counter value */ - start_count = pdc_read_counter(probe_ent); + start_count = pdc_read_counter(host); /* Start the test mode */ scr = readl(mmio_base + PDC_SYS_CTL); @@ -673,7 +703,7 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent) mdelay(100); /* Read the counter values again */ - end_count = pdc_read_counter(probe_ent); + end_count = pdc_read_counter(host); /* Stop the test mode */ scr = readl(mmio_base + PDC_SYS_CTL); @@ -692,11 +722,10 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent) /** * pdc_hardware_init - Initialize the hardware. - * @pdev: instance of pci_dev found - * @pdc_controller: controller specific information - * @pe: for the port address + * @host: target ATA host + * @board_idx: board identifier */ -static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, unsigned int board_idx) +static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx) { long pll_clock; @@ -706,15 +735,15 @@ static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, uns * Ex. 25MHz or 40MHz, we have to adjust the cycle_time. * The pdc20275 controller employs PLL circuit to help correct timing registers setting. */ - pll_clock = pdc_detect_pll_input_clock(pe); + pll_clock = pdc_detect_pll_input_clock(host); if (pll_clock < 0) /* counter overflow? Try again. */ - pll_clock = pdc_detect_pll_input_clock(pe); + pll_clock = pdc_detect_pll_input_clock(host); - dev_printk(KERN_INFO, &pdev->dev, "PLL input clock %ld kHz\n", pll_clock/1000); + dev_printk(KERN_INFO, host->dev, "PLL input clock %ld kHz\n", pll_clock/1000); /* Adjust PLL control register */ - pdc_adjust_pll(pe, pll_clock, board_idx); + pdc_adjust_pll(host, pll_clock, board_idx); return 0; } @@ -746,8 +775,7 @@ static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base) * Called when an instance of PCI adapter is inserted. * This function checks whether the hardware is supported, * initialize hardware and register an instance of ata_host to - * libata by providing struct ata_probe_ent and ata_device_add(). - * (implements struct pci_driver.probe() ) + * libata. (implements struct pci_driver.probe() ) * * @pdev: instance of pci_dev found * @ent: matching entry in the id_tbl[] @@ -756,14 +784,21 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de { static int printed_version; unsigned int board_idx = (unsigned int) ent->driver_data; - - struct ata_probe_ent *probe_ent; + const struct ata_port_info *ppi[] = + { &pdc2027x_port_info[board_idx], NULL }; + struct ata_host *host; void __iomem *mmio_base; int rc; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* alloc host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2); + if (!host) + return -ENOMEM; + + /* acquire resources and fill host */ rc = pcim_enable_device(pdev); if (rc) return rc; @@ -771,6 +806,7 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME); if (rc) return rc; + host->iomap = pcim_iomap_table(pdev); rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -780,46 +816,22 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de if (rc) return rc; - /* Prepare the probe entry */ - probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) - return -ENOMEM; - - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - - probe_ent->sht = pdc2027x_port_info[board_idx].sht; - probe_ent->port_flags = pdc2027x_port_info[board_idx].flags; - probe_ent->pio_mask = pdc2027x_port_info[board_idx].pio_mask; - probe_ent->mwdma_mask = pdc2027x_port_info[board_idx].mwdma_mask; - probe_ent->udma_mask = pdc2027x_port_info[board_idx].udma_mask; - probe_ent->port_ops = pdc2027x_port_info[board_idx].port_ops; + mmio_base = host->iomap[PDC_MMIO_BAR]; - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->iomap = pcim_iomap_table(pdev); + pdc_ata_setup_port(&host->ports[0]->ioaddr, mmio_base + 0x17c0); + host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x1000; + pdc_ata_setup_port(&host->ports[1]->ioaddr, mmio_base + 0x15c0); + host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x1008; - mmio_base = probe_ent->iomap[PDC_MMIO_BAR]; - - pdc_ata_setup_port(&probe_ent->port[0], mmio_base + 0x17c0); - probe_ent->port[0].bmdma_addr = mmio_base + 0x1000; - pdc_ata_setup_port(&probe_ent->port[1], mmio_base + 0x15c0); - probe_ent->port[1].bmdma_addr = mmio_base + 0x1008; - - probe_ent->n_ports = 2; - - pci_set_master(pdev); //pci_enable_intx(pdev); /* initialize adapter */ - if (pdc_hardware_init(pdev, probe_ent, board_idx) != 0) + if (pdc_hardware_init(host, board_idx) != 0) return -EIO; - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(&pdev->dev, probe_ent); - return 0; + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED, + &pdc2027x_sht); } /** diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 6dd63413a52..ee636beb05e 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -2,13 +2,14 @@ * pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer * (C) 2005 Red Hat Inc * Alan Cox <alan@redhat.com> + * (C) 2007 Bartlomiej Zolnierkiewicz * * Based in part on linux/drivers/ide/pci/pdc202xx_old.c * * First cut with LBA48/ATAPI * * TODO: - * Channel interlock/reset on both required ? + * Channel interlock/reset on both required */ #include <linux/kernel.h> @@ -21,45 +22,17 @@ #include <linux/libata.h> #define DRV_NAME "pata_pdc202xx_old" -#define DRV_VERSION "0.2.3" +#define DRV_VERSION "0.4.2" -/** - * pdc2024x_pre_reset - probe begin - * @ap: ATA port - * - * Set up cable type and use generic probe init - */ - -static int pdc2024x_pre_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA40; - return ata_std_prereset(ap); -} - - -static void pdc2024x_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, pdc2024x_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} - - -static int pdc2026x_pre_reset(struct ata_port *ap) +static int pdc2026x_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u16 cis; pci_read_config_word(pdev, 0x50, &cis); if (cis & (1 << (10 + ap->port_no))) - ap->cbl = ATA_CBL_PATA80; - else - ap->cbl = ATA_CBL_PATA40; - - return ata_std_prereset(ap); -} - -static void pdc2026x_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, pdc2026x_pre_reset, ata_std_softreset, NULL, ata_std_postreset); + return ATA_CBL_PATA80; + return ATA_CBL_PATA40; } /** @@ -76,7 +49,7 @@ static void pdc2026x_error_handler(struct ata_port *ap) static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - int port = 0x60 + 4 * ap->port_no + 2 * adev->devno; + int port = 0x60 + 8 * ap->port_no + 4 * adev->devno; static u16 pio_timing[5] = { 0x0913, 0x050C , 0x0308, 0x0206, 0x0104 }; @@ -85,7 +58,7 @@ static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *a pci_read_config_byte(pdev, port, &r_ap); pci_read_config_byte(pdev, port + 1, &r_bp); r_ap &= ~0x3F; /* Preserve ERRDY_EN, SYNC_IN */ - r_bp &= ~0x07; + r_bp &= ~0x1F; r_ap |= (pio_timing[pio] >> 8); r_bp |= (pio_timing[pio] & 0xFF); @@ -123,7 +96,7 @@ static void pdc202xx_set_piomode(struct ata_port *ap, struct ata_device *adev) static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - int port = 0x60 + 4 * ap->port_no + 2 * adev->devno; + int port = 0x60 + 8 * ap->port_no + 4 * adev->devno; static u8 udma_timing[6][2] = { { 0x60, 0x03 }, /* 33 Mhz Clock */ { 0x40, 0x02 }, @@ -132,12 +105,17 @@ static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev) { 0x20, 0x01 }, { 0x20, 0x01 } }; + static u8 mdma_timing[3][2] = { + { 0x60, 0x03 }, + { 0x60, 0x04 }, + { 0xe0, 0x0f }, + }; u8 r_bp, r_cp; pci_read_config_byte(pdev, port + 1, &r_bp); pci_read_config_byte(pdev, port + 2, &r_cp); - r_bp &= ~0xF0; + r_bp &= ~0xE0; r_cp &= ~0x0F; if (adev->dma_mode >= XFER_UDMA_0) { @@ -147,8 +125,8 @@ static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev) } else { int speed = adev->dma_mode - XFER_MW_DMA_0; - r_bp |= 0x60; - r_cp |= (5 - speed); + r_bp |= mdma_timing[speed][0]; + r_cp |= mdma_timing[speed][1]; } pci_write_config_byte(pdev, port + 1, r_bp); pci_write_config_byte(pdev, port + 2, r_cp); @@ -189,7 +167,7 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc) /* Cases the state machine will not complete correctly without help */ if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATA_PROT_ATAPI_DMA) { - len = qc->nbytes; + len = qc->nbytes / 2; if (tf->flags & ATA_TFLAG_WRITE) len |= 0x06000000; @@ -238,7 +216,6 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc) /** * pdc2026x_dev_config - device setup hook - * @ap: ATA port * @adev: newly found device * * Perform chip specific early setup. We need to lock the transfer @@ -246,7 +223,7 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc) * barf. */ -static void pdc2026x_dev_config(struct ata_port *ap, struct ata_device *adev) +static void pdc2026x_dev_config(struct ata_device *adev) { adev->max_sectors = 256; } @@ -267,8 +244,10 @@ static struct scsi_host_template pdc202xx_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations pdc2024x_port_ops = { @@ -284,8 +263,9 @@ static struct ata_port_operations pdc2024x_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = pdc2024x_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -318,8 +298,9 @@ static struct ata_port_operations pdc2026x_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = pdc2026x_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = pdc2026x_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = pdc2026x_bmdma_start, @@ -399,8 +380,10 @@ static struct pci_driver pdc202xx_pci_driver = { .id_table = pdc202xx, .probe = pdc202xx_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init pdc202xx_init(void) diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 479a326114e..a0a650c7f27 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -42,6 +42,7 @@ static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unuse dev->pio_mode = dev->xfer_mode = XFER_PIO_0; dev->xfer_shift = ATA_SHIFT_PIO; dev->flags |= ATA_DFLAG_PIO; + ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); } } return 0; @@ -79,13 +80,13 @@ static struct ata_port_operations pata_platform_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_unknown, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .data_xfer = ata_data_xfer_noirq, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -134,7 +135,8 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, static int __devinit pata_platform_probe(struct platform_device *pdev) { struct resource *io_res, *ctl_res; - struct ata_probe_ent ae; + struct ata_host *host; + struct ata_port *ap; unsigned int mmio; /* @@ -174,44 +176,41 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) /* * Now that that's out of the way, wire up the port.. */ - memset(&ae, 0, sizeof(struct ata_probe_ent)); - INIT_LIST_HEAD(&ae.node); - ae.dev = &pdev->dev; - ae.port_ops = &pata_platform_port_ops; - ae.sht = &pata_platform_sht; - ae.n_ports = 1; - ae.pio_mask = pio_mask; - ae.irq = platform_get_irq(pdev, 0); - ae.irq_flags = 0; - ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + return -ENOMEM; + ap = host->ports[0]; + + ap->ops = &pata_platform_port_ops; + ap->pio_mask = pio_mask; + ap->flags |= ATA_FLAG_SLAVE_POSS; /* * Handle the MMIO case */ if (mmio) { - ae.port[0].cmd_addr = devm_ioremap(&pdev->dev, io_res->start, + ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, io_res->start, io_res->end - io_res->start + 1); - ae.port[0].ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start, + ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start, ctl_res->end - ctl_res->start + 1); } else { - ae.port[0].cmd_addr = devm_ioport_map(&pdev->dev, io_res->start, + ap->ioaddr.cmd_addr = devm_ioport_map(&pdev->dev, io_res->start, io_res->end - io_res->start + 1); - ae.port[0].ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start, + ap->ioaddr.ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start, ctl_res->end - ctl_res->start + 1); } - if (!ae.port[0].cmd_addr || !ae.port[0].ctl_addr) { + if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) { dev_err(&pdev->dev, "failed to map IO/CTL base\n"); return -ENOMEM; } - ae.port[0].altstatus_addr = ae.port[0].ctl_addr; + ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; - pata_platform_setup_port(&ae.port[0], pdev->dev.platform_data); + pata_platform_setup_port(&ap->ioaddr, pdev->dev.platform_data); - if (unlikely(ata_device_add(&ae) == 0)) - return -ENODEV; - - return 0; + /* activate */ + return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt, + 0, &pata_platform_sht); } /** @@ -227,7 +226,6 @@ static int __devexit pata_platform_remove(struct platform_device *pdev) struct ata_host *host = dev_get_drvdata(dev); ata_host_detach(host); - dev_set_drvdata(dev, NULL); return 0; } diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index 4362141976a..27685ce63ce 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c @@ -26,7 +26,7 @@ #include <linux/platform_device.h> #define DRV_NAME "pata_qdi" -#define DRV_VERSION "0.2.4" +#define DRV_VERSION "0.3.0" #define NR_HOST 4 /* Two 6580s */ @@ -183,13 +183,13 @@ static struct ata_port_operations qdi6500_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = qdi_qc_issue_prot, .data_xfer = qdi_data_xfer, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -211,13 +211,13 @@ static struct ata_port_operations qdi6580_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = qdi_qc_issue_prot, .data_xfer = qdi_data_xfer, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -238,8 +238,9 @@ static struct ata_port_operations qdi6580_port_ops = { static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast) { - struct ata_probe_ent ae; struct platform_device *pdev; + struct ata_host *host; + struct ata_port *ap; void __iomem *io_addr, *ctl_addr; int ret; @@ -257,34 +258,31 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i if (!io_addr || !ctl_addr) goto fail; - memset(&ae, 0, sizeof(struct ata_probe_ent)); - INIT_LIST_HEAD(&ae.node); - ae.dev = &pdev->dev; + ret = -ENOMEM; + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + goto fail; + ap = host->ports[0]; if (type == 6580) { - ae.port_ops = &qdi6580_port_ops; - ae.pio_mask = 0x1F; - ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; + ap->ops = &qdi6580_port_ops; + ap->pio_mask = 0x1F; + ap->flags |= ATA_FLAG_SLAVE_POSS; } else { - ae.port_ops = &qdi6500_port_ops; - ae.pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */ - ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | - ATA_FLAG_NO_IORDY; + ap->ops = &qdi6500_port_ops; + ap->pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */ + ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY; } - ae.sht = &qdi_sht; - ae.n_ports = 1; - ae.irq = irq; - ae.irq_flags = 0; - ae.port[0].cmd_addr = io_addr; - ae.port[0].altstatus_addr = ctl_addr; - ae.port[0].ctl_addr = ctl_addr; - ata_std_ports(&ae.port[0]); + ap->ioaddr.cmd_addr = io_addr; + ap->ioaddr.altstatus_addr = ctl_addr; + ap->ioaddr.ctl_addr = ctl_addr; + ata_std_ports(&ap->ioaddr); /* * Hook in a private data structure per channel */ - ae.private_data = &qdi_data[nr_qdi_host]; + ap->private_data = &qdi_data[nr_qdi_host]; qdi_data[nr_qdi_host].timing = port; qdi_data[nr_qdi_host].fast = fast; @@ -292,8 +290,9 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io); - ret = -ENODEV; - if (!ata_device_add(&ae)) + /* activate */ + ret = ata_host_activate(host, irq, ata_interrupt, 0, &qdi_sht); + if (ret) goto fail; qdi_host[nr_qdi_host++] = dev_get_drvdata(&pdev->dev); @@ -363,7 +362,8 @@ static __init int qdi_init(void) release_region(port, 2); continue; } - ct += qdi_init_one(port, 6500, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04); + if (qdi_init_one(port, 6500, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04) == 0) + ct++; } if (((r & 0xF0) == 0xA0) || (r & 0xF0) == 0x50) { /* QD6580: dual channel */ @@ -375,11 +375,14 @@ static __init int qdi_init(void) res = inb(port + 3); if (res & 1) { /* Single channel mode */ - ct += qdi_init_one(port, 6580, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04); + if (qdi_init_one(port, 6580, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04)) + ct++; } else { /* Dual channel mode */ - ct += qdi_init_one(port, 6580, 0x1F0, 14, r & 0x04); - ct += qdi_init_one(port + 2, 6580, 0x170, 15, r & 0x04); + if (qdi_init_one(port, 6580, 0x1F0, 14, r & 0x04) == 0) + ct++; + if (qdi_init_one(port + 2, 6580, 0x170, 15, r & 0x04) == 0) + ct++; } } } diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index 0d1e571ef63..1c54673e008 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c @@ -24,40 +24,12 @@ #include <linux/ata.h> #define DRV_NAME "pata_radisys" -#define DRV_VERSION "0.4.1" - -/** - * radisys_probe_init - probe begin - * @ap: ATA port - * - * Set up cable type and use generic probe init - */ - -static int radisys_pre_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA80; - return ata_std_prereset(ap); -} - - -/** - * radisys_pata_error_handler - Probe specified port on PATA host controller - * @ap: Port to probe - * @classes: - * - * LOCKING: - * None (inherited from caller). - */ - -static void radisys_pata_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, radisys_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} +#define DRV_VERSION "0.4.4" /** * radisys_set_piomode - Initialize host controller PATA PIO timings - * @ap: Port whose timings we are configuring - * @adev: um + * @ap: ATA port + * @adev: Device whose timings we are configuring * * Set PIO mode for device, in host controller PCI config space. * @@ -228,8 +200,10 @@ static struct scsi_host_template radisys_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static const struct ata_port_operations radisys_pata_ops = { @@ -246,8 +220,9 @@ static const struct ata_port_operations radisys_pata_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = radisys_pata_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_unknown, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -312,8 +287,10 @@ static struct pci_driver radisys_pci_driver = { .id_table = radisys_pci_tbl, .probe = radisys_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init radisys_init(void) diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index 71a2bac09e0..85c45290eee 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -25,31 +25,6 @@ /** - * rz1000_prereset - probe begin - * @ap: ATA port - * - * Set up cable type and use generics - */ - -static int rz1000_prereset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA40; - return ata_std_prereset(ap); -} - -/** - * rz1000_error_handler - probe reset - * @ap: ATA port - * - * Perform the ATA standard reset sequence - */ - -static void rz1000_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, rz1000_prereset, ata_std_softreset, NULL, ata_std_postreset); -} - -/** * rz1000_set_mode - mode setting function * @ap: ATA interface * @unused: returned device on set_mode failure @@ -71,6 +46,7 @@ static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused) dev->xfer_mode = XFER_PIO_0; dev->xfer_shift = ATA_SHIFT_PIO; dev->flags |= ATA_DFLAG_PIO; + ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); } } return 0; @@ -93,8 +69,10 @@ static struct scsi_host_template rz1000_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations rz1000_port_ops = { @@ -119,8 +97,9 @@ static struct ata_port_operations rz1000_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = rz1000_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -177,6 +156,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en return -ENODEV; } +#ifdef CONFIG_PM static int rz1000_reinit_one(struct pci_dev *pdev) { /* If this fails on resume (which is a "cant happen" case), we @@ -185,6 +165,7 @@ static int rz1000_reinit_one(struct pci_dev *pdev) panic("rz1000 fifo"); return ata_pci_device_resume(pdev); } +#endif static const struct pci_device_id pata_rz1000[] = { { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), }, @@ -198,8 +179,10 @@ static struct pci_driver rz1000_pci_driver = { .id_table = pata_rz1000, .probe = rz1000_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = rz1000_reinit_one, +#endif }; static int __init rz1000_init(void) diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 58e42fbd14f..66e8ff467c8 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c @@ -194,8 +194,10 @@ static struct scsi_host_template sc1200_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations sc1200_port_ops = { @@ -210,7 +212,11 @@ static struct ata_port_operations sc1200_port_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -266,8 +272,10 @@ static struct pci_driver sc1200_pci_driver = { .id_table = sc1200, .probe = sc1200_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init sc1200_init(void) diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c new file mode 100644 index 00000000000..5df354d573e --- /dev/null +++ b/drivers/ata/pata_scc.c @@ -0,0 +1,1211 @@ +/* + * Support for IDE interfaces on Celleb platform + * + * (C) Copyright 2006 TOSHIBA CORPORATION + * + * This code is based on drivers/ata/ata_piix.c: + * Copyright 2003-2005 Red Hat Inc + * Copyright 2003-2005 Jeff Garzik + * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> + * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> + * + * and drivers/ata/ahci.c: + * Copyright 2004-2005 Red Hat, Inc. + * + * and drivers/ata/libata-core.c: + * Copyright 2003-2004 Red Hat, Inc. All rights reserved. + * Copyright 2003-2004 Jeff Garzik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/blkdev.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <scsi/scsi_host.h> +#include <linux/libata.h> + +#define DRV_NAME "pata_scc" +#define DRV_VERSION "0.1" + +#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 + +/* PCI BARs */ +#define SCC_CTRL_BAR 0 +#define SCC_BMID_BAR 1 + +/* offset of CTRL registers */ +#define SCC_CTL_PIOSHT 0x000 +#define SCC_CTL_PIOCT 0x004 +#define SCC_CTL_MDMACT 0x008 +#define SCC_CTL_MCRCST 0x00C +#define SCC_CTL_SDMACT 0x010 +#define SCC_CTL_SCRCST 0x014 +#define SCC_CTL_UDENVT 0x018 +#define SCC_CTL_TDVHSEL 0x020 +#define SCC_CTL_MODEREG 0x024 +#define SCC_CTL_ECMODE 0xF00 +#define SCC_CTL_MAEA0 0xF50 +#define SCC_CTL_MAEC0 0xF54 +#define SCC_CTL_CCKCTRL 0xFF0 + +/* offset of BMID registers */ +#define SCC_DMA_CMD 0x000 +#define SCC_DMA_STATUS 0x004 +#define SCC_DMA_TABLE_OFS 0x008 +#define SCC_DMA_INTMASK 0x010 +#define SCC_DMA_INTST 0x014 +#define SCC_DMA_PTERADD 0x018 +#define SCC_REG_CMD_ADDR 0x020 +#define SCC_REG_DATA 0x000 +#define SCC_REG_ERR 0x004 +#define SCC_REG_FEATURE 0x004 +#define SCC_REG_NSECT 0x008 +#define SCC_REG_LBAL 0x00C +#define SCC_REG_LBAM 0x010 +#define SCC_REG_LBAH 0x014 +#define SCC_REG_DEVICE 0x018 +#define SCC_REG_STATUS 0x01C +#define SCC_REG_CMD 0x01C +#define SCC_REG_ALTSTATUS 0x020 + +/* register value */ +#define TDVHSEL_MASTER 0x00000001 +#define TDVHSEL_SLAVE 0x00000004 + +#define MODE_JCUSFEN 0x00000080 + +#define ECMODE_VALUE 0x01 + +#define CCKCTRL_ATARESET 0x00040000 +#define CCKCTRL_BUFCNT 0x00020000 +#define CCKCTRL_CRST 0x00010000 +#define CCKCTRL_OCLKEN 0x00000100 +#define CCKCTRL_ATACLKOEN 0x00000002 +#define CCKCTRL_LCLKEN 0x00000001 + +#define QCHCD_IOS_SS 0x00000001 + +#define QCHSD_STPDIAG 0x00020000 + +#define INTMASK_MSK 0xD1000012 +#define INTSTS_SERROR 0x80000000 +#define INTSTS_PRERR 0x40000000 +#define INTSTS_RERR 0x10000000 +#define INTSTS_ICERR 0x01000000 +#define INTSTS_BMSINT 0x00000010 +#define INTSTS_BMHE 0x00000008 +#define INTSTS_IOIRQS 0x00000004 +#define INTSTS_INTRQ 0x00000002 +#define INTSTS_ACTEINT 0x00000001 + + +/* PIO transfer mode table */ +/* JCHST */ +static const unsigned long JCHSTtbl[2][7] = { + {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */ + {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */ +}; + +/* JCHHT */ +static const unsigned long JCHHTtbl[2][7] = { + {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */ + {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */ +}; + +/* JCHCT */ +static const unsigned long JCHCTtbl[2][7] = { + {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */ + {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */ +}; + +/* DMA transfer mode table */ +/* JCHDCTM/JCHDCTS */ +static const unsigned long JCHDCTxtbl[2][7] = { + {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */ + {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */ +}; + +/* JCSTWTM/JCSTWTS */ +static const unsigned long JCSTWTxtbl[2][7] = { + {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */ + {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ +}; + +/* JCTSS */ +static const unsigned long JCTSStbl[2][7] = { + {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */ + {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */ +}; + +/* JCENVT */ +static const unsigned long JCENVTtbl[2][7] = { + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */ + {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ +}; + +/* JCACTSELS/JCACTSELM */ +static const unsigned long JCACTSELtbl[2][7] = { + {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */ +}; + +static const struct pci_device_id scc_pci_tbl[] = { + {PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { } /* terminate list */ +}; + +/** + * scc_set_piomode - Initialize host controller PATA PIO timings + * @ap: Port whose timings we are configuring + * @adev: um + * + * Set PIO mode for device. + * + * LOCKING: + * None (inherited from caller). + */ + +static void scc_set_piomode (struct ata_port *ap, struct ata_device *adev) +{ + unsigned int pio = adev->pio_mode - XFER_PIO_0; + void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; + void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL; + void __iomem *piosht_port = ctrl_base + SCC_CTL_PIOSHT; + void __iomem *pioct_port = ctrl_base + SCC_CTL_PIOCT; + unsigned long reg; + int offset; + + reg = in_be32(cckctrl_port); + if (reg & CCKCTRL_ATACLKOEN) + offset = 1; /* 133MHz */ + else + offset = 0; /* 100MHz */ + + reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio]; + out_be32(piosht_port, reg); + reg = JCHCTtbl[offset][pio]; + out_be32(pioct_port, reg); +} + +/** + * scc_set_dmamode - Initialize host controller PATA DMA timings + * @ap: Port whose timings we are configuring + * @adev: um + * @udma: udma mode, 0 - 6 + * + * Set UDMA mode for device. + * + * LOCKING: + * None (inherited from caller). + */ + +static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) +{ + unsigned int udma = adev->dma_mode; + unsigned int is_slave = (adev->devno != 0); + u8 speed = udma; + void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; + void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL; + void __iomem *mdmact_port = ctrl_base + SCC_CTL_MDMACT; + void __iomem *mcrcst_port = ctrl_base + SCC_CTL_MCRCST; + void __iomem *sdmact_port = ctrl_base + SCC_CTL_SDMACT; + void __iomem *scrcst_port = ctrl_base + SCC_CTL_SCRCST; + void __iomem *udenvt_port = ctrl_base + SCC_CTL_UDENVT; + void __iomem *tdvhsel_port = ctrl_base + SCC_CTL_TDVHSEL; + int offset, idx; + + if (in_be32(cckctrl_port) & CCKCTRL_ATACLKOEN) + offset = 1; /* 133MHz */ + else + offset = 0; /* 100MHz */ + + if (speed >= XFER_UDMA_0) + idx = speed - XFER_UDMA_0; + else + return; + + if (is_slave) { + out_be32(sdmact_port, JCHDCTxtbl[offset][idx]); + out_be32(scrcst_port, JCSTWTxtbl[offset][idx]); + out_be32(tdvhsel_port, + (in_be32(tdvhsel_port) & ~TDVHSEL_SLAVE) | (JCACTSELtbl[offset][idx] << 2)); + } else { + out_be32(mdmact_port, JCHDCTxtbl[offset][idx]); + out_be32(mcrcst_port, JCSTWTxtbl[offset][idx]); + out_be32(tdvhsel_port, + (in_be32(tdvhsel_port) & ~TDVHSEL_MASTER) | JCACTSELtbl[offset][idx]); + } + out_be32(udenvt_port, + JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]); +} + +/** + * scc_tf_load - send taskfile registers to host controller + * @ap: Port to which output is sent + * @tf: ATA taskfile register set + * + * Note: Original code is ata_tf_load(). + */ + +static void scc_tf_load (struct ata_port *ap, const struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; + + if (tf->ctl != ap->last_ctl) { + out_be32(ioaddr->ctl_addr, tf->ctl); + ap->last_ctl = tf->ctl; + ata_wait_idle(ap); + } + + if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { + out_be32(ioaddr->feature_addr, tf->hob_feature); + out_be32(ioaddr->nsect_addr, tf->hob_nsect); + out_be32(ioaddr->lbal_addr, tf->hob_lbal); + out_be32(ioaddr->lbam_addr, tf->hob_lbam); + out_be32(ioaddr->lbah_addr, tf->hob_lbah); + VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->hob_feature, + tf->hob_nsect, + tf->hob_lbal, + tf->hob_lbam, + tf->hob_lbah); + } + + if (is_addr) { + out_be32(ioaddr->feature_addr, tf->feature); + out_be32(ioaddr->nsect_addr, tf->nsect); + out_be32(ioaddr->lbal_addr, tf->lbal); + out_be32(ioaddr->lbam_addr, tf->lbam); + out_be32(ioaddr->lbah_addr, tf->lbah); + VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", + tf->feature, + tf->nsect, + tf->lbal, + tf->lbam, + tf->lbah); + } + + if (tf->flags & ATA_TFLAG_DEVICE) { + out_be32(ioaddr->device_addr, tf->device); + VPRINTK("device 0x%X\n", tf->device); + } + + ata_wait_idle(ap); +} + +/** + * scc_check_status - Read device status reg & clear interrupt + * @ap: port where the device is + * + * Note: Original code is ata_check_status(). + */ + +static u8 scc_check_status (struct ata_port *ap) +{ + return in_be32(ap->ioaddr.status_addr); +} + +/** + * scc_tf_read - input device's ATA taskfile shadow registers + * @ap: Port from which input is read + * @tf: ATA taskfile register set for storing input + * + * Note: Original code is ata_tf_read(). + */ + +static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + + tf->command = scc_check_status(ap); + tf->feature = in_be32(ioaddr->error_addr); + tf->nsect = in_be32(ioaddr->nsect_addr); + tf->lbal = in_be32(ioaddr->lbal_addr); + tf->lbam = in_be32(ioaddr->lbam_addr); + tf->lbah = in_be32(ioaddr->lbah_addr); + tf->device = in_be32(ioaddr->device_addr); + + if (tf->flags & ATA_TFLAG_LBA48) { + out_be32(ioaddr->ctl_addr, tf->ctl | ATA_HOB); + tf->hob_feature = in_be32(ioaddr->error_addr); + tf->hob_nsect = in_be32(ioaddr->nsect_addr); + tf->hob_lbal = in_be32(ioaddr->lbal_addr); + tf->hob_lbam = in_be32(ioaddr->lbam_addr); + tf->hob_lbah = in_be32(ioaddr->lbah_addr); + } +} + +/** + * scc_exec_command - issue ATA command to host controller + * @ap: port to which command is being issued + * @tf: ATA taskfile register set + * + * Note: Original code is ata_exec_command(). + */ + +static void scc_exec_command (struct ata_port *ap, + const struct ata_taskfile *tf) +{ + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); + + out_be32(ap->ioaddr.command_addr, tf->command); + ata_pause(ap); +} + +/** + * scc_check_altstatus - Read device alternate status reg + * @ap: port where the device is + */ + +static u8 scc_check_altstatus (struct ata_port *ap) +{ + return in_be32(ap->ioaddr.altstatus_addr); +} + +/** + * scc_std_dev_select - Select device 0/1 on ATA bus + * @ap: ATA channel to manipulate + * @device: ATA device (numbered from zero) to select + * + * Note: Original code is ata_std_dev_select(). + */ + +static void scc_std_dev_select (struct ata_port *ap, unsigned int device) +{ + u8 tmp; + + if (device == 0) + tmp = ATA_DEVICE_OBS; + else + tmp = ATA_DEVICE_OBS | ATA_DEV1; + + out_be32(ap->ioaddr.device_addr, tmp); + ata_pause(ap); +} + +/** + * scc_bmdma_setup - Set up PCI IDE BMDMA transaction + * @qc: Info associated with this ATA transaction. + * + * Note: Original code is ata_bmdma_setup(). + */ + +static void scc_bmdma_setup (struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); + u8 dmactl; + void __iomem *mmio = ap->ioaddr.bmdma_addr; + + /* load PRD table addr */ + out_be32(mmio + SCC_DMA_TABLE_OFS, ap->prd_dma); + + /* specify data direction, triple-check start bit is clear */ + dmactl = in_be32(mmio + SCC_DMA_CMD); + dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); + if (!rw) + dmactl |= ATA_DMA_WR; + out_be32(mmio + SCC_DMA_CMD, dmactl); + + /* issue r/w command */ + ap->ops->exec_command(ap, &qc->tf); +} + +/** + * scc_bmdma_start - Start a PCI IDE BMDMA transaction + * @qc: Info associated with this ATA transaction. + * + * Note: Original code is ata_bmdma_start(). + */ + +static void scc_bmdma_start (struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + u8 dmactl; + void __iomem *mmio = ap->ioaddr.bmdma_addr; + + /* start host DMA transaction */ + dmactl = in_be32(mmio + SCC_DMA_CMD); + out_be32(mmio + SCC_DMA_CMD, dmactl | ATA_DMA_START); +} + +/** + * scc_devchk - PATA device presence detection + * @ap: ATA channel to examine + * @device: Device to examine (starting at zero) + * + * Note: Original code is ata_devchk(). + */ + +static unsigned int scc_devchk (struct ata_port *ap, + unsigned int device) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + u8 nsect, lbal; + + ap->ops->dev_select(ap, device); + + out_be32(ioaddr->nsect_addr, 0x55); + out_be32(ioaddr->lbal_addr, 0xaa); + + out_be32(ioaddr->nsect_addr, 0xaa); + out_be32(ioaddr->lbal_addr, 0x55); + + out_be32(ioaddr->nsect_addr, 0x55); + out_be32(ioaddr->lbal_addr, 0xaa); + + nsect = in_be32(ioaddr->nsect_addr); + lbal = in_be32(ioaddr->lbal_addr); + + if ((nsect == 0x55) && (lbal == 0xaa)) + return 1; /* we found a device */ + + return 0; /* nothing found */ +} + +/** + * scc_bus_post_reset - PATA device post reset + * + * Note: Original code is ata_bus_post_reset(). + */ + +static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + unsigned int dev0 = devmask & (1 << 0); + unsigned int dev1 = devmask & (1 << 1); + unsigned long timeout; + + /* if device 0 was found in ata_devchk, wait for its + * BSY bit to clear + */ + if (dev0) + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); + + /* if device 1 was found in ata_devchk, wait for + * register access, then wait for BSY to clear + */ + timeout = jiffies + ATA_TMOUT_BOOT; + while (dev1) { + u8 nsect, lbal; + + ap->ops->dev_select(ap, 1); + nsect = in_be32(ioaddr->nsect_addr); + lbal = in_be32(ioaddr->lbal_addr); + if ((nsect == 1) && (lbal == 1)) + break; + if (time_after(jiffies, timeout)) { + dev1 = 0; + break; + } + msleep(50); /* give drive a breather */ + } + if (dev1) + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); + + /* is all this really necessary? */ + ap->ops->dev_select(ap, 0); + if (dev1) + ap->ops->dev_select(ap, 1); + if (dev0) + ap->ops->dev_select(ap, 0); +} + +/** + * scc_bus_softreset - PATA device software reset + * + * Note: Original code is ata_bus_softreset(). + */ + +static unsigned int scc_bus_softreset (struct ata_port *ap, + unsigned int devmask) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + + DPRINTK("ata%u: bus reset via SRST\n", ap->print_id); + + /* software reset. causes dev0 to be selected */ + out_be32(ioaddr->ctl_addr, ap->ctl); + udelay(20); + out_be32(ioaddr->ctl_addr, ap->ctl | ATA_SRST); + udelay(20); + out_be32(ioaddr->ctl_addr, ap->ctl); + + /* spec mandates ">= 2ms" before checking status. + * We wait 150ms, because that was the magic delay used for + * ATAPI devices in Hale Landis's ATADRVR, for the period of time + * between when the ATA command register is written, and then + * status is checked. Because waiting for "a while" before + * checking status is fine, post SRST, we perform this magic + * delay here as well. + * + * Old drivers/ide uses the 2mS rule and then waits for ready + */ + msleep(150); + + /* Before we perform post reset processing we want to see if + * the bus shows 0xFF because the odd clown forgets the D7 + * pulldown resistor. + */ + if (scc_check_status(ap) == 0xFF) + return 0; + + scc_bus_post_reset(ap, devmask); + + return 0; +} + +/** + * scc_std_softreset - reset host port via ATA SRST + * @ap: port to reset + * @classes: resulting classes of attached devices + * + * Note: Original code is ata_std_softreset(). + */ + +static int scc_std_softreset (struct ata_port *ap, unsigned int *classes) +{ + unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; + unsigned int devmask = 0, err_mask; + u8 err; + + DPRINTK("ENTER\n"); + + if (ata_port_offline(ap)) { + classes[0] = ATA_DEV_NONE; + goto out; + } + + /* determine if device 0/1 are present */ + if (scc_devchk(ap, 0)) + devmask |= (1 << 0); + if (slave_possible && scc_devchk(ap, 1)) + devmask |= (1 << 1); + + /* select device 0 again */ + ap->ops->dev_select(ap, 0); + + /* issue bus reset */ + DPRINTK("about to softreset, devmask=%x\n", devmask); + err_mask = scc_bus_softreset(ap, devmask); + if (err_mask) { + ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n", + err_mask); + return -EIO; + } + + /* determine by signature whether we have ATA or ATAPI devices */ + classes[0] = ata_dev_try_classify(ap, 0, &err); + if (slave_possible && err != 0x81) + classes[1] = ata_dev_try_classify(ap, 1, &err); + + out: + DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); + return 0; +} + +/** + * scc_bmdma_stop - Stop PCI IDE BMDMA transfer + * @qc: Command we are ending DMA for + */ + +static void scc_bmdma_stop (struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; + void __iomem *bmid_base = ap->host->iomap[SCC_BMID_BAR]; + u32 reg; + + while (1) { + reg = in_be32(bmid_base + SCC_DMA_INTST); + + if (reg & INTSTS_SERROR) { + printk(KERN_WARNING "%s: SERROR\n", DRV_NAME); + out_be32(bmid_base + SCC_DMA_INTST, INTSTS_SERROR|INTSTS_BMSINT); + out_be32(bmid_base + SCC_DMA_CMD, + in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); + continue; + } + + if (reg & INTSTS_PRERR) { + u32 maea0, maec0; + maea0 = in_be32(ctrl_base + SCC_CTL_MAEA0); + maec0 = in_be32(ctrl_base + SCC_CTL_MAEC0); + printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", DRV_NAME, maea0, maec0); + out_be32(bmid_base + SCC_DMA_INTST, INTSTS_PRERR|INTSTS_BMSINT); + out_be32(bmid_base + SCC_DMA_CMD, + in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); + continue; + } + + if (reg & INTSTS_RERR) { + printk(KERN_WARNING "%s: Response Error\n", DRV_NAME); + out_be32(bmid_base + SCC_DMA_INTST, INTSTS_RERR|INTSTS_BMSINT); + out_be32(bmid_base + SCC_DMA_CMD, + in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); + continue; + } + + if (reg & INTSTS_ICERR) { + out_be32(bmid_base + SCC_DMA_CMD, + in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); + printk(KERN_WARNING "%s: Illegal Configuration\n", DRV_NAME); + out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ICERR|INTSTS_BMSINT); + continue; + } + + if (reg & INTSTS_BMSINT) { + unsigned int classes; + printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); + out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); + /* TBD: SW reset */ + scc_std_softreset(ap, &classes); + continue; + } + + if (reg & INTSTS_BMHE) { + out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMHE); + continue; + } + + if (reg & INTSTS_ACTEINT) { + out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ACTEINT); + continue; + } + + if (reg & INTSTS_IOIRQS) { + out_be32(bmid_base + SCC_DMA_INTST, INTSTS_IOIRQS); + continue; + } + break; + } + + /* clear start/stop bit */ + out_be32(bmid_base + SCC_DMA_CMD, + in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); + + /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ + ata_altstatus(ap); /* dummy read */ +} + +/** + * scc_bmdma_status - Read PCI IDE BMDMA status + * @ap: Port associated with this ATA transaction. + */ + +static u8 scc_bmdma_status (struct ata_port *ap) +{ + u8 host_stat; + void __iomem *mmio = ap->ioaddr.bmdma_addr; + + host_stat = in_be32(mmio + SCC_DMA_STATUS); + + /* Workaround for PTERADD: emulate DMA_INTR when + * - IDE_STATUS[ERR] = 1 + * - INT_STATUS[INTRQ] = 1 + * - DMA_STATUS[IORACTA] = 1 + */ + if (!(host_stat & ATA_DMA_INTR)) { + u32 int_status = in_be32(mmio + SCC_DMA_INTST); + if (ata_altstatus(ap) & ATA_ERR && + int_status & INTSTS_INTRQ && + host_stat & ATA_DMA_ACTIVE) + host_stat |= ATA_DMA_INTR; + } + + return host_stat; +} + +/** + * scc_data_xfer - Transfer data by PIO + * @adev: device for this I/O + * @buf: data buffer + * @buflen: buffer length + * @write_data: read/write + * + * Note: Original code is ata_data_xfer(). + */ + +static void scc_data_xfer (struct ata_device *adev, unsigned char *buf, + unsigned int buflen, int write_data) +{ + struct ata_port *ap = adev->ap; + unsigned int words = buflen >> 1; + unsigned int i; + u16 *buf16 = (u16 *) buf; + void __iomem *mmio = ap->ioaddr.data_addr; + + /* Transfer multiple of 2 bytes */ + if (write_data) { + for (i = 0; i < words; i++) + out_be32(mmio, cpu_to_le16(buf16[i])); + } else { + for (i = 0; i < words; i++) + buf16[i] = le16_to_cpu(in_be32(mmio)); + } + + /* Transfer trailing 1 byte, if any. */ + if (unlikely(buflen & 0x01)) { + u16 align_buf[1] = { 0 }; + unsigned char *trailing_buf = buf + buflen - 1; + + if (write_data) { + memcpy(align_buf, trailing_buf, 1); + out_be32(mmio, cpu_to_le16(align_buf[0])); + } else { + align_buf[0] = le16_to_cpu(in_be32(mmio)); + memcpy(trailing_buf, align_buf, 1); + } + } +} + +/** + * scc_irq_on - Enable interrupts on a port. + * @ap: Port on which interrupts are enabled. + * + * Note: Original code is ata_irq_on(). + */ + +static u8 scc_irq_on (struct ata_port *ap) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + u8 tmp; + + ap->ctl &= ~ATA_NIEN; + ap->last_ctl = ap->ctl; + + out_be32(ioaddr->ctl_addr, ap->ctl); + tmp = ata_wait_idle(ap); + + ap->ops->irq_clear(ap); + + return tmp; +} + +/** + * scc_irq_ack - Acknowledge a device interrupt. + * @ap: Port on which interrupts are enabled. + * + * Note: Original code is ata_irq_ack(). + */ + +static u8 scc_irq_ack (struct ata_port *ap, unsigned int chk_drq) +{ + unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; + u8 host_stat, post_stat, status; + + status = ata_busy_wait(ap, bits, 1000); + if (status & bits) + if (ata_msg_err(ap)) + printk(KERN_ERR "abnormal status 0x%X\n", status); + + /* get controller status; clear intr, err bits */ + host_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS); + out_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS, + host_stat | ATA_DMA_INTR | ATA_DMA_ERR); + + post_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS); + + if (ata_msg_intr(ap)) + printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n", + __FUNCTION__, + host_stat, post_stat, status); + + return status; +} + +/** + * scc_bmdma_freeze - Freeze BMDMA controller port + * @ap: port to freeze + * + * Note: Original code is ata_bmdma_freeze(). + */ + +static void scc_bmdma_freeze (struct ata_port *ap) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + + ap->ctl |= ATA_NIEN; + ap->last_ctl = ap->ctl; + + out_be32(ioaddr->ctl_addr, ap->ctl); + + /* Under certain circumstances, some controllers raise IRQ on + * ATA_NIEN manipulation. Also, many controllers fail to mask + * previously pending IRQ on ATA_NIEN assertion. Clear it. + */ + ata_chk_status(ap); + + ap->ops->irq_clear(ap); +} + +/** + * scc_pata_prereset - prepare for reset + * @ap: ATA port to be reset + */ + +static int scc_pata_prereset (struct ata_port *ap) +{ + ap->cbl = ATA_CBL_PATA80; + return ata_std_prereset(ap); +} + +/** + * scc_std_postreset - standard postreset callback + * @ap: the target ata_port + * @classes: classes of attached devices + * + * Note: Original code is ata_std_postreset(). + */ + +static void scc_std_postreset (struct ata_port *ap, unsigned int *classes) +{ + DPRINTK("ENTER\n"); + + /* re-enable interrupts */ + if (!ap->ops->error_handler) + ap->ops->irq_on(ap); + + /* is double-select really necessary? */ + if (classes[0] != ATA_DEV_NONE) + ap->ops->dev_select(ap, 1); + if (classes[1] != ATA_DEV_NONE) + ap->ops->dev_select(ap, 0); + + /* bail out if no device is present */ + if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { + DPRINTK("EXIT, no device\n"); + return; + } + + /* set up device control */ + if (ap->ioaddr.ctl_addr) + out_be32(ap->ioaddr.ctl_addr, ap->ctl); + + DPRINTK("EXIT\n"); +} + +/** + * scc_error_handler - Stock error handler for BMDMA controller + * @ap: port to handle error for + */ + +static void scc_error_handler (struct ata_port *ap) +{ + ata_bmdma_drive_eh(ap, scc_pata_prereset, scc_std_softreset, NULL, + scc_std_postreset); +} + +/** + * scc_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. + * @ap: Port associated with this ATA transaction. + * + * Note: Original code is ata_bmdma_irq_clear(). + */ + +static void scc_bmdma_irq_clear (struct ata_port *ap) +{ + void __iomem *mmio = ap->ioaddr.bmdma_addr; + + if (!mmio) + return; + + out_be32(mmio + SCC_DMA_STATUS, in_be32(mmio + SCC_DMA_STATUS)); +} + +/** + * scc_port_start - Set port up for dma. + * @ap: Port to initialize + * + * Allocate space for PRD table using ata_port_start(). + * Set PRD table address for PTERADD. (PRD Transfer End Read) + */ + +static int scc_port_start (struct ata_port *ap) +{ + void __iomem *mmio = ap->ioaddr.bmdma_addr; + int rc; + + rc = ata_port_start(ap); + if (rc) + return rc; + + out_be32(mmio + SCC_DMA_PTERADD, ap->prd_dma); + return 0; +} + +/** + * scc_port_stop - Undo scc_port_start() + * @ap: Port to shut down + * + * Reset PTERADD. + */ + +static void scc_port_stop (struct ata_port *ap) +{ + void __iomem *mmio = ap->ioaddr.bmdma_addr; + + out_be32(mmio + SCC_DMA_PTERADD, 0); +} + +static struct scsi_host_template scc_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .ioctl = ata_scsi_ioctl, + .queuecommand = ata_scsi_queuecmd, + .can_queue = ATA_DEF_QUEUE, + .this_id = ATA_SHT_THIS_ID, + .sg_tablesize = LIBATA_MAX_PRD, + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, + .emulated = ATA_SHT_EMULATED, + .use_clustering = ATA_SHT_USE_CLUSTERING, + .proc_name = DRV_NAME, + .dma_boundary = ATA_DMA_BOUNDARY, + .slave_configure = ata_scsi_slave_config, + .slave_destroy = ata_scsi_slave_destroy, + .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM + .resume = ata_scsi_device_resume, + .suspend = ata_scsi_device_suspend, +#endif +}; + +static const struct ata_port_operations scc_pata_ops = { + .port_disable = ata_port_disable, + .set_piomode = scc_set_piomode, + .set_dmamode = scc_set_dmamode, + .mode_filter = ata_pci_default_filter, + + .tf_load = scc_tf_load, + .tf_read = scc_tf_read, + .exec_command = scc_exec_command, + .check_status = scc_check_status, + .check_altstatus = scc_check_altstatus, + .dev_select = scc_std_dev_select, + + .bmdma_setup = scc_bmdma_setup, + .bmdma_start = scc_bmdma_start, + .bmdma_stop = scc_bmdma_stop, + .bmdma_status = scc_bmdma_status, + .data_xfer = scc_data_xfer, + + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + + .freeze = scc_bmdma_freeze, + .error_handler = scc_error_handler, + .post_internal_cmd = scc_bmdma_stop, + + .irq_clear = scc_bmdma_irq_clear, + .irq_on = scc_irq_on, + .irq_ack = scc_irq_ack, + + .port_start = scc_port_start, + .port_stop = scc_port_stop, +}; + +static struct ata_port_info scc_port_info[] = { + { + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x00, + .udma_mask = ATA_UDMA6, + .port_ops = &scc_pata_ops, + }, +}; + +/** + * scc_reset_controller - initialize SCC PATA controller. + */ + +static int scc_reset_controller(struct ata_host *host) +{ + void __iomem *ctrl_base = host->iomap[SCC_CTRL_BAR]; + void __iomem *bmid_base = host->iomap[SCC_BMID_BAR]; + void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL; + void __iomem *mode_port = ctrl_base + SCC_CTL_MODEREG; + void __iomem *ecmode_port = ctrl_base + SCC_CTL_ECMODE; + void __iomem *intmask_port = bmid_base + SCC_DMA_INTMASK; + void __iomem *dmastatus_port = bmid_base + SCC_DMA_STATUS; + u32 reg = 0; + + out_be32(cckctrl_port, reg); + reg |= CCKCTRL_ATACLKOEN; + out_be32(cckctrl_port, reg); + reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN; + out_be32(cckctrl_port, reg); + reg |= CCKCTRL_CRST; + out_be32(cckctrl_port, reg); + + for (;;) { + reg = in_be32(cckctrl_port); + if (reg & CCKCTRL_CRST) + break; + udelay(5000); + } + + reg |= CCKCTRL_ATARESET; + out_be32(cckctrl_port, reg); + out_be32(ecmode_port, ECMODE_VALUE); + out_be32(mode_port, MODE_JCUSFEN); + out_be32(intmask_port, INTMASK_MSK); + + if (in_be32(dmastatus_port) & QCHSD_STPDIAG) { + printk(KERN_WARNING "%s: failed to detect 80c cable. (PDIAG# is high)\n", DRV_NAME); + return -EIO; + } + + return 0; +} + +/** + * scc_setup_ports - initialize ioaddr with SCC PATA port offsets. + * @ioaddr: IO address structure to be initialized + * @base: base address of BMID region + */ + +static void scc_setup_ports (struct ata_ioports *ioaddr, void __iomem *base) +{ + ioaddr->cmd_addr = base + SCC_REG_CMD_ADDR; + ioaddr->altstatus_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS; + ioaddr->ctl_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS; + ioaddr->bmdma_addr = base; + ioaddr->data_addr = ioaddr->cmd_addr + SCC_REG_DATA; + ioaddr->error_addr = ioaddr->cmd_addr + SCC_REG_ERR; + ioaddr->feature_addr = ioaddr->cmd_addr + SCC_REG_FEATURE; + ioaddr->nsect_addr = ioaddr->cmd_addr + SCC_REG_NSECT; + ioaddr->lbal_addr = ioaddr->cmd_addr + SCC_REG_LBAL; + ioaddr->lbam_addr = ioaddr->cmd_addr + SCC_REG_LBAM; + ioaddr->lbah_addr = ioaddr->cmd_addr + SCC_REG_LBAH; + ioaddr->device_addr = ioaddr->cmd_addr + SCC_REG_DEVICE; + ioaddr->status_addr = ioaddr->cmd_addr + SCC_REG_STATUS; + ioaddr->command_addr = ioaddr->cmd_addr + SCC_REG_CMD; +} + +static int scc_host_init(struct ata_host *host) +{ + struct pci_dev *pdev = to_pci_dev(host->dev); + int rc; + + rc = scc_reset_controller(host); + if (rc) + return rc; + + rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + return rc; + rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + return rc; + + scc_setup_ports(&host->ports[0]->ioaddr, host->iomap[SCC_BMID_BAR]); + + pci_set_master(pdev); + + return 0; +} + +/** + * scc_init_one - Register SCC PATA device with kernel services + * @pdev: PCI device to register + * @ent: Entry in scc_pci_tbl matching with @pdev + * + * LOCKING: + * Inherited from PCI layer (may sleep). + * + * RETURNS: + * Zero on success, or -ERRNO value. + */ + +static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static int printed_version; + unsigned int board_idx = (unsigned int) ent->driver_data; + const struct ata_port_info *ppi[] = { &scc_port_info[board_idx], NULL }; + struct device *dev = &pdev->dev; + int rc; + + if (!printed_version++) + dev_printk(KERN_DEBUG, &pdev->dev, + "version " DRV_VERSION "\n"); + + host = ata_port_alloc_pinfo(&pdev->dev, ppi, 1); + if (!host) + return -ENOMEM; + + rc = pcim_enable_device(pdev); + if (rc) + return rc; + + rc = pcim_iomap_regions(pdev, (1 << SCC_CTRL_BAR) | (1 << SCC_BMID_BAR), DRV_NAME); + if (rc == -EBUSY) + pcim_pin_device(pdev); + if (rc) + return rc; + host->iomap = pcim_iomap_table(pdev); + + rc = scc_host_init(host); + if (rc) + return rc; + + return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED, + &scc_sht); +} + +static struct pci_driver scc_pci_driver = { + .name = DRV_NAME, + .id_table = scc_pci_tbl, + .probe = scc_init_one, + .remove = ata_pci_remove_one, +#ifdef CONFIG_PM + .suspend = ata_pci_device_suspend, + .resume = ata_pci_device_resume, +#endif +}; + +static int __init scc_init (void) +{ + int rc; + + DPRINTK("pci_register_driver\n"); + rc = pci_register_driver(&scc_pci_driver); + if (rc) + return rc; + + DPRINTK("done\n"); + return 0; +} + +static void __exit scc_exit (void) +{ + pci_unregister_driver(&scc_pci_driver); +} + +module_init(scc_init); +module_exit(scc_exit); + +MODULE_AUTHOR("Toshiba corp"); +MODULE_DESCRIPTION("SCSI low-level driver for Toshiba SCC PATA controller"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, scc_pci_tbl); +MODULE_VERSION(DRV_VERSION); diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index ad5b43fef3d..3956ef26936 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -1,5 +1,5 @@ /* - * ata-serverworks.c - Serverworks PATA for new ATA layer + * pata_serverworks.c - Serverworks PATA for new ATA layer * (C) 2005 Red Hat Inc * Alan Cox <alan@redhat.com> * @@ -41,7 +41,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_serverworks" -#define DRV_VERSION "0.3.9" +#define DRV_VERSION "0.4.0" #define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ #define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ @@ -137,14 +137,14 @@ static struct sv_cable_table cable_detect[] = { }; /** - * serverworks_pre_reset - cable detection + * serverworks_cable_detect - cable detection * @ap: ATA port * * Perform cable detection according to the device and subvendor * identifications */ -static int serverworks_pre_reset(struct ata_port *ap) { +static int serverworks_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct sv_cable_table *cb = cable_detect; @@ -152,8 +152,7 @@ static int serverworks_pre_reset(struct ata_port *ap) { if (cb->device == pdev->device && (cb->subvendor == pdev->subsystem_vendor || cb->subvendor == PCI_ANY_ID)) { - ap->cbl = cb->cable_detect(ap); - return ata_std_prereset(ap); + return cb->cable_detect(ap); } cb++; } @@ -162,11 +161,6 @@ static int serverworks_pre_reset(struct ata_port *ap) { return -1; /* kill compiler warning */ } -static void serverworks_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, serverworks_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} - /** * serverworks_is_csb - Check for CSB or OSB * @pdev: PCI device to check @@ -191,31 +185,31 @@ static u8 serverworks_is_csb(struct pci_dev *pdev) /** * serverworks_osb4_filter - mode selection filter - * @ap: ATA interface * @adev: ATA device + * @mask: Mask of proposed modes * * Filter the offered modes for the device to apply controller * specific rules. OSB4 requires no UDMA for disks due to a FIFO * bug we hit. */ -static unsigned long serverworks_osb4_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask) +static unsigned long serverworks_osb4_filter(struct ata_device *adev, unsigned long mask) { if (adev->class == ATA_DEV_ATA) mask &= ~ATA_MASK_UDMA; - return ata_pci_default_filter(ap, adev, mask); + return ata_pci_default_filter(adev, mask); } /** * serverworks_csb_filter - mode selection filter - * @ap: ATA interface * @adev: ATA device + * @mask: Mask of proposed modes * * Check the blacklist and disable UDMA5 if matched */ -static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask) +static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned long mask) { const char *p; char model_num[ATA_ID_PROD_LEN + 1]; @@ -223,7 +217,7 @@ static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct at /* Disk, UDMA */ if (adev->class != ATA_DEV_ATA) - return ata_pci_default_filter(ap, adev, mask); + return ata_pci_default_filter(adev, mask); /* Actually do need to check */ ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num)); @@ -232,7 +226,7 @@ static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct at if (!strcmp(p, model_num)) mask &= ~(0x1F << ATA_SHIFT_UDMA); } - return ata_pci_default_filter(ap, adev, mask); + return ata_pci_default_filter(adev, mask); } @@ -319,8 +313,10 @@ static struct scsi_host_template serverworks_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations serverworks_osb4_port_ops = { @@ -337,8 +333,9 @@ static struct ata_port_operations serverworks_osb4_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = serverworks_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = serverworks_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -372,8 +369,9 @@ static struct ata_port_operations serverworks_csb_port_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = serverworks_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = serverworks_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -548,6 +546,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id return ata_pci_init_one(pdev, port_info, ports); } +#ifdef CONFIG_PM static int serverworks_reinit_one(struct pci_dev *pdev) { /* Force master latency timer to 64 PCI clocks */ @@ -571,6 +570,7 @@ static int serverworks_reinit_one(struct pci_dev *pdev) } return ata_pci_device_resume(pdev); } +#endif static const struct pci_device_id serverworks[] = { { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0}, @@ -587,8 +587,10 @@ static struct pci_driver serverworks_pci_driver = { .id_table = serverworks, .probe = serverworks_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = serverworks_reinit_one, +#endif }; static int __init serverworks_init(void) diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index ed79fabe025..6770820cfca 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -33,7 +33,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_sil680" -#define DRV_VERSION "0.4.1" +#define DRV_VERSION "0.4.6" /** * sil680_selreg - return register base @@ -91,12 +91,6 @@ static int sil680_cable_detect(struct ata_port *ap) { return ATA_CBL_PATA40; } -static int sil680_pre_reset(struct ata_port *ap) -{ - ap->cbl = sil680_cable_detect(ap); - return ata_std_prereset(ap); -} - /** * sil680_bus_reset - reset the SIL680 bus * @ap: ATA port to reset @@ -119,7 +113,7 @@ static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes) static void sil680_error_handler(struct ata_port *ap) { - ata_bmdma_drive_eh(ap, sil680_pre_reset, sil680_bus_reset, NULL, ata_std_postreset); + ata_bmdma_drive_eh(ap, ata_std_prereset, sil680_bus_reset, NULL, ata_std_postreset); } /** @@ -139,10 +133,13 @@ static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev) unsigned long tfaddr = sil680_selreg(ap, 0x02); unsigned long addr = sil680_seldev(ap, adev, 0x04); + unsigned long addr_mask = 0x80 + 4 * ap->port_no; struct pci_dev *pdev = to_pci_dev(ap->host->dev); int pio = adev->pio_mode - XFER_PIO_0; int lowest_pio = pio; + int port_shift = 4 * adev->devno; u16 reg; + u8 mode; struct ata_device *pair = ata_dev_pair(adev); @@ -153,10 +150,17 @@ static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev) pci_write_config_word(pdev, tfaddr, speed_t[lowest_pio]); pci_read_config_word(pdev, tfaddr-2, ®); + pci_read_config_byte(pdev, addr_mask, &mode); + reg &= ~0x0200; /* Clear IORDY */ - if (ata_pio_need_iordy(adev)) + mode &= ~(3 << port_shift); /* Clear IORDY and DMA bits */ + + if (ata_pio_need_iordy(adev)) { reg |= 0x0200; /* Enable IORDY */ + mode |= 1 << port_shift; + } pci_write_config_word(pdev, tfaddr-2, reg); + pci_write_config_byte(pdev, addr_mask, mode); } /** @@ -226,6 +230,10 @@ static struct scsi_host_template sil680_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM + .suspend = ata_scsi_device_suspend, + .resume = ata_scsi_device_resume, +#endif }; static struct ata_port_operations sil680_port_ops = { @@ -243,6 +251,7 @@ static struct ata_port_operations sil680_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = sil680_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = sil680_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -367,11 +376,13 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ata_pci_init_one(pdev, port_info, 2); } +#ifdef CONFIG_PM static int sil680_reinit_one(struct pci_dev *pdev) { sil680_init_chip(pdev); return ata_pci_device_resume(pdev); } +#endif static const struct pci_device_id sil680[] = { { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), }, @@ -384,8 +395,10 @@ static struct pci_driver sil680_pci_driver = { .id_table = sil680, .probe = sil680_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = sil680_reinit_one, +#endif }; static int __init sil680_init(void) diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 560103d55b2..a3fbcee6fb3 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -32,11 +32,10 @@ #include <scsi/scsi_host.h> #include <linux/libata.h> #include <linux/ata.h> -#include "libata.h" +#include "sis.h" -#undef DRV_NAME /* already defined in libata.h, for libata-core */ #define DRV_NAME "pata_sis" -#define DRV_VERSION "0.4.5" +#define DRV_VERSION "0.5.1" struct sis_chipset { u16 device; /* PCI host ID */ @@ -87,106 +86,55 @@ static int sis_port_base(struct ata_device *adev) } /** - * sis_133_pre_reset - check for 40/80 pin + * sis_133_cable_detect - check for 40/80 pin * @ap: Port * * Perform cable detection for the later UDMA133 capable * SiS chipset. */ -static int sis_133_pre_reset(struct ata_port *ap) +static int sis_133_cable_detect(struct ata_port *ap) { - static const struct pci_bits sis_enable_bits[] = { - { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ - { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */ - }; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); u16 tmp; - if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) - return -ENOENT; - /* The top bit of this register is the cable detect bit */ pci_read_config_word(pdev, 0x50 + 2 * ap->port_no, &tmp); if ((tmp & 0x8000) && !sis_short_ata40(pdev)) - ap->cbl = ATA_CBL_PATA40; - else - ap->cbl = ATA_CBL_PATA80; - - return ata_std_prereset(ap); -} - -/** - * sis_error_handler - Probe specified port on PATA host controller - * @ap: Port to probe - * - * LOCKING: - * None (inherited from caller). - */ - -static void sis_133_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, sis_133_pre_reset, ata_std_softreset, NULL, ata_std_postreset); + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; } - /** - * sis_66_pre_reset - check for 40/80 pin + * sis_66_cable_detect - check for 40/80 pin * @ap: Port * * Perform cable detection on the UDMA66, UDMA100 and early UDMA133 * SiS IDE controllers. */ -static int sis_66_pre_reset(struct ata_port *ap) +static int sis_66_cable_detect(struct ata_port *ap) { - static const struct pci_bits sis_enable_bits[] = { - { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ - { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */ - }; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 tmp; - if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } /* Older chips keep cable detect in bits 4/5 of reg 0x48 */ pci_read_config_byte(pdev, 0x48, &tmp); tmp >>= ap->port_no; if ((tmp & 0x10) && !sis_short_ata40(pdev)) - ap->cbl = ATA_CBL_PATA40; - else - ap->cbl = ATA_CBL_PATA80; - - return ata_std_prereset(ap); + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; } -/** - * sis_66_error_handler - Probe specified port on PATA host controller - * @ap: Port to probe - * @classes: - * - * LOCKING: - * None (inherited from caller). - */ - -static void sis_66_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, sis_66_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} /** - * sis_old_pre_reset - probe begin + * sis_pre_reset - probe begin * @ap: ATA port * * Set up cable type and use generic probe init */ -static int sis_old_pre_reset(struct ata_port *ap) +static int sis_pre_reset(struct ata_port *ap) { static const struct pci_bits sis_enable_bits[] = { { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ @@ -195,27 +143,23 @@ static int sis_old_pre_reset(struct ata_port *ap) struct pci_dev *pdev = to_pci_dev(ap->host->dev); - if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } - ap->cbl = ATA_CBL_PATA40; + if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) + return -ENOENT; return ata_std_prereset(ap); } /** - * sis_old_error_handler - Probe specified port on PATA host controller + * sis_error_handler - Probe specified port on PATA host controller * @ap: Port to probe * * LOCKING: * None (inherited from caller). */ -static void sis_old_error_handler(struct ata_port *ap) +static void sis_error_handler(struct ata_port *ap) { - ata_bmdma_drive_eh(ap, sis_old_pre_reset, ata_std_softreset, NULL, ata_std_postreset); + ata_bmdma_drive_eh(ap, sis_pre_reset, ata_std_softreset, NULL, ata_std_postreset); } /** @@ -495,7 +439,7 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a int drive_pci = sis_port_base(adev); u16 timing; - const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100}; + static const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100}; pci_read_config_word(pdev, drive_pci, &timing); @@ -532,8 +476,8 @@ static void sis_133_set_dmamode (struct ata_port *ap, struct ata_device *adev) u32 reg54; /* bits 4- cycle time 8 - cvs time */ - const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 }; - const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 }; + static const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 }; + static const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 }; /* If bit 14 is set then the registers are mapped at 0x70 not 0x40 */ pci_read_config_dword(pdev, 0x54, ®54); @@ -576,8 +520,10 @@ static struct scsi_host_template sis_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static const struct ata_port_operations sis_133_ops = { @@ -594,8 +540,9 @@ static const struct ata_port_operations sis_133_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = sis_133_error_handler, + .error_handler = sis_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = sis_133_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -627,8 +574,9 @@ static const struct ata_port_operations sis_133_early_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = sis_66_error_handler, + .error_handler = sis_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = sis_66_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -660,9 +608,9 @@ static const struct ata_port_operations sis_100_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = sis_66_error_handler, + .error_handler = sis_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - + .cable_detect = sis_66_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -691,10 +639,11 @@ static const struct ata_port_operations sis_66_ops = { .check_status = ata_check_status, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .cable_detect = sis_66_cable_detect, .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = sis_66_error_handler, + .error_handler = sis_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, .bmdma_setup = ata_bmdma_setup, @@ -727,8 +676,9 @@ static const struct ata_port_operations sis_old_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = sis_old_error_handler, + .error_handler = sis_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -877,6 +827,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) struct ata_port_info *port; struct pci_dev *host = NULL; struct sis_chipset *chipset = NULL; + struct sis_chipset *sets; static struct sis_chipset sis_chipsets[] = { @@ -931,10 +882,11 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) /* We have to find the bridge first */ - for (chipset = &sis_chipsets[0]; chipset->device; chipset++) { - host = pci_get_device(PCI_VENDOR_ID_SI, chipset->device, NULL); + for (sets = &sis_chipsets[0]; sets->device; sets++) { + host = pci_get_device(PCI_VENDOR_ID_SI, sets->device, NULL); if (host != NULL) { - if (chipset->device == 0x630) { /* SIS630 */ + chipset = sets; /* Match found */ + if (sets->device == 0x630) { /* SIS630 */ u8 host_rev; pci_read_config_byte(host, PCI_REVISION_ID, &host_rev); if (host_rev >= 0x30) /* 630 ET */ @@ -945,7 +897,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) } /* Look for concealed bridges */ - if (host == NULL) { + if (chipset == NULL) { /* Second check */ u32 idemisc; u16 trueid; @@ -1033,8 +985,10 @@ static struct pci_driver sis_pci_driver = { .id_table = sis_pci_tbl, .probe = sis_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init sis_init(void) diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 96e890fd645..da9e22b2575 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c @@ -7,6 +7,13 @@ * SL82C105/Winbond 553 IDE driver * * and in part on the documentation and errata sheet + * + * + * Note: The controller like many controllers has shared timings for + * PIO and DMA. We thus flip to the DMA timings in dma_start and flip back + * in the dma_stop function. Thus we actually don't need a set_dmamode + * method as the PIO method is always called and will set the right PIO + * timing parameters. */ #include <linux/kernel.h> @@ -19,7 +26,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_sl82c105" -#define DRV_VERSION "0.2.3" +#define DRV_VERSION "0.3.0" enum { /* @@ -51,7 +58,6 @@ static int sl82c105_pre_reset(struct ata_port *ap) if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no])) return -ENOENT; - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -126,33 +132,6 @@ static void sl82c105_configure_dmamode(struct ata_port *ap, struct ata_device *a } /** - * sl82c105_set_dmamode - set initial DMA mode data - * @ap: ATA interface - * @adev: ATA device - * - * Called to do the DMA mode setup. This replaces the PIO timings - * for the device in question. Set appropriate PIO timings not DMA - * timings at this point. - */ - -static void sl82c105_set_dmamode(struct ata_port *ap, struct ata_device *adev) -{ - switch(adev->dma_mode) { - case XFER_MW_DMA_0: - sl82c105_configure_piomode(ap, adev, 0); - break; - case XFER_MW_DMA_1: - sl82c105_configure_piomode(ap, adev, 3); - break; - case XFER_MW_DMA_2: - sl82c105_configure_piomode(ap, adev, 4); - break; - default: - BUG(); - } -} - -/** * sl82c105_reset_engine - Reset the DMA engine * @ap: ATA interface * @@ -222,7 +201,7 @@ static void sl82c105_bmdma_stop(struct ata_queued_cmd *qc) /* This will redo the initial setup of the DMA device to matching PIO timings */ - sl82c105_set_dmamode(ap, qc->dev); + sl82c105_set_piomode(ap, qc->dev); } static struct scsi_host_template sl82c105_sht = { @@ -246,7 +225,6 @@ static struct scsi_host_template sl82c105_sht = { static struct ata_port_operations sl82c105_port_ops = { .port_disable = ata_port_disable, .set_piomode = sl82c105_set_piomode, - .set_dmamode = sl82c105_set_dmamode, .mode_filter = ata_pci_default_filter, .tf_load = ata_tf_load, @@ -255,7 +233,11 @@ static struct ata_port_operations sl82c105_port_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, .error_handler = sl82c105_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = sl82c105_bmdma_start, diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index 453ab90b721..e618ffd6e94 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c @@ -43,7 +43,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_triflex" -#define DRV_VERSION "0.2.7" +#define DRV_VERSION "0.2.8" /** * triflex_prereset - probe begin @@ -63,7 +63,6 @@ static int triflex_prereset(struct ata_port *ap) if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no])) return -ENOENT; - ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -193,8 +192,10 @@ static struct scsi_host_template triflex_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations triflex_port_ops = { @@ -212,6 +213,7 @@ static struct ata_port_operations triflex_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = triflex_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .bmdma_setup = ata_bmdma_setup, .bmdma_start = triflex_bmdma_start, @@ -260,8 +262,10 @@ static struct pci_driver triflex_pci_driver = { .id_table = triflex, .probe = triflex_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, +#endif }; static int __init triflex_init(void) diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 220fcd6c549..96b71791d2f 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -62,7 +62,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_via" -#define DRV_VERSION "0.2.1" +#define DRV_VERSION "0.3.1" /* * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx @@ -135,16 +135,23 @@ static const struct via_isa_bridge { */ static int via_cable_detect(struct ata_port *ap) { + const struct via_isa_bridge *config = ap->host->private_data; struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 ata66; + /* Early chips are 40 wire */ + if ((config->flags & VIA_UDMA) < VIA_UDMA_66) + return ATA_CBL_PATA40; + /* UDMA 66 chips have only drive side logic */ + else if((config->flags & VIA_UDMA) < VIA_UDMA_100) + return ATA_CBL_PATA_UNK; + /* UDMA 100 or later */ pci_read_config_dword(pdev, 0x50, &ata66); /* Check both the drive cable reporting bits, we might not have two drives */ if (ata66 & (0x10100000 >> (16 * ap->port_no))) return ATA_CBL_PATA80; - else - return ATA_CBL_PATA40; + return ATA_CBL_PATA40; } static int via_pre_reset(struct ata_port *ap) @@ -156,22 +163,10 @@ static int via_pre_reset(struct ata_port *ap) { 0x40, 1, 0x02, 0x02 }, { 0x40, 1, 0x01, 0x01 } }; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no])) return -ENOENT; } - - if ((config->flags & VIA_UDMA) >= VIA_UDMA_100) - ap->cbl = via_cable_detect(ap); - /* The UDMA66 series has no cable detect so do drive side detect */ - else if ((config->flags & VIA_UDMA) < VIA_UDMA_66) - ap->cbl = ATA_CBL_PATA40; - else - ap->cbl = ATA_CBL_PATA_UNK; - - return ata_std_prereset(ap); } @@ -305,8 +300,10 @@ static struct scsi_host_template via_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, +#endif }; static struct ata_port_operations via_port_ops = { @@ -325,6 +322,7 @@ static struct ata_port_operations via_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = via_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = via_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -360,6 +358,7 @@ static struct ata_port_operations via_port_ops_noirq = { .thaw = ata_bmdma_thaw, .error_handler = via_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = via_cable_detect, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -560,6 +559,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ata_pci_init_one(pdev, port_info, 2); } +#ifdef CONFIG_PM /** * via_reinit_one - reinit after resume * @pdev; PCI device @@ -592,6 +592,7 @@ static int via_reinit_one(struct pci_dev *pdev) } return ata_pci_device_resume(pdev); } +#endif static const struct pci_device_id via[] = { { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), }, @@ -607,8 +608,10 @@ static struct pci_driver via_pci_driver = { .id_table = via, .probe = via_init_one, .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = via_reinit_one, +#endif }; static int __init via_init(void) diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index 0888b4f19f4..cc4ad271afb 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c @@ -8,7 +8,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/pci.h> #include <linux/init.h> #include <linux/blkdev.h> #include <linux/delay.h> @@ -17,7 +16,7 @@ #include <linux/platform_device.h> #define DRV_NAME "pata_winbond" -#define DRV_VERSION "0.0.1" +#define DRV_VERSION "0.0.2" #define NR_HOST 4 /* Two winbond controllers, two channels each */ @@ -36,7 +35,7 @@ static int probe_winbond = 1; static int probe_winbond; #endif -static spinlock_t winbond_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(winbond_lock); static void winbond_writecfg(unsigned long port, u8 reg, u8 val) { @@ -152,13 +151,13 @@ static struct ata_port_operations winbond_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .data_xfer = winbond_data_xfer, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -179,11 +178,9 @@ static struct ata_port_operations winbond_port_ops = { static __init int winbond_init_one(unsigned long port) { - struct ata_probe_ent ae; struct platform_device *pdev; - int ret; u8 reg; - int i; + int i, rc; reg = winbond_readcfg(port, 0x81); reg |= 0x80; /* jumpered mode off */ @@ -202,58 +199,56 @@ static __init int winbond_init_one(unsigned long port) for (i = 0; i < 2 ; i ++) { unsigned long cmd_port = 0x1F0 - (0x80 * i); + struct ata_host *host; + struct ata_port *ap; void __iomem *cmd_addr, *ctl_addr; - if (reg & (1 << i)) { - /* - * Fill in a probe structure first of all - */ - - pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8); - ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1); - if (!cmd_addr || !ctl_addr) { - platform_device_unregister(pdev); - return -ENOMEM; - } - - memset(&ae, 0, sizeof(struct ata_probe_ent)); - INIT_LIST_HEAD(&ae.node); - ae.dev = &pdev->dev; - - ae.port_ops = &winbond_port_ops; - ae.pio_mask = 0x1F; - - ae.sht = &winbond_sht; - - ae.n_ports = 1; - ae.irq = 14 + i; - ae.irq_flags = 0; - ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; - ae.port[0].cmd_addr = cmd_addr; - ae.port[0].altstatus_addr = ctl_addr; - ae.port[0].ctl_addr = ctl_addr; - ata_std_ports(&ae.port[0]); - /* - * Hook in a private data structure per channel - */ - ae.private_data = &winbond_data[nr_winbond_host]; - winbond_data[nr_winbond_host].config = port; - winbond_data[nr_winbond_host].platform_dev = pdev; - - ret = ata_device_add(&ae); - if (ret == 0) { - platform_device_unregister(pdev); - return -ENODEV; - } - winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev); - } + if (!(reg & (1 << i))) + continue; + + pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + rc = -ENOMEM; + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + goto err_unregister; + + rc = -ENOMEM; + cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8); + ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1); + if (!cmd_addr || !ctl_addr) + goto err_unregister; + + ap = host->ports[0]; + ap->ops = &winbond_port_ops; + ap->pio_mask = 0x1F; + ap->flags |= ATA_FLAG_SLAVE_POSS; + ap->ioaddr.cmd_addr = cmd_addr; + ap->ioaddr.altstatus_addr = ctl_addr; + ap->ioaddr.ctl_addr = ctl_addr; + ata_std_ports(&ap->ioaddr); + + /* hook in a private data structure per channel */ + host->private_data = &winbond_data[nr_winbond_host]; + winbond_data[nr_winbond_host].config = port; + winbond_data[nr_winbond_host].platform_dev = pdev; + + /* activate */ + rc = ata_host_activate(host, 14 + i, ata_interrupt, 0, + &winbond_sht); + if (rc) + goto err_unregister; + + winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev); } return 0; + + err_unregister: + platform_device_unregister(pdev); + return rc; } /** diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 857ac23217a..52b69530ab2 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -44,7 +44,7 @@ #include <linux/libata.h> #define DRV_NAME "pdc_adma" -#define DRV_VERSION "0.04" +#define DRV_VERSION "0.05" /* macro to calculate base address for ATA regs */ #define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40)) @@ -52,9 +52,9 @@ /* macro to calculate base address for ADMA regs */ #define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20)) -/* macro to obtain addresses from ata_host */ -#define ADMA_HOST_REGS(host,port_no) \ - ADMA_REGS((host)->iomap[ADMA_MMIO_BAR], port_no) +/* macro to obtain addresses from ata_port */ +#define ADMA_PORT_REGS(ap) \ + ADMA_REGS((ap)->host->iomap[ADMA_MMIO_BAR], ap->port_no) enum { ADMA_MMIO_BAR = 4, @@ -128,7 +128,6 @@ struct adma_port_priv { static int adma_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static irqreturn_t adma_intr (int irq, void *dev_instance); static int adma_port_start(struct ata_port *ap); static void adma_host_stop(struct ata_host *host); static void adma_port_stop(struct ata_port *ap); @@ -172,7 +171,6 @@ static const struct ata_port_operations adma_ata_ops = { .qc_issue = adma_qc_issue, .eng_timeout = adma_eng_timeout, .data_xfer = ata_data_xfer, - .irq_handler = adma_intr, .irq_clear = adma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -186,7 +184,6 @@ static const struct ata_port_operations adma_ata_ops = { static struct ata_port_info adma_port_info[] = { /* board_1841_idx */ { - .sht = &adma_ata_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, @@ -229,8 +226,10 @@ static void adma_irq_clear(struct ata_port *ap) /* nothing */ } -static void adma_reset_engine(void __iomem *chan) +static void adma_reset_engine(struct ata_port *ap) { + void __iomem *chan = ADMA_PORT_REGS(ap); + /* reset ADMA to idle state */ writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL); udelay(2); @@ -241,14 +240,14 @@ static void adma_reset_engine(void __iomem *chan) static void adma_reinit_engine(struct ata_port *ap) { struct adma_port_priv *pp = ap->private_data; - void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no); + void __iomem *chan = ADMA_PORT_REGS(ap); /* mask/clear ATA interrupts */ writeb(ATA_NIEN, ap->ioaddr.ctl_addr); ata_check_status(ap); /* reset the ADMA engine */ - adma_reset_engine(chan); + adma_reset_engine(ap); /* set in-FIFO threshold to 0x100 */ writew(0x100, chan + ADMA_FIFO_IN); @@ -268,7 +267,7 @@ static void adma_reinit_engine(struct ata_port *ap) static inline void adma_enter_reg_mode(struct ata_port *ap) { - void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no); + void __iomem *chan = ADMA_PORT_REGS(ap); writew(aPIOMD4, chan + ADMA_CONTROL); readb(chan + ADMA_STATUS); /* flush */ @@ -415,7 +414,7 @@ static void adma_qc_prep(struct ata_queued_cmd *qc) static inline void adma_packet_start(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no); + void __iomem *chan = ADMA_PORT_REGS(ap); VPRINTK("ENTER, ap %p\n", ap); @@ -453,7 +452,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host) struct ata_port *ap = host->ports[port_no]; struct adma_port_priv *pp; struct ata_queued_cmd *qc; - void __iomem *chan = ADMA_HOST_REGS(host, port_no); + void __iomem *chan = ADMA_PORT_REGS(ap); u8 status = readb(chan + ADMA_STATUS); if (status == 0) @@ -498,7 +497,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host) if ((status & ATA_BUSY)) continue; DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", - ap->id, qc->tf.protocol, status); + ap->print_id, qc->tf.protocol, status); /* complete taskfile transaction */ pp->state = adma_state_idle; @@ -575,7 +574,7 @@ static int adma_port_start(struct ata_port *ap) static void adma_port_stop(struct ata_port *ap) { - adma_reset_engine(ADMA_HOST_REGS(ap->host, ap->port_no)); + adma_reset_engine(ap); } static void adma_host_stop(struct ata_host *host) @@ -583,21 +582,19 @@ static void adma_host_stop(struct ata_host *host) unsigned int port_no; for (port_no = 0; port_no < ADMA_PORTS; ++port_no) - adma_reset_engine(ADMA_HOST_REGS(host, port_no)); + adma_reset_engine(host->ports[port_no]); } -static void adma_host_init(unsigned int chip_id, - struct ata_probe_ent *probe_ent) +static void adma_host_init(struct ata_host *host, unsigned int chip_id) { unsigned int port_no; - void __iomem *mmio_base = probe_ent->iomap[ADMA_MMIO_BAR]; /* enable/lock aGO operation */ - writeb(7, mmio_base + ADMA_MODE_LOCK); + writeb(7, host->iomap[ADMA_MMIO_BAR] + ADMA_MODE_LOCK); /* reset the ADMA logic */ for (port_no = 0; port_no < ADMA_PORTS; ++port_no) - adma_reset_engine(ADMA_REGS(mmio_base, port_no)); + adma_reset_engine(host->ports[port_no]); } static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base) @@ -623,14 +620,21 @@ static int adma_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_probe_ent *probe_ent = NULL; - void __iomem *mmio_base; unsigned int board_idx = (unsigned int) ent->driver_data; + const struct ata_port_info *ppi[] = { &adma_port_info[board_idx], NULL }; + struct ata_host *host; + void __iomem *mmio_base; int rc, port_no; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* alloc host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, ADMA_PORTS); + if (!host) + return -ENOMEM; + + /* acquire resources and fill host */ rc = pcim_enable_device(pdev); if (rc) return rc; @@ -641,46 +645,23 @@ static int adma_ata_init_one(struct pci_dev *pdev, rc = pcim_iomap_regions(pdev, 1 << ADMA_MMIO_BAR, DRV_NAME); if (rc) return rc; - mmio_base = pcim_iomap_table(pdev)[ADMA_MMIO_BAR]; + host->iomap = pcim_iomap_table(pdev); + mmio_base = host->iomap[ADMA_MMIO_BAR]; rc = adma_set_dma_masks(pdev, mmio_base); if (rc) return rc; - probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) - return -ENOMEM; - - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - - probe_ent->sht = adma_port_info[board_idx].sht; - probe_ent->port_flags = adma_port_info[board_idx].flags; - probe_ent->pio_mask = adma_port_info[board_idx].pio_mask; - probe_ent->mwdma_mask = adma_port_info[board_idx].mwdma_mask; - probe_ent->udma_mask = adma_port_info[board_idx].udma_mask; - probe_ent->port_ops = adma_port_info[board_idx].port_ops; - - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->n_ports = ADMA_PORTS; - probe_ent->iomap = pcim_iomap_table(pdev); - - for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) { - adma_ata_setup_port(&probe_ent->port[port_no], + for (port_no = 0; port_no < ADMA_PORTS; ++port_no) + adma_ata_setup_port(&host->ports[port_no]->ioaddr, ADMA_ATA_REGS(mmio_base, port_no)); - } - - pci_set_master(pdev); /* initialize adapter */ - adma_host_init(board_idx, probe_ent); + adma_host_init(host, board_idx); - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(&pdev->dev, probe_ent); - return 0; + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, adma_intr, IRQF_SHARED, + &adma_ata_sht); } static int __init adma_ata_init(void) diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 31b636fac98..f099a1d83a0 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -135,8 +135,10 @@ static struct scsi_host_template inic_sht = { .slave_configure = inic_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .suspend = ata_scsi_device_suspend, .resume = ata_scsi_device_resume, +#endif }; static const int scr_map[] = { @@ -486,11 +488,11 @@ static void inic_error_handler(struct ata_port *ap) static void inic_post_internal_cmd(struct ata_queued_cmd *qc) { /* make DMA engine forget about the failed command */ - if (qc->err_mask) + if (qc->flags & ATA_QCFLAG_FAILED) inic_reset_port(inic_port_base(qc->ap)); } -static void inic_dev_config(struct ata_port *ap, struct ata_device *dev) +static void inic_dev_config(struct ata_device *dev) { /* inic can only handle upto LBA28 max sectors */ if (dev->max_sectors > ATA_MAX_SECTORS) @@ -557,7 +559,6 @@ static struct ata_port_operations inic_port_ops = { .bmdma_stop = inic_bmdma_stop, .bmdma_status = inic_bmdma_status, - .irq_handler = inic_interrupt, .irq_clear = inic_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -578,7 +579,6 @@ static struct ata_port_operations inic_port_ops = { }; static struct ata_port_info inic_port_info = { - .sht = &inic_sht, /* For some reason, ATA_PROT_ATAPI is broken on this * controller, and no, PIO_POLLING does't fix it. It somehow * manages to report the wrong ireason and ignoring ireason @@ -632,6 +632,7 @@ static int init_controller(void __iomem *mmio_base, u16 hctl) return 0; } +#ifdef CONFIG_PM static int inic_pci_device_resume(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); @@ -639,10 +640,11 @@ static int inic_pci_device_resume(struct pci_dev *pdev) void __iomem *mmio_base = host->iomap[MMIO_BAR]; int rc; - ata_pci_device_do_resume(pdev); + rc = ata_pci_device_do_resume(pdev); + if (rc) + return rc; if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - printk("XXX\n"); rc = init_controller(mmio_base, hpriv->cached_hctl); if (rc) return rc; @@ -652,12 +654,13 @@ static int inic_pci_device_resume(struct pci_dev *pdev) return 0; } +#endif static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_port_info *pinfo = &inic_port_info; - struct ata_probe_ent *probe_ent; + const struct ata_port_info *ppi[] = { &inic_port_info, NULL }; + struct ata_host *host; struct inic_host_priv *hpriv; void __iomem * const *iomap; int i, rc; @@ -665,18 +668,38 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - rc = pcim_enable_device(pdev); - if (rc) - return rc; + /* alloc host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS); + hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); + if (!host || !hpriv) + return -ENOMEM; + + host->private_data = hpriv; - rc = pci_request_regions(pdev, DRV_NAME); + /* acquire resources and fill host */ + rc = pcim_enable_device(pdev); if (rc) return rc; rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME); if (rc) return rc; - iomap = pcim_iomap_table(pdev); + host->iomap = iomap = pcim_iomap_table(pdev); + + for (i = 0; i < NR_PORTS; i++) { + struct ata_ioports *port = &host->ports[i]->ioaddr; + void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE; + + port->cmd_addr = iomap[2 * i]; + port->altstatus_addr = + port->ctl_addr = (void __iomem *) + ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS); + port->scr_addr = port_base + PORT_SCR; + + ata_std_ports(port); + } + + hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL); /* Set dma_mask. This devices doesn't support 64bit addressing. */ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); @@ -693,43 +716,6 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return rc; } - probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); - hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); - if (!probe_ent || !hpriv) - return -ENOMEM; - - probe_ent->dev = &pdev->dev; - INIT_LIST_HEAD(&probe_ent->node); - - probe_ent->sht = pinfo->sht; - probe_ent->port_flags = pinfo->flags; - probe_ent->pio_mask = pinfo->pio_mask; - probe_ent->mwdma_mask = pinfo->mwdma_mask; - probe_ent->udma_mask = pinfo->udma_mask; - probe_ent->port_ops = pinfo->port_ops; - probe_ent->n_ports = NR_PORTS; - - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - - probe_ent->iomap = iomap; - - for (i = 0; i < NR_PORTS; i++) { - struct ata_ioports *port = &probe_ent->port[i]; - void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE; - - port->cmd_addr = iomap[2 * i]; - port->altstatus_addr = - port->ctl_addr = (void __iomem *) - ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS); - port->scr_addr = port_base + PORT_SCR; - - ata_std_ports(port); - } - - probe_ent->private_data = hpriv; - hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL); - rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl); if (rc) { dev_printk(KERN_ERR, &pdev->dev, @@ -738,13 +724,8 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } pci_set_master(pdev); - - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(&pdev->dev, probe_ent); - - return 0; + return ata_host_activate(host, pdev->irq, inic_interrupt, IRQF_SHARED, + &inic_sht); } static const struct pci_device_id inic_pci_tbl[] = { @@ -755,8 +736,10 @@ static const struct pci_device_id inic_pci_tbl[] = { static struct pci_driver inic_pci_driver = { .name = DRV_NAME, .id_table = inic_pci_tbl, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = inic_pci_device_resume, +#endif .probe = inic_init_one, .remove = ata_pci_remove_one, }; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index d689df52eae..cb9b9ac12b4 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -35,7 +35,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_mv" -#define DRV_VERSION "0.7" +#define DRV_VERSION "0.8" enum { /* BAR's are enumerated in terms of pci_resource_start() terms */ @@ -137,14 +137,19 @@ enum { PCI_ERR = (1 << 18), TRAN_LO_DONE = (1 << 19), /* 6xxx: IRQ coalescing */ TRAN_HI_DONE = (1 << 20), /* 6xxx: IRQ coalescing */ + PORTS_0_3_COAL_DONE = (1 << 8), + PORTS_4_7_COAL_DONE = (1 << 17), PORTS_0_7_COAL_DONE = (1 << 21), /* 6xxx: IRQ coalescing */ GPIO_INT = (1 << 22), SELF_INT = (1 << 23), TWSI_INT = (1 << 24), HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ + HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | HC_MAIN_RSVD), + HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | + HC_MAIN_RSVD_5), /* SATAHC registers */ HC_CFG_OFS = 0, @@ -248,10 +253,7 @@ enum { #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) enum { - /* Our DMA boundary is determined by an ePRD being unable to handle - * anything larger than 64KB - */ - MV_DMA_BOUNDARY = 0xffffU, + MV_DMA_BOUNDARY = 0xffffffffU, EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U, @@ -345,7 +347,6 @@ static void mv_port_stop(struct ata_port *ap); static void mv_qc_prep(struct ata_queued_cmd *qc); static void mv_qc_prep_iie(struct ata_queued_cmd *qc); static unsigned int mv_qc_issue(struct ata_queued_cmd *qc); -static irqreturn_t mv_interrupt(int irq, void *dev_instance); static void mv_eng_timeout(struct ata_port *ap); static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); @@ -379,10 +380,10 @@ static struct scsi_host_template mv_sht = { .queuecommand = ata_scsi_queuecmd, .can_queue = MV_USE_Q_DEPTH, .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = MV_MAX_SG_CT / 2, + .sg_tablesize = MV_MAX_SG_CT, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, - .use_clustering = ATA_SHT_USE_CLUSTERING, + .use_clustering = 1, .proc_name = DRV_NAME, .dma_boundary = MV_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, @@ -400,6 +401,7 @@ static const struct ata_port_operations mv5_ops = { .dev_select = ata_std_dev_select, .phy_reset = mv_phy_reset, + .cable_detect = ata_cable_sata, .qc_prep = mv_qc_prep, .qc_issue = mv_qc_issue, @@ -407,7 +409,6 @@ static const struct ata_port_operations mv5_ops = { .eng_timeout = mv_eng_timeout, - .irq_handler = mv_interrupt, .irq_clear = mv_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -429,6 +430,7 @@ static const struct ata_port_operations mv6_ops = { .dev_select = ata_std_dev_select, .phy_reset = mv_phy_reset, + .cable_detect = ata_cable_sata, .qc_prep = mv_qc_prep, .qc_issue = mv_qc_issue, @@ -436,7 +438,6 @@ static const struct ata_port_operations mv6_ops = { .eng_timeout = mv_eng_timeout, - .irq_handler = mv_interrupt, .irq_clear = mv_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -458,6 +459,7 @@ static const struct ata_port_operations mv_iie_ops = { .dev_select = ata_std_dev_select, .phy_reset = mv_phy_reset, + .cable_detect = ata_cable_sata, .qc_prep = mv_qc_prep_iie, .qc_issue = mv_qc_issue, @@ -465,7 +467,6 @@ static const struct ata_port_operations mv_iie_ops = { .eng_timeout = mv_eng_timeout, - .irq_handler = mv_interrupt, .irq_clear = mv_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -479,35 +480,30 @@ static const struct ata_port_operations mv_iie_ops = { static const struct ata_port_info mv_port_info[] = { { /* chip_504x */ - .sht = &mv_sht, .flags = MV_COMMON_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &mv5_ops, }, { /* chip_508x */ - .sht = &mv_sht, .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &mv5_ops, }, { /* chip_5080 */ - .sht = &mv_sht, .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &mv5_ops, }, { /* chip_604x */ - .sht = &mv_sht, .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &mv6_ops, }, { /* chip_608x */ - .sht = &mv_sht, .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | MV_FLAG_DUAL_HC), .pio_mask = 0x1f, /* pio0-4 */ @@ -515,14 +511,12 @@ static const struct ata_port_info mv_port_info[] = { .port_ops = &mv6_ops, }, { /* chip_6042 */ - .sht = &mv_sht, .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &mv_iie_ops, }, { /* chip_7042 */ - .sht = &mv_sht, .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ @@ -546,6 +540,9 @@ static const struct pci_device_id mv_pci_tbl[] = { { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, + /* add Marvell 7042 support */ + { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 }, + { } /* terminate list */ }; @@ -580,6 +577,39 @@ static const struct mv_hw_ops mv6xxx_ops = { static int msi; /* Use PCI msi; either zero (off, default) or non-zero */ +/* move to PCI layer or libata core? */ +static int pci_go_64(struct pci_dev *pdev) +{ + int rc; + + if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { + rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); + if (rc) { + rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, + "64-bit DMA enable failed\n"); + return rc; + } + } + } else { + rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, + "32-bit DMA enable failed\n"); + return rc; + } + rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, + "32-bit consistent DMA enable failed\n"); + return rc; + } + } + + return rc; +} + /* * Functions */ @@ -793,20 +823,18 @@ static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in) { unsigned int ofs = mv_scr_offset(sc_reg_in); - if (0xffffffffU != ofs) { + if (0xffffffffU != ofs) return readl(mv_ap_base(ap) + ofs); - } else { + else return (u32) ofs; - } } static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) { unsigned int ofs = mv_scr_offset(sc_reg_in); - if (0xffffffffU != ofs) { + if (0xffffffffU != ofs) writelfl(val, mv_ap_base(ap) + ofs); - } } static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio) @@ -814,23 +842,27 @@ static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio) u32 cfg = readl(port_mmio + EDMA_CFG_OFS); /* set up non-NCQ EDMA configuration */ - cfg &= ~0x1f; /* clear queue depth */ - cfg &= ~EDMA_CFG_NCQ; /* clear NCQ mode */ cfg &= ~(1 << 9); /* disable equeue */ - if (IS_GEN_I(hpriv)) + if (IS_GEN_I(hpriv)) { + cfg &= ~0x1f; /* clear queue depth */ cfg |= (1 << 8); /* enab config burst size mask */ + } - else if (IS_GEN_II(hpriv)) + else if (IS_GEN_II(hpriv)) { + cfg &= ~0x1f; /* clear queue depth */ cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN; + cfg &= ~(EDMA_CFG_NCQ | EDMA_CFG_NCQ_GO_ON_ERR); /* clear NCQ */ + } else if (IS_GEN_IIE(hpriv)) { - cfg |= (1 << 23); /* dis RX PM port mask */ - cfg &= ~(1 << 16); /* dis FIS-based switching (for now) */ + cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ + cfg |= (1 << 22); /* enab 4-entry host queue cache */ cfg &= ~(1 << 19); /* dis 128-entry queue (for now?) */ cfg |= (1 << 18); /* enab early completion */ - cfg |= (1 << 17); /* enab host q cache */ - cfg |= (1 << 22); /* enab cutthrough */ + cfg |= (1 << 17); /* enab cut-through (dis stor&forwrd) */ + cfg &= ~(1 << 16); /* dis FIS-based switching (for now) */ + cfg &= ~(EDMA_CFG_NCQ | EDMA_CFG_NCQ_GO_ON_ERR); /* clear NCQ */ } writelfl(cfg, port_mmio + EDMA_CFG_OFS); @@ -950,38 +982,30 @@ static void mv_port_stop(struct ata_port *ap) * LOCKING: * Inherited from caller. */ -static void mv_fill_sg(struct ata_queued_cmd *qc) +static unsigned int mv_fill_sg(struct ata_queued_cmd *qc) { struct mv_port_priv *pp = qc->ap->private_data; - unsigned int i = 0; + unsigned int n_sg = 0; struct scatterlist *sg; + struct mv_sg *mv_sg; + mv_sg = pp->sg_tbl; ata_for_each_sg(sg, qc) { - dma_addr_t addr; - u32 sg_len, len, offset; - - addr = sg_dma_address(sg); - sg_len = sg_dma_len(sg); - - while (sg_len) { - offset = addr & MV_DMA_BOUNDARY; - len = sg_len; - if ((offset + sg_len) > 0x10000) - len = 0x10000 - offset; + dma_addr_t addr = sg_dma_address(sg); + u32 sg_len = sg_dma_len(sg); - pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); - pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); - pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff); + mv_sg->addr = cpu_to_le32(addr & 0xffffffff); + mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); + mv_sg->flags_size = cpu_to_le32(sg_len & 0xffff); - sg_len -= len; - addr += len; + if (ata_sg_is_last(sg, qc)) + mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); - if (!sg_len && ata_sg_is_last(sg, qc)) - pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); - - i++; - } + mv_sg++; + n_sg++; } + + return n_sg; } static inline unsigned mv_inc_q_index(unsigned index) @@ -1276,7 +1300,7 @@ static void mv_err_intr(struct ata_port *ap, int reset_allowed) pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; } DPRINTK(KERN_ERR "ata%u: port error; EDMA err cause: 0x%08x " - "SERR: 0x%08x\n", ap->id, edma_err_cause, serr); + "SERR: 0x%08x\n", ap->print_id, edma_err_cause, serr); /* Clear EDMA now that SERR cleanup done */ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); @@ -1311,17 +1335,15 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) int shift, port, port0, hard_port, handled; unsigned int err_mask; - if (hc == 0) { + if (hc == 0) port0 = 0; - } else { + else port0 = MV_PORTS_PER_HC; - } /* we'll need the HC success int register in most cases */ hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); - if (hc_irq_cause) { + if (hc_irq_cause) writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); - } VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n", hc,relevant,hc_irq_cause); @@ -1416,9 +1438,8 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) /* check the cases where we either have nothing pending or have read * a bogus register value which can indicate HW removal or PCI fault */ - if (!irq_stat || (0xffffffffU == irq_stat)) { + if (!irq_stat || (0xffffffffU == irq_stat)) return IRQ_NONE; - } n_hcs = mv_get_hc_count(host->ports[0]->flags); spin_lock(&host->lock); @@ -1943,7 +1964,6 @@ comreset_retry: ata_port_disable(ap); return; } - ap->cbl = ATA_CBL_SATA; /* even after SStatus reflects that device is ready, * it seems to take a while for link to be fully @@ -2052,7 +2072,7 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS; /* unused: */ - port->cmd_addr = port->bmdma_addr = port->scr_addr = 0; + port->cmd_addr = port->bmdma_addr = port->scr_addr = NULL; /* Clear any currently outstanding port interrupt conditions */ serr_ofs = mv_scr_offset(SCR_ERROR); @@ -2068,9 +2088,10 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); } -static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, - unsigned int board_idx) +static int mv_chip_id(struct ata_host *host, unsigned int board_idx) { + struct pci_dev *pdev = to_pci_dev(host->dev); + struct mv_host_priv *hpriv = host->private_data; u8 rev_id; u32 hp_flags = hpriv->hp_flags; @@ -2168,8 +2189,8 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, /** * mv_init_host - Perform some early initialization of the host. - * @pdev: host PCI device - * @probe_ent: early data struct representing the host + * @host: ATA host to initialize + * @board_idx: controller index * * If possible, do an early global reset of the host. Then do * our port init and clear/unmask all/relevant host interrupts. @@ -2177,24 +2198,23 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, * LOCKING: * Inherited from caller. */ -static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, - unsigned int board_idx) +static int mv_init_host(struct ata_host *host, unsigned int board_idx) { int rc = 0, n_hc, port, hc; - void __iomem *mmio = probe_ent->iomap[MV_PRIMARY_BAR]; - struct mv_host_priv *hpriv = probe_ent->private_data; + struct pci_dev *pdev = to_pci_dev(host->dev); + void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; + struct mv_host_priv *hpriv = host->private_data; /* global interrupt mask */ writel(0, mmio + HC_MAIN_IRQ_MASK_OFS); - rc = mv_chip_id(pdev, hpriv, board_idx); + rc = mv_chip_id(host, board_idx); if (rc) goto done; - n_hc = mv_get_hc_count(probe_ent->port_flags); - probe_ent->n_ports = MV_PORTS_PER_HC * n_hc; + n_hc = mv_get_hc_count(host->ports[0]->flags); - for (port = 0; port < probe_ent->n_ports; port++) + for (port = 0; port < host->n_ports; port++) hpriv->ops->read_preamp(hpriv, port, mmio); rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc); @@ -2205,7 +2225,7 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, hpriv->ops->reset_bus(pdev, mmio); hpriv->ops->enable_leds(hpriv, mmio); - for (port = 0; port < probe_ent->n_ports; port++) { + for (port = 0; port < host->n_ports; port++) { if (IS_60XX(hpriv)) { void __iomem *port_mmio = mv_port_base(mmio, port); @@ -2218,9 +2238,9 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, hpriv->ops->phy_errata(hpriv, mmio, port); } - for (port = 0; port < probe_ent->n_ports; port++) { + for (port = 0; port < host->n_ports; port++) { void __iomem *port_mmio = mv_port_base(mmio, port); - mv_port_init(&probe_ent->port[port], port_mmio); + mv_port_init(&host->ports[port]->ioaddr, port_mmio); } for (hc = 0; hc < n_hc; hc++) { @@ -2240,7 +2260,11 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, /* and unmask interrupt generation for host regs */ writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS); - writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS); + + if (IS_50XX(hpriv)) + writelfl(~HC_MAIN_MASKED_IRQS_5, mmio + HC_MAIN_IRQ_MASK_OFS); + else + writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS); VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x " "PCI int cause/mask=0x%08x/0x%08x\n", @@ -2255,17 +2279,17 @@ done: /** * mv_print_info - Dump key info to kernel log for perusal. - * @probe_ent: early data struct representing the host + * @host: ATA host to print info about * * FIXME: complete this. * * LOCKING: * Inherited from caller. */ -static void mv_print_info(struct ata_probe_ent *probe_ent) +static void mv_print_info(struct ata_host *host) { - struct pci_dev *pdev = to_pci_dev(probe_ent->dev); - struct mv_host_priv *hpriv = probe_ent->private_data; + struct pci_dev *pdev = to_pci_dev(host->dev); + struct mv_host_priv *hpriv = host->private_data; u8 rev_id, scc; const char *scc_s; @@ -2284,7 +2308,7 @@ static void mv_print_info(struct ata_probe_ent *probe_ent) dev_printk(KERN_INFO, &pdev->dev, "%u slots %u ports %s mode IRQ via %s\n", - (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports, + (unsigned)MV_MAX_Q_DEPTH, host->n_ports, scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx"); } @@ -2299,65 +2323,55 @@ static void mv_print_info(struct ata_probe_ent *probe_ent) static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version = 0; - struct device *dev = &pdev->dev; - struct ata_probe_ent *probe_ent; - struct mv_host_priv *hpriv; unsigned int board_idx = (unsigned int)ent->driver_data; - int rc; + const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; + struct ata_host *host; + struct mv_host_priv *hpriv; + int n_ports, rc; if (!printed_version++) dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); + /* allocate host */ + n_ports = mv_get_hc_count(ppi[0]->flags) * MV_PORTS_PER_HC; + + host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); + hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); + if (!host || !hpriv) + return -ENOMEM; + host->private_data = hpriv; + + /* acquire resources */ rc = pcim_enable_device(pdev); if (rc) return rc; - pci_set_master(pdev); rc = pcim_iomap_regions(pdev, 1 << MV_PRIMARY_BAR, DRV_NAME); if (rc == -EBUSY) pcim_pin_device(pdev); if (rc) return rc; + host->iomap = pcim_iomap_table(pdev); - probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) - return -ENOMEM; - - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - - hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); - if (!hpriv) - return -ENOMEM; - - probe_ent->sht = mv_port_info[board_idx].sht; - probe_ent->port_flags = mv_port_info[board_idx].flags; - probe_ent->pio_mask = mv_port_info[board_idx].pio_mask; - probe_ent->udma_mask = mv_port_info[board_idx].udma_mask; - probe_ent->port_ops = mv_port_info[board_idx].port_ops; - - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->iomap = pcim_iomap_table(pdev); - probe_ent->private_data = hpriv; + rc = pci_go_64(pdev); + if (rc) + return rc; /* initialize adapter */ - rc = mv_init_host(pdev, probe_ent, board_idx); + rc = mv_init_host(host, board_idx); if (rc) return rc; /* Enable interrupts */ - if (msi && !pci_enable_msi(pdev)) + if (msi && pci_enable_msi(pdev)) pci_intx(pdev, 1); mv_dump_pci_cfg(pdev, 0x68); - mv_print_info(probe_ent); + mv_print_info(host); - if (ata_device_add(probe_ent) == 0) - return -ENODEV; - - devm_kfree(dev, probe_ent); - return 0; + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, + &mv_sht); } static int __init mv_init(void) diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index ab92f208dae..02169740ed2 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -219,6 +219,7 @@ struct nv_adma_port_priv { void __iomem * gen_block; void __iomem * notifier_clear_block; u8 flags; + int last_issue_ncq; }; struct nv_host_priv { @@ -229,7 +230,9 @@ struct nv_host_priv { static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void nv_remove_one (struct pci_dev *pdev); +#ifdef CONFIG_PM static int nv_pci_device_resume(struct pci_dev *pdev); +#endif static void nv_ck804_host_stop(struct ata_host *host); static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); @@ -250,14 +253,14 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance); static void nv_adma_irq_clear(struct ata_port *ap); static int nv_adma_port_start(struct ata_port *ap); static void nv_adma_port_stop(struct ata_port *ap); +#ifdef CONFIG_PM static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg); static int nv_adma_port_resume(struct ata_port *ap); +#endif static void nv_adma_error_handler(struct ata_port *ap); static void nv_adma_host_stop(struct ata_host *host); -static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc); -static void nv_adma_bmdma_start(struct ata_queued_cmd *qc); -static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc); -static u8 nv_adma_bmdma_status(struct ata_port *ap); +static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc); +static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf); enum nv_host_type { @@ -297,8 +300,10 @@ static struct pci_driver nv_pci_driver = { .name = DRV_NAME, .id_table = nv_pci_tbl, .probe = nv_init_one, +#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = nv_pci_device_resume, +#endif .remove = nv_remove_one, }; @@ -318,8 +323,10 @@ static struct scsi_host_template nv_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .suspend = ata_scsi_device_suspend, .resume = ata_scsi_device_resume, +#endif }; static struct scsi_host_template nv_adma_sht = { @@ -338,8 +345,10 @@ static struct scsi_host_template nv_adma_sht = { .slave_configure = nv_adma_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .suspend = ata_scsi_device_suspend, .resume = ata_scsi_device_resume, +#endif }; static const struct ata_port_operations nv_generic_ops = { @@ -360,7 +369,6 @@ static const struct ata_port_operations nv_generic_ops = { .error_handler = nv_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, .data_xfer = ata_data_xfer, - .irq_handler = nv_generic_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -387,7 +395,6 @@ static const struct ata_port_operations nv_nf2_ops = { .error_handler = nv_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, .data_xfer = ata_data_xfer, - .irq_handler = nv_nf2_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -414,7 +421,6 @@ static const struct ata_port_operations nv_ck804_ops = { .error_handler = nv_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, .data_xfer = ata_data_xfer, - .irq_handler = nv_ck804_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -427,23 +433,22 @@ static const struct ata_port_operations nv_ck804_ops = { static const struct ata_port_operations nv_adma_ops = { .port_disable = ata_port_disable, .tf_load = ata_tf_load, - .tf_read = ata_tf_read, + .tf_read = nv_adma_tf_read, .check_atapi_dma = nv_adma_check_atapi_dma, .exec_command = ata_exec_command, .check_status = ata_check_status, .dev_select = ata_std_dev_select, - .bmdma_setup = nv_adma_bmdma_setup, - .bmdma_start = nv_adma_bmdma_start, - .bmdma_stop = nv_adma_bmdma_stop, - .bmdma_status = nv_adma_bmdma_status, + .bmdma_setup = ata_bmdma_setup, + .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, .qc_prep = nv_adma_qc_prep, .qc_issue = nv_adma_qc_issue, .freeze = nv_ck804_freeze, .thaw = nv_ck804_thaw, .error_handler = nv_adma_error_handler, - .post_internal_cmd = nv_adma_bmdma_stop, + .post_internal_cmd = nv_adma_post_internal_cmd, .data_xfer = ata_data_xfer, - .irq_handler = nv_adma_interrupt, .irq_clear = nv_adma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -451,8 +456,10 @@ static const struct ata_port_operations nv_adma_ops = { .scr_write = nv_scr_write, .port_start = nv_adma_port_start, .port_stop = nv_adma_port_stop, +#ifdef CONFIG_PM .port_suspend = nv_adma_port_suspend, .port_resume = nv_adma_port_resume, +#endif .host_stop = nv_adma_host_stop, }; @@ -466,6 +473,7 @@ static struct ata_port_info nv_port_info[] = { .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, .port_ops = &nv_generic_ops, + .irq_handler = nv_generic_interrupt, }, /* nforce2/3 */ { @@ -476,6 +484,7 @@ static struct ata_port_info nv_port_info[] = { .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, .port_ops = &nv_nf2_ops, + .irq_handler = nv_nf2_interrupt, }, /* ck804 */ { @@ -486,6 +495,7 @@ static struct ata_port_info nv_port_info[] = { .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, .port_ops = &nv_ck804_ops, + .irq_handler = nv_ck804_interrupt, }, /* ADMA */ { @@ -497,6 +507,7 @@ static struct ata_port_info nv_port_info[] = { .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, .port_ops = &nv_adma_ops, + .irq_handler = nv_adma_interrupt, }, }; @@ -657,34 +668,47 @@ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc) return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE); } +static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf) +{ + /* Since commands where a result TF is requested are not + executed in ADMA mode, the only time this function will be called + in ADMA mode will be if a command fails. In this case we + don't care about going into register mode with ADMA commands + pending, as the commands will all shortly be aborted anyway. */ + nv_adma_register_mode(ap); + + ata_tf_read(ap, tf); +} + static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb) { unsigned int idx = 0; - cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device | WNB); - - if ((tf->flags & ATA_TFLAG_LBA48) == 0) { - cpb[idx++] = cpu_to_le16(IGN); - cpb[idx++] = cpu_to_le16(IGN); - cpb[idx++] = cpu_to_le16(IGN); - cpb[idx++] = cpu_to_le16(IGN); - cpb[idx++] = cpu_to_le16(IGN); + if(tf->flags & ATA_TFLAG_ISADDR) { + if (tf->flags & ATA_TFLAG_LBA48) { + cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->hob_feature | WNB); + cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->hob_nsect); + cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->hob_lbal); + cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->hob_lbam); + cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->hob_lbah); + cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->feature); + } else + cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->feature | WNB); + + cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->nsect); + cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->lbal); + cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->lbam); + cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->lbah); } - else { - cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->hob_feature); - cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->hob_nsect); - cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->hob_lbal); - cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->hob_lbam); - cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->hob_lbah); - } - cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->feature); - cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->nsect); - cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->lbal); - cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->lbam); - cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->lbah); + + if(tf->flags & ATA_TFLAG_DEVICE) + cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device); cpb[idx++] = cpu_to_le16((ATA_REG_CMD << 8) | tf->command | CMDEND); + while(idx < 12) + cpb[idx++] = cpu_to_le16(IGN); + return idx; } @@ -727,20 +751,23 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) return 1; } - if (flags & NV_CPB_RESP_DONE) { + if (likely(flags & NV_CPB_RESP_DONE)) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num); VPRINTK("CPB flags done, flags=0x%x\n", flags); if (likely(qc)) { - /* Grab the ATA port status for non-NCQ commands. - For NCQ commands the current status may have nothing to do with - the command just completed. */ - if (qc->tf.protocol != ATA_PROT_NCQ) { - u8 ata_status = readb(pp->ctl_block + (ATA_REG_STATUS * 4)); - qc->err_mask |= ac_err_mask(ata_status); - } - DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num, - qc->err_mask); + DPRINTK("Completing qc from tag %d\n",cpb_num); ata_qc_complete(qc); + } else { + struct ata_eh_info *ehi = &ap->eh_info; + /* Notifier bits set without a command may indicate the drive + is misbehaving. Raise host state machine violation on this + condition. */ + ata_port_printk(ap, KERN_ERR, "notifier for tag %d with no command?\n", + cpb_num); + ehi->err_mask |= AC_ERR_HSM; + ehi->action |= ATA_EH_SOFTRESET; + ata_port_freeze(ap); + return 1; } } return 0; @@ -852,22 +879,20 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) if (status & (NV_ADMA_STAT_DONE | NV_ADMA_STAT_CPBERR)) { - /** Check CPBs for completed commands */ + u32 check_commands; + int pos, error = 0; - if (ata_tag_valid(ap->active_tag)) { - /* Non-NCQ command */ - nv_adma_check_cpb(ap, ap->active_tag, - notifier_error & (1 << ap->active_tag)); - } else { - int pos, error = 0; - u32 active = ap->sactive; - - while ((pos = ffs(active)) && !error) { - pos--; - error = nv_adma_check_cpb(ap, pos, - notifier_error & (1 << pos) ); - active &= ~(1 << pos ); - } + if(ata_tag_valid(ap->active_tag)) + check_commands = 1 << ap->active_tag; + else + check_commands = ap->sactive; + + /** Check CPBs for completed commands */ + while ((pos = ffs(check_commands)) && !error) { + pos--; + error = nv_adma_check_cpb(ap, pos, + notifier_error & (1 << pos) ); + check_commands &= ~(1 << pos ); } } } @@ -905,73 +930,12 @@ static void nv_adma_irq_clear(struct ata_port *ap) iowrite8(ioread8(dma_stat_addr), dma_stat_addr); } -static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc) +static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc) { - struct ata_port *ap = qc->ap; - unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); - struct nv_adma_port_priv *pp = ap->private_data; - u8 dmactl; - - if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) { - WARN_ON(1); - return; - } - - /* load PRD table addr. */ - iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS); - - /* specify data direction, triple-check start bit is clear */ - dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); - if (!rw) - dmactl |= ATA_DMA_WR; - - iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - - /* issue r/w command */ - ata_exec_command(ap, &qc->tf); -} - -static void nv_adma_bmdma_start(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct nv_adma_port_priv *pp = ap->private_data; - u8 dmactl; - - if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) { - WARN_ON(1); - return; - } - - /* start host DMA transaction */ - dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - iowrite8(dmactl | ATA_DMA_START, - ap->ioaddr.bmdma_addr + ATA_DMA_CMD); -} - -static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct nv_adma_port_priv *pp = ap->private_data; - - if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) - return; - - /* clear start/stop bit */ - iowrite8(ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START, - ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - - /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_altstatus(ap); /* dummy read */ -} - -static u8 nv_adma_bmdma_status(struct ata_port *ap) -{ - struct nv_adma_port_priv *pp = ap->private_data; - - WARN_ON(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)); + struct nv_adma_port_priv *pp = qc->ap->private_data; - return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); + if(pp->flags & NV_ADMA_PORT_REGISTER_MODE) + ata_bmdma_post_internal_cmd(qc); } static int nv_adma_port_start(struct ata_port *ap) @@ -1040,14 +1004,15 @@ static int nv_adma_port_start(struct ata_port *ap) /* clear GO for register mode, enable interrupt */ tmp = readw(mmio + NV_ADMA_CTL); - writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL); + writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN | + NV_ADMA_CTL_HOTPLUG_IEN, mmio + NV_ADMA_CTL); tmp = readw(mmio + NV_ADMA_CTL); writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); - readl( mmio + NV_ADMA_CTL ); /* flush posted write */ + readw( mmio + NV_ADMA_CTL ); /* flush posted write */ udelay(1); writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); - readl( mmio + NV_ADMA_CTL ); /* flush posted write */ + readw( mmio + NV_ADMA_CTL ); /* flush posted write */ return 0; } @@ -1061,6 +1026,7 @@ static void nv_adma_port_stop(struct ata_port *ap) writew(0, mmio + NV_ADMA_CTL); } +#ifdef CONFIG_PM static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg) { struct nv_adma_port_priv *pp = ap->private_data; @@ -1099,26 +1065,28 @@ static int nv_adma_port_resume(struct ata_port *ap) /* clear GO for register mode, enable interrupt */ tmp = readw(mmio + NV_ADMA_CTL); - writew((tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL); + writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN | + NV_ADMA_CTL_HOTPLUG_IEN, mmio + NV_ADMA_CTL); tmp = readw(mmio + NV_ADMA_CTL); writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); - readl( mmio + NV_ADMA_CTL ); /* flush posted write */ + readw( mmio + NV_ADMA_CTL ); /* flush posted write */ udelay(1); writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); - readl( mmio + NV_ADMA_CTL ); /* flush posted write */ + readw( mmio + NV_ADMA_CTL ); /* flush posted write */ return 0; } +#endif -static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port) +static void nv_adma_setup_port(struct ata_port *ap) { - void __iomem *mmio = probe_ent->iomap[NV_MMIO_BAR]; - struct ata_ioports *ioport = &probe_ent->port[port]; + void __iomem *mmio = ap->host->iomap[NV_MMIO_BAR]; + struct ata_ioports *ioport = &ap->ioaddr; VPRINTK("ENTER\n"); - mmio += NV_ADMA_PORT + port * NV_ADMA_PORT_SIZE; + mmio += NV_ADMA_PORT + ap->port_no * NV_ADMA_PORT_SIZE; ioport->cmd_addr = mmio; ioport->data_addr = mmio + (ATA_REG_DATA * 4); @@ -1135,9 +1103,9 @@ static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int por ioport->ctl_addr = mmio + 0x20; } -static int nv_adma_host_init(struct ata_probe_ent *probe_ent) +static int nv_adma_host_init(struct ata_host *host) { - struct pci_dev *pdev = to_pci_dev(probe_ent->dev); + struct pci_dev *pdev = to_pci_dev(host->dev); unsigned int i; u32 tmp32; @@ -1152,8 +1120,8 @@ static int nv_adma_host_init(struct ata_probe_ent *probe_ent) pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32); - for (i = 0; i < probe_ent->n_ports; i++) - nv_adma_setup_port(probe_ent, i); + for (i = 0; i < host->n_ports; i++) + nv_adma_setup_port(host->ports[i]); return 0; } @@ -1163,11 +1131,7 @@ static void nv_adma_fill_aprd(struct ata_queued_cmd *qc, int idx, struct nv_adma_prd *aprd) { - u8 flags; - - memset(aprd, 0, sizeof(struct nv_adma_prd)); - - flags = 0; + u8 flags = 0; if (qc->tf.flags & ATA_TFLAG_WRITE) flags |= NV_APRD_WRITE; if (idx == qc->n_elem - 1) @@ -1178,6 +1142,7 @@ static void nv_adma_fill_aprd(struct ata_queued_cmd *qc, aprd->addr = cpu_to_le64(((u64)sg_dma_address(sg))); aprd->len = cpu_to_le32(((u32)sg_dma_len(sg))); /* len in bytes */ aprd->flags = flags; + aprd->packet_len = 0; } static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb) @@ -1198,6 +1163,8 @@ static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb) } if (idx > 5) cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag))); + else + cpb->next_aprd = cpu_to_le64(0); } static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc) @@ -1205,9 +1172,11 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc) struct nv_adma_port_priv *pp = qc->ap->private_data; /* ADMA engine can only be used for non-ATAPI DMA commands, - or interrupt-driven no-data commands. */ + or interrupt-driven no-data commands, where a result taskfile + is not required. */ if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) || - (qc->tf.flags & ATA_TFLAG_POLLING)) + (qc->tf.flags & ATA_TFLAG_POLLING) || + (qc->flags & ATA_QCFLAG_RESULT_TF)) return 1; if((qc->flags & ATA_QCFLAG_DMAMAP) || @@ -1230,7 +1199,10 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc) return; } - memset(cpb, 0, sizeof(struct nv_adma_cpb)); + cpb->resp_flags = NV_CPB_RESP_DONE; + wmb(); + cpb->ctl_flags = 0; + wmb(); cpb->len = 3; cpb->tag = qc->tag; @@ -1254,12 +1226,15 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc) finished filling in all of the contents */ wmb(); cpb->ctl_flags = ctl_flags; + wmb(); + cpb->resp_flags = 0; } static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) { struct nv_adma_port_priv *pp = qc->ap->private_data; void __iomem *mmio = pp->ctl_block; + int curr_ncq = (qc->tf.protocol == ATA_PROT_NCQ); VPRINTK("ENTER\n"); @@ -1274,6 +1249,14 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) /* write append register, command tag in lower 8 bits and (number of cpbs to append -1) in top 8 bits */ wmb(); + + if(curr_ncq != pp->last_issue_ncq) { + /* Seems to need some delay before switching between NCQ and non-NCQ + commands, else we get command timeouts and such. */ + udelay(20); + pp->last_issue_ncq = curr_ncq; + } + writew(qc->tag, mmio + NV_ADMA_APPEND); DPRINTK("Issued tag %u\n",qc->tag); @@ -1447,6 +1430,30 @@ static void nv_adma_error_handler(struct ata_port *ap) int i; u16 tmp; + if(ata_tag_valid(ap->active_tag) || ap->sactive) { + u32 notifier = readl(mmio + NV_ADMA_NOTIFIER); + u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR); + u32 gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL); + u32 status = readw(mmio + NV_ADMA_STAT); + u8 cpb_count = readb(mmio + NV_ADMA_CPB_COUNT); + u8 next_cpb_idx = readb(mmio + NV_ADMA_NEXT_CPB_IDX); + + ata_port_printk(ap, KERN_ERR, "EH in ADMA mode, notifier 0x%X " + "notifier_error 0x%X gen_ctl 0x%X status 0x%X " + "next cpb count 0x%X next cpb idx 0x%x\n", + notifier, notifier_error, gen_ctl, status, + cpb_count, next_cpb_idx); + + for( i=0;i<NV_ADMA_MAX_CPBS;i++) { + struct nv_adma_cpb *cpb = &pp->cpb[i]; + if( (ata_tag_valid(ap->active_tag) && i == ap->active_tag) || + ap->sactive & (1 << i) ) + ata_port_printk(ap, KERN_ERR, + "CPB %d: ctl_flags 0x%x, resp_flags 0x%x\n", + i, cpb->ctl_flags, cpb->resp_flags); + } + } + /* Push us back into port register mode for error handling. */ nv_adma_register_mode(ap); @@ -1460,10 +1467,10 @@ static void nv_adma_error_handler(struct ata_port *ap) /* Reset channel */ tmp = readw(mmio + NV_ADMA_CTL); writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); - readl( mmio + NV_ADMA_CTL ); /* flush posted write */ + readw( mmio + NV_ADMA_CTL ); /* flush posted write */ udelay(1); writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); - readl( mmio + NV_ADMA_CTL ); /* flush posted write */ + readw( mmio + NV_ADMA_CTL ); /* flush posted write */ } ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, @@ -1473,14 +1480,13 @@ static void nv_adma_error_handler(struct ata_port *ap) static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version = 0; - struct ata_port_info *ppi[2]; - struct ata_probe_ent *probe_ent; + const struct ata_port_info *ppi[2]; + struct ata_host *host; struct nv_host_priv *hpriv; int rc; u32 bar; void __iomem *base; unsigned long type = ent->driver_data; - int mask_set = 0; // Make sure this is a SATA controller by counting the number of bars // (NVIDIA SATA controllers will always have six bars). Otherwise, @@ -1496,50 +1502,38 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) { - pcim_pin_device(pdev); - return rc; - } - - if(type >= CK804 && adma_enabled) { + /* determine type and allocate host */ + if (type >= CK804 && adma_enabled) { dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n"); type = ADMA; - if(!pci_set_dma_mask(pdev, DMA_64BIT_MASK) && - !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) - mask_set = 1; - } - - if(!mask_set) { - rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - return rc; - rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - return rc; } - rc = -ENOMEM; + ppi[0] = ppi[1] = &nv_port_info[type]; + rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host); + if (rc) + return rc; hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) return -ENOMEM; + hpriv->type = type; + host->private_data = hpriv; - ppi[0] = ppi[1] = &nv_port_info[type]; - probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); - if (!probe_ent) - return -ENOMEM; - - if (!pcim_iomap(pdev, NV_MMIO_BAR, 0)) - return -EIO; - probe_ent->iomap = pcim_iomap_table(pdev); + /* set 64bit dma masks, may fail */ + if (type == ADMA) { + if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) + pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); + } - probe_ent->private_data = hpriv; - hpriv->type = type; + /* request and iomap NV_MMIO_BAR */ + rc = pcim_iomap_regions(pdev, 1 << NV_MMIO_BAR, DRV_NAME); + if (rc) + return rc; - base = probe_ent->iomap[NV_MMIO_BAR]; - probe_ent->port[0].scr_addr = base + NV_PORT0_SCR_REG_OFFSET; - probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET; + /* configure SCR access */ + base = host->iomap[NV_MMIO_BAR]; + host->ports[0]->ioaddr.scr_addr = base + NV_PORT0_SCR_REG_OFFSET; + host->ports[1]->ioaddr.scr_addr = base + NV_PORT1_SCR_REG_OFFSET; /* enable SATA space for CK804 */ if (type >= CK804) { @@ -1550,20 +1544,16 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval); } - pci_set_master(pdev); - + /* init ADMA */ if (type == ADMA) { - rc = nv_adma_host_init(probe_ent); + rc = nv_adma_host_init(host); if (rc) return rc; } - rc = ata_device_add(probe_ent); - if (rc != NV_PORTS) - return -ENODEV; - - devm_kfree(&pdev->dev, probe_ent); - return 0; + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, ppi[0]->irq_handler, + IRQF_SHARED, ppi[0]->sht); } static void nv_remove_one (struct pci_dev *pdev) @@ -1575,6 +1565,7 @@ static void nv_remove_one (struct pci_dev *pdev) kfree(hpriv); } +#ifdef CONFIG_PM static int nv_pci_device_resume(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); @@ -1622,6 +1613,7 @@ static int nv_pci_device_resume(struct pci_dev *pdev) return 0; } +#endif static void nv_ck804_host_stop(struct ata_host *host) { diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index cf9ed8c3930..f56549b90aa 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -45,10 +45,11 @@ #include "sata_promise.h" #define DRV_NAME "sata_promise" -#define DRV_VERSION "1.05" +#define DRV_VERSION "2.05" enum { + PDC_MAX_PORTS = 4, PDC_MMIO_BAR = 3, /* register offsets */ @@ -70,14 +71,31 @@ enum { PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */ PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */ - PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) | - (1<<8) | (1<<9) | (1<<10), + /* PDC_GLOBAL_CTL bit definitions */ + PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */ + PDC_SH_ERR = (1 << 9), /* PCI error while loading S/G table */ + PDC_DH_ERR = (1 << 10), /* PCI error while loading data */ + PDC2_HTO_ERR = (1 << 12), /* host bus timeout */ + PDC2_ATA_HBA_ERR = (1 << 13), /* error during SATA DATA FIS transmission */ + PDC2_ATA_DMA_CNT_ERR = (1 << 14), /* DMA DATA FIS size differs from S/G count */ + PDC_OVERRUN_ERR = (1 << 19), /* S/G byte count larger than HD requires */ + PDC_UNDERRUN_ERR = (1 << 20), /* S/G byte count less than HD requires */ + PDC_DRIVE_ERR = (1 << 21), /* drive error */ + PDC_PCI_SYS_ERR = (1 << 22), /* PCI system error */ + PDC1_PCI_PARITY_ERR = (1 << 23), /* PCI parity error (from SATA150 driver) */ + PDC1_ERR_MASK = PDC1_PCI_PARITY_ERR, + PDC2_ERR_MASK = PDC2_HTO_ERR | PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR, + PDC_ERR_MASK = (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC_OVERRUN_ERR + | PDC_UNDERRUN_ERR | PDC_DRIVE_ERR | PDC_PCI_SYS_ERR + | PDC1_ERR_MASK | PDC2_ERR_MASK), board_2037x = 0, /* FastTrak S150 TX2plus */ - board_20319 = 1, /* FastTrak S150 TX4 */ - board_20619 = 2, /* FastTrak TX4000 */ - board_2057x = 3, /* SATAII150 Tx2plus */ - board_40518 = 4, /* SATAII150 Tx4 */ + board_2037x_pata = 1, /* FastTrak S150 TX2plus PATA port */ + board_20319 = 2, /* FastTrak S150 TX4 */ + board_20619 = 3, /* FastTrak TX4000 */ + board_2057x = 4, /* SATAII150 Tx2plus */ + board_2057x_pata = 5, /* SATAII150 Tx2plus */ + board_40518 = 6, /* SATAII150 Tx4 */ PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ @@ -100,8 +118,10 @@ enum { ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, - /* hp->flags bits */ - PDC_FLAG_GEN_II = (1 << 0), + /* ap->flags bits */ + PDC_FLAG_GEN_II = (1 << 24), + PDC_FLAG_SATA_PATA = (1 << 25), /* supports SATA + PATA */ + PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */ }; @@ -110,28 +130,25 @@ struct pdc_port_priv { dma_addr_t pkt_dma; }; -struct pdc_host_priv { - unsigned long flags; - unsigned long port_flags[ATA_MAX_PORTS]; -}; - static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static irqreturn_t pdc_interrupt (int irq, void *dev_instance); -static int pdc_port_start(struct ata_port *ap); +static int pdc_common_port_start(struct ata_port *ap); +static int pdc_sata_port_start(struct ata_port *ap); static void pdc_qc_prep(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); static int pdc_check_atapi_dma(struct ata_queued_cmd *qc); -static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc); +static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc); static void pdc_irq_clear(struct ata_port *ap); static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); static void pdc_freeze(struct ata_port *ap); static void pdc_thaw(struct ata_port *ap); -static void pdc_error_handler(struct ata_port *ap); +static void pdc_pata_error_handler(struct ata_port *ap); +static void pdc_sata_error_handler(struct ata_port *ap); static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); - +static int pdc_pata_cable_detect(struct ata_port *ap); +static int pdc_sata_cable_detect(struct ata_port *ap); static struct scsi_host_template pdc_ata_sht = { .module = THIS_MODULE, @@ -164,17 +181,17 @@ static const struct ata_port_operations pdc_sata_ops = { .qc_issue = pdc_qc_issue_prot, .freeze = pdc_freeze, .thaw = pdc_thaw, - .error_handler = pdc_error_handler, + .error_handler = pdc_sata_error_handler, .post_internal_cmd = pdc_post_internal_cmd, + .cable_detect = pdc_sata_cable_detect, .data_xfer = ata_data_xfer, - .irq_handler = pdc_interrupt, .irq_clear = pdc_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, .scr_read = pdc_sata_scr_read, .scr_write = pdc_sata_scr_write, - .port_start = pdc_port_start, + .port_start = pdc_sata_port_start, }; /* First-generation chips need a more restrictive ->check_atapi_dma op */ @@ -185,23 +202,23 @@ static const struct ata_port_operations pdc_old_sata_ops = { .check_status = ata_check_status, .exec_command = pdc_exec_command_mmio, .dev_select = ata_std_dev_select, - .check_atapi_dma = pdc_old_check_atapi_dma, + .check_atapi_dma = pdc_old_sata_check_atapi_dma, .qc_prep = pdc_qc_prep, .qc_issue = pdc_qc_issue_prot, .freeze = pdc_freeze, .thaw = pdc_thaw, - .error_handler = pdc_error_handler, + .error_handler = pdc_sata_error_handler, .post_internal_cmd = pdc_post_internal_cmd, + .cable_detect = pdc_sata_cable_detect, .data_xfer = ata_data_xfer, - .irq_handler = pdc_interrupt, .irq_clear = pdc_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, .scr_read = pdc_sata_scr_read, .scr_write = pdc_sata_scr_write, - .port_start = pdc_port_start, + .port_start = pdc_sata_port_start, }; static const struct ata_port_operations pdc_pata_ops = { @@ -217,31 +234,41 @@ static const struct ata_port_operations pdc_pata_ops = { .qc_issue = pdc_qc_issue_prot, .freeze = pdc_freeze, .thaw = pdc_thaw, - .error_handler = pdc_error_handler, + .error_handler = pdc_pata_error_handler, + .post_internal_cmd = pdc_post_internal_cmd, + .cable_detect = pdc_pata_cable_detect, .data_xfer = ata_data_xfer, - .irq_handler = pdc_interrupt, .irq_clear = pdc_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, - .port_start = pdc_port_start, + .port_start = pdc_common_port_start, }; static const struct ata_port_info pdc_port_info[] = { /* board_2037x */ { - .sht = &pdc_ata_sht, - .flags = PDC_COMMON_FLAGS, + .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | + PDC_FLAG_SATA_PATA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &pdc_old_sata_ops, }, + /* board_2037x_pata */ + { + .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .port_ops = &pdc_pata_ops, + }, + /* board_20319 */ { - .sht = &pdc_ata_sht, - .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, + .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | + PDC_FLAG_4_PORTS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -250,8 +277,8 @@ static const struct ata_port_info pdc_port_info[] = { /* board_20619 */ { - .sht = &pdc_ata_sht, - .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, + .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS | + PDC_FLAG_4_PORTS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -260,18 +287,28 @@ static const struct ata_port_info pdc_port_info[] = { /* board_2057x */ { - .sht = &pdc_ata_sht, - .flags = PDC_COMMON_FLAGS, + .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | + PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &pdc_sata_ops, }, + /* board_2057x_pata */ + { + .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, + PDC_FLAG_GEN_II, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .port_ops = &pdc_pata_ops, + }, + /* board_40518 */ { - .sht = &pdc_ata_sht, - .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, + .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | + PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -312,18 +349,12 @@ static struct pci_driver pdc_ata_pci_driver = { }; -static int pdc_port_start(struct ata_port *ap) +static int pdc_common_port_start(struct ata_port *ap) { struct device *dev = ap->host->dev; - struct pdc_host_priv *hp = ap->host->private_data; struct pdc_port_priv *pp; int rc; - /* fix up port flags and cable type for SATA+PATA chips */ - ap->flags |= hp->port_flags[ap->port_no]; - if (ap->flags & ATA_FLAG_SATA) - ap->cbl = ATA_CBL_SATA; - rc = ata_port_start(ap); if (rc) return rc; @@ -338,8 +369,19 @@ static int pdc_port_start(struct ata_port *ap) ap->private_data = pp; + return 0; +} + +static int pdc_sata_port_start(struct ata_port *ap) +{ + int rc; + + rc = pdc_common_port_start(ap); + if (rc) + return rc; + /* fix up PHYMODE4 align timing */ - if ((hp->flags & PDC_FLAG_GEN_II) && sata_scr_valid(ap)) { + if (ap->flags & PDC_FLAG_GEN_II) { void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr; unsigned int tmp; @@ -373,23 +415,25 @@ static void pdc_reset_port(struct ata_port *ap) readl(mmio); /* flush */ } -static void pdc_pata_cbl_detect(struct ata_port *ap) +static int pdc_pata_cable_detect(struct ata_port *ap) { u8 tmp; void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; tmp = readb(mmio); + if (tmp & 0x01) + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; +} - if (tmp & 0x01) { - ap->cbl = ATA_CBL_PATA40; - ap->udma_mask &= ATA_UDMA_MASK_40C; - } else - ap->cbl = ATA_CBL_PATA80; +static int pdc_sata_cable_detect(struct ata_port *ap) +{ + return ATA_CBL_SATA; } static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { - if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA) + if (sc_reg > SCR_CONTROL) return 0xffffffffU; return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -398,7 +442,7 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { - if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA) + if (sc_reg > SCR_CONTROL) return; writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -554,52 +598,79 @@ static void pdc_thaw(struct ata_port *ap) readl(mmio + PDC_CTLSTAT); /* flush */ } -static int pdc_pre_reset(struct ata_port *ap) +static void pdc_common_error_handler(struct ata_port *ap, ata_reset_fn_t hardreset) { - if (!sata_scr_valid(ap)) - pdc_pata_cbl_detect(ap); - return ata_std_prereset(ap); -} - -static void pdc_error_handler(struct ata_port *ap) -{ - ata_reset_fn_t hardreset; - if (!(ap->pflags & ATA_PFLAG_FROZEN)) pdc_reset_port(ap); - hardreset = NULL; - if (sata_scr_valid(ap)) - hardreset = sata_std_hardreset; - /* perform recovery */ - ata_do_eh(ap, pdc_pre_reset, ata_std_softreset, hardreset, + ata_do_eh(ap, ata_std_prereset, ata_std_softreset, hardreset, ata_std_postreset); } +static void pdc_pata_error_handler(struct ata_port *ap) +{ + pdc_common_error_handler(ap, NULL); +} + +static void pdc_sata_error_handler(struct ata_port *ap) +{ + pdc_common_error_handler(ap, sata_std_hardreset); +} + static void pdc_post_internal_cmd(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - if (qc->flags & ATA_QCFLAG_FAILED) - qc->err_mask |= AC_ERR_OTHER; - /* make DMA engine forget about the failed command */ - if (qc->err_mask) + if (qc->flags & ATA_QCFLAG_FAILED) pdc_reset_port(ap); } +static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, + u32 port_status, u32 err_mask) +{ + struct ata_eh_info *ehi = &ap->eh_info; + unsigned int ac_err_mask = 0; + + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "port_status 0x%08x", port_status); + port_status &= err_mask; + + if (port_status & PDC_DRIVE_ERR) + ac_err_mask |= AC_ERR_DEV; + if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR)) + ac_err_mask |= AC_ERR_HSM; + if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR)) + ac_err_mask |= AC_ERR_ATA_BUS; + if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR + | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR)) + ac_err_mask |= AC_ERR_HOST_BUS; + + if (sata_scr_valid(ap)) + ehi->serror |= pdc_sata_scr_read(ap, SCR_ERROR); + + qc->err_mask |= ac_err_mask; + + pdc_reset_port(ap); +} + static inline unsigned int pdc_host_intr( struct ata_port *ap, struct ata_queued_cmd *qc) { unsigned int handled = 0; - u32 tmp; - void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL; + void __iomem *port_mmio = ap->ioaddr.cmd_addr; + u32 port_status, err_mask; - tmp = readl(mmio); - if (tmp & PDC_ERR_MASK) { - qc->err_mask |= AC_ERR_DEV; - pdc_reset_port(ap); + err_mask = PDC_ERR_MASK; + if (ap->flags & PDC_FLAG_GEN_II) + err_mask &= ~PDC1_ERR_MASK; + else + err_mask &= ~PDC2_ERR_MASK; + port_status = readl(port_mmio + PDC_GLOBAL_CTL); + if (unlikely(port_status & err_mask)) { + pdc_error_intr(ap, qc, port_status, err_mask); + return 1; } switch (qc->tf.protocol) { @@ -766,42 +837,40 @@ static int pdc_check_atapi_dma(struct ata_queued_cmd *qc) return pio; } -static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc) +static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc) { - struct ata_port *ap = qc->ap; - /* First generation chips cannot use ATAPI DMA on SATA ports */ - if (sata_scr_valid(ap)) - return 1; - return pdc_check_atapi_dma(qc); + return 1; } -static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base) +static void pdc_ata_setup_port(struct ata_port *ap, + void __iomem *base, void __iomem *scr_addr) { - port->cmd_addr = base; - port->data_addr = base; - port->feature_addr = - port->error_addr = base + 0x4; - port->nsect_addr = base + 0x8; - port->lbal_addr = base + 0xc; - port->lbam_addr = base + 0x10; - port->lbah_addr = base + 0x14; - port->device_addr = base + 0x18; - port->command_addr = - port->status_addr = base + 0x1c; - port->altstatus_addr = - port->ctl_addr = base + 0x38; + ap->ioaddr.cmd_addr = base; + ap->ioaddr.data_addr = base; + ap->ioaddr.feature_addr = + ap->ioaddr.error_addr = base + 0x4; + ap->ioaddr.nsect_addr = base + 0x8; + ap->ioaddr.lbal_addr = base + 0xc; + ap->ioaddr.lbam_addr = base + 0x10; + ap->ioaddr.lbah_addr = base + 0x14; + ap->ioaddr.device_addr = base + 0x18; + ap->ioaddr.command_addr = + ap->ioaddr.status_addr = base + 0x1c; + ap->ioaddr.altstatus_addr = + ap->ioaddr.ctl_addr = base + 0x38; + ap->ioaddr.scr_addr = scr_addr; } -static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) +static void pdc_host_init(struct ata_host *host) { - void __iomem *mmio = pe->iomap[PDC_MMIO_BAR]; - struct pdc_host_priv *hp = pe->private_data; + void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; + int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II; int hotplug_offset; u32 tmp; - if (hp->flags & PDC_FLAG_GEN_II) + if (is_gen2) hotplug_offset = PDC2_SATA_PLUG_CSR; else hotplug_offset = PDC_SATA_PLUG_CSR; @@ -815,7 +884,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */ tmp = readl(mmio + PDC_FLASH_CTL); tmp |= 0x02000; /* bit 13 (enable bmr burst) */ - if (!(hp->flags & PDC_FLAG_GEN_II)) + if (!is_gen2) tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */ writel(tmp, mmio + PDC_FLASH_CTL); @@ -828,7 +897,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) writel(tmp | 0xff0000, mmio + hotplug_offset); /* don't initialise TBG or SLEW on 2nd generation chips */ - if (hp->flags & PDC_FLAG_GEN_II) + if (is_gen2) return; /* reduce TBG clock to 133 Mhz. */ @@ -850,16 +919,16 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_probe_ent *probe_ent; - struct pdc_host_priv *hp; + const struct ata_port_info *pi = &pdc_port_info[ent->driver_data]; + const struct ata_port_info *ppi[PDC_MAX_PORTS]; + struct ata_host *host; void __iomem *base; - unsigned int board_idx = (unsigned int) ent->driver_data; - int rc; - u8 tmp; + int n_ports, i, rc; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* enable and acquire resources */ rc = pcim_enable_device(pdev); if (rc) return rc; @@ -869,100 +938,49 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e pcim_pin_device(pdev); if (rc) return rc; + base = pcim_iomap_table(pdev)[PDC_MMIO_BAR]; - rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - return rc; - rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - return rc; - - probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) - return -ENOMEM; - - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - - hp = devm_kzalloc(&pdev->dev, sizeof(*hp), GFP_KERNEL); - if (hp == NULL) - return -ENOMEM; - - probe_ent->private_data = hp; + /* determine port configuration and setup host */ + n_ports = 2; + if (pi->flags & PDC_FLAG_4_PORTS) + n_ports = 4; + for (i = 0; i < n_ports; i++) + ppi[i] = pi; - probe_ent->sht = pdc_port_info[board_idx].sht; - probe_ent->port_flags = pdc_port_info[board_idx].flags; - probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask; - probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask; - probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask; - probe_ent->port_ops = pdc_port_info[board_idx].port_ops; - - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->iomap = pcim_iomap_table(pdev); - - base = probe_ent->iomap[PDC_MMIO_BAR]; - - pdc_ata_setup_port(&probe_ent->port[0], base + 0x200); - pdc_ata_setup_port(&probe_ent->port[1], base + 0x280); - - probe_ent->port[0].scr_addr = base + 0x400; - probe_ent->port[1].scr_addr = base + 0x500; - - /* notice 4-port boards */ - switch (board_idx) { - case board_40518: - hp->flags |= PDC_FLAG_GEN_II; - /* Fall through */ - case board_20319: - probe_ent->n_ports = 4; - - pdc_ata_setup_port(&probe_ent->port[2], base + 0x300); - pdc_ata_setup_port(&probe_ent->port[3], base + 0x380); - - probe_ent->port[2].scr_addr = base + 0x600; - probe_ent->port[3].scr_addr = base + 0x700; - break; - case board_2057x: - hp->flags |= PDC_FLAG_GEN_II; - /* Fall through */ - case board_2037x: - /* TX2plus boards also have a PATA port */ - tmp = readb(base + PDC_FLASH_CTL+1); + if (pi->flags & PDC_FLAG_SATA_PATA) { + u8 tmp = readb(base + PDC_FLASH_CTL+1); if (!(tmp & 0x80)) { - probe_ent->n_ports = 3; - pdc_ata_setup_port(&probe_ent->port[2], base + 0x300); - hp->port_flags[2] = ATA_FLAG_SLAVE_POSS; - printk(KERN_INFO DRV_NAME " PATA port found\n"); - } else - probe_ent->n_ports = 2; - hp->port_flags[0] = ATA_FLAG_SATA; - hp->port_flags[1] = ATA_FLAG_SATA; - break; - case board_20619: - probe_ent->n_ports = 4; - - pdc_ata_setup_port(&probe_ent->port[2], base + 0x300); - pdc_ata_setup_port(&probe_ent->port[3], base + 0x380); + ppi[n_ports++] = pi + 1; + dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n"); + } + } - probe_ent->port[2].scr_addr = base + 0x600; - probe_ent->port[3].scr_addr = base + 0x700; - break; - default: - BUG(); - break; + host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); + if (!host) { + dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n"); + return -ENOMEM; } + host->iomap = pcim_iomap_table(pdev); - pci_set_master(pdev); + for (i = 0; i < host->n_ports; i++) + pdc_ata_setup_port(host->ports[i], + base + 0x200 + i * 0x80, + base + 0x400 + i * 0x100); /* initialize adapter */ - pdc_host_init(board_idx, probe_ent); + pdc_host_init(host); - if (!ata_device_add(probe_ent)) - return -ENODEV; + rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + return rc; + rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + return rc; - devm_kfree(&pdev->dev, probe_ent); - return 0; + /* start host, request IRQ and attach */ + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, pdc_interrupt, IRQF_SHARED, + &pdc_ata_sht); } diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 6097d8f2a0c..f5a05de0093 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -39,7 +39,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_qstor" -#define DRV_VERSION "0.06" +#define DRV_VERSION "0.07" enum { QS_MMIO_BAR = 4, @@ -114,7 +114,6 @@ struct qs_port_priv { static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg); static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static irqreturn_t qs_intr (int irq, void *dev_instance); static int qs_port_start(struct ata_port *ap); static void qs_host_stop(struct ata_host *host); static void qs_phy_reset(struct ata_port *ap); @@ -158,7 +157,6 @@ static const struct ata_port_operations qs_ata_ops = { .qc_issue = qs_qc_issue, .data_xfer = ata_data_xfer, .eng_timeout = qs_eng_timeout, - .irq_handler = qs_intr, .irq_clear = qs_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -173,7 +171,6 @@ static const struct ata_port_operations qs_ata_ops = { static const struct ata_port_info qs_port_info[] = { /* board_2068_idx */ { - .sht = &qs_ata_sht, .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET | //FIXME ATA_FLAG_SRST | @@ -446,7 +443,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host) if ((status & ATA_BUSY)) continue; DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", - ap->id, qc->tf.protocol, status); + ap->print_id, qc->tf.protocol, status); /* complete taskfile transaction */ pp->state = qs_state_idle; @@ -530,16 +527,16 @@ static void qs_host_stop(struct ata_host *host) writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ } -static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) +static void qs_host_init(struct ata_host *host, unsigned int chip_id) { - void __iomem *mmio_base = pe->iomap[QS_MMIO_BAR]; + void __iomem *mmio_base = host->iomap[QS_MMIO_BAR]; unsigned int port_no; writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ /* reset each channel in turn */ - for (port_no = 0; port_no < pe->n_ports; ++port_no) { + for (port_no = 0; port_no < host->n_ports; ++port_no) { u8 __iomem *chan = mmio_base + (port_no * 0x4000); writeb(QS_CTR1_RDEV|QS_CTR1_RCHN, chan + QS_CCT_CTR1); writeb(QS_CTR0_REG, chan + QS_CCT_CTR0); @@ -547,7 +544,7 @@ static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) } writeb(QS_SERD3_PHY_ENA, mmio_base + QS_HVS_SERD3); /* enable phy */ - for (port_no = 0; port_no < pe->n_ports; ++port_no) { + for (port_no = 0; port_no < host->n_ports; ++port_no) { u8 __iomem *chan = mmio_base + (port_no * 0x4000); /* set FIFO depths to same settings as Windows driver */ writew(32, chan + QS_CFC_HUFT); @@ -607,14 +604,20 @@ static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_probe_ent *probe_ent; - void __iomem * const *iomap; unsigned int board_idx = (unsigned int) ent->driver_data; + const struct ata_port_info *ppi[] = { &qs_port_info[board_idx], NULL }; + struct ata_host *host; int rc, port_no; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* alloc host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, QS_PORTS); + if (!host) + return -ENOMEM; + + /* acquire resources and fill host */ rc = pcim_enable_device(pdev); if (rc) return rc; @@ -625,47 +628,24 @@ static int qs_ata_init_one(struct pci_dev *pdev, rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME); if (rc) return rc; - iomap = pcim_iomap_table(pdev); + host->iomap = pcim_iomap_table(pdev); - rc = qs_set_dma_masks(pdev, iomap[QS_MMIO_BAR]); + rc = qs_set_dma_masks(pdev, host->iomap[QS_MMIO_BAR]); if (rc) return rc; - probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) - return -ENOMEM; - - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - - probe_ent->sht = qs_port_info[board_idx].sht; - probe_ent->port_flags = qs_port_info[board_idx].flags; - probe_ent->pio_mask = qs_port_info[board_idx].pio_mask; - probe_ent->mwdma_mask = qs_port_info[board_idx].mwdma_mask; - probe_ent->udma_mask = qs_port_info[board_idx].udma_mask; - probe_ent->port_ops = qs_port_info[board_idx].port_ops; - - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->iomap = iomap; - probe_ent->n_ports = QS_PORTS; - - for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) { + for (port_no = 0; port_no < host->n_ports; ++port_no) { void __iomem *chan = - probe_ent->iomap[QS_MMIO_BAR] + (port_no * 0x4000); - qs_ata_setup_port(&probe_ent->port[port_no], chan); + host->iomap[QS_MMIO_BAR] + (port_no * 0x4000); + qs_ata_setup_port(&host->ports[port_no]->ioaddr, chan); } - pci_set_master(pdev); - /* initialize adapter */ - qs_host_init(board_idx, probe_ent); + qs_host_init(host, board_idx); - if (ata_device_add(probe_ent) != QS_PORTS) - return -EIO; - - devm_kfree(&pdev->dev, probe_ent); - return 0; + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, qs_intr, IRQF_SHARED, + &qs_ata_sht); } static int __init qs_ata_init(void) diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index dca3d3749f0..0a1e417f309 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -46,7 +46,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_sil" -#define DRV_VERSION "2.0" +#define DRV_VERSION "2.2" enum { SIL_MMIO_BAR = 5, @@ -114,11 +114,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); #ifdef CONFIG_PM static int sil_pci_device_resume(struct pci_dev *pdev); #endif -static void sil_dev_config(struct ata_port *ap, struct ata_device *dev); +static void sil_dev_config(struct ata_device *dev); static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); -static void sil_post_set_mode (struct ata_port *ap); -static irqreturn_t sil_interrupt(int irq, void *dev_instance); +static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed); static void sil_freeze(struct ata_port *ap); static void sil_thaw(struct ata_port *ap); @@ -183,8 +182,10 @@ static struct scsi_host_template sil_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .suspend = ata_scsi_device_suspend, .resume = ata_scsi_device_resume, +#endif }; static const struct ata_port_operations sil_ops = { @@ -195,7 +196,7 @@ static const struct ata_port_operations sil_ops = { .check_status = ata_check_status, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, - .post_set_mode = sil_post_set_mode, + .set_mode = sil_set_mode, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, @@ -207,7 +208,6 @@ static const struct ata_port_operations sil_ops = { .thaw = sil_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .irq_handler = sil_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -219,7 +219,6 @@ static const struct ata_port_operations sil_ops = { static const struct ata_port_info sil_port_info[] = { /* sil_3112 */ { - .sht = &sil_sht, .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -228,7 +227,6 @@ static const struct ata_port_info sil_port_info[] = { }, /* sil_3112_no_sata_irq */ { - .sht = &sil_sht, .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE | SIL_FLAG_NO_SATA_IRQ, .pio_mask = 0x1f, /* pio0-4 */ @@ -238,7 +236,6 @@ static const struct ata_port_info sil_port_info[] = { }, /* sil_3512 */ { - .sht = &sil_sht, .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -247,7 +244,6 @@ static const struct ata_port_info sil_port_info[] = { }, /* sil_3114 */ { - .sht = &sil_sht, .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -295,7 +291,16 @@ static unsigned char sil_get_device_cache_line(struct pci_dev *pdev) return cache_line; } -static void sil_post_set_mode (struct ata_port *ap) +/** + * sil_set_mode - wrap set_mode functions + * @ap: port to set up + * @r_failed: returned device when we fail + * + * Wrap the libata method for device setup as after the setup we need + * to inspect the results and do some configuration work + */ + +static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed) { struct ata_host *host = ap->host; struct ata_device *dev; @@ -303,6 +308,11 @@ static void sil_post_set_mode (struct ata_port *ap) void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode; u32 tmp, dev_mode[2]; unsigned int i; + int rc; + + rc = ata_do_set_mode(ap, r_failed); + if (rc) + return rc; for (i = 0; i < 2; i++) { dev = &ap->device[i]; @@ -321,6 +331,7 @@ static void sil_post_set_mode (struct ata_port *ap) tmp |= (dev_mode[1] << 4); writel(tmp, addr); readl(addr); /* flush */ + return 0; } static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg) @@ -339,7 +350,7 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_re break; } - return 0; + return NULL; } static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg) @@ -386,9 +397,15 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) goto freeze; } - if (unlikely(!qc || qc->tf.ctl & ATA_NIEN)) + if (unlikely(!qc)) goto freeze; + if (unlikely(qc->tf.flags & ATA_TFLAG_POLLING)) { + /* this sometimes happens, just clear IRQ */ + ata_chk_status(ap); + return; + } + /* Check whether we are expecting interrupt in this state */ switch (ap->hsm_task_state) { case HSM_ST_FIRST: @@ -513,7 +530,6 @@ static void sil_thaw(struct ata_port *ap) /** * sil_dev_config - Apply device/host-specific errata fixups - * @ap: Port containing device to be examined * @dev: Device to be examined * * After the IDENTIFY [PACKET] DEVICE step is complete, and a @@ -540,8 +556,9 @@ static void sil_thaw(struct ata_port *ap) * appreciated. * - But then again UDMA5 is hardly anything to complain about */ -static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) +static void sil_dev_config(struct ata_device *dev) { + struct ata_port *ap = dev->ap; int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO; unsigned int n, quirks = 0; unsigned char model_num[ATA_ID_PROD_LEN + 1]; @@ -575,10 +592,10 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) } } -static void sil_init_controller(struct pci_dev *pdev, - int n_ports, unsigned long port_flags, - void __iomem *mmio_base) +static void sil_init_controller(struct ata_host *host) { + struct pci_dev *pdev = to_pci_dev(host->dev); + void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR]; u8 cls; u32 tmp; int i; @@ -588,7 +605,7 @@ static void sil_init_controller(struct pci_dev *pdev, if (cls) { cls >>= 3; cls++; /* cls = (line_size/8)+1 */ - for (i = 0; i < n_ports; i++) + for (i = 0; i < host->n_ports; i++) writew(cls << 8 | cls, mmio_base + sil_port[i].fifo_cfg); } else @@ -596,10 +613,10 @@ static void sil_init_controller(struct pci_dev *pdev, "cache line size not set. Driver may not function\n"); /* Apply R_ERR on DMA activate FIS errata workaround */ - if (port_flags & SIL_FLAG_RERR_ON_DMA_ACT) { + if (host->ports[0]->flags & SIL_FLAG_RERR_ON_DMA_ACT) { int cnt; - for (i = 0, cnt = 0; i < n_ports; i++) { + for (i = 0, cnt = 0; i < host->n_ports; i++) { tmp = readl(mmio_base + sil_port[i].sfis_cfg); if ((tmp & 0x3) != 0x01) continue; @@ -612,7 +629,7 @@ static void sil_init_controller(struct pci_dev *pdev, } } - if (n_ports == 4) { + if (host->n_ports == 4) { /* flip the magic "make 4 ports work" bit */ tmp = readl(mmio_base + sil_port[2].bmdma); if ((tmp & SIL_INTR_STEERING) == 0) @@ -624,15 +641,26 @@ static void sil_init_controller(struct pci_dev *pdev, static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct device *dev = &pdev->dev; - struct ata_probe_ent *probe_ent; + int board_id = ent->driver_data; + const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL }; + struct ata_host *host; void __iomem *mmio_base; - int rc; + int n_ports, rc; unsigned int i; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* allocate host */ + n_ports = 2; + if (board_id == sil_3114) + n_ports = 4; + + host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); + if (!host) + return -ENOMEM; + + /* acquire resources and fill host */ rc = pcim_enable_device(pdev); if (rc) return rc; @@ -642,6 +670,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) pcim_pin_device(pdev); if (rc) return rc; + host->iomap = pcim_iomap_table(pdev); rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -650,45 +679,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) - return -ENOMEM; + mmio_base = host->iomap[SIL_MMIO_BAR]; - INIT_LIST_HEAD(&probe_ent->node); - probe_ent->dev = pci_dev_to_dev(pdev); - probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops; - probe_ent->sht = sil_port_info[ent->driver_data].sht; - probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2; - probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask; - probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask; - probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask; - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->port_flags = sil_port_info[ent->driver_data].flags; - - probe_ent->iomap = pcim_iomap_table(pdev); - - mmio_base = probe_ent->iomap[SIL_MMIO_BAR]; - - for (i = 0; i < probe_ent->n_ports; i++) { - probe_ent->port[i].cmd_addr = mmio_base + sil_port[i].tf; - probe_ent->port[i].altstatus_addr = - probe_ent->port[i].ctl_addr = mmio_base + sil_port[i].ctl; - probe_ent->port[i].bmdma_addr = mmio_base + sil_port[i].bmdma; - probe_ent->port[i].scr_addr = mmio_base + sil_port[i].scr; - ata_std_ports(&probe_ent->port[i]); + for (i = 0; i < host->n_ports; i++) { + struct ata_ioports *ioaddr = &host->ports[i]->ioaddr; + + ioaddr->cmd_addr = mmio_base + sil_port[i].tf; + ioaddr->altstatus_addr = + ioaddr->ctl_addr = mmio_base + sil_port[i].ctl; + ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma; + ioaddr->scr_addr = mmio_base + sil_port[i].scr; + ata_std_ports(ioaddr); } - sil_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags, - mmio_base); + /* initialize and activate */ + sil_init_controller(host); pci_set_master(pdev); - - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(dev, probe_ent); - return 0; + return ata_host_activate(host, pdev->irq, sil_interrupt, IRQF_SHARED, + &sil_sht); } #ifdef CONFIG_PM @@ -701,8 +710,7 @@ static int sil_pci_device_resume(struct pci_dev *pdev) if (rc) return rc; - sil_init_controller(pdev, host->n_ports, host->ports[0]->flags, - host->iomap[SIL_MMIO_BAR]); + sil_init_controller(host); ata_host_resume(host); return 0; diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index e65e8d55da3..e6223ba667d 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -30,7 +30,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_sil24" -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.8" /* * Port request block (PRB) 32 bytes @@ -323,7 +323,7 @@ struct sil24_port_priv { struct ata_taskfile tf; /* Cached taskfile registers */ }; -static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev); +static void sil24_dev_config(struct ata_device *dev); static u8 sil24_check_status(struct ata_port *ap); static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); @@ -331,7 +331,6 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); static void sil24_qc_prep(struct ata_queued_cmd *qc); static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); static void sil24_irq_clear(struct ata_port *ap); -static irqreturn_t sil24_interrupt(int irq, void *dev_instance); static void sil24_freeze(struct ata_port *ap); static void sil24_thaw(struct ata_port *ap); static void sil24_error_handler(struct ata_port *ap); @@ -346,6 +345,7 @@ static const struct pci_device_id sil24_pci_tbl[] = { { PCI_VDEVICE(CMD, 0x3124), BID_SIL3124 }, { PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 }, { PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 }, + { PCI_VDEVICE(CMD, 0x0242), BID_SIL3132 }, { PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 }, { PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 }, @@ -380,8 +380,10 @@ static struct scsi_host_template sil24_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, +#ifdef CONFIG_PM .suspend = ata_scsi_device_suspend, .resume = ata_scsi_device_resume, +#endif }; static const struct ata_port_operations sil24_ops = { @@ -398,7 +400,6 @@ static const struct ata_port_operations sil24_ops = { .qc_prep = sil24_qc_prep, .qc_issue = sil24_qc_issue, - .irq_handler = sil24_interrupt, .irq_clear = sil24_irq_clear, .irq_on = ata_dummy_irq_on, .irq_ack = ata_dummy_irq_ack, @@ -421,10 +422,9 @@ static const struct ata_port_operations sil24_ops = { #define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30) #define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1) -static struct ata_port_info sil24_port_info[] = { +static const struct ata_port_info sil24_port_info[] = { /* sil_3124 */ { - .sht = &sil24_sht, .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) | SIL24_FLAG_PCIX_IRQ_WOC, .pio_mask = 0x1f, /* pio0-4 */ @@ -434,7 +434,6 @@ static struct ata_port_info sil24_port_info[] = { }, /* sil_3132 */ { - .sht = &sil24_sht, .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -443,7 +442,6 @@ static struct ata_port_info sil24_port_info[] = { }, /* sil_3131/sil_3531 */ { - .sht = &sil24_sht, .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -459,9 +457,9 @@ static int sil24_tag(int tag) return tag; } -static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev) +static void sil24_dev_config(struct ata_device *dev) { - void __iomem *port = ap->ioaddr.cmd_addr; + void __iomem *port = dev->ap->ioaddr.cmd_addr; if (dev->cdb_len == 16) writel(PORT_CS_CDB16, port + PORT_CTRL_STAT); @@ -647,7 +645,6 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc, struct sil24_sge *sge) { struct scatterlist *sg; - unsigned int idx = 0; ata_for_each_sg(sg, qc) { sge->addr = cpu_to_le64(sg_dma_address(sg)); @@ -656,9 +653,7 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc, sge->flags = cpu_to_le32(SGE_TRM); else sge->flags = 0; - sge++; - idx++; } } @@ -924,11 +919,8 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - if (qc->flags & ATA_QCFLAG_FAILED) - qc->err_mask |= AC_ERR_OTHER; - /* make DMA engine forget about the failed command */ - if (qc->err_mask) + if (qc->flags & ATA_QCFLAG_FAILED) sil24_init_port(ap); } @@ -964,11 +956,10 @@ static int sil24_port_start(struct ata_port *ap) return 0; } -static void sil24_init_controller(struct pci_dev *pdev, int n_ports, - unsigned long port_flags, - void __iomem *host_base, - void __iomem *port_base) +static void sil24_init_controller(struct ata_host *host) { + void __iomem *host_base = host->iomap[SIL24_HOST_BAR]; + void __iomem *port_base = host->iomap[SIL24_PORT_BAR]; u32 tmp; int i; @@ -979,7 +970,7 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports, writel(0, host_base + HOST_CTRL); /* init ports */ - for (i = 0; i < n_ports; i++) { + for (i = 0; i < host->n_ports; i++) { void __iomem *port = port_base + i * PORT_REGS_SIZE; /* Initial PHY setting */ @@ -993,12 +984,12 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports, PORT_CS_PORT_RST, PORT_CS_PORT_RST, 10, 100); if (tmp & PORT_CS_PORT_RST) - dev_printk(KERN_ERR, &pdev->dev, + dev_printk(KERN_ERR, host->dev, "failed to clear port RST\n"); } /* Configure IRQ WoC */ - if (port_flags & SIL24_FLAG_PCIX_IRQ_WOC) + if (host->ports[0]->flags & SIL24_FLAG_PCIX_IRQ_WOC) writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT); else writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); @@ -1026,18 +1017,17 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports, static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version = 0; - struct device *dev = &pdev->dev; - unsigned int board_id = (unsigned int)ent->driver_data; - struct ata_port_info *pinfo = &sil24_port_info[board_id]; - struct ata_probe_ent *probe_ent; - void __iomem *host_base; - void __iomem *port_base; + struct ata_port_info pi = sil24_port_info[ent->driver_data]; + const struct ata_port_info *ppi[] = { &pi, NULL }; + void __iomem * const *iomap; + struct ata_host *host; int i, rc; u32 tmp; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* acquire resources */ rc = pcim_enable_device(pdev); if (rc) return rc; @@ -1047,33 +1037,36 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) DRV_NAME); if (rc) return rc; + iomap = pcim_iomap_table(pdev); - /* allocate & init probe_ent */ - probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); - if (!probe_ent) - return -ENOMEM; + /* apply workaround for completion IRQ loss on PCI-X errata */ + if (pi.flags & SIL24_FLAG_PCIX_IRQ_WOC) { + tmp = readl(iomap[SIL24_HOST_BAR] + HOST_CTRL); + if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL)) + dev_printk(KERN_INFO, &pdev->dev, + "Applying completion IRQ loss on PCI-X " + "errata fix\n"); + else + pi.flags &= ~SIL24_FLAG_PCIX_IRQ_WOC; + } - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); + /* allocate and fill host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, + SIL24_FLAG2NPORTS(ppi[0]->flags)); + if (!host) + return -ENOMEM; + host->iomap = iomap; - probe_ent->sht = pinfo->sht; - probe_ent->port_flags = pinfo->flags; - probe_ent->pio_mask = pinfo->pio_mask; - probe_ent->mwdma_mask = pinfo->mwdma_mask; - probe_ent->udma_mask = pinfo->udma_mask; - probe_ent->port_ops = pinfo->port_ops; - probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->flags); + for (i = 0; i < host->n_ports; i++) { + void __iomem *port = iomap[SIL24_PORT_BAR] + i * PORT_REGS_SIZE; - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->iomap = pcim_iomap_table(pdev); + host->ports[i]->ioaddr.cmd_addr = port; + host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL; - host_base = probe_ent->iomap[SIL24_HOST_BAR]; - port_base = probe_ent->iomap[SIL24_PORT_BAR]; + ata_std_ports(&host->ports[i]->ioaddr); + } - /* - * Configure the device - */ + /* configure and activate the device */ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); if (rc) { @@ -1099,36 +1092,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } } - /* Apply workaround for completion IRQ loss on PCI-X errata */ - if (probe_ent->port_flags & SIL24_FLAG_PCIX_IRQ_WOC) { - tmp = readl(host_base + HOST_CTRL); - if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL)) - dev_printk(KERN_INFO, &pdev->dev, - "Applying completion IRQ loss on PCI-X " - "errata fix\n"); - else - probe_ent->port_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC; - } - - for (i = 0; i < probe_ent->n_ports; i++) { - void __iomem *port = port_base + i * PORT_REGS_SIZE; - - probe_ent->port[i].cmd_addr = port; - probe_ent->port[i].scr_addr = port + PORT_SCONTROL; - - ata_std_ports(&probe_ent->port[i]); - } - - sil24_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags, - host_base, port_base); + sil24_init_controller(host); pci_set_master(pdev); - - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(dev, probe_ent); - return 0; + return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED, + &sil24_sht); } #ifdef CONFIG_PM @@ -1136,7 +1104,6 @@ static int sil24_pci_device_resume(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); void __iomem *host_base = host->iomap[SIL24_HOST_BAR]; - void __iomem *port_base = host->iomap[SIL24_PORT_BAR]; int rc; rc = ata_pci_device_do_resume(pdev); @@ -1146,8 +1113,7 @@ static int sil24_pci_device_resume(struct pci_dev *pdev) if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL); - sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags, - host_base, port_base); + sil24_init_controller(host); ata_host_resume(host); diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 49c9e2bd706..d8ee062e82f 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -40,9 +40,8 @@ #include <linux/device.h> #include <scsi/scsi_host.h> #include <linux/libata.h> -#include "libata.h" +#include "sis.h" -#undef DRV_NAME /* already defined in libata.h, for libata-core */ #define DRV_NAME "sata_sis" #define DRV_VERSION "0.7" @@ -122,7 +121,6 @@ static const struct ata_port_operations sis_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -132,7 +130,6 @@ static const struct ata_port_operations sis_ops = { }; static struct ata_port_info sis_port_info = { - .sht = &sis_sht, .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0x7, @@ -257,12 +254,13 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_probe_ent *probe_ent = NULL; - int rc; + struct ata_port_info pi = sis_port_info; + const struct ata_port_info *ppi[2] = { &pi, &pi }; + struct ata_host *host; u32 genctl, val; - struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi }; u8 pmr; u8 port2_start = 0x20; + int rc; if (!printed_version++) dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); @@ -271,19 +269,6 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) { - pcim_pin_device(pdev); - return rc; - } - - rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - return rc; - rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - return rc; - /* check and see if the SCRs are in IO space or PCI cfg space */ pci_read_config_dword(pdev, SIS_GENCTL, &genctl); if ((genctl & GENCTL_IOMAPPED_SCR) == 0) @@ -310,7 +295,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) case 0x10: ppi[1] = &sis_info133; break; - + case 0x30: ppi[0] = &sis_info133; break; @@ -350,30 +335,26 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) break; } - probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); - if (!probe_ent) - return -ENOMEM; + rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host); + if (rc) + return rc; - if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) { - void *mmio; + if (!(pi.flags & SIS_FLAG_CFGSCR)) { + void __iomem *mmio; - mmio = pcim_iomap(pdev, SIS_SCR_PCI_BAR, 0); - if (!mmio) - return -ENOMEM; + rc = pcim_iomap_regions(pdev, 1 << SIS_SCR_PCI_BAR, DRV_NAME); + if (rc) + return rc; + mmio = host->iomap[SIS_SCR_PCI_BAR]; - probe_ent->port[0].scr_addr = mmio; - probe_ent->port[1].scr_addr = mmio + port2_start; + host->ports[0]->ioaddr.scr_addr = mmio; + host->ports[1]->ioaddr.scr_addr = mmio + port2_start; } pci_set_master(pdev); pci_intx(pdev, 1); - - if (!ata_device_add(probe_ent)) - return -EIO; - - devm_kfree(&pdev->dev, probe_ent); - return 0; - + return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED, + &sis_sht); } static int __init sis_init(void) diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 4e428999420..cc07aac10e8 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -53,10 +53,12 @@ #endif /* CONFIG_PPC_OF */ #define DRV_NAME "sata_svw" -#define DRV_VERSION "2.0" +#define DRV_VERSION "2.1" enum { - K2_FLAG_NO_ATAPI_DMA = (1 << 29), + /* ap->flags bits */ + K2_FLAG_SATA_8_PORTS = (1 << 24), + K2_FLAG_NO_ATAPI_DMA = (1 << 25), /* Taskfile registers offsets */ K2_SATA_TF_CMD_OFFSET = 0x00, @@ -90,17 +92,6 @@ enum { board_svw8 = 1, }; -static const struct k2_board_info { - unsigned int n_ports; - unsigned long port_flags; -} k2_board_info[] = { - /* board_svw4 */ - { 4, K2_FLAG_NO_ATAPI_DMA }, - - /* board_svw8 */ - { 8, K2_FLAG_NO_ATAPI_DMA }, -}; - static u8 k2_stat_check_status(struct ata_port *ap); @@ -354,7 +345,6 @@ static const struct ata_port_operations k2_sata_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -363,6 +353,28 @@ static const struct ata_port_operations k2_sata_ops = { .port_start = ata_port_start, }; +static const struct ata_port_info k2_port_info[] = { + /* board_svw4 */ + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = 0x7f, + .port_ops = &k2_sata_ops, + }, + /* board_svw8 */ + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | + K2_FLAG_SATA_8_PORTS, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = 0x7f, + .port_ops = &k2_sata_ops, + }, +}; + static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base) { port->cmd_addr = base + K2_SATA_TF_CMD_OFFSET; @@ -386,17 +398,24 @@ static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base) static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct device *dev = &pdev->dev; - struct ata_probe_ent *probe_ent; + const struct ata_port_info *ppi[] = + { &k2_port_info[ent->driver_data], NULL }; + struct ata_host *host; void __iomem *mmio_base; - const struct k2_board_info *board_info = - &k2_board_info[ent->driver_data]; - int rc; - int i; + int n_ports, i, rc; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* allocate host */ + n_ports = 4; + if (ppi[0]->flags & K2_FLAG_SATA_8_PORTS) + n_ports = 8; + + host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); + if (!host) + return -ENOMEM; + /* * If this driver happens to only be useful on Apple's K2, then * we should check that here as it has a normal Serverworks ID @@ -404,6 +423,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e rc = pcim_enable_device(pdev); if (rc) return rc; + /* * Check if we have resources mapped at all (second function may * have been disabled by firmware) @@ -417,6 +437,15 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e pcim_pin_device(pdev); if (rc) return rc; + host->iomap = pcim_iomap_table(pdev); + mmio_base = host->iomap[5]; + + /* different controllers have different number of ports - currently 4 or 8 */ + /* All ports are on the same function. Multi-function device is no + * longer available. This should not be seen in any system. */ + for (i = 0; i < host->n_ports; i++) + k2_sata_setup_port(&host->ports[i]->ioaddr, + mmio_base + i * K2_SATA_PORT_OFFSET); rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -425,38 +454,6 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e if (rc) return rc; - probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) - return -ENOMEM; - - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - - probe_ent->sht = &k2_sata_sht; - probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | board_info->port_flags; - probe_ent->port_ops = &k2_sata_ops; - probe_ent->n_ports = 4; - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->iomap = pcim_iomap_table(pdev); - - /* We don't care much about the PIO/UDMA masks, but the core won't like us - * if we don't fill these - */ - probe_ent->pio_mask = 0x1f; - probe_ent->mwdma_mask = 0x7; - probe_ent->udma_mask = 0x7f; - - mmio_base = probe_ent->iomap[5]; - - /* different controllers have different number of ports - currently 4 or 8 */ - /* All ports are on the same function. Multi-function device is no - * longer available. This should not be seen in any system. */ - for (i = 0; i < board_info->n_ports; i++) - k2_sata_setup_port(&probe_ent->port[i], - mmio_base + i * K2_SATA_PORT_OFFSET); - /* Clear a magic bit in SCR1 according to Darwin, those help * some funky seagate drives (though so far, those were already * set by the firmware on the machines I had access to) @@ -469,12 +466,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e writel(0x0, mmio_base + K2_SATA_SIM_OFFSET); pci_set_master(pdev); - - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(dev, probe_ent); - return 0; + return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED, + &k2_sata_sht); } /* 0x240 is device ID for Apple K2 device diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 0ebd77b080d..3a4f44559d0 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -44,7 +44,7 @@ #include "sata_promise.h" #define DRV_NAME "sata_sx4" -#define DRV_VERSION "0.9" +#define DRV_VERSION "0.10" enum { @@ -151,24 +151,23 @@ struct pdc_host_priv { static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance); static void pdc_eng_timeout(struct ata_port *ap); static void pdc_20621_phy_reset (struct ata_port *ap); static int pdc_port_start(struct ata_port *ap); static void pdc20621_qc_prep(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); -static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe); -static int pdc20621_detect_dimm(struct ata_probe_ent *pe); -static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, +static unsigned int pdc20621_dimm_init(struct ata_host *host); +static int pdc20621_detect_dimm(struct ata_host *host); +static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device, u32 subaddr, u32 *pdata); -static int pdc20621_prog_dimm0(struct ata_probe_ent *pe); -static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe); +static int pdc20621_prog_dimm0(struct ata_host *host); +static unsigned int pdc20621_prog_dimm_global(struct ata_host *host); #ifdef ATA_VERBOSE_DEBUG -static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, +static void pdc20621_get_from_dimm(struct ata_host *host, void *psource, u32 offset, u32 size); #endif -static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, +static void pdc20621_put_to_dimm(struct ata_host *host, void *psource, u32 offset, u32 size); static void pdc20621_irq_clear(struct ata_port *ap); static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc); @@ -204,7 +203,6 @@ static const struct ata_port_operations pdc_20621_ops = { .qc_issue = pdc20621_qc_issue_prot, .data_xfer = ata_data_xfer, .eng_timeout = pdc_eng_timeout, - .irq_handler = pdc20621_interrupt, .irq_clear = pdc20621_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -214,7 +212,6 @@ static const struct ata_port_operations pdc_20621_ops = { static const struct ata_port_info pdc_port_info[] = { /* board_20621 */ { - .sht = &pdc_sata_sht, .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, @@ -421,7 +418,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); - VPRINTK("ata%u: ENTER\n", ap->id); + VPRINTK("ata%u: ENTER\n", ap->print_id); /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -478,7 +475,7 @@ static void pdc20621_nodata_prep(struct ata_queued_cmd *qc) unsigned int portno = ap->port_no; unsigned int i; - VPRINTK("ata%u: ENTER\n", ap->id); + VPRINTK("ata%u: ENTER\n", ap->print_id); /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -605,7 +602,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc) /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; - VPRINTK("ata%u: ENTER\n", ap->id); + VPRINTK("ata%u: ENTER\n", ap->print_id); wmb(); /* flush PRD, pkt writes */ @@ -672,7 +669,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, /* step two - DMA from DIMM to host */ if (doing_hdma) { - VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id, + VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); @@ -683,7 +680,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, /* step one - exec ATA command */ else { u8 seq = (u8) (port_no + 1 + 4); - VPRINTK("ata%u: read ata, 0x%x 0x%x\n", ap->id, + VPRINTK("ata%u: read ata, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* submit hdma pkt */ @@ -698,7 +695,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, /* step one - DMA from host to DIMM */ if (doing_hdma) { u8 seq = (u8) (port_no + 1); - VPRINTK("ata%u: write hdma, 0x%x 0x%x\n", ap->id, + VPRINTK("ata%u: write hdma, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* submit ata pkt */ @@ -711,7 +708,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, /* step two - execute ATA command */ else { - VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, + VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); @@ -882,15 +879,15 @@ static void pdc_sata_setup_port(struct ata_ioports *port, void __iomem *base) #ifdef ATA_VERBOSE_DEBUG -static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, +static void pdc20621_get_from_dimm(struct ata_host *host, void *psource, u32 offset, u32 size) { u32 window_size; u16 idx; u8 page_mask; long dist; - void __iomem *mmio = pe->iomap[PDC_MMIO_BAR]; - void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR]; + void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; + void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR]; /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -937,15 +934,15 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, #endif -static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, +static void pdc20621_put_to_dimm(struct ata_host *host, void *psource, u32 offset, u32 size) { u32 window_size; u16 idx; u8 page_mask; long dist; - void __iomem *mmio = pe->iomap[PDC_MMIO_BAR]; - void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR]; + void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; + void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR]; /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -987,10 +984,10 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, } -static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, +static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device, u32 subaddr, u32 *pdata) { - void __iomem *mmio = pe->iomap[PDC_MMIO_BAR]; + void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; u32 i2creg = 0; u32 status; u32 count =0; @@ -1023,17 +1020,17 @@ static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, } -static int pdc20621_detect_dimm(struct ata_probe_ent *pe) +static int pdc20621_detect_dimm(struct ata_host *host) { u32 data=0 ; - if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, + if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, PDC_DIMM_SPD_SYSTEM_FREQ, &data)) { if (data == 100) return 100; } else return 0; - if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) { + if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) { if(data <= 0x75) return 133; } else @@ -1043,13 +1040,13 @@ static int pdc20621_detect_dimm(struct ata_probe_ent *pe) } -static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) +static int pdc20621_prog_dimm0(struct ata_host *host) { u32 spd0[50]; u32 data = 0; int size, i; u8 bdimmsize; - void __iomem *mmio = pe->iomap[PDC_MMIO_BAR]; + void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; static const struct { unsigned int reg; unsigned int ofs; @@ -1072,7 +1069,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) mmio += PDC_CHIP0_OFS; for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++) - pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, + pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, pdc_i2c_read_data[i].reg, &spd0[pdc_i2c_read_data[i].ofs]); @@ -1108,11 +1105,11 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) } -static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe) +static unsigned int pdc20621_prog_dimm_global(struct ata_host *host) { u32 data, spd0; int error, i; - void __iomem *mmio = pe->iomap[PDC_MMIO_BAR]; + void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -1129,7 +1126,7 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe) readl(mmio + PDC_SDRAM_CONTROL_OFFSET); /* Turn on for ECC */ - pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, + pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, PDC_DIMM_SPD_TYPE, &spd0); if (spd0 == 0x02) { data |= (0x01 << 16); @@ -1156,7 +1153,7 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe) } -static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) +static unsigned int pdc20621_dimm_init(struct ata_host *host) { int speed, size, length; u32 addr,spd0,pci_status; @@ -1166,7 +1163,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) u32 ticks=0; u32 clock=0; u32 fparam=0; - void __iomem *mmio = pe->iomap[PDC_MMIO_BAR]; + void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -1225,18 +1222,18 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) Read SPD of DIMM by I2C interface, and program the DIMM Module Controller. */ - if (!(speed = pdc20621_detect_dimm(pe))) { + if (!(speed = pdc20621_detect_dimm(host))) { printk(KERN_ERR "Detect Local DIMM Fail\n"); return 1; /* DIMM error */ } VPRINTK("Local DIMM Speed = %d\n", speed); /* Programming DIMM0 Module Control Register (index_CID0:80h) */ - size = pdc20621_prog_dimm0(pe); + size = pdc20621_prog_dimm0(host); VPRINTK("Local DIMM Size = %dMB\n",size); /* Programming DIMM Module Global Control Register (index_CID0:88h) */ - if (pdc20621_prog_dimm_global(pe)) { + if (pdc20621_prog_dimm_global(host)) { printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n"); return 1; } @@ -1249,20 +1246,20 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) '9','8','0','3','1','6','1','2',0,0}; u8 test_parttern2[40] = {0}; - pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x10040, 40); - pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x40, 40); + pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x10040, 40); + pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x40, 40); - pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x10040, 40); - pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); + pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x10040, 40); + pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40); printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], test_parttern2[1], &(test_parttern2[2])); - pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x10040, + pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x10040, 40); printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], test_parttern2[1], &(test_parttern2[2])); - pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x40, 40); - pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); + pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x40, 40); + pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40); printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], test_parttern2[1], &(test_parttern2[2])); } @@ -1270,14 +1267,14 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) /* ECC initiliazation. */ - pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, + pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, PDC_DIMM_SPD_TYPE, &spd0); if (spd0 == 0x02) { VPRINTK("Start ECC initialization\n"); addr = 0; length = size * 1024 * 1024; while (addr < length) { - pdc20621_put_to_dimm(pe, (void *) &tmp, addr, + pdc20621_put_to_dimm(host, (void *) &tmp, addr, sizeof(u32)); addr += sizeof(u32); } @@ -1287,10 +1284,10 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) } -static void pdc_20621_init(struct ata_probe_ent *pe) +static void pdc_20621_init(struct ata_host *host) { u32 tmp; - void __iomem *mmio = pe->iomap[PDC_MMIO_BAR]; + void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -1321,15 +1318,25 @@ static void pdc_20621_init(struct ata_probe_ent *pe) static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_probe_ent *probe_ent; + const struct ata_port_info *ppi[] = + { &pdc_port_info[ent->driver_data], NULL }; + struct ata_host *host; void __iomem *base; struct pdc_host_priv *hpriv; - unsigned int board_idx = (unsigned int) ent->driver_data; int rc; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* allocate host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4); + hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); + if (!host || !hpriv) + return -ENOMEM; + + host->private_data = hpriv; + + /* acquire resources and fill host */ rc = pcim_enable_device(pdev); if (rc) return rc; @@ -1340,7 +1347,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * pcim_pin_device(pdev); if (rc) return rc; + host->iomap = pcim_iomap_table(pdev); + + base = host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS; + pdc_sata_setup_port(&host->ports[0]->ioaddr, base + 0x200); + pdc_sata_setup_port(&host->ports[1]->ioaddr, base + 0x280); + pdc_sata_setup_port(&host->ports[2]->ioaddr, base + 0x300); + pdc_sata_setup_port(&host->ports[3]->ioaddr, base + 0x380); + /* configure and activate */ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) return rc; @@ -1348,50 +1363,13 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * if (rc) return rc; - probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) + if (pdc20621_dimm_init(host)) return -ENOMEM; - - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - - hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); - if (!hpriv) - return -ENOMEM; - - probe_ent->sht = pdc_port_info[board_idx].sht; - probe_ent->port_flags = pdc_port_info[board_idx].flags; - probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask; - probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask; - probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask; - probe_ent->port_ops = pdc_port_info[board_idx].port_ops; - - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->iomap = pcim_iomap_table(pdev); - - probe_ent->private_data = hpriv; - base = probe_ent->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS; - - probe_ent->n_ports = 4; - pdc_sata_setup_port(&probe_ent->port[0], base + 0x200); - pdc_sata_setup_port(&probe_ent->port[1], base + 0x280); - pdc_sata_setup_port(&probe_ent->port[2], base + 0x300); - pdc_sata_setup_port(&probe_ent->port[3], base + 0x380); + pdc_20621_init(host); pci_set_master(pdev); - - /* initialize adapter */ - /* initialize local dimm */ - if (pdc20621_dimm_init(probe_ent)) - return -ENOMEM; - pdc_20621_init(probe_ent); - - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(&pdev->dev, probe_ent); - return 0; + return ata_host_activate(host, pdev->irq, pdc20621_interrupt, + IRQF_SHARED, &pdc_sata_sht); } diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index 80131eec68f..f74e383de08 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -36,7 +36,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_uli" -#define DRV_VERSION "1.0" +#define DRV_VERSION "1.1" enum { uli_5289 = 0, @@ -115,7 +115,6 @@ static const struct ata_port_operations uli_ops = { .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -127,7 +126,6 @@ static const struct ata_port_operations uli_ops = { }; static struct ata_port_info uli_port_info = { - .sht = &uli_sht, .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_IGN_SIMPLEX, .pio_mask = 0x1f, /* pio0-4 */ @@ -185,12 +183,13 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_probe_ent *probe_ent; - struct ata_port_info *ppi[2]; - int rc; + const struct ata_port_info *ppi[] = { &uli_port_info, NULL }; unsigned int board_idx = (unsigned int) ent->driver_data; + struct ata_host *host; struct uli_priv *hpriv; void __iomem * const *iomap; + struct ata_ioports *ioaddr; + int n_ports, rc; if (!printed_version++) dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); @@ -199,54 +198,42 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) { - pcim_pin_device(pdev); - return rc; - } - - rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - return rc; - rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); + n_ports = 2; + if (board_idx == uli_5287) + n_ports = 4; + rc = ata_pci_prepare_native_host(pdev, ppi, n_ports, &host); if (rc) return rc; - ppi[0] = ppi[1] = &uli_port_info; - probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); - if (!probe_ent) - return -ENOMEM; - hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) return -ENOMEM; + host->private_data = hpriv; - probe_ent->private_data = hpriv; - - iomap = pcim_iomap_table(pdev); + iomap = host->iomap; switch (board_idx) { case uli_5287: hpriv->scr_cfg_addr[0] = ULI5287_BASE; hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS; - probe_ent->n_ports = 4; - probe_ent->port[2].cmd_addr = iomap[0] + 8; - probe_ent->port[2].altstatus_addr = - probe_ent->port[2].ctl_addr = (void __iomem *) + ioaddr = &host->ports[2]->ioaddr; + ioaddr->cmd_addr = iomap[0] + 8; + ioaddr->altstatus_addr = + ioaddr->ctl_addr = (void __iomem *) ((unsigned long)iomap[1] | ATA_PCI_CTL_OFS) + 4; - probe_ent->port[2].bmdma_addr = iomap[4] + 16; + ioaddr->bmdma_addr = iomap[4] + 16; hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4; + ata_std_ports(ioaddr); - probe_ent->port[3].cmd_addr = iomap[2] + 8; - probe_ent->port[3].altstatus_addr = - probe_ent->port[3].ctl_addr = (void __iomem *) + ioaddr = &host->ports[3]->ioaddr; + ioaddr->cmd_addr = iomap[2] + 8; + ioaddr->altstatus_addr = + ioaddr->ctl_addr = (void __iomem *) ((unsigned long)iomap[3] | ATA_PCI_CTL_OFS) + 4; - probe_ent->port[3].bmdma_addr = iomap[4] + 24; + ioaddr->bmdma_addr = iomap[4] + 24; hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5; - - ata_std_ports(&probe_ent->port[2]); - ata_std_ports(&probe_ent->port[3]); + ata_std_ports(ioaddr); break; case uli_5289: @@ -266,12 +253,8 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); pci_intx(pdev, 1); - - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(&pdev->dev, probe_ent); - return 0; + return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED, + &uli_sht); } static int __init uli_init(void) diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index baca6d79bb0..1d855f55f5f 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -46,7 +46,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_via" -#define DRV_VERSION "2.0" +#define DRV_VERSION "2.1" enum board_ids_enum { vt6420, @@ -60,12 +60,10 @@ enum { SATA_PATA_SHARING = 0x49, /* PATA/SATA sharing func ctrl */ PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */ PATA_PIO_TIMING = 0xAB, /* PATA timing register */ - + PORT0 = (1 << 1), PORT1 = (1 << 0), ALL_PORTS = PORT0 | PORT1, - PATA_PORT = 2, /* PATA is port 2 */ - N_PORTS = 3, NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), @@ -78,11 +76,9 @@ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void svia_noop_freeze(struct ata_port *ap); static void vt6420_error_handler(struct ata_port *ap); -static void vt6421_sata_error_handler(struct ata_port *ap); -static void vt6421_pata_error_handler(struct ata_port *ap); +static int vt6421_pata_cable_detect(struct ata_port *ap); static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev); static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev); -static int vt6421_port_start(struct ata_port *ap); static const struct pci_device_id svia_pci_tbl[] = { { PCI_VDEVICE(VIA, 0x5337), vt6420 }, @@ -141,7 +137,6 @@ static const struct ata_port_operations vt6420_sata_ops = { .error_handler = vt6420_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -151,7 +146,7 @@ static const struct ata_port_operations vt6420_sata_ops = { static const struct ata_port_operations vt6421_pata_ops = { .port_disable = ata_port_disable, - + .set_piomode = vt6421_set_pio_mode, .set_dmamode = vt6421_set_dma_mode, @@ -172,20 +167,20 @@ static const struct ata_port_operations vt6421_pata_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = vt6421_pata_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = vt6421_pata_cable_detect, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, - .port_start = vt6421_port_start, + .port_start = ata_port_start, }; static const struct ata_port_operations vt6421_sata_ops = { .port_disable = ata_port_disable, - + .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, @@ -203,10 +198,10 @@ static const struct ata_port_operations vt6421_sata_ops = { .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, - .error_handler = vt6421_sata_error_handler, + .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_sata, - .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -214,11 +209,10 @@ static const struct ata_port_operations vt6421_sata_ops = { .scr_read = svia_scr_read, .scr_write = svia_scr_write, - .port_start = vt6421_port_start, + .port_start = ata_port_start, }; -static struct ata_port_info vt6420_port_info = { - .sht = &svia_sht, +static const struct ata_port_info vt6420_port_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0x07, @@ -226,6 +220,22 @@ static struct ata_port_info vt6420_port_info = { .port_ops = &vt6420_sata_ops, }; +static struct ata_port_info vt6421_sport_info = { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = 0x7f, + .port_ops = &vt6421_sata_ops, +}; + +static struct ata_port_info vt6421_pport_info = { + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY, + .pio_mask = 0x1f, + .mwdma_mask = 0, + .udma_mask = 0x7f, + .port_ops = &vt6421_pata_ops, +}; + MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers"); MODULE_LICENSE("GPL"); @@ -330,35 +340,15 @@ static void vt6420_error_handler(struct ata_port *ap) NULL, ata_std_postreset); } -static int vt6421_pata_prereset(struct ata_port *ap) +static int vt6421_pata_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 tmp; pci_read_config_byte(pdev, PATA_UDMA_TIMING, &tmp); if (tmp & 0x10) - ap->cbl = ATA_CBL_PATA40; - else - ap->cbl = ATA_CBL_PATA80; - return 0; -} - -static void vt6421_pata_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, vt6421_pata_prereset, ata_std_softreset, - NULL, ata_std_postreset); -} - -static int vt6421_sata_prereset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_SATA; - return 0; -} - -static void vt6421_sata_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, vt6421_sata_prereset, ata_std_softreset, - NULL, ata_std_postreset); + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; } static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev) @@ -375,16 +365,6 @@ static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev) pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->pio_mode - XFER_UDMA_0]); } -static int vt6421_port_start(struct ata_port *ap) -{ - if (ap->port_no == PATA_PORT) { - ap->ops = &vt6421_pata_ops; - ap->mwdma_mask = 0; - ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST; - } - return ata_port_start(ap); -} - static const unsigned int svia_bar_sizes[] = { 8, 4, 8, 4, 16, 256 }; @@ -403,67 +383,78 @@ static void __iomem * vt6421_scr_addr(void __iomem *addr, unsigned int port) return addr + (port * 64); } -static void vt6421_init_addrs(struct ata_probe_ent *probe_ent, - void __iomem * const *iomap, unsigned int port) +static void vt6421_init_addrs(struct ata_port *ap) { - void __iomem *reg_addr = iomap[port]; - void __iomem *bmdma_addr = iomap[4] + (port * 8); - - probe_ent->port[port].cmd_addr = reg_addr; - probe_ent->port[port].altstatus_addr = - probe_ent->port[port].ctl_addr = (void __iomem *) + void __iomem * const * iomap = ap->host->iomap; + void __iomem *reg_addr = iomap[ap->port_no]; + void __iomem *bmdma_addr = iomap[4] + (ap->port_no * 8); + struct ata_ioports *ioaddr = &ap->ioaddr; + + ioaddr->cmd_addr = reg_addr; + ioaddr->altstatus_addr = + ioaddr->ctl_addr = (void __iomem *) ((unsigned long)(reg_addr + 8) | ATA_PCI_CTL_OFS); - probe_ent->port[port].bmdma_addr = bmdma_addr; - probe_ent->port[port].scr_addr = vt6421_scr_addr(iomap[5], port); + ioaddr->bmdma_addr = bmdma_addr; + ioaddr->scr_addr = vt6421_scr_addr(iomap[5], ap->port_no); - ata_std_ports(&probe_ent->port[port]); + ata_std_ports(ioaddr); } -static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev) +static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) { - struct ata_probe_ent *probe_ent; - struct ata_port_info *ppi[2]; - void __iomem * const *iomap; + const struct ata_port_info *ppi[] = { &vt6420_port_info, NULL }; + struct ata_host *host; + int rc; - ppi[0] = ppi[1] = &vt6420_port_info; - probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); - if (!probe_ent) - return NULL; + rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host); + if (rc) + return rc; + *r_host = host; - iomap = pcim_iomap_table(pdev); - probe_ent->port[0].scr_addr = svia_scr_addr(iomap[5], 0); - probe_ent->port[1].scr_addr = svia_scr_addr(iomap[5], 1); + rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, "failed to iomap PCI BAR 5\n"); + return rc; + } + + host->ports[0]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 0); + host->ports[1]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 1); - return probe_ent; + return 0; } -static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev) +static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) { - struct ata_probe_ent *probe_ent; - unsigned int i; - - probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); - if (!probe_ent) - return NULL; + const struct ata_port_info *ppi[] = + { &vt6421_sport_info, &vt6421_sport_info, &vt6421_pport_info }; + struct ata_host *host; + int i, rc; + + *r_host = host = ata_host_alloc_pinfo(&pdev->dev, ppi, ARRAY_SIZE(ppi)); + if (!host) { + dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n"); + return -ENOMEM; + } - memset(probe_ent, 0, sizeof(*probe_ent)); - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); + rc = pcim_iomap_regions(pdev, 0x1f, DRV_NAME); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, "failed to request/iomap " + "PCI BARs (errno=%d)\n", rc); + return rc; + } + host->iomap = pcim_iomap_table(pdev); - probe_ent->sht = &svia_sht; - probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY; - probe_ent->port_ops = &vt6421_sata_ops; - probe_ent->n_ports = N_PORTS; - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->pio_mask = 0x1f; - probe_ent->mwdma_mask = 0x07; - probe_ent->udma_mask = 0x7f; + for (i = 0; i < host->n_ports; i++) + vt6421_init_addrs(host->ports[i]); - for (i = 0; i < N_PORTS; i++) - vt6421_init_addrs(probe_ent, pcim_iomap_table(pdev), i); + rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + return rc; + rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); + if (rc) + return rc; - return probe_ent; + return 0; } static void svia_configure(struct pci_dev *pdev) @@ -510,7 +501,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static int printed_version; unsigned int i; int rc; - struct ata_probe_ent *probe_ent; + struct ata_host *host; int board_id = (int) ent->driver_data; const int *bar_sizes; u8 tmp8; @@ -522,12 +513,6 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - rc = pcim_iomap_regions(pdev, 0x1f, DRV_NAME); - if (rc) { - pcim_pin_device(pdev); - return rc; - } - if (board_id == vt6420) { pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8); if (tmp8 & SATA_2DEV) { @@ -553,32 +538,18 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) return -ENODEV; } - rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - return rc; - rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - return rc; - if (board_id == vt6420) - probe_ent = vt6420_init_probe_ent(pdev); + rc = vt6420_prepare_host(pdev, &host); else - probe_ent = vt6421_init_probe_ent(pdev); - - if (!probe_ent) { - dev_printk(KERN_ERR, &pdev->dev, "out of memory\n"); - return -ENOMEM; - } + rc = vt6421_prepare_host(pdev, &host); + if (rc) + return rc; svia_configure(pdev); pci_set_master(pdev); - - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(&pdev->dev, probe_ent); - return 0; + return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED, + &svia_sht); } static int __init svia_init(void) diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index 2fd037bde09..80126f835d3 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c @@ -47,7 +47,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_vsc" -#define DRV_VERSION "2.0" +#define DRV_VERSION "2.1" enum { VSC_MMIO_BAR = 0, @@ -98,10 +98,6 @@ enum { VSC_SATA_INT_PHY_CHANGE), }; -#define is_vsc_sata_int_err(port_idx, int_status) \ - (int_status & (VSC_SATA_INT_ERROR << (8 * port_idx))) - - static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) @@ -119,6 +115,28 @@ static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, } +static void vsc_freeze(struct ata_port *ap) +{ + void __iomem *mask_addr; + + mask_addr = ap->host->iomap[VSC_MMIO_BAR] + + VSC_SATA_INT_MASK_OFFSET + ap->port_no; + + writeb(0, mask_addr); +} + + +static void vsc_thaw(struct ata_port *ap) +{ + void __iomem *mask_addr; + + mask_addr = ap->host->iomap[VSC_MMIO_BAR] + + VSC_SATA_INT_MASK_OFFSET + ap->port_no; + + writeb(0xff, mask_addr); +} + + static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl) { void __iomem *mask_addr; @@ -203,6 +221,36 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) } } +static inline void vsc_error_intr(u8 port_status, struct ata_port *ap) +{ + if (port_status & (VSC_SATA_INT_PHY_CHANGE | VSC_SATA_INT_ERROR_M)) + ata_port_freeze(ap); + else + ata_port_abort(ap); +} + +static void vsc_port_intr(u8 port_status, struct ata_port *ap) +{ + struct ata_queued_cmd *qc; + int handled = 0; + + if (unlikely(port_status & VSC_SATA_INT_ERROR)) { + vsc_error_intr(port_status, ap); + return; + } + + qc = ata_qc_from_tag(ap, ap->active_tag); + if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING))) + handled = ata_host_intr(ap, qc); + + /* We received an interrupt during a polled command, + * or some other spurious condition. Interrupt reporting + * with this hardware is fairly reliable so it is safe to + * simply clear the interrupt + */ + if (unlikely(!handled)) + ata_chk_status(ap); +} /* * vsc_sata_interrupt @@ -214,59 +262,36 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance) struct ata_host *host = dev_instance; unsigned int i; unsigned int handled = 0; - u32 int_status; - - spin_lock(&host->lock); + u32 status; - int_status = readl(host->iomap[VSC_MMIO_BAR] + - VSC_SATA_INT_STAT_OFFSET); + status = readl(host->iomap[VSC_MMIO_BAR] + VSC_SATA_INT_STAT_OFFSET); - for (i = 0; i < host->n_ports; i++) { - if (int_status & ((u32) 0xFF << (8 * i))) { - struct ata_port *ap; + if (unlikely(status == 0xffffffff || status == 0)) { + if (status) + dev_printk(KERN_ERR, host->dev, + ": IRQ status == 0xffffffff, " + "PCI fault or device removal?\n"); + goto out; + } - ap = host->ports[i]; + spin_lock(&host->lock); - if (is_vsc_sata_int_err(i, int_status)) { - u32 err_status; - printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); - err_status = ap ? vsc_sata_scr_read(ap, SCR_ERROR) : 0; - vsc_sata_scr_write(ap, SCR_ERROR, err_status); - handled++; - } + for (i = 0; i < host->n_ports; i++) { + u8 port_status = (status >> (8 * i)) & 0xff; + if (port_status) { + struct ata_port *ap = host->ports[i]; if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { - struct ata_queued_cmd *qc; - - qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) - handled += ata_host_intr(ap, qc); - else if (is_vsc_sata_int_err(i, int_status)) { - /* - * On some chips (i.e. Intel 31244), an error - * interrupt will sneak in at initialization - * time (phy state changes). Clearing the SCR - * error register is not required, but it prevents - * the phy state change interrupts from recurring - * later. - */ - u32 err_status; - err_status = vsc_sata_scr_read(ap, SCR_ERROR); - printk(KERN_DEBUG "%s: clearing interrupt, " - "status %x; sata err status %x\n", - __FUNCTION__, - int_status, err_status); - vsc_sata_scr_write(ap, SCR_ERROR, err_status); - /* Clear interrupt status */ - ata_chk_status(ap); - handled++; - } - } + vsc_port_intr(port_status, ap); + handled++; + } else + dev_printk(KERN_ERR, host->dev, + ": interrupt from disabled port %d\n", i); } } spin_unlock(&host->lock); - +out: return IRQ_RETVAL(handled); } @@ -304,11 +329,10 @@ static const struct ata_port_operations vsc_sata_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .data_xfer = ata_data_xfer, - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, + .freeze = vsc_freeze, + .thaw = vsc_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .irq_handler = vsc_sata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, @@ -342,30 +366,50 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port, static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { + static const struct ata_port_info pi = { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = 0x7f, + .port_ops = &vsc_sata_ops, + }; + const struct ata_port_info *ppi[] = { &pi, NULL }; static int printed_version; - struct ata_probe_ent *probe_ent; + struct ata_host *host; void __iomem *mmio_base; - int rc; + int i, rc; u8 cls; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* allocate host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4); + if (!host) + return -ENOMEM; + rc = pcim_enable_device(pdev); if (rc) return rc; - /* - * Check if we have needed resource mapped. - */ + /* check if we have needed resource mapped */ if (pci_resource_len(pdev, 0) == 0) return -ENODEV; + /* map IO regions and intialize host accordingly */ rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME); if (rc == -EBUSY) pcim_pin_device(pdev); if (rc) return rc; + host->iomap = pcim_iomap_table(pdev); + + mmio_base = host->iomap[VSC_MMIO_BAR]; + + for (i = 0; i < host->n_ports; i++) + vsc_sata_setup_port(&host->ports[i]->ioaddr, + mmio_base + (i + 1) * VSC_SATA_PORT_OFFSET); /* * Use 32 bit DMA mask, because 64 bit address support is poor. @@ -377,12 +421,6 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d if (rc) return rc; - probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) - return -ENOMEM; - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - /* * Due to a bug in the chip, the default cache line size can't be * used (unless the default is non-zero). @@ -393,33 +431,6 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d if (pci_enable_msi(pdev) == 0) pci_intx(pdev, 0); - else - probe_ent->irq_flags = IRQF_SHARED; - - probe_ent->sht = &vsc_sata_sht; - probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO; - probe_ent->port_ops = &vsc_sata_ops; - probe_ent->n_ports = 4; - probe_ent->irq = pdev->irq; - probe_ent->iomap = pcim_iomap_table(pdev); - - /* We don't care much about the PIO/UDMA masks, but the core won't like us - * if we don't fill these - */ - probe_ent->pio_mask = 0x1f; - probe_ent->mwdma_mask = 0x07; - probe_ent->udma_mask = 0x7f; - - mmio_base = probe_ent->iomap[VSC_MMIO_BAR]; - - /* We have 4 ports per PCI function */ - vsc_sata_setup_port(&probe_ent->port[0], mmio_base + 1 * VSC_SATA_PORT_OFFSET); - vsc_sata_setup_port(&probe_ent->port[1], mmio_base + 2 * VSC_SATA_PORT_OFFSET); - vsc_sata_setup_port(&probe_ent->port[2], mmio_base + 3 * VSC_SATA_PORT_OFFSET); - vsc_sata_setup_port(&probe_ent->port[3], mmio_base + 4 * VSC_SATA_PORT_OFFSET); - - pci_set_master(pdev); /* * Config offset 0x98 is "Extended Control and Status Register 0" @@ -429,11 +440,9 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d */ pci_write_config_dword(pdev, 0x98, 0); - if (!ata_device_add(probe_ent)) - return -ENODEV; - - devm_kfree(&pdev->dev, probe_ent); - return 0; + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, vsc_sata_interrupt, + IRQF_SHARED, &vsc_sata_sht); } static const struct pci_device_id vsc_sata_pci_tbl[] = { diff --git a/drivers/ata/sis.h b/drivers/ata/sis.h new file mode 100644 index 00000000000..231da8fc220 --- /dev/null +++ b/drivers/ata/sis.h @@ -0,0 +1,5 @@ + +struct ata_port_info; + +/* pata_sis.c */ +extern struct ata_port_info sis_info133; |