diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci.c | 15 | ||||
-rw-r--r-- | drivers/ata/ata_piix.c | 2 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 38 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 5 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 2 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 3 | ||||
-rw-r--r-- | drivers/ata/sata_promise.c | 2 |
7 files changed, 55 insertions, 12 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b8bea10..b343903 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -2868,6 +2868,21 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) }, .driver_data = "F.23", /* cutoff BIOS version */ }, + /* + * Acer eMachines G725 has the same problem. BIOS + * V1.03 is known to be broken. V3.04 is known to + * work. Inbetween, there are V1.06, V2.06 and V3.03 + * that we don't have much idea about. For now, + * blacklist anything older than V3.04. + */ + { + .ident = "G725", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "eMachines"), + DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"), + }, + .driver_data = "V3.04", /* cutoff BIOS version */ + }, { } /* terminate list */ }; const struct dmi_system_id *dmi = dmi_first_match(sysids); diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 19136a7..6f3f225 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -329,7 +329,7 @@ static struct ata_port_operations ich_pata_ops = { }; static struct ata_port_operations piix_sata_ops = { - .inherits = &ata_bmdma_port_ops, + .inherits = &ata_bmdma32_port_ops, }; static struct ata_port_operations piix_sidpr_sata_ops = { diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 22ff51b..6728328 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3790,21 +3790,45 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params, int sata_link_resume(struct ata_link *link, const unsigned long *params, unsigned long deadline) { + int tries = ATA_LINK_RESUME_TRIES; u32 scontrol, serror; int rc; if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) return rc; - scontrol = (scontrol & 0x0f0) | 0x300; + /* + * Writes to SControl sometimes get ignored under certain + * controllers (ata_piix SIDPR). Make sure DET actually is + * cleared. + */ + do { + scontrol = (scontrol & 0x0f0) | 0x300; + if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) + return rc; + /* + * Some PHYs react badly if SStatus is pounded + * immediately after resuming. Delay 200ms before + * debouncing. + */ + msleep(200); - if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) - return rc; + /* is SControl restored correctly? */ + if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) + return rc; + } while ((scontrol & 0xf0f) != 0x300 && --tries); - /* Some PHYs react badly if SStatus is pounded immediately - * after resuming. Delay 200ms before debouncing. - */ - msleep(200); + if ((scontrol & 0xf0f) != 0x300) { + ata_link_printk(link, KERN_ERR, + "failed to resume link (SControl %X)\n", + scontrol); + return 0; + } + + if (tries < ATA_LINK_RESUME_TRIES) + ata_link_printk(link, KERN_WARNING, + "link resume succeeded after %d retries\n", + ATA_LINK_RESUME_TRIES - tries); if ((rc = sata_link_debounce(link, params, deadline))) return rc; diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 0ea97c9..9f6cfac 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2028,8 +2028,9 @@ static void ata_eh_link_autopsy(struct ata_link *link) qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); /* determine whether the command is worth retrying */ - if (!(qc->err_mask & AC_ERR_INVALID) && - ((qc->flags & ATA_QCFLAG_IO) || qc->err_mask != AC_ERR_DEV)) + if (qc->flags & ATA_QCFLAG_IO || + (!(qc->err_mask & AC_ERR_INVALID) && + qc->err_mask != AC_ERR_DEV)) qc->flags |= ATA_QCFLAG_RETRY; /* accumulate error info */ diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index f4ea5a8..d096fbc 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2875,7 +2875,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) * write indication (used for PIO/DMA setup), result TF is * copied back and we don't whine too much about its failure. */ - tf->flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; if (scmd->sc_data_direction == DMA_TO_DEVICE) tf->flags |= ATA_TFLAG_WRITE; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 741065c..730ef3c 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -893,6 +893,9 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) do_write); } + if (!do_write) + flush_dcache_page(page); + qc->curbytes += qc->sect_size; qc->cursg_ofs += qc->sect_size; diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 07d8d00..6330628 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -862,7 +862,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, if (port_status & PDC_DRIVE_ERR) ac_err_mask |= AC_ERR_DEV; if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR)) - ac_err_mask |= AC_ERR_HSM; + ac_err_mask |= AC_ERR_OTHER; if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR)) ac_err_mask |= AC_ERR_ATA_BUS; if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR |