Bartlomiej Zolnierkiewicz wrote: > On Wed, Feb 23, 2011 at 9:45 AM, Bartlomiej Zolnierkiewicz > <bzolnier@xxxxxxxxx> wrote: > > > As for increased memory usage -- we are talking here only about 10-20k > > more. If it really is a problem maybe ata_piix can be redesigned into > > ata_generic-style manner so with the help of existing config options > > we can keep code size / memory usage on a existing level. > > s/ata_generic/pata_legacy/ of course -- what I have in mind is making > Intel specific code depended on ATA_PIIX and adding new config option > ATA_PIIXALIKE for generic code which would be selected by existing > PATA_[EFAR,IT8213, OLDPIIX,RADISYS,RDC] options. *Draft* patch against my current "piixalike" tree to just show the idea and implement the final conversion stage (after optional code in ata_piix gets tested and we are ready to remove separate drivers). CONFIG_PATA_EFAR=y only: before: text data bss dec hex filename 1578 1008 8 2594 a22 drivers/ata/pata_efar.o after: text data bss dec hex filename 2778 1152 8 3938 f62 drivers/ata/ata_piix.o so it pretty much solves code size / memory usage issue (I'm counting in my other patch https://lkml.org/lkml/2011/2/9/150).. --- drivers/ata/Kconfig | 102 +++--- drivers/ata/Makefile | 7 drivers/ata/ata_piix.c | 652 ++++++++++++++++++----------------------- drivers/ata/ata_piix_efar.h | 28 + drivers/ata/ata_piix_it8213.h | 28 + drivers/ata/ata_piix_oldpiix.h | 49 +++ 6 files changed, 454 insertions(+), 412 deletions(-) Index: b/drivers/ata/Kconfig =================================================================== --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -167,9 +167,19 @@ if ATA_BMDMA comment "SATA SFF controllers with BMDMA" +config ATA_PIIXALIKE + tristate "Intel PIIX-alikes PATA/SATA support" + depends on PCI + default y + help + This option enables support needed for all Intel PIIX-alike + Serial ATA and PATA host controllers. + + If unsure, say Y. + config ATA_PIIX tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support" - depends on PCI + depends on ATA_PIIXALIKE help This option enables support for ICH5/6/7/8 Serial ATA and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series @@ -177,6 +187,51 @@ config ATA_PIIX If unsure, say N. +config PATA_EFAR + bool "EFAR SLC90E66 support" + depends on ATA_PIIXALIKE + help + This option enables support for the EFAR SLC90E66 + IDE controller found on some older machines. + + If unsure, say N. + +config PATA_IT8213 + bool "IT8213 PATA support (Experimental)" + depends on ATA_PIIXALIKE && EXPERIMENTAL + help + This option enables support for the ITE 821 PATA + controllers via the new ATA layer. + + If unsure, say N. + +config PATA_OLDPIIX + bool "Intel PATA old PIIX support" + depends on ATA_PIIXALIKE + help + This option enables support for early PIIX PATA support. + + If unsure, say N. + +config PATA_RADISYS + bool "RADISYS 82600 PATA support (Experimental)" + depends on ATA_PIIXALIKE && EXPERIMENTAL + help + This option enables support for the RADISYS 82600 + PATA controllers via the new ATA layer + + If unsure, say N. + +config PATA_RDC + bool "RDC PATA support" + depends on ATA_PIIXALIKE + help + This option enables basic support for the later RDC PATA controllers + controllers via the new ATA layer. For the RDC 1010, you need to + enable the IT821X driver instead. + + If unsure, say N. + config SATA_DWC tristate "DesignWare Cores SATA support" depends on 460EX @@ -372,15 +427,6 @@ config PATA_CYPRESS If unsure, say N. -config PATA_EFAR - tristate "EFAR SLC90E66 support" - depends on PCI - help - This option enables support for the EFAR SLC90E66 - IDE controller found on some older machines. - - If unsure, say N. - config PATA_HPT366 tristate "HPT 366/368 PATA support" depends on PCI @@ -433,15 +479,6 @@ config PATA_ICSIDE interface card. This is not required for ICS partition support. If you are unsure, say N to this. -config PATA_IT8213 - tristate "IT8213 PATA support (Experimental)" - depends on PCI && EXPERIMENTAL - help - This option enables support for the ITE 821 PATA - controllers via the new ATA layer. - - If unsure, say N. - config PATA_IT821X tristate "IT8211/2 PATA support" depends on PCI @@ -518,14 +555,6 @@ config PATA_NS87415 If unsure, say N. -config PATA_OLDPIIX - tristate "Intel PATA old PIIX support" - depends on PCI - help - This option enables support for early PIIX PATA support. - - If unsure, say N. - config PATA_OPTIDMA tristate "OPTI FireStar PATA support (Very Experimental)" depends on PCI && EXPERIMENTAL @@ -553,25 +582,6 @@ config PATA_PDC_OLD If unsure, say N. -config PATA_RADISYS - tristate "RADISYS 82600 PATA support (Experimental)" - depends on PCI && EXPERIMENTAL - help - This option enables support for the RADISYS 82600 - PATA controllers via the new ATA layer - - If unsure, say N. - -config PATA_RDC - tristate "RDC PATA support" - depends on PCI - help - This option enables basic support for the later RDC PATA controllers - controllers via the new ATA layer. For the RDC 1010, you need to - enable the IT821X driver instead. - - If unsure, say N. - config PATA_SC1200 tristate "SC1200 PATA support" depends on PCI Index: b/drivers/ata/Makefile =================================================================== --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o obj-$(CONFIG_SATA_SX4) += sata_sx4.o # SFF SATA w/ BMDMA -obj-$(CONFIG_ATA_PIIX) += ata_piix.o +obj-$(CONFIG_ATA_PIIXALIKE) += ata_piix.o obj-$(CONFIG_SATA_MV) += sata_mv.o obj-$(CONFIG_SATA_NV) += sata_nv.o obj-$(CONFIG_SATA_PROMISE) += sata_promise.o @@ -40,13 +40,11 @@ obj-$(CONFIG_PATA_CS5530) += pata_cs5530 obj-$(CONFIG_PATA_CS5535) += pata_cs5535.o obj-$(CONFIG_PATA_CS5536) += pata_cs5536.o obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o -obj-$(CONFIG_PATA_EFAR) += pata_efar.o obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o -obj-$(CONFIG_PATA_IT8213) += pata_it8213.o obj-$(CONFIG_PATA_IT821X) += pata_it821x.o obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o obj-$(CONFIG_PATA_MACIO) += pata_macio.o @@ -55,12 +53,9 @@ obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52 obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o -obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o obj-$(CONFIG_PATA_PDC2027X) += pata_pdc2027x.o obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o -obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o -obj-$(CONFIG_PATA_RDC) += pata_rdc.o obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o obj-$(CONFIG_PATA_SCC) += pata_scc.o obj-$(CONFIG_PATA_SCH) += pata_sch.o Index: b/drivers/ata/ata_piix.c =================================================================== --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -169,6 +169,7 @@ enum piix_controller_ids { it8213_pata, oldpiix_pata, radisys_pata, + rdc_pata, ich5_sata, ich6_sata, ich6m_sata, @@ -191,33 +192,10 @@ struct piix_host_priv { void __iomem *sidpr; }; -static int piix_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent); -static void piix_remove_one(struct pci_dev *pdev); -static int piix_pata_prereset(struct ata_link *link, unsigned long deadline); -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 int efar_pata_cable_detect(struct ata_port *ap); -static int it8213_pata_cable_detect(struct ata_port *ap); -static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc); -static u8 piix_vmw_bmdma_status(struct ata_port *ap); -static int piix_sidpr_scr_read(struct ata_link *link, - unsigned int reg, u32 *val); -static int piix_sidpr_scr_write(struct ata_link *link, - unsigned int reg, u32 val); -static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, - unsigned hints); -static bool piix_irq_check(struct ata_port *ap); -#ifdef CONFIG_PM -static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); -static int piix_pci_device_resume(struct pci_dev *pdev); -#endif - static unsigned int in_module_init = 1; static const struct pci_device_id piix_pci_tbl[] = { +#ifdef CONFIG_ATA_PIIX /* Intel PIIX3 for the 430HX etc */ { 0x8086, 0x7010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_mwdma }, /* VMware ICH4 */ @@ -261,23 +239,29 @@ static const struct pci_device_id piix_p { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100_nomwdma1 }, /* ICH8 Mobile PATA Controller */ { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, - +#endif +#ifdef CONFIG_PATA_EFAR /* EFAR */ { 0x1055, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, efar_pata }, - +#endif +#ifdef CONFIG_PATA_IT8213 /* IT8213 */ { 0x1283, 0x8213, PCI_ANY_ID, PCI_ANY_ID, 0, 0, it8213_pata }, - +#endif +#ifdef CONFIG_PATA_RDC /* RDC is ICH like */ - { 0x17F3, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, - { 0x17F3, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, - + { 0x17F3, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rdc_pata }, + { 0x17F3, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rdc_pata }, +#endif +#ifdef CONFIG_PATA_OLDPIIX /* PIIXb (a.k.a. oldpiix) */ { 0x8086, 0x1230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, oldpiix_pata }, - +#endif +#ifdef CONFIG_PATA_RADISYS /* Radisys R82600 */ { 0x1331, 0x8201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, radisys_pata }, - +#endif +#ifdef CONFIG_ATA_PIIX /* SATA ports */ /* 82801EB (ICH5) */ @@ -359,98 +343,10 @@ static const struct pci_device_id piix_p /* SATA Controller IDE (PBG) */ { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { } /* terminate list */ -}; - -static struct pci_driver piix_pci_driver = { - .name = DRV_NAME, - .id_table = piix_pci_tbl, - .probe = piix_init_one, - .remove = piix_remove_one, -#ifdef CONFIG_PM - .suspend = piix_pci_device_suspend, - .resume = piix_pci_device_resume, #endif }; -static struct scsi_host_template piix_sht = { - ATA_BMDMA_SHT(DRV_NAME), -}; - -static struct ata_port_operations piix_sata_ops = { - .inherits = &ata_bmdma32_port_ops, - .sff_irq_check = piix_irq_check, -}; - -static struct ata_port_operations piix_pata_ops = { - .inherits = &piix_sata_ops, - .cable_detect = ata_cable_40wire, - .set_piomode = piix_set_piomode, - .set_dmamode = piix_set_dmamode, - .prereset = piix_pata_prereset, -}; - -static struct ata_port_operations piix_vmw_ops = { - .inherits = &piix_pata_ops, - .bmdma_status = piix_vmw_bmdma_status, -}; - -static struct ata_port_operations ich_pata_ops = { - .inherits = &piix_pata_ops, - .cable_detect = ich_pata_cable_detect, - .set_dmamode = ich_set_dmamode, -}; - -static struct device_attribute *piix_sidpr_shost_attrs[] = { - &dev_attr_link_power_management_policy, - NULL -}; - -static struct scsi_host_template piix_sidpr_sht = { - ATA_BMDMA_SHT(DRV_NAME), - .shost_attrs = piix_sidpr_shost_attrs, -}; - -static struct ata_port_operations piix_sidpr_sata_ops = { - .inherits = &piix_sata_ops, - .hardreset = sata_std_hardreset, - .scr_read = piix_sidpr_scr_read, - .scr_write = piix_sidpr_scr_write, - .set_lpm = piix_sidpr_set_lpm, -}; - -static struct ata_port_operations efar_pata_ops = { - .inherits = &ata_bmdma_port_ops, - .set_piomode = piix_set_piomode, - .set_dmamode = piix_set_dmamode, - .prereset = piix_pata_prereset, - .cable_detect = efar_pata_cable_detect, -}; - -static struct ata_port_operations it8213_pata_ops = { - .inherits = &ata_bmdma_port_ops, - .set_piomode = piix_set_piomode, - .set_dmamode = ich_set_dmamode, - .prereset = piix_pata_prereset, - .cable_detect = it8213_pata_cable_detect, -}; - -static struct ata_port_operations oldpiix_pata_ops = { - .inherits = &ata_bmdma_port_ops, - .qc_issue = oldpiix_qc_issue, - .cable_detect = ata_cable_40wire, - .set_piomode = piix_set_piomode, - .set_dmamode = piix_set_dmamode, - .prereset = piix_pata_prereset, -}; - -static struct ata_port_operations radisys_pata_ops = { - .inherits = &ata_bmdma_port_ops, - .qc_issue = oldpiix_qc_issue, - .cable_detect = ata_cable_unknown, - .set_piomode = piix_set_piomode, - .set_dmamode = piix_set_dmamode, -}; - +#ifdef CONFIG_ATA_PIIX static const struct piix_map_db ich5_map_db = { .mask = 0x7, .port_enable = 0x3, @@ -553,169 +449,7 @@ static const struct piix_map_db *piix_ma [ich8m_apple_sata] = &ich8m_apple_map_db, [tolapai_sata] = &tolapai_map_db, }; - -static struct ata_port_info piix_port_info[] = { - [piix_pata_mwdma] = /* PIIX3 MWDMA only */ - { - .flags = PIIX_PATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ - .port_ops = &piix_pata_ops, - }, - - [piix_pata_33] = /* PIIX4 at 33MHz */ - { - .flags = PIIX_PATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ - .udma_mask = ATA_UDMA2, - .port_ops = &piix_pata_ops, - }, - - [ich_pata_33] = /* ICH0 - ICH at 33Mhz*/ - { - .flags = PIIX_PATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, /* Check: maybe MWDMA0 is ok */ - .udma_mask = ATA_UDMA2, - .port_ops = &ich_pata_ops, - }, - - [ich_pata_66] = /* ICH controllers up to 66MHz */ - { - .flags = PIIX_PATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, /* MWDMA0 is broken on chip */ - .udma_mask = ATA_UDMA4, - .port_ops = &ich_pata_ops, - }, - - [ich_pata_100] = - { - .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, - .udma_mask = ATA_UDMA5, - .port_ops = &ich_pata_ops, - }, - - [ich_pata_100_nomwdma1] = - { - .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2_ONLY, - .udma_mask = ATA_UDMA5, - .port_ops = &ich_pata_ops, - }, - - [ich5_sata] = - { - .flags = PIIX_SATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - - [ich6_sata] = - { - .flags = PIIX_SATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - - [ich6m_sata] = - { - .flags = PIIX_SATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - - [ich8_sata] = - { - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - - [ich8_2port_sata] = - { - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - - [tolapai_sata] = - { - .flags = PIIX_SATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - - [ich8m_apple_sata] = - { - .flags = PIIX_SATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, - - [piix_pata_vmw] = - { - .flags = PIIX_PATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ - .udma_mask = ATA_UDMA2, - .port_ops = &piix_vmw_ops, - }, - - [efar_pata] = - { - .flags = PIIX_PATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, - .udma_mask = ATA_UDMA4, - .port_ops = &efar_pata_ops, - }, - - [it8213_pata] = - { - .flags = PIIX_PATA_FLAGS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, - .udma_mask = ATA_UDMA6, - .port_ops = &it8213_pata_ops, - }, - - [oldpiix_pata] = - { - .flags = PIIX_PATA_FLAGS | PIIX_FLAG_NO_SITRE, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, - .port_ops = &oldpiix_pata_ops, - }, - - [radisys_pata] = - { - .flags = PIIX_PATA_FLAGS | PIIX_FLAG_NO_SITRE | - PIIX_FLAG_RADISYS, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA12_ONLY, - .udma_mask = ATA_UDMA24_ONLY, - .port_ops = &radisys_pata_ops, - }, -}; +#endif static struct pci_bits piix_enable_bits[] = { { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ @@ -728,6 +462,7 @@ MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, piix_pci_tbl); MODULE_VERSION(DRV_VERSION); +#if defined(CONFIG_ATA_PIIX) || defined(CONFIG_PATA_RDC) struct ich_laptop { u16 device; u16 subvendor; @@ -787,49 +522,12 @@ static int ich_pata_cable_detect(struct } /* check BIOS cable detect results */ - mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; - if ((hpriv->saved_iocfg & mask) == 0) - return ATA_CBL_PATA40; - return ATA_CBL_PATA80; -} - -/** - * efar_pata_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_pata_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; -} - -/** - * it8213_pata_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_pata_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 */ + mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; + if ((hpriv->saved_iocfg & mask) == 0) return ATA_CBL_PATA40; return ATA_CBL_PATA80; } +#endif /** * piix_pata_prereset - prereset for PATA host controller @@ -839,7 +537,8 @@ static int it8213_pata_cable_detect(stru * LOCKING: * None (inherited from caller). */ -static int piix_pata_prereset(struct ata_link *link, unsigned long deadline) +static int __maybe_unused piix_pata_prereset(struct ata_link *link, + unsigned long deadline) { struct ata_port *ap = link->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); @@ -987,7 +686,8 @@ static void piix_set_timings(struct ata_ * None (inherited from caller). */ -static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) +static void __maybe_unused piix_set_piomode(struct ata_port *ap, + struct ata_device *adev) { piix_set_timings(ap, adev, adev->pio_mode - XFER_PIO_0, 0); } @@ -1092,7 +792,8 @@ static void do_pata_set_dmamode(struct a * None (inherited from caller). */ -static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev) +static void __maybe_unused piix_set_dmamode(struct ata_port *ap, + struct ata_device *adev) { do_pata_set_dmamode(ap, adev, 0); } @@ -1108,39 +809,13 @@ static void piix_set_dmamode(struct ata_ * None (inherited from caller). */ -static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev) +static void __maybe_unused ich_set_dmamode(struct ata_port *ap, + struct ata_device *adev) { do_pata_set_dmamode(ap, adev, 1); } -/** - * oldpiix_qc_issue - command issue - * @qc: command pending - * - * Called when the libata layer is about to issue a command. We wrap - * this interface so that we can load the correct ATA timings if - * necessary. Our logic also clears TIME0/TIME1 for the other device so - * that, even if we get this wrong, cycles to the other device will - * be made PIO0. - */ - -static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct ata_device *adev = qc->dev; - - if (adev != ap->private_data) { - /* UDMA timing is not shared */ - if (adev->dma_mode < XFER_UDMA_0) { - if (adev->dma_mode) - piix_set_dmamode(ap, adev); - else if (adev->pio_mode) - piix_set_piomode(ap, adev); - } - } - return ata_bmdma_qc_issue(qc); -} - +#ifdef CONFIG_ATA_PIIX /* * Serial ATA Index/Data Pair Superset Registers access * @@ -1732,8 +1407,253 @@ static bool piix_broken_system_poweroff( return false; } +#else +#define piix_pci_device_suspend ata_pci_device_suspend +#define piix_pci_device_resume ata_pci_device_resume +static inline bool piix_broken_system_poweroff(struct pci_dev *d) { return 0; } +#endif + +static struct scsi_host_template piix_sht = { + ATA_BMDMA_SHT(DRV_NAME), +}; + +#ifdef CONFIG_ATA_PIIX +static struct ata_port_operations piix_sata_ops = { + .inherits = &ata_bmdma32_port_ops, + .sff_irq_check = piix_irq_check, +}; + +static struct ata_port_operations piix_pata_ops = { + .inherits = &piix_sata_ops, + .cable_detect = ata_cable_40wire, + .set_piomode = piix_set_piomode, + .set_dmamode = piix_set_dmamode, + .prereset = piix_pata_prereset, +}; + +static struct ata_port_operations ich_pata_ops = { + .inherits = &piix_pata_ops, + .cable_detect = ich_pata_cable_detect, + .set_dmamode = ich_set_dmamode, +}; + +static struct ata_port_operations piix_vmw_ops = { + .inherits = &piix_pata_ops, + .bmdma_status = piix_vmw_bmdma_status, +}; + +static struct device_attribute *piix_sidpr_shost_attrs[] = { + &dev_attr_link_power_management_policy, + NULL +}; + +static struct scsi_host_template piix_sidpr_sht = { + ATA_BMDMA_SHT(DRV_NAME), + .shost_attrs = piix_sidpr_shost_attrs, +}; + +static struct ata_port_operations piix_sidpr_sata_ops = { + .inherits = &piix_sata_ops, + .hardreset = sata_std_hardreset, + .scr_read = piix_sidpr_scr_read, + .scr_write = piix_sidpr_scr_write, + .set_lpm = piix_sidpr_set_lpm, +}; +#endif + +#include "ata_piix_efar.h" +#include "ata_piix_it8213.h" +#include "ata_piix_oldpiix.h" /* covers Radisys */ +#ifdef CONFIG_PATA_RDC +static struct ata_port_operations rdc_pata_ops = { + .inherits = &ata_bmdma32_port_ops, + .cable_detect = ich_pata_cable_detect, + .set_piomode = piix_set_piomode, + .set_dmamode = ich_set_dmamode, + .prereset = piix_pata_prereset, +}; +#endif + +static struct ata_port_info piix_port_info[] = { +#ifdef CONFIG_ATA_PIIX + [piix_pata_mwdma] = /* PIIX3 MWDMA only */ + { + .flags = PIIX_PATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ + .port_ops = &piix_pata_ops, + }, + + [piix_pata_33] = /* PIIX4 at 33MHz */ + { + .flags = PIIX_PATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ + .udma_mask = ATA_UDMA2, + .port_ops = &piix_pata_ops, + }, + + [ich_pata_33] = /* ICH0 - ICH at 33Mhz*/ + { + .flags = PIIX_PATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, /* Check: maybe MWDMA0 is ok */ + .udma_mask = ATA_UDMA2, + .port_ops = &ich_pata_ops, + }, + + [ich_pata_66] = /* ICH controllers up to 66MHz */ + { + .flags = PIIX_PATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, /* MWDMA0 is broken on chip */ + .udma_mask = ATA_UDMA4, + .port_ops = &ich_pata_ops, + }, + + [ich_pata_100] = + { + .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, + .udma_mask = ATA_UDMA5, + .port_ops = &ich_pata_ops, + }, + + [ich_pata_100_nomwdma1] = + { + .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2_ONLY, + .udma_mask = ATA_UDMA5, + .port_ops = &ich_pata_ops, + }, + + [ich5_sata] = + { + .flags = PIIX_SATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + + [ich6_sata] = + { + .flags = PIIX_SATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + + [ich6m_sata] = + { + .flags = PIIX_SATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + + [ich8_sata] = + { + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + + [ich8_2port_sata] = + { + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + + [tolapai_sata] = + { + .flags = PIIX_SATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + + [ich8m_apple_sata] = + { + .flags = PIIX_SATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + + [piix_pata_vmw] = + { + .flags = PIIX_PATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ + .udma_mask = ATA_UDMA2, + .port_ops = &piix_vmw_ops, + }, +#endif +#ifdef CONFIG_PATA_EFAR + [efar_pata] = + { + .flags = PIIX_PATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, + .udma_mask = ATA_UDMA4, + .port_ops = &efar_pata_ops, + }, +#endif +#ifdef CONFIG_PATA_IT8213 + [it8213_pata] = + { + .flags = PIIX_PATA_FLAGS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, + .udma_mask = ATA_UDMA6, + .port_ops = &it8213_pata_ops, + }, +#endif +#ifdef CONFIG_PATA_OLDPIIX + [oldpiix_pata] = + { + .flags = PIIX_PATA_FLAGS | PIIX_FLAG_NO_SITRE, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, + .port_ops = &oldpiix_pata_ops, + }, +#endif +#ifdef CONFIG_PATA_RADISYS + [radisys_pata] = + { + .flags = PIIX_PATA_FLAGS | PIIX_FLAG_NO_SITRE | + PIIX_FLAG_RADISYS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, + .udma_mask = ATA_UDMA24_ONLY, + .port_ops = &radisys_pata_ops, + }, +#endif +#ifdef CONFIG_PATA_RDC + [rdc_pata] = + { + .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA12_ONLY, + .udma_mask = ATA_UDMA5, + .port_ops = &rdc_pata_ops, + }, +#endif +}; -static int all_piixalikes; /* claim all PIIX-alike devices */ +static int all_piixalikes = 1; /* claim all PIIX-alike devices */ /** * piix_init_one - Register PIIX ATA PCI device with kernel services @@ -1810,7 +1730,7 @@ static int __devinit piix_init_one(struc if (pdev->vendor == PCI_VENDOR_ID_INTEL || pdev->vendor == PCI_VENDOR_ID_RDC) pci_read_config_dword(pdev, PIIX_IOCFG, &hpriv->saved_iocfg); - +#ifdef CONFIG_ATA_PIIX /* ICH6R may be driven by either ata_piix or ahci driver * regardless of BIOS configuration. Make sure AHCI mode is * off. @@ -1825,12 +1745,12 @@ static int __devinit piix_init_one(struc if (port_flags & ATA_FLAG_SATA) hpriv->map = piix_init_sata_map(pdev, port_info, piix_map_db_table[idx]); - +#endif rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); if (rc) return rc; host->private_data = hpriv; - +#ifdef CONFIG_ATA_PIIX /* initialize controller */ if (port_flags & ATA_FLAG_SATA) { piix_init_pcs(host, piix_map_db_table[idx]); @@ -1862,6 +1782,7 @@ static int __devinit piix_init_one(struc host->ports[1]->mwdma_mask = 0; host->ports[1]->udma_mask = 0; } +#endif host->flags |= ATA_HOST_PARALLEL_SCAN; pci_set_master(pdev); @@ -1880,6 +1801,17 @@ static void piix_remove_one(struct pci_d ata_pci_remove_one(pdev); } +static struct pci_driver piix_pci_driver = { + .name = DRV_NAME, + .id_table = piix_pci_tbl, + .probe = piix_init_one, + .remove = piix_remove_one, +#ifdef CONFIG_PM + .suspend = piix_pci_device_suspend, + .resume = piix_pci_device_resume, +#endif +}; + static int __init piix_init(void) { int rc; Index: b/drivers/ata/ata_piix_efar.h =================================================================== --- /dev/null +++ b/drivers/ata/ata_piix_efar.h @@ -0,0 +1,28 @@ +#ifdef CONFIG_PATA_EFAR +/** + * efar_pata_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_pata_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; +} + +static struct ata_port_operations efar_pata_ops = { + .inherits = &ata_bmdma_port_ops, + .set_piomode = piix_set_piomode, + .set_dmamode = piix_set_dmamode, + .prereset = piix_pata_prereset, + .cable_detect = efar_pata_cable_detect, +}; +#endif Index: b/drivers/ata/ata_piix_it8213.h =================================================================== --- /dev/null +++ b/drivers/ata/ata_piix_it8213.h @@ -0,0 +1,28 @@ +#ifdef CONFIG_PATA_IT8213 +/** + * it8213_pata_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_pata_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; +} + +static struct ata_port_operations it8213_pata_ops = { + .inherits = &ata_bmdma_port_ops, + .set_piomode = piix_set_piomode, + .set_dmamode = ich_set_dmamode, + .prereset = piix_pata_prereset, + .cable_detect = it8213_pata_cable_detect, +}; +#endif Index: b/drivers/ata/ata_piix_oldpiix.h =================================================================== --- /dev/null +++ b/drivers/ata/ata_piix_oldpiix.h @@ -0,0 +1,49 @@ +#if defined(CONFIG_PATA_OLDPIIX) || defined(CONFIG_PATA_RADISYS) +/** + * oldpiix_qc_issue - command issue + * @qc: command pending + * + * Called when the libata layer is about to issue a command. We wrap + * this interface so that we can load the correct ATA timings if + * necessary. Our logic also clears TIME0/TIME1 for the other device so + * that, even if we get this wrong, cycles to the other device will + * be made PIO0. + */ + +static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ata_device *adev = qc->dev; + + if (adev != ap->private_data) { + /* UDMA timing is not shared */ + if (adev->dma_mode < XFER_UDMA_0) { + if (adev->dma_mode) + piix_set_dmamode(ap, adev); + else if (adev->pio_mode) + piix_set_piomode(ap, adev); + } + } + return ata_bmdma_qc_issue(qc); +} +#endif + +#ifdef CONFIG_PATA_OLDPIIX +static struct ata_port_operations oldpiix_pata_ops = { + .inherits = &ata_bmdma_port_ops, + .qc_issue = oldpiix_qc_issue, + .cable_detect = ata_cable_40wire, + .set_piomode = piix_set_piomode, + .set_dmamode = piix_set_dmamode, + .prereset = piix_pata_prereset, +}; +#endif +#ifdef CONFIG_PATA_RADISYS +static struct ata_port_operations radisys_pata_ops = { + .inherits = &ata_bmdma_port_ops, + .qc_issue = oldpiix_qc_issue, + .cable_detect = ata_cable_unknown, + .set_piomode = piix_set_piomode, + .set_dmamode = piix_set_dmamode, +}; +#endif -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html