Hi,
a colleague has been fiddling with ahci(4) wondering why the disk fails
on attach on his hardware. He came up with the following diff.
Considering this is quite an intrusive though small diff, I would like
to ask for tests on various hardware to make sure this does not break
any hardware we currently support. Disks should keep being properly
attached.
Patrick
---zip---
Turn off the code which waits for AHCI_PREG_CMD_CR to be set by the
HBA after ahci_default_port_start() sets AHCI_PREG_CMD_ST. The AHCI
spec. rev. 1.3 only requires the inverse to be true, i. e. that a
HBA clears AHCI_PREG_CMD_CR when AHCI_PREG_CMD_ST gets cleared by
software/driver. In fact, some HBAs will not raise AHCI_PREG_CMD_CR
as an immediate consequence of AHCI_PREG_CMD_ST being set. Actually
neither the FreeBSD, Linux nor NetBSD counterpart of ahci(4) has an
analogous check. Disabling that wait fixes "failed to start command
DMA on port N, disabling" bails during attach.
>From Marius Strobl
diff --git sys/dev/ic/ahci.c sys/dev/ic/ahci.c
index d600f3e..da93478 100644
--- sys/dev/ic/ahci.c
+++ sys/dev/ic/ahci.c
@@ -890,10 +890,20 @@ ahci_default_port_start(struct ahci_port *ap, int
fre_only)
}
#endif
+#if 0
/* Wait for CR to come on */
+ /*
+ * Doesn't work: According to section 5.3.16.1, HBAs are required
+ * to clear AHCI_PREG_CMD_CR if AHCI_PREG_CMD_ST is cleared to 0.
+ * However, nowhere in the AHCI v1.3 specification the inverse is
+ * stated, i. e. that an HBA must transit to a state in which the
+ * AHCI_PREG_CMD_CR bit must be set as an immediate result of the
+ * software/driver setting AHCI_PREG_CMD_ST.
+ */
if (!fre_only &&
ahci_pwait_set(ap, AHCI_PREG_CMD, AHCI_PREG_CMD_CR, 1))
return (1);
+#endif
return (0);
}