Date: Sat, 15 Feb 2014 17:59:33 +0000 (UTC) From: Ian Lepore <ian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r261940 - head/sys/dev/sdhci Message-ID: <201402151759.s1FHxXNH034120@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ian Date: Sat Feb 15 17:59:32 2014 New Revision: 261940 URL: http://svnweb.freebsd.org/changeset/base/261940 Log: 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. Modified: head/sys/dev/sdhci/sdhci.c Modified: head/sys/dev/sdhci/sdhci.c ============================================================================== --- head/sys/dev/sdhci/sdhci.c Sat Feb 15 17:55:35 2014 (r261939) +++ head/sys/dev/sdhci/sdhci.c Sat Feb 15 17:59:32 2014 (r261940) @@ -767,8 +767,17 @@ sdhci_start_command(struct sdhci_slot *s /* 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 "
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402151759.s1FHxXNH034120>