summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-02-15 16:05:48 +0000
committermav <mav@FreeBSD.org>2009-02-15 16:05:48 +0000
commit1685dd7b40c5a1dede2e26c8e6595117a2306f5a (patch)
tree10279d8d614479314bf742409e9efe59cdcb5958 /sys/dev/ata
parentb13005f9d814cba5ac98e00cd9c9cecd759fd5c4 (diff)
downloadFreeBSD-src-1685dd7b40c5a1dede2e26c8e6595117a2306f5a.zip
FreeBSD-src-1685dd7b40c5a1dede2e26c8e6595117a2306f5a.tar.gz
Add workaround for some ATI chips, failing to soft-reset
when port multiplicator supported, but absent.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/chipsets/ata-ahci.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c
index 02616d0..51e8a88 100644
--- a/sys/dev/ata/chipsets/ata-ahci.c
+++ b/sys/dev/ata/chipsets/ata-ahci.c
@@ -595,7 +595,7 @@ ata_ahci_start(device_t dev)
(ch->devices & ATA_PORTMULTIPLIER ? ATA_AHCI_P_CMD_PMA : 0));
}
-static void
+static int
ata_ahci_wait_ready(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
@@ -608,11 +608,12 @@ ata_ahci_wait_ready(device_t dev)
DELAY(1000);
if (timeout++ > 1000) {
device_printf(dev, "port is not ready\n");
- break;
+ return (-1);
}
}
if (bootverbose)
device_printf(dev, "ready wait time=%dms\n", timeout);
+ return (0);
}
static u_int32_t
@@ -651,7 +652,8 @@ ata_ahci_softreset(device_t dev, int port)
if (ata_ahci_issue_cmd(dev, 0, 0))
return -1;
- ata_ahci_wait_ready(dev);
+ if (ata_ahci_wait_ready(dev))
+ return (-1);
return ATA_INL(ctlr->r_res2, ATA_AHCI_P_SIG + offset);
}
@@ -713,9 +715,14 @@ ata_ahci_reset(device_t dev)
ata_ahci_wait_ready(dev);
/* only probe for PortMultiplier if HW has support */
- if (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_SPM)
+ if (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_SPM) {
signature = ata_ahci_softreset(dev, ATA_PM);
- else {
+ /* Workaround for some ATI chips, failing to soft-reset
+ * when port multiplicator supported, but absent.
+ * XXX: We can also check PxIS.IPMS==1 here to be sure. */
+ if (signature == 0xffffffff)
+ signature = ata_ahci_softreset(dev, 0);
+ } else {
signature = ata_ahci_softreset(dev, 0);
}
if (bootverbose)
OpenPOWER on IntegriCloud