booting with ATA-AHCI now broken
Alexander Motin
mav at FreeBSD.org
Sun Feb 15 06:44:55 PST 2009
Gary Jennejohn wrote:
> On Sun, 15 Feb 2009 14:42:41 +0200
> Alexander Motin <mav at FreeBSD.org> wrote:
>
>> Gary Jennejohn wrote:
>>> The latest commit to dev/ata/chipsets/ata-ahci.c totally breaks
>>> booting on my machine.
>>>
>>> I didn't save the commit message so I can't quote the exact commit
>>> revision number.
>>>
>>> _Every_ ata port now times out.
>>>
>>> Here the relevant bits from pciconf:
>>>
>>> atapci0 at pci0:0:17:0: class=0x010601 card=0xb0021458 chip=0x43911002 rev=0x00 hdr=0x00
>>> vendor = 'ATI Technologies Inc'
>>> class = mass storage
>>> subclass = SATA
>> According to Linux drivers, this chip has bug with port multiplier
>> probing which this commit may trigger. Can you try to change
>> 'ata_ahci_softreset(dev, ATA_PM)' with 'ata_ahci_softreset(dev, 0)' in
>> ata-ahci.c to check it?
>>
>
> Yes, that fixes it. Thanks for the quick response.
>
> Do you still want the verbose boot output?
Please try attached patch instead, it should be more correct solution,
and send me it's output instead.
--
Alexander Motin
-------------- next part --------------
diff -ruNp ata.prev3/chipsets/ata-ahci.c ata/chipsets/ata-ahci.c
--- ata.prev3/chipsets/ata-ahci.c 2009-02-14 23:07:18.000000000 +0200
+++ ata/chipsets/ata-ahci.c 2009-02-15 16:36:39.000000000 +0200
@@ -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 por
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)
More information about the svn-src-all
mailing list