diff options
| -rw-r--r-- | drivers/ata/ata_piix.c | 2 | ||||
| -rw-r--r-- | drivers/ata/libata-core.c | 38 | ||||
| -rw-r--r-- | drivers/ata/sata_promise.c | 2 | ||||
| -rw-r--r-- | include/linux/libata.h | 3 |
4 files changed, 36 insertions, 9 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 19136a7e1064..6f3f2257d0f0 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 = { | |||
| 329 | }; | 329 | }; |
| 330 | 330 | ||
| 331 | static struct ata_port_operations piix_sata_ops = { | 331 | static struct ata_port_operations piix_sata_ops = { |
| 332 | .inherits = &ata_bmdma_port_ops, | 332 | .inherits = &ata_bmdma32_port_ops, |
| 333 | }; | 333 | }; |
| 334 | 334 | ||
| 335 | static struct ata_port_operations piix_sidpr_sata_ops = { | 335 | static struct ata_port_operations piix_sidpr_sata_ops = { |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 22ff51bdbc8a..6728328f3bea 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, | |||
| 3790 | int sata_link_resume(struct ata_link *link, const unsigned long *params, | 3790 | int sata_link_resume(struct ata_link *link, const unsigned long *params, |
| 3791 | unsigned long deadline) | 3791 | unsigned long deadline) |
| 3792 | { | 3792 | { |
| 3793 | int tries = ATA_LINK_RESUME_TRIES; | ||
| 3793 | u32 scontrol, serror; | 3794 | u32 scontrol, serror; |
| 3794 | int rc; | 3795 | int rc; |
| 3795 | 3796 | ||
| 3796 | if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) | 3797 | if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) |
| 3797 | return rc; | 3798 | return rc; |
| 3798 | 3799 | ||
| 3799 | scontrol = (scontrol & 0x0f0) | 0x300; | 3800 | /* |
| 3801 | * Writes to SControl sometimes get ignored under certain | ||
| 3802 | * controllers (ata_piix SIDPR). Make sure DET actually is | ||
| 3803 | * cleared. | ||
| 3804 | */ | ||
| 3805 | do { | ||
| 3806 | scontrol = (scontrol & 0x0f0) | 0x300; | ||
| 3807 | if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) | ||
| 3808 | return rc; | ||
| 3809 | /* | ||
| 3810 | * Some PHYs react badly if SStatus is pounded | ||
| 3811 | * immediately after resuming. Delay 200ms before | ||
| 3812 | * debouncing. | ||
| 3813 | */ | ||
| 3814 | msleep(200); | ||
| 3800 | 3815 | ||
| 3801 | if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol))) | 3816 | /* is SControl restored correctly? */ |
| 3802 | return rc; | 3817 | if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol))) |
| 3818 | return rc; | ||
| 3819 | } while ((scontrol & 0xf0f) != 0x300 && --tries); | ||
| 3803 | 3820 | ||
| 3804 | /* Some PHYs react badly if SStatus is pounded immediately | 3821 | if ((scontrol & 0xf0f) != 0x300) { |
| 3805 | * after resuming. Delay 200ms before debouncing. | 3822 | ata_link_printk(link, KERN_ERR, |
| 3806 | */ | 3823 | "failed to resume link (SControl %X)\n", |
| 3807 | msleep(200); | 3824 | scontrol); |
| 3825 | return 0; | ||
| 3826 | } | ||
| 3827 | |||
| 3828 | if (tries < ATA_LINK_RESUME_TRIES) | ||
| 3829 | ata_link_printk(link, KERN_WARNING, | ||
| 3830 | "link resume succeeded after %d retries\n", | ||
| 3831 | ATA_LINK_RESUME_TRIES - tries); | ||
| 3808 | 3832 | ||
| 3809 | if ((rc = sata_link_debounce(link, params, deadline))) | 3833 | if ((rc = sata_link_debounce(link, params, deadline))) |
| 3810 | return rc; | 3834 | return rc; |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 07d8d00b4d34..63306285c843 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, | |||
| 862 | if (port_status & PDC_DRIVE_ERR) | 862 | if (port_status & PDC_DRIVE_ERR) |
| 863 | ac_err_mask |= AC_ERR_DEV; | 863 | ac_err_mask |= AC_ERR_DEV; |
| 864 | if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR)) | 864 | if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR)) |
| 865 | ac_err_mask |= AC_ERR_HSM; | 865 | ac_err_mask |= AC_ERR_OTHER; |
| 866 | if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR)) | 866 | if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR)) |
| 867 | ac_err_mask |= AC_ERR_ATA_BUS; | 867 | ac_err_mask |= AC_ERR_ATA_BUS; |
| 868 | if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR | 868 | if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 6a9c4ddd3d95..73112250862c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -354,6 +354,9 @@ enum { | |||
| 354 | /* max tries if error condition is still set after ->error_handler */ | 354 | /* max tries if error condition is still set after ->error_handler */ |
| 355 | ATA_EH_MAX_TRIES = 5, | 355 | ATA_EH_MAX_TRIES = 5, |
| 356 | 356 | ||
| 357 | /* sometimes resuming a link requires several retries */ | ||
| 358 | ATA_LINK_RESUME_TRIES = 5, | ||
| 359 | |||
| 357 | /* how hard are we gonna try to probe/recover devices */ | 360 | /* how hard are we gonna try to probe/recover devices */ |
| 358 | ATA_PROBE_MAX_TRIES = 3, | 361 | ATA_PROBE_MAX_TRIES = 3, |
| 359 | ATA_EH_DEV_TRIES = 3, | 362 | ATA_EH_DEV_TRIES = 3, |
