The branch main has been updated by imp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=e7dc08415a324d1000cd067fbc12b1ec79e0b2ac

commit e7dc08415a324d1000cd067fbc12b1ec79e0b2ac
Author:     Austin Shafer <asha...@badland.io>
AuthorDate: 2021-06-03 01:46:23 +0000
Commit:     Warner Losh <i...@freebsd.org>
CommitDate: 2021-06-03 01:46:23 +0000

    mmc: ignore CRC errors from CMD13 (status) when changing rates
    
    Update mmc_switch_status to ignore a few CRC errrors when asking for the
    card status after setting the new rate with CMD6. Since the card may
    take a little while to make the switch, it's possible we'll get a
    communications error if we sent the command at the wrong time. Several
    low end laptops needs this workaround as they have a window that seems
    longer than other systems. This is known to fix at least the Acer Aspire
    A114-32-P7E5.
    
    Reviewed by:            imp@, manu@
    Differential Revision:  https://reviews.freebsd.org/D24740
---
 sys/dev/mmc/mmc_subr.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/sys/dev/mmc/mmc_subr.c b/sys/dev/mmc/mmc_subr.c
index 53c9009c6e64..b43a233820bb 100644
--- a/sys/dev/mmc/mmc_subr.c
+++ b/sys/dev/mmc/mmc_subr.c
@@ -193,7 +193,7 @@ int
 mmc_switch_status(device_t busdev, device_t dev, uint16_t rca, u_int timeout)
 {
        struct timeval cur, end;
-       int err;
+       int err, crc_timeout;
        uint32_t status;
 
        KASSERT(timeout != 0, ("%s: no timeout", __func__));
@@ -205,7 +205,19 @@ mmc_switch_status(device_t busdev, device_t dev, uint16_t 
rca, u_int timeout)
         */
        end.tv_sec = end.tv_usec = 0;
        for (;;) {
-               err = mmc_send_status(busdev, dev, rca, &status);
+               crc_timeout=0;
+               do {
+                       /*
+                        * CRC errors indicate that the command wasn't accepted
+                        * and executed due to a communications error. Retry
+                        * CRC errors a couple of times to cope with transient
+                        * failures.
+                        *
+                        * This is required for some cheap laptops to boot.
+                        */
+                       err = mmc_send_status(busdev, dev, rca, &status);
+                       crc_timeout++;
+               } while (err == MMC_ERR_BADCRC && crc_timeout < 10);
                if (err != MMC_ERR_NONE)
                        break;
                if (R1_CURRENT_STATE(status) == R1_STATE_TRAN)
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to