Re: [PATCH 13/15] ide: fix UDMA/MWDMA/SWDMA masks
Hello. Bartlomiej Zolnierkiewicz wrote: [PATCH] ide: fix UDMA/MWDMA/SWDMA masks * use 0x00 instead of 0x80 to disable -{ultra,mwdma,swdma}_mask * add udma_mask field to ide_pci_device_t and use it to initialize -ultra_mask in aec62xx, cmd64x, pdc202xx_{new,old} and piix drivers * fix UDMA masks to match with chipset specific *_ratemask() (alim15x3, hpt366, serverworks and siimage drivers need UDMA mask filtering method - done in the next patch) v2: * piix: fix cable detection for 82801AA_1 and 82372FB_1 [ Noticed by Sergei Shtylyov [EMAIL PROTECTED]. ] * cmd64x: use hwif-cds-udma_mask [ Suggested by Sergei Shtylyov [EMAIL PROTECTED]. ] * aec62xx: fix newly introduced bug - check DMA status not command register [ Noticed by Sergei Shtylyov [EMAIL PROTECTED]. ] v3: * piix: use hwif-cds-udma_mask [ Suggested by Sergei Shtylyov [EMAIL PROTECTED]. ] Index: b/drivers/ide/pci/aec62xx.c === --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -270,11 +270,13 @@ static unsigned int __devinit init_chips static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) { + struct pci_dev *dev = hwif-pci_dev; + hwif-autodma = 0; hwif-tuneproc = aec62xx_tune_drive; hwif-speedproc = aec62xx_tune_chipset; - if (hwif-pci_dev-device == PCI_DEVICE_ID_ARTOP_ATP850UF) + if (dev-device == PCI_DEVICE_ID_ARTOP_ATP850UF) hwif-serialized = hwif-channel; if (hwif-mate) @@ -286,7 +288,15 @@ static void __devinit init_hwif_aec62xx( return; } - hwif-ultra_mask = 0x7f; + hwif-ultra_mask = hwif-cds-udma_mask; + + /* atp865 and atp865r */ + if (hwif-ultra_mask == 0x3f) { + /* check bit 0x10 of DMA status register */ + if (inb(pci_resource_start(dev, 4) + 2) 0x10) + hwif-ultra_mask = 0x7f; /* udma0-6 */ + } + IMO, this asks to be put into init_setup_aec6x80() instead but since I'm already cleaning up that function, I'll move it there myself. MBR, Sergei - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] pata_amd: remove contamination added during cable_detect conversion
This is added by added by cff63dfceb52c564fe1ba5394d50ab7d599a11b9 - pata: cable methods. Signed-off-by: Tejun Heo [EMAIL PROTECTED] Cc: Alan Cox [EMAIL PROTECTED] --- drivers/ata/pata_amd.c |5 - 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 5a77e4e..536ee89 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -639,11 +639,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (type == 1 rev 0x7) type = 2; -#if defined(CONFIG_ATA_ACPI) - /* Prefer the ACPI driver for Nvidia hardware */ - if (pdev-vendor == PCI_VENDOR_ID_NVIDIA ata_pata_acpi_present(pdev)) - return -ENODEV; -#endif /* Check for AMD7411 */ if (type == 3) /* FIFO is broken */ -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] libata: add missing call to -cable_detect() in new EH path
-cable_detect() used to be called on by the old ata_bus_probe() path. Add invocation to ata_eh_revalidate_and_attach() right after IDENTIFYs are done. Signed-off-by: Tejun Heo [EMAIL PROTECTED] Cc: Alan Cox [EMAIL PROTECTED] --- drivers/ata/libata-eh.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 0dbee55..67bf150 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1810,6 +1810,10 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, } } + /* 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); + /* Configure new devices forward such that user doesn't see * device detection messages backwards. */ -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] libata-acpi: fix _GTF command protocol for ATAPI devices
_GTF command is never ATA_PROT_ATAPI_NODATA whether the device is ATAPI or not. It's always ATA_PROT_NODATA. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-acpi.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 03a0acf..cb3eab6 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -489,8 +489,7 @@ static void taskfile_load_raw(struct ata_port *ap, /* 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.protocol = ATA_PROT_NODATA; tf.feature = gtf-tfa[0]; /* 0x1f1 */ tf.nsect = gtf-tfa[1]; /* 0x1f2 */ tf.lbal= gtf-tfa[2]; /* 0x1f3 */ -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] libata-acpi: fix _GTF command protocol for ATAPI devices
On Mon, 23 Apr 2007 02:06:46 +0900 Tejun Heo [EMAIL PROTECTED] wrote: _GTF command is never ATA_PROT_ATAPI_NODATA whether the device is ATAPI or not. It's always ATA_PROT_NODATA. Signed-off-by: Tejun Heo [EMAIL PROTECTED] Acked-by: Alan Cox [EMAIL PROTECTED] - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] libata: add missing call to -cable_detect() in new EH path
On Mon, 23 Apr 2007 02:05:53 +0900 Tejun Heo [EMAIL PROTECTED] wrote: -cable_detect() used to be called on by the old ata_bus_probe() path. Add invocation to ata_eh_revalidate_and_attach() right after IDENTIFYs are done. Signed-off-by: Tejun Heo [EMAIL PROTECTED] Cc: Alan Cox [EMAIL PROTECTED] Acked-by: Alan Cox [EMAIL PROTECTED] I need to push the if the drive is SATA the cable is SATA patch once all this has settled too. - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] pata_amd: remove contamination added during cable_detect conversion
On Mon, 23 Apr 2007 02:04:38 +0900 Tejun Heo [EMAIL PROTECTED] wrote: This is added by added by cff63dfceb52c564fe1ba5394d50ab7d599a11b9 - pata: cable methods. The Cable method fix for the Nvidia hardware if ACPI drivers are present and usable is to use the ACPI driver, so its not a contamination its a fix for the fact the Nvidia code can't do cable detect any other way - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/13] ahci: consolidate common port flags
Consolidate common port flags into AHCI_FLAG_COMMON. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/ahci.c | 29 ++--- 1 files changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 7c61bc7..34c5534 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -170,6 +170,10 @@ enum { 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 { @@ -323,54 +327,41 @@ static const struct ata_port_operations ahci_vt8251_ops = { static const struct ata_port_info ahci_port_info[] = { /* board_ahci */ { - .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 */ { - .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 */ { - .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 */ { - .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 */ { - .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 | AHCI_FLAG_IGN_SERR_INTERNAL, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = ahci_ops, }, - }; static const struct pci_device_id ahci_pci_tbl[] = { -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/13] libata: separate ATA_EHI_DID_RESET into DID_SOFTRESET and DID_HARDRESET
Separate ATA_EHI_DID_RESET into ATA_EHI_DID_SOFTRESET and ATA_EHI_DID_HARDRESET. ATA_EHI_DID_RESET is redefined as OR of the two flags. This patch doesn't introduce any behavior change. This will be used later to determine whether _SDD is necessary or not. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-eh.c |5 - include/linux/libata.h | 10 ++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 67bf150..2bff9ad 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1671,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); diff --git a/include/linux/libata.h b/include/linux/libata.h index 73b86dd..d8cfc72 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -282,11 +282,13 @@ enum { ATA_EHI_NO_AUTOPSY = (1 2), /* no autopsy */ ATA_EHI_QUIET = (1 3), /* be quiet */ - ATA_EHI_DID_RESET = (1 16), /* already reset this port */ - ATA_EHI_PRINTINFO = (1 17), /* print configuration info */ - ATA_EHI_SETMODE = (1 18), /* configure transfer mode */ - ATA_EHI_POST_SETMODE= (1 19), /* revaildating after setmode */ + ATA_EHI_DID_SOFTRESET = (1 16), /* already soft-reset this port */ + ATA_EHI_DID_HARDRESET = (1 17), /* already soft-reset this port */ + ATA_EHI_PRINTINFO = (1 18), /* print configuration info */ + ATA_EHI_SETMODE = (1 19), /* configure transfer mode */ + ATA_EHI_POST_SETMODE= (1 20), /* revaildating after setmode */ + ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET, ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK, /* max repeat if error condition is still set after -error_handler */ -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/13] libata: separate out ata_dev_reread_id()
Separate out ata_dev_reread_id() from ata_dev_revalidate(). ata_dev_reread_id() reads IDENTIFY page and determines whether the same device is still there. ata_dev_revalidate() reconfigures after reread completes. This will be used by ACPI update. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-core.c | 47 drivers/ata/libata.h |3 +- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 6d0a946..7a6e8fd 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3562,8 +3562,8 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, } /** - * ata_dev_revalidate - Revalidate ATA device - * @dev: device to revalidate + * ata_dev_reread_id - Re-read IDENTIFY data + * @adev: target ATA device * @readid_flags: read ID flags * * Re-read IDENTIFY page and make sure @dev is still attached to @@ -3575,29 +3575,50 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, * RETURNS: * 0 on success, negative errno otherwise */ -int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags) +int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags) { unsigned int class = dev-class; u16 *id = (void *)dev-ap-sector_buf; int rc; - if (!ata_dev_enabled(dev)) { - rc = -ENODEV; - goto fail; - } - /* read ID data */ rc = ata_dev_read_id(dev, class, readid_flags, id); if (rc) - goto fail; + return rc; /* is the device still there? */ - if (!ata_dev_same_device(dev, class, id)) { - rc = -ENODEV; - goto fail; - } + if (!ata_dev_same_device(dev, class, id)) + return -ENODEV; memcpy(dev-id, id, sizeof(id[0]) * ATA_ID_WORDS); + return 0; +} + +/** + * ata_dev_revalidate - Revalidate ATA device + * @dev: device to revalidate + * @readid_flags: read ID flags + * + * Re-read IDENTIFY page, make sure @dev is still attached to the + * port and reconfigure it according to the new IDENTIFY page. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, negative errno otherwise + */ +int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags) +{ + int rc; + + if (!ata_dev_enabled(dev)) + return -ENODEV; + + /* re-read ID */ + rc = ata_dev_reread_id(dev, readid_flags); + if (rc) + goto fail; /* configure device according to the new ID */ rc = ata_dev_configure(dev); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 5f4d40c..c40665a 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -75,7 +75,8 @@ extern unsigned ata_exec_internal_sg(struct ata_device *dev, extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, unsigned int flags, u16 *id); -extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags); +extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags); +extern int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_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); -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHSET] libata: improve ATA ACPI support
Hello, all. This patchset improves ATA ACPI support as proposed in the following message. http://article.gmane.org/gmane.linux.ide/17554 Improvements are... * safe and simpler ACPI node association * major code cleanup * invoke ACPI methods only when ACPI spec says necessary * proper ACPI error handling with a retry * after successfully executing _GTF taskfiles, IDENTIFY page is reloaded * _GTM/_STM support This patchset is composed of 13 patches. #01-02 : misc preparation #03-04 : separate out ata_dev_reread_id() and make revalidation robust against size change during device configuration #05-06 : clean up libata-acpi.c #07-08 : implement ata_acpi_associate() #09-10 : more cleanups #11-13 : reimplement ACPI invocation so that methods are called where the spec specifies and errors are properly handled, and add _GTM/_STM support. Tested on three desktop boards (nf ultra, ich7 and ich8) and a notebook. This patchset is against... upstream (5365067b4bb17d1801fefe995d1342108b324471) + [1] pata_amd-remove-contamination + [2] libata-add-missing-call-to-cable_detect-in-new-EH + [3] libata-acpi-fix-GTF-command-protocol-for-ATAPI Thanks. -- tejun [1] http://article.gmane.org/gmane.linux.ide/18120 [2] http://article.gmane.org/gmane.linux.ide/18121 [3] http://article.gmane.org/gmane.linux.ide/18122 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/13] libata: during revalidation, check n_sectors after device is configured
Device might be resized during ata_dev_configure() due to HPA or (later) ACPI _GTF. Currently it's worked around by caching n_sectors before turning off HPA. The cached original size is overwritten if the device is reconfigured without being hardreset - which always happens after configuring trasnfer mode. If the device gets hardreset for some reason after that, revalidation fails with -ENODEV. This patch makes size checking more robust by moving n_sectors check from ata_dev_reread_id() to ata_dev_revalidate() after the device is fully configured. No matter what happens during configuration, a device must have the same n_sectors after fully configured to be treated as the same device. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-core.c | 33 +++-- include/linux/libata.h|1 - 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7a6e8fd..2171af6 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1862,7 +1862,6 @@ int ata_dev_configure(struct ata_device *dev) 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, @@ -3519,7 +3518,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, const u16 *old_id = dev-id; unsigned char model[2][ATA_ID_PROD_LEN + 1]; unsigned char serial[2][ATA_ID_SERNO_LEN + 1]; - u64 new_n_sectors; if (dev-class != new_class) { ata_dev_printk(dev, KERN_INFO, class mismatch %d != %d\n, @@ -3531,7 +3529,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1])); ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0])); ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1])); - new_n_sectors = ata_id_n_sectors(new_id); if (strcmp(model[0], model[1])) { ata_dev_printk(dev, KERN_INFO, model number mismatch @@ -3545,19 +3542,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, return 0; } - if (dev-class == ATA_DEV_ATA dev-n_sectors != new_n_sectors) { - ata_dev_printk(dev, KERN_INFO, n_sectors mismatch - %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; - } - return 1; } @@ -3610,6 +3594,7 @@ int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags) */ int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags) { + u64 n_sectors = dev-n_sectors; int rc; if (!ata_dev_enabled(dev)) @@ -3622,8 +3607,20 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags) /* configure device according to the new ID */ rc = ata_dev_configure(dev); - if (rc == 0) - return 0; + if (rc) + goto fail; + + /* verify n_sectors hasn't changed */ + if (dev-class == ATA_DEV_ATA dev-n_sectors != n_sectors) { + ata_dev_printk(dev, KERN_INFO, n_sectors mismatch + %llu != %llu\n, + (unsigned long long)n_sectors, + (unsigned long long)dev-n_sectors); + rc = -ENODEV; + goto fail; + } + + return 0; fail: ata_dev_printk(dev, KERN_ERR, revalidation failed (errno=%d)\n, rc); diff --git a/include/linux/libata.h b/include/linux/libata.h index d8cfc72..3cffbf6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -448,7 +448,6 @@ struct ata_device { struct scsi_device *sdev; /* attached SCSI device */ /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ u64 n_sectors; /* size of device, if ATA */ - u64 n_sectors_boot; /* size of ATA device at startup */ unsigned intclass; /* ATA_DEV_xxx */ u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ u8 pio_mode; -- 1.5.0.3 - To unsubscribe from this
[PATCH 07/13] libata-acpi: add ATA_FLAG_ACPI_SATA port flag
Whether a controller needs IDE or SATA ACPI hierarchy is determined by the programming interface of the controller not by whether the controller is SATA or PATA, or it supports slave device or not. This patch adds ATA_FLAG_ACPI_SATA port flags which tells libata-acpi that the port needs SATA ACPI nodes, and sets the flag for ahci and sata_sil24. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/ahci.c|3 ++- drivers/ata/libata-acpi.c | 10 +- drivers/ata/sata_sil24.c |3 ++- include/linux/libata.h|1 + 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 34c5534..7f739e8 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -173,7 +173,8 @@ enum { AHCI_FLAG_COMMON= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_SKIP_D2H_BSY, + ATA_FLAG_SKIP_D2H_BSY | + ATA_FLAG_ACPI_SATA, }; struct ahci_cmd_hdr { diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index f005730..24c2198 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -321,7 +321,7 @@ static int do_drive_get_GTF(struct ata_device *adev, unsigned int *gtf_length, /* Don't continue if device has no _ADR method. * _GTF is intended for known motherboard devices. */ - if (!(ap-cbl == ATA_CBL_SATA)) { + if (!(ap-flags ATA_FLAG_ACPI_SATA)) { err = pata_get_dev_handle(dev, dev_handle, pcidevfn); if (err 0) { if (ata_msg_probe(ap)) @@ -343,7 +343,7 @@ static int do_drive_get_GTF(struct ata_device *adev, unsigned int *gtf_length, /* Get this drive's _ADR info. if not already known. */ if (!adev-obj_handle) { - if (!(ap-cbl == ATA_CBL_SATA)) { + if (!(ap-flags ATA_FLAG_ACPI_SATA)) { /* get child objects of dev_handle == channel objects, * + _their_ children == drive objects */ /* channel is ap-port_no */ @@ -528,7 +528,7 @@ static int do_drive_set_taskfiles(struct ata_device *adev, ata_dev_printk(adev, KERN_DEBUG, %s: ENTER: port#: %d\n, __FUNCTION__, ap-port_no); - if (libata_noacpi || !(ap-cbl == ATA_CBL_SATA)) + if (libata_noacpi || !(ap-flags ATA_FLAG_ACPI_SATA)) return 0; if (!ata_dev_enabled(adev) || (ap-flags ATA_FLAG_DISABLED)) @@ -578,7 +578,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap) * we should not run GTF on PATA devices since some * PATA require execution of GTM/STM before GTF. */ - if (!(ap-cbl == ATA_CBL_SATA)) + if (!(ap-flags ATA_FLAG_ACPI_SATA)) return 0; for (ix = 0; ix ATA_MAX_DEVICES; ix++) { @@ -641,7 +641,7 @@ int ata_acpi_push_id(struct ata_device *adev) __FUNCTION__, adev-devno, ap-port_no); /* Don't continue if not a SATA device. */ - if (!(ap-cbl == ATA_CBL_SATA)) { + if (!(ap-flags ATA_FLAG_ACPI_SATA)) { if (ata_msg_probe(ap)) ata_dev_printk(adev, KERN_DEBUG, %s: Not a SATA device\n, __FUNCTION__); diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index e6223ba..a499369 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -237,7 +237,8 @@ enum { /* host flags */ SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY, + ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY | + ATA_FLAG_ACPI_SATA, SIL24_FLAG_PCIX_IRQ_WOC = (1 24), /* IRQ loss errata on PCI-X */ IRQ_STAT_4PORTS = 0xf, diff --git a/include/linux/libata.h b/include/linux/libata.h index 8a577c2..a26bb7f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -174,6 +174,7 @@ enum { ATA_FLAG_SETXFER_POLLING= (1 14), /* use polling for SETXFER */ ATA_FLAG_IGN_SIMPLEX= (1 15), /* ignore SIMPLEX */ ATA_FLAG_NO_IORDY = (1 16), /* controller lacks iordy */ + ATA_FLAG_ACPI_SATA = (1 17), /* need native SATA ACPI layout */ /* The following flag belongs to ap-pflags but is kept in * ap-flags because it's referenced in many LLDs and will be -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/13] libata-acpi: miscellaneous cleanups
* Add missing LOCKING: and RETURNS: to function comment. * Don't conditionalize warning messages with ata_msg_probe(). Print directly with KERN_WARNING. * Drop duplicate debug messages. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-acpi.c | 51 1 files changed, 23 insertions(+), 28 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 21aad07..2750c36 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -174,21 +174,17 @@ static int do_drive_get_GTF(struct ata_device *adev, struct ata_acpi_gtf **gtf, out_obj = output.pointer; if (out_obj-type != ACPI_TYPE_BUFFER) { - if (ata_msg_probe(ap)) - ata_dev_printk(adev, KERN_DEBUG, %s: Run _GTF: - error: expected object type of -ACPI_TYPE_BUFFER, got 0x%x\n, - __FUNCTION__, out_obj-type); + ata_dev_printk(adev, KERN_WARNING, + _GTF unexpected object type 0x%x\n, + out_obj-type); rc = -EINVAL; goto out_free; } if (out_obj-buffer.length % REGS_PER_GTF) { - if (ata_msg_drv(ap)) - ata_dev_printk(adev, KERN_ERR, - %s: unexpected GTF length (%d) or addr (0x%p)\n, - __FUNCTION__, out_obj-buffer.length, - out_obj-buffer.pointer); + ata_dev_printk(adev, KERN_WARNING, + unexpected _GTF length (%d)\n, + out_obj-buffer.length); rc = -EINVAL; goto out_free; } @@ -319,6 +315,12 @@ static int do_drive_set_taskfiles(struct ata_device *adev, * @ap: the ata_port for the drive * * This applies to both PATA and SATA drives. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. */ int ata_acpi_exec_tfs(struct ata_port *ap) { @@ -344,24 +346,14 @@ int ata_acpi_exec_tfs(struct ata_port *ap) ret = do_drive_get_GTF(adev, gtf, ptr_to_free); if (ret == 0) continue; - if (ret 0) { - if (ata_msg_probe(ap)) - ata_port_printk(ap, KERN_DEBUG, - %s: get_GTF error (%d)\n, - __FUNCTION__, ret); + if (ret 0) break; - } gtf_count = ret; ret = do_drive_set_taskfiles(adev, gtf, gtf_count); kfree(ptr_to_free); - if (ret 0) { - if (ata_msg_probe(ap)) - ata_port_printk(ap, KERN_DEBUG, - %s: set_taskfiles error (%d)\n, - __FUNCTION__, ret); + if (ret 0) break; - } } return ret; @@ -376,6 +368,12 @@ int ata_acpi_exec_tfs(struct ata_port *ap) * 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. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. */ int ata_acpi_push_id(struct ata_device *adev) { @@ -415,12 +413,9 @@ int ata_acpi_push_id(struct ata_device *adev) swap_buf_le16(adev-id, ATA_ID_WORDS); err = ACPI_FAILURE(status) ? -EIO : 0; - if (err 0) { - if (ata_msg_probe(ap)) - ata_dev_printk(adev, KERN_DEBUG, - %s _SDD error: status = 0x%x\n, - __FUNCTION__, status); - } + if (err 0) + ata_dev_printk(adev, KERN_WARNING, + ACPI _SDD failed (AE 0x%x)\n, status); /* always return success */ out: -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/13] libata-acpi: s/CONFIG_SATA_ACPI/CONFIG_ATA_ACPI/
ACPI applies to both SATA and PATA. Drop the 'S' from the config variable. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/Kconfig| 26 +- drivers/ata/Makefile |2 +- drivers/ata/libata.h |2 +- include/linux/libata.h |2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 365c306..6ee8f42 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -23,6 +23,19 @@ config ATA_NONSTANDARD bool default n +config ATA_ACPI + bool + depends on ACPI PCI + default y + help + This option adds support for ATA-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 SATA_AHCI tristate AHCI SATA support depends on PCI @@ -156,19 +169,6 @@ config SATA_INIC162X help This option enables support for Initio 162x Serial ATA. -config SATA_ACPI - bool - 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) depends on PCI EXPERIMENTAL diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index b7055e3..f9e53c1 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -68,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 +libata-$(CONFIG_ATA_ACPI) += libata-acpi.o diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index c40665a..122bc16 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -97,7 +97,7 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); extern struct ata_port *ata_port_alloc(struct ata_host *host); /* libata-acpi.c */ -#ifdef CONFIG_SATA_ACPI +#ifdef CONFIG_ATA_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 diff --git a/include/linux/libata.h b/include/linux/libata.h index 3cffbf6..8a577c2 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -474,7 +474,7 @@ struct ata_device { struct ata_eringering; int spdn_cnt; unsigned inthorkage;/* List of broken features */ -#ifdef CONFIG_SATA_ACPI +#ifdef CONFIG_ATA_ACPI /* ACPI objects info */ acpi_handle obj_handle; #endif -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/13] libata: reimplement ACPI invocation
This patch reimplements ACPI invocation such that, instead of exporting ACPI details to the rest of libata, ACPI event handlers - ata_acpi_on_resume() and ata_acpi_on_devcfg() - are used. These two functions are responsible for determining whether specific ACPI method is used and when. On resume, _GTF is scheduled by setting ATA_DFLAG_ACPI_PENDING device flag. This is done this way to avoid performing the action on wrong device device (device swapping while suspended). On every ata_dev_configure(), ata_acpi_on_devcfg() is called, which performs _SDD and _GTF. _GTF is performed only after resuming and, if SATA, hardreset as the ACPI spec specifies. As _GTF may contain arbitrary commands, IDENTIFY page is re-read after _GTF taskfiles are executed. If one of ACPI methods fails, ata_acpi_on_devcfg() retries on the first failure. If it fails again on the second try, ACPI is disabled on the device. Note that successful configuration clears ACPI failed status. With all feature checks moved to the above two functions, do_drive_set_taskfiles() is trivial and thus collapsed into ata_acpi_exec_tfs(), which is now static and converted to return the number of executed taskfiles to be used by ata_acpi_on_resume(). As failures are handled properly, ata_acpi_push_id() now returns -errno on errors instead of unconditional zero. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-acpi.c | 204 +++- drivers/ata/libata-core.c | 16 ++-- drivers/ata/libata-eh.c |3 + drivers/ata/libata.h | 14 +-- include/linux/libata.h|2 + 5 files changed, 140 insertions(+), 99 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 2750c36..63b77b9 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -272,91 +272,47 @@ static int taskfile_load_raw(struct ata_device *adev, } /** - * do_drive_set_taskfiles - write the drive taskfile settings from _GTF - * @adev: target ATA device - * @gtf: pointer to array of _GTF taskfiles to execute - * @gtf_count: number of taskfiles - * - * This applies to both PATA and SATA drives. - * - * Execute taskfiles in @gtf. - * - * LOCKING: - * EH context. - * - * RETURNS: - * 0 on success, -errno on failure. - */ -static int do_drive_set_taskfiles(struct ata_device *adev, - struct ata_acpi_gtf *gtf, int gtf_count) -{ - struct ata_port *ap = adev-ap; - int ix; - - if (ata_msg_probe(ap)) - ata_dev_printk(adev, KERN_DEBUG, %s: ENTER: port#: %d\n, - __FUNCTION__, ap-port_no); - - if (!(ap-flags ATA_FLAG_ACPI_SATA)) - return 0; - - if (!ata_dev_enabled(adev) || (ap-flags ATA_FLAG_DISABLED)) - return -ENODEV; - - /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ - for (ix = 0; ix gtf_count; ix++) -taskfile_load_raw(adev, gtf++); - - return 0; -} - -/** * ata_acpi_exec_tfs - get then write drive taskfile settings - * @ap: the ata_port for the drive + * @adev: target ATA device * - * This applies to both PATA and SATA drives. + * Evaluate _GTF and excute returned taskfiles. * * LOCKING: * EH context. * * RETURNS: - * 0 on success, -errno on failure. + * Number of executed taskfiles on success, 0 if _GTF doesn't exist or + * doesn't contain valid data. -errno on other errors. */ -int ata_acpi_exec_tfs(struct ata_port *ap) +static int ata_acpi_exec_tfs(struct ata_device *adev) { - int ix, ret = 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-flags ATA_FLAG_ACPI_SATA)) - return 0; - - for (ix = 0; ix ATA_MAX_DEVICES; ix++) { - struct ata_device *adev = ap-device[ix]; - struct ata_acpi_gtf *gtf = NULL; - int gtf_count; - void *ptr_to_free = NULL; - - if (!ata_dev_enabled(adev)) - continue; - - ret = do_drive_get_GTF(adev, gtf, ptr_to_free); - if (ret == 0) - continue; - if (ret 0) - break; - gtf_count = ret; - - ret = do_drive_set_taskfiles(adev, gtf, gtf_count); - kfree(ptr_to_free); - if (ret 0) - break; + struct ata_acpi_gtf *gtf = NULL; + void *ptr_to_free = NULL; + int gtf_count, i, rc; + + /* get taskfiles */ + rc = do_drive_get_GTF(adev, gtf, ptr_to_free); + if (rc 0) + return rc; + gtf_count = rc; + + /* execute them */ + for (i = 0, rc = 0; i gtf_count; i++) { + int tmp; + + /* ACPI errors are eventually ignored. Run till the +
[PATCH 12/13] libata-acpi: remove redundant checks
Remove remaining unnecessary feature and status checks. Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-acpi.c | 23 --- 1 files changed, 0 insertions(+), 23 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 63b77b9..0ba0e79 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -134,22 +134,10 @@ static int do_drive_get_GTF(struct ata_device *adev, struct ata_acpi_gtf **gtf, output.length = ACPI_ALLOCATE_BUFFER; output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ - if (!adev-acpi_handle) - goto out_free; - if (ata_msg_probe(ap)) ata_dev_printk(adev, KERN_DEBUG, %s: ENTER: port#: %d\n, __FUNCTION__, ap-port_no); - if (!ata_dev_enabled(adev) || (ap-flags ATA_FLAG_DISABLED)) { - if (ata_msg_probe(ap)) - ata_dev_printk(adev, KERN_DEBUG, %s: ERR: - ata_dev_present: %d, PORT_DISABLED: %lu\n, - __FUNCTION__, ata_dev_enabled(adev), - ap-flags ATA_FLAG_DISABLED); - goto out_free; - } - /* _GTF has no input parameters */ status = acpi_evaluate_object(adev-acpi_handle, _GTF, NULL, output); if (ACPI_FAILURE(status)) { @@ -339,21 +327,10 @@ static int ata_acpi_push_id(struct ata_device *adev) struct acpi_object_list input; union acpi_object in_params[1]; - if (!adev-acpi_handle) - return 0; - if (ata_msg_probe(ap)) ata_dev_printk(adev, KERN_DEBUG, %s: ix = %d, port#: %d\n, __FUNCTION__, adev-devno, ap-port_no); - /* Don't continue if not a SATA device. */ - if (!(ap-flags ATA_FLAG_ACPI_SATA)) { - if (ata_msg_probe(ap)) - ata_dev_printk(adev, KERN_DEBUG, - %s: Not a SATA device\n, __FUNCTION__); - return 0; - } - /* Give the drive Identify data to the drive via the _SDD method */ /* _SDD: set up input parameters */ input.count = 1; -- 1.5.0.3 - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/13] libata-acpi: clean up ata_acpi_exec_tfs()
This patch cleans up ata_acpi_exec_tfs() and its friends. * Rename taskfile_array to ata_acpi_gtf and make it __packed as it's used as argument to ACPI method, and use pointer to ata_acpi_gtf and number of taskfiles to represent _GTF taskfiles instead of a pointer casted into unsigned long and byte count. This makes argument re-checking in do_drive_set_taskfiles() unnecessary. * Pointer in void * not in unsigned long. * Clean up do_drive_get_GTF() error handling and make do_drive_get_GTF() return number of taskfiles on success, 0 if _GTF doesn't exist or doesn't contain valid ata. -errno on other errors. * Remove superflous check for acpi-buffer.pointer. * Update taskfile_load_raw() such that printed messages look similar to the messages printed by ata_eh_report(). Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-acpi.c | 219 ++--- 1 files changed, 107 insertions(+), 112 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index a2745b5..21aad07 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -28,9 +28,9 @@ #define SATA_ADR(root,pmp) (((root) 16) | (pmp)) #define REGS_PER_GTF 7 -struct taskfile_array { - u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ -}; +struct ata_acpi_gtf { + u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ +} __packed; /* * Helper - belongs in the PCI layer somewhere eventually @@ -103,8 +103,8 @@ void ata_acpi_associate(struct ata_host *host) /** * do_drive_get_GTF - get the drive bootup default taskfile settings * @adev: target ATA device - * @gtf_length: number of bytes of _GTF data returned at @gtf_address - * @gtf_address: buffer containing _GTF taskfile arrays + * @gtf: output parameter for buffer containing _GTF taskfile arrays + * @ptr_to_free: pointer which should be freed * * This applies to both PATA and SATA drives. * @@ -114,24 +114,28 @@ void ata_acpi_associate(struct ata_host *host) * 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. + * LOCKING: + * EH context. + * + * RETURNS: + * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't + * contain valid data. -errno on other errors. */ -static int do_drive_get_GTF(struct ata_device *adev, unsigned int *gtf_length, - unsigned long *gtf_address, unsigned long *obj_loc) +static int do_drive_get_GTF(struct ata_device *adev, struct ata_acpi_gtf **gtf, + void **ptr_to_free) { struct ata_port *ap = adev-ap; acpi_status status; struct acpi_buffer output; union acpi_object *out_obj; - int err = -ENODEV; + int rc = 0; - *gtf_length = 0; - *gtf_address = 0UL; - *obj_loc = 0UL; + /* set up output buffer */ + output.length = ACPI_ALLOCATE_BUFFER; + output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ if (!adev-acpi_handle) - return 0; + goto out_free; if (ata_msg_probe(ap)) ata_dev_printk(adev, KERN_DEBUG, %s: ENTER: port#: %d\n, @@ -143,23 +147,19 @@ static int do_drive_get_GTF(struct ata_device *adev, unsigned int *gtf_length, ata_dev_present: %d, PORT_DISABLED: %lu\n, __FUNCTION__, ata_dev_enabled(adev), ap-flags ATA_FLAG_DISABLED); - goto out; + goto out_free; } - /* 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(adev-acpi_handle, _GTF, - NULL, output); + status = acpi_evaluate_object(adev-acpi_handle, _GTF, NULL, output); if (ACPI_FAILURE(status)) { - if (ata_msg_probe(ap)) - ata_dev_printk(adev, KERN_DEBUG, - %s: Run _GTF error: status = 0x%x\n, - __FUNCTION__, status); - goto out; + if (status != AE_NOT_FOUND) { + ata_dev_printk(adev, KERN_WARNING, + _GTF evaluation failed (AE 0x%x)\n, + status); + rc = -EIO; + } + goto out_free; } if (!output.length || !output.pointer) { @@ -169,43 +169,43 @@ static int do_drive_get_GTF(struct ata_device *adev, unsigned int *gtf_length, __FUNCTION__,
[PATCH 13/13] libata-acpi: implement _GTM/_STM support
Implement _GTM/_STM support. acpi_gtm is added to ata_port which stores _GTM parameters over suspend/resume cycle. A new hook ata_acpi_on_suspend() is responsible for storing _GTM parameters during suspend. _STM is executed in ata_acpi_on_resume(). With this change, invoking _GTF is safe on IDE hierarchy and acpi_sata check before _GTF is removed. ata_acpi_gtm() and ata_acpi_stm() implementation is taken from Alan Cox's pata_acpi implementation. ata_acpi_gtm() is fixed such that the result parameter is not shifted by sizeof(union acpi_object). Signed-off-by: Tejun Heo [EMAIL PROTECTED] Cc: Alan Cox [EMAIL PROTECTED] --- drivers/ata/libata-acpi.c | 153 +++- drivers/ata/libata-eh.c |8 ++- drivers/ata/libata.h |2 + include/linux/libata.h| 13 4 files changed, 171 insertions(+), 5 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 0ba0e79..8403c50 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -101,6 +101,108 @@ void ata_acpi_associate(struct ata_host *host) } /** + * ata_acpi_gtm - execute _GTM + * @ap: target ATA port + * @gtm: out parameter for _GTM result + * + * Evaluate _GTM and store the result in @gtm. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure. + */ +static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm) +{ + struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER }; + union acpi_object *out_obj; + acpi_status status; + int rc = 0; + + status = acpi_evaluate_object(ap-acpi_handle, _GTM, NULL, output); + + rc = -ENOENT; + if (status == AE_NOT_FOUND) + goto out_free; + + rc = -EINVAL; + if (ACPI_FAILURE(status)) { + ata_port_printk(ap, KERN_ERR, + ACPI get timing mode failed (AE 0x%x)\n, + status); + goto out_free; + } + + out_obj = output.pointer; + if (out_obj-type != ACPI_TYPE_BUFFER) { + ata_port_printk(ap, KERN_WARNING, + _GTM returned unexpected object type 0x%x\n, + out_obj-type); + + goto out_free; + } + + if (out_obj-buffer.length != sizeof(struct ata_acpi_gtm)) { + ata_port_printk(ap, KERN_ERR, + _GTM returned invalid length %d\n, + out_obj-buffer.length); + goto out_free; + } + + memcpy(gtm, out_obj-buffer.pointer, sizeof(struct ata_acpi_gtm)); + rc = 0; + out_free: + kfree(output.pointer); + return rc; +} + +/** + * ata_acpi_stm - execute _STM + * @ap: target ATA port + * @stm: timing parameter to _STM + * + * Evaluate _STM with timing parameter @stm. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure. + */ +static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm) +{ + acpi_status status; + struct acpi_object_list input; + union acpi_object in_params[3]; + + in_params[0].type = ACPI_TYPE_BUFFER; + in_params[0].buffer.length = sizeof(struct ata_acpi_gtm); + in_params[0].buffer.pointer = (u8 *)stm; + /* Buffers for id may need byteswapping ? */ + in_params[1].type = ACPI_TYPE_BUFFER; + in_params[1].buffer.length = 512; + in_params[1].buffer.pointer = (u8 *)ap-device[0].id; + in_params[2].type = ACPI_TYPE_BUFFER; + in_params[2].buffer.length = 512; + in_params[2].buffer.pointer = (u8 *)ap-device[1].id; + + input.count = 3; + input.pointer = in_params; + + status = acpi_evaluate_object(ap-acpi_handle, _STM, input, NULL); + + if (status == AE_NOT_FOUND) + return -ENOENT; + if (ACPI_FAILURE(status)) { + ata_port_printk(ap, KERN_ERR, + ACPI set timing mode failed (status=0x%x)\n, status); + return -EINVAL; + } + return 0; +} + +/** * do_drive_get_GTF - get the drive bootup default taskfile settings * @adev: target ATA device * @gtf: output parameter for buffer containing _GTF taskfile arrays @@ -354,6 +456,46 @@ static int ata_acpi_push_id(struct ata_device *adev) } /** + * ata_acpi_on_suspend - ATA ACPI hook called on suspend + * @ap: target ATA port + * + * This function is called when @ap is about to be suspended. All + * devices are already put to sleep but the port_suspend() callback + * hasn't been executed yet. Error return from this function aborts + * suspend. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int ata_acpi_on_suspend(struct ata_port *ap) +{ + unsigned long flags; + int rc; + + /* proceed
[PATCH 06/13] libata-acpi: clean up parameters and misc stuff
This patch cleans up libata-acpi such that it looks similar to other libata files. This patch doesn't introuce any behavior changes. * make libata-acpi functions take ata_device instead of ata_port + device index * s/atadev/adev/ * de-indent local variable declarations Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-acpi.c | 184 ++--- drivers/ata/libata-core.c |2 +- drivers/ata/libata.h |4 +- 3 files changed, 94 insertions(+), 96 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index cb3eab6..f005730 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -270,8 +270,7 @@ out: /** * do_drive_get_GTF - get the drive bootup default taskfile settings - * @ap: the ata_port for the drive - * @ix: target ata_device (drive) index + * @adev: target ATA device * @gtf_length: number of bytes of _GTF data returned at @gtf_address * @gtf_address: buffer containing _GTF taskfile arrays * @@ -286,20 +285,19 @@ out: * 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) +static int do_drive_get_GTF(struct ata_device *adev, 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_integerpcidevfn = 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; + struct ata_port *ap = adev-ap; + 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; + int err = -ENODEV; *gtf_length = 0; *gtf_address = 0UL; @@ -309,14 +307,14 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, return 0; if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, %s: ENTER: port#: %d\n, + ata_dev_printk(adev, KERN_DEBUG, %s: ENTER: port#: %d\n, __FUNCTION__, ap-port_no); - if (!ata_dev_enabled(atadev) || (ap-flags ATA_FLAG_DISABLED)) { + if (!ata_dev_enabled(adev) || (ap-flags ATA_FLAG_DISABLED)) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, %s: ERR: + ata_dev_printk(adev, KERN_DEBUG, %s: ERR: ata_dev_present: %d, PORT_DISABLED: %lu\n, - __FUNCTION__, ata_dev_enabled(atadev), + __FUNCTION__, ata_dev_enabled(adev), ap-flags ATA_FLAG_DISABLED); goto out; } @@ -327,7 +325,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, err = pata_get_dev_handle(dev, dev_handle, pcidevfn); if (err 0) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(adev, KERN_DEBUG, %s: pata_get_dev_handle failed (%d)\n, __FUNCTION__, err); goto out; @@ -336,7 +334,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, err = sata_get_dev_handle(dev, dev_handle, pcidevfn); if (err 0) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(adev, KERN_DEBUG, %s: sata_get_dev_handle failed (%d\n, __FUNCTION__, err); goto out; @@ -344,7 +342,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, } /* Get this drive's _ADR info. if not already known. */ - if (!atadev-obj_handle) { + if (!adev-obj_handle) { if (!(ap-cbl == ATA_CBL_SATA)) { /* get child objects of dev_handle == channel objects, * + _their_ children == drive objects */ @@ -352,7 +350,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
[PATCH 08/13] libata-acpi: implement ata_acpi_associate()
* Add acpi_handle to ata_host and ata_port. Rename ata_device-obj_handle to -acpi_handle and move it above such that it doesn't get cleared on reconfiguration. * Replace ACPI node association which ata_acpi_associate() which is called once during host initialization. Unlike the previous implementation, ata_acpi_associate() uses ATA_FLAG_ACPI_SATA to choose between IDE or SATA ACPI hierarchy and uses simple child look up instead of recursive walk to match the nodes. This is way safer and simpler. Please read the following message for more info. http://article.gmane.org/gmane.linux.ide/17554 Signed-off-by: Tejun Heo [EMAIL PROTECTED] --- drivers/ata/libata-acpi.c | 369 ++--- drivers/ata/libata-core.c |3 + drivers/ata/libata.h |2 + include/linux/libata.h| 13 +- 4 files changed, 63 insertions(+), 324 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 24c2198..a2745b5 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -24,10 +24,8 @@ #include acpi/acmacros.h #include acpi/actypes.h -#define SATA_ROOT_PORT(x) (((x) 16) 0x) -#define SATA_PORT_NUMBER(x)((x) 0x) /* or NO_PORT_MULT */ #define NO_PORT_MULT 0x -#define SATA_ADR_RSVD 0x +#define SATA_ADR(root,pmp) (((root) 16) | (pmp)) #define REGS_PER_GTF 7 struct taskfile_array { @@ -42,230 +40,64 @@ 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) +static void ata_acpi_associate_sata_port(struct ata_port *ap) { - struct pci_dev *pci_dev; - acpi_integeraddr; - - 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; + acpi_integer adr = SATA_ADR(ap-port_no, NO_PORT_MULT); + + ap-device-acpi_handle = acpi_get_child(ap-host-acpi_handle, adr); } -/** - * 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) +static void ata_acpi_associate_ide_port(struct ata_port *ap) { - 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; - } + int max_devices, i; - 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_integerpcidevfn; - unsigned intdrivenum; - acpi_handle obj_handle; - struct ata_port *ataport; - struct ata_device *atadev; - u32 sata_adr; -
Re: [PATCH 01/13] ahci: consolidate common port flags
On Mon, 23 Apr 2007 02:41:05 +0900 Tejun Heo [EMAIL PROTECTED] wrote: Consolidate common port flags into AHCI_FLAG_COMMON. Signed-off-by: Tejun Heo [EMAIL PROTECTED] Acked-by: Alan Cox [EMAIL PROTECTED] - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 02/13] libata: separate ATA_EHI_DID_RESET into DID_SOFTRESET and DID_HARDRESET
On Mon, 23 Apr 2007 02:41:05 +0900 Tejun Heo [EMAIL PROTECTED] wrote: Separate ATA_EHI_DID_RESET into ATA_EHI_DID_SOFTRESET and ATA_EHI_DID_HARDRESET. ATA_EHI_DID_RESET is redefined as OR of the two flags. This patch doesn't introduce any behavior change. This will be used later to determine whether _SDD is necessary or not. Signed-off-by: Tejun Heo [EMAIL PROTECTED] Acked-by: Alan Cox [EMAIL PROTECTED] - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] pata_amd: remove contamination added during cable_detect conversion
Hello, Alan Cox wrote: On Mon, 23 Apr 2007 02:04:38 +0900 Tejun Heo [EMAIL PROTECTED] wrote: This is added by added by cff63dfceb52c564fe1ba5394d50ab7d599a11b9 - pata: cable methods. The Cable method fix for the Nvidia hardware if ACPI drivers are present and usable is to use the ACPI driver, so its not a contamination its a fix for the fact the Nvidia code can't do cable detect any other way But pata_amd modifications should be merged together with pata_acpi not separately. Anyways, I've been testing pata_acpi and it doesn't work on my nforce ultra machine. Whether the cable is 40c or not, _STM happily sets UDMA mode above 2 resulting in a series of transfer errors. EH kicks in eventually and drops transfer speed. Also, ata_acpi_gtm() implementation was broken in that it skipped one level of indirection (acpi_object, please take a look at the last patch of just posted patchset), so it was basically returning garbage values. I have patches to update pata_amd to use _STM/_GTM for cable detection (a lot are taken from pata_acpi) but ACPI cable detection is just as broken as PCI config one. Thanks. -- tejun - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 07/13] libata-acpi: add ATA_FLAG_ACPI_SATA port flag
On Mon, 23 Apr 2007 02:41:06 +0900 Tejun Heo [EMAIL PROTECTED] wrote: Whether a controller needs IDE or SATA ACPI hierarchy is determined by the programming interface of the controller not by whether the controller is SATA or PATA NAK I keep trying to point out that this is not true. The ACPI interface to use can only be safely determined one way - and that is to see what methods the BIOS has attached to the device and use those. Take the ACPI handle, go look for _GTF, _SDD etc and believe the firmware. Nothing else works. Alan - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] pata_amd: remove contamination added during cable_detect conversion
I have patches to update pata_amd to use _STM/_GTM for cable detection (a lot are taken from pata_acpi) but ACPI cable detection is just as broken as PCI config one. I'm unclear we can safely mix _STM/_GTM and direct access to the drive in a general form. The ACPI documentation seems to be carefully very silent on the subject. Whatever works in this area is good. Alan - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 07/13] libata-acpi: add ATA_FLAG_ACPI_SATA port flag
The ACPI interface to use can only be safely determined one way - and that is to see what methods the BIOS has attached to the device and use those. Take the ACPI handle, go look for _GTF, _SDD etc and believe the firmware. Nothing else works. Actually its even worse a mess than I thought 8( We have to look at the BIOS method offered and we have to know if we changed the mode of the controller. If the BIOS mode of an IDE controller is SFF and we flip it into AHCI mode then we can no longer use the BIOS provided methods because they are the wrong ones. For the sane cases (where we don't frob the device) we can ask the BIOS what methods it has to guess what to use. If we change the mode of the controller we need to look for methods that match our change, and be aware we may have totally hosed the ACPI method support by changing the chip config. Bletch, ACPI, its like openprom crossed with european law, a million times larger than needed, and full of holes. - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 07/13] libata-acpi: add ATA_FLAG_ACPI_SATA port flag
Alan Cox wrote: On Mon, 23 Apr 2007 02:41:06 +0900 Tejun Heo [EMAIL PROTECTED] wrote: Whether a controller needs IDE or SATA ACPI hierarchy is determined by the programming interface of the controller not by whether the controller is SATA or PATA NAK I keep trying to point out that this is not true. The ACPI interface to use can only be safely determined one way - and that is to see what methods the BIOS has attached to the device and use those. Take the ACPI handle, go look for _GTF, _SDD etc and believe the firmware. Nothing else works. Actually, that's dangerous. For example, you must not do _STM/_GTM on ahci becuase _STM/_GTM access PCI config registers which must not be accessed in achi modes and some BIOSen supply the same _STM/_GTM nodes whether the controller is in ata_piix mode or ahci mode. Also, on ICH8, the association gets quite weird due to PCI device splitting. The ACPI spec says the layout is dependent on controller interface and I can see reasons why we need to follow that but not the other way around. Do you have counter-examples? -- tejun - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] pata_amd: remove contamination added during cable_detect conversion
Yeap, definitely. Can you please retest pata_acpi with ata_acpi_gtm() fixed? I have an UDMA2 ODD (HL-DT-ST DVDRAM GSA-H10N) and UDMA4 HDD (WDC WD153AA) attached to 40c cable and ACPI mode discovery doesn't work at all. The only thing I can get working here is storing the BIOS setting. :-( I'll try it next week although my BIOS worked beautifully with the original code and without ata_acpi_gtm being fixed ! I've also seen some BIOSes which implement _gtm/_stm solely as stuff it back in BIOS boot up mode Alan - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2.6.20 11/14; CRIS architecture update - IDE driver
The attached patch updates the CRIS IDE driver. Signed-off-by: Mikael Starvik [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] /Mikael cris11_ide.patch Description: cris11_ide.patch
[PATCH 2.6.21-rc7] sata_promise: SATAII-150/300 TX4 port numbering fix
There is a known problem with sata_promise on SATAII-150/300 TX4 controller cards: it enumerates drives in an order that differs from the port numbers printed on the controller cards. However, Promise's BIOS and Linux driver both get the order right. I investigated Promise's Linux driver (v1.01.0.23), and found that it explicitly changes the mapping from logical port number to ATA engine MMIO address on the SATAII TX4 cards. It does this on all SATAII TX4 cards, without inspecting revision etc. The SATAII TX2plus cards continue to use the same mapping that was used for the first-generation chips. This patch updates sata_promise to use the new port number to ATA engine mapping on SATAII TX4 cards, which fixes the drive enumeration order problem on those cards. Tested on 300 TX4, 300 TX2plus, and SATAII-150 TX2plus chips. Signed-off-by: Mikael Pettersson [EMAIL PROTECTED] --- This patch should apply to 2.6.21-rc7 and libata#upstream. It won't apply to libata#ALL because of the massive changes for the new init model. I will do a new and cleaner patch for #ALL once I can get it as a patch in -mm (I don't do git). --- linux-2.6.21-rc7/drivers/ata/sata_promise.c.~1~ 2007-04-23 00:17:35.0 +0200 +++ linux-2.6.21-rc7/drivers/ata/sata_promise.c 2007-04-23 00:18:06.0 +0200 @@ -989,7 +989,13 @@ static int pdc_ata_init_one (struct pci_ switch (board_idx) { case board_40518: hp-flags |= PDC_FLAG_GEN_II; - /* Fall through */ + printk(KERN_INFO DRV_NAME : applying SATAII-150/300 TX4 port numbering workaround\n); + probe_ent-n_ports = 4; + pdc_ata_setup_port(probe_ent-port[2], base + 0x200, base + 0x400); + pdc_ata_setup_port(probe_ent-port[1], base + 0x280, base + 0x500); + pdc_ata_setup_port(probe_ent-port[3], base + 0x300, base + 0x600); + pdc_ata_setup_port(probe_ent-port[0], base + 0x380, base + 0x700); + break; case board_20319: probe_ent-n_ports = 4; pdc_ata_setup_port(probe_ent-port[2], base + 0x300, base + 0x600); - To unsubscribe from this list: send the line unsubscribe linux-ide in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html