summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-02-15 17:59:32 +0000
committerian <ian@FreeBSD.org>2014-02-15 17:59:32 +0000
commit71ef75416769754b299954be72f8a1bf971f7268 (patch)
tree2934c5ff5d360053d3e3ed0494368d4aeaaf26e4
parent882689c35315cd4920853d73ee80d05648924085 (diff)
downloadFreeBSD-src-71ef75416769754b299954be72f8a1bf971f7268.zip
FreeBSD-src-71ef75416769754b299954be72f8a1bf971f7268.tar.gz
Increase the wait time for acquiring the bus from 10 to 250ms.
Normally it never needs to wait here at all; waiting is done at the end of the prior command. When doing a crash dump, the normal interrupt mechanism isn't used; instead the interrupt handler is called repeatedly in a polling-like manner. This can subvert hardware-specific drivers and lead to trying to start a new command while the previous command is still busy on the bus. Since the SD spec says the longest a card can take to execute any command is 250ms, use that as a timeout.
-rw-r--r--sys/dev/sdhci/sdhci.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c
index c9c3ae9..78bcab9 100644
--- a/sys/dev/sdhci/sdhci.c
+++ b/sys/dev/sdhci/sdhci.c
@@ -767,8 +767,17 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd)
/* We shouldn't wait for DAT for stop commands. */
if (cmd == slot->req->stop)
mask &= ~SDHCI_DAT_INHIBIT;
- /* Wait for bus no more then 10 ms. */
- timeout = 10;
+ /*
+ * Wait for bus no more then 250 ms. Typically there will be no wait
+ * here at all, but when writing a crash dump we may be bypassing the
+ * host platform's interrupt handler, and in some cases that handler
+ * may be working around hardware quirks such as not respecting r1b
+ * busy indications. In those cases, this wait-loop serves the purpose
+ * of waiting for the prior command and data transfers to be done, and
+ * SD cards are allowed to take up to 250ms for write and erase ops.
+ * (It's usually more like 20-30ms in the real world.)
+ */
+ timeout = 250;
while (state & mask) {
if (timeout == 0) {
slot_printf(slot, "Controller never released "
OpenPOWER on IntegriCloud