Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/sdmmc Add and use sdmmc_pause to avoid long-term bus...



details:   https://anonhg.NetBSD.org/src/rev/776904eacd92
branches:  trunk
changeset: 464880:776904eacd92
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Mon Oct 28 06:16:46 2019 +0000

description:
Add and use sdmmc_pause to avoid long-term busy waits.
Add sdio abort function.
Additional error messages.
Print parameters for SDIO devices.
Minor cosmetics.

diffstat:

 sys/dev/sdmmc/sdmmc.c     |  26 ++++++++++++++++++++----
 sys/dev/sdmmc/sdmmc_io.c  |  49 +++++++++++++++++++++++++++++++++++++++++-----
 sys/dev/sdmmc/sdmmc_mem.c |   8 +++---
 sys/dev/sdmmc/sdmmcvar.h  |   5 +++-
 4 files changed, 72 insertions(+), 16 deletions(-)

diffs (251 lines):

diff -r c4dd67e8ac4c -r 776904eacd92 sys/dev/sdmmc/sdmmc.c
--- a/sys/dev/sdmmc/sdmmc.c     Mon Oct 28 06:00:14 2019 +0000
+++ b/sys/dev/sdmmc/sdmmc.c     Mon Oct 28 06:16:46 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmc.c,v 1.38 2019/10/23 05:20:52 hkenken Exp $       */
+/*     $NetBSD: sdmmc.c,v 1.39 2019/10/28 06:16:46 mlelstv Exp $       */
 /*     $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $  */
 
 /*
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.38 2019/10/23 05:20:52 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.39 2019/10/28 06:16:46 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -568,7 +568,7 @@
        }
 
        /* XXX wait for card to power up */
-       sdmmc_delay(100000);
+       sdmmc_pause(100000, NULL);
 
        if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
                /* Initialize SD I/O card function(s). */
@@ -790,6 +790,17 @@
        delay(usecs);
 }
 
+void
+sdmmc_pause(u_int usecs, kmutex_t *lock)
+{
+       unsigned ticks = mstohz(usecs/1000);
+
+       if (cold || ticks < 1)
+               delay(usecs);
+       else
+               kpause("sdmmcdelay", false, ticks, lock);
+}
+
 int
 sdmmc_app_command(struct sdmmc_softc *sc, struct sdmmc_function *sf, struct sdmmc_command *cmd)
 {
@@ -910,7 +921,7 @@
        /* Don't lock */
 
        if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
-               aprint_error_dev(sc->sc_dev,
+               device_printf(sc->sc_dev,
                        "sdmmc_set_relative_addr: SMC_CAPS_SPI_MODE set");
                return EIO;
        }
@@ -943,7 +954,7 @@
        /* Don't lock */
 
        if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
-               aprint_error_dev(sc->sc_dev,
+               device_printf(sc->sc_dev,
                        "sdmmc_select_card: SMC_CAPS_SPI_MODE set");
                return EIO;
        }
@@ -962,6 +973,11 @@
        if (error == 0 || sf == NULL)
                sc->sc_card = sf;
 
+       if (error) {
+               device_printf(sc->sc_dev,
+                       "sdmmc_select_card: error %d", error);
+       }
+
        return error;
 }
 
diff -r c4dd67e8ac4c -r 776904eacd92 sys/dev/sdmmc/sdmmc_io.c
--- a/sys/dev/sdmmc/sdmmc_io.c  Mon Oct 28 06:00:14 2019 +0000
+++ b/sys/dev/sdmmc/sdmmc_io.c  Mon Oct 28 06:16:46 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmc_io.c,v 1.16 2019/09/02 11:09:42 jmcneill Exp $   */
+/*     $NetBSD: sdmmc_io.c,v 1.17 2019/10/28 06:16:46 mlelstv Exp $    */
 /*     $OpenBSD: sdmmc_io.c,v 1.10 2007/09/17 01:33:33 krw Exp $       */
 
 /*
@@ -20,7 +20,7 @@
 /* Routines for SD I/O cards. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.16 2019/09/02 11:09:42 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.17 2019/10/28 06:16:46 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -230,7 +230,7 @@
                        sf->csd.tran_speed = 50000;     /* 50MHz */
 
                        /* Wait 400KHz x 8 clock */
-                       delay(1);
+                       sdmmc_delay(20);
                }
                if (sc->sc_busclk > sf->csd.tran_speed)
                        sc->sc_busclk = sf->csd.tran_speed;
@@ -240,6 +240,15 @@
                if (error)
                        aprint_error_dev(sc->sc_dev,
                            "can't change bus clock\n");
+
+               aprint_normal_dev(sc->sc_dev, "%u-bit width,", sf->width);
+               if ((sc->sc_busclk / 1000) != 0)
+                       aprint_normal(" %u.%03u MHz\n",
+                           sc->sc_busclk / 1000, sc->sc_busclk % 1000);
+               else
+                       aprint_normal(" %u KHz\n", sc->sc_busclk % 1000);
+
+
        } else {
                reg = sdmmc_io_read_1(sf0, SD_IO_FBR(sf->number) + 0x000);
                sf->interface = FBR_STD_FUNC_IF_CODE(reg);
@@ -357,7 +366,15 @@
        cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5;
 
        error = sdmmc_mmc_command(sc, &cmd);
-       *datap = SD_R5_DATA(cmd.c_resp);
+       if (error == 0)
+               *datap = SD_R5_DATA(cmd.c_resp);
+
+       if (error) {
+               device_printf(sc->sc_dev,
+                   "direct I/O error %d, r=%d p=%p %s\n",
+                   error, reg, datap,
+                   ISSET(arg, SD_ARG_CMD53_WRITE) ? "write" : "read");
+       }
 
        return error;
 }
@@ -404,6 +421,13 @@
 
        error = sdmmc_mmc_command(sc, &cmd);
 
+       if (error) {
+               device_printf(sc->sc_dev,
+                   "extended I/O error %d, r=%d p=%p l=%d %s\n",
+                   error, reg, datap, datalen,
+                   ISSET(arg, SD_ARG_CMD53_WRITE) ? "write" : "read");
+       }
+
        return error;
 }
 
@@ -603,6 +627,18 @@
 #endif
 
 /*
+ * Abort I/O function of the card
+ */
+int
+sdmmc_io_function_abort(struct sdmmc_function *sf)
+{
+       u_char data = CCCR_CTL_AS(sf->number);
+
+       return sdmmc_io_rw_direct(sf->sc, NULL, SD_IO_CCCR_CTL, &data,
+           SD_ARG_CMD52_WRITE);
+}
+
+/*
  * Reset the I/O functions of the card.
  */
 static void
@@ -612,7 +648,7 @@
 
        if (sdmmc_io_rw_direct(sc, NULL, SD_IO_CCCR_CTL, &data,
            SD_ARG_CMD52_WRITE) == 0)
-               sdmmc_delay(100000);
+               sdmmc_pause(100000, NULL); /* XXX SDMMC_LOCK */
 }
 
 /*
@@ -647,7 +683,7 @@
                        break;
 
                error = ETIMEDOUT;
-               sdmmc_delay(10000);
+               sdmmc_pause(10000, NULL);
        }
        if (error == 0 && ocrp != NULL)
                *ocrp = MMC_R4(cmd.c_resp);
@@ -814,3 +850,4 @@
 
        return error;
 }
+
diff -r c4dd67e8ac4c -r 776904eacd92 sys/dev/sdmmc/sdmmc_mem.c
--- a/sys/dev/sdmmc/sdmmc_mem.c Mon Oct 28 06:00:14 2019 +0000
+++ b/sys/dev/sdmmc/sdmmc_mem.c Mon Oct 28 06:16:46 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmc_mem.c,v 1.68 2019/06/06 20:50:46 jmcneill Exp $  */
+/*     $NetBSD: sdmmc_mem.c,v 1.69 2019/10/28 06:16:46 mlelstv Exp $   */
 /*     $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg Exp $      */
 
 /*
@@ -45,7 +45,7 @@
 /* Routines for SD/MMC memory cards. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.68 2019/06/06 20:50:46 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.69 2019/10/28 06:16:46 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -651,7 +651,7 @@
                }
 
                error = ETIMEDOUT;
-               sdmmc_delay(10000);
+               sdmmc_pause(10000, NULL);
        }
        if (ocrp != NULL) {
                if (error == 0 &&
@@ -1057,7 +1057,7 @@
                }
 
                /*
-                * HS_TIMING must be set to â??0x1â?? before setting BUS_WIDTH
+                * HS_TIMING must be set to 0x1 before setting BUS_WIDTH
                 * for dual data rate operation
                 */
                if (ddr &&
diff -r c4dd67e8ac4c -r 776904eacd92 sys/dev/sdmmc/sdmmcvar.h
--- a/sys/dev/sdmmc/sdmmcvar.h  Mon Oct 28 06:00:14 2019 +0000
+++ b/sys/dev/sdmmc/sdmmcvar.h  Mon Oct 28 06:16:46 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmcvar.h,v 1.32 2019/10/23 05:20:52 hkenken Exp $    */
+/*     $NetBSD: sdmmcvar.h,v 1.33 2019/10/28 06:16:46 mlelstv Exp $    */
 /*     $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $       */
 
 /*
@@ -373,6 +373,7 @@
 int    sdmmc_io_write_region_1(struct sdmmc_function *, int, u_char *, int);
 int    sdmmc_io_function_enable(struct sdmmc_function *);
 void   sdmmc_io_function_disable(struct sdmmc_function *);
+int    sdmmc_io_function_abort(struct sdmmc_function *);
 
 int    sdmmc_read_cis(struct sdmmc_function *, struct sdmmc_cis *);
 void   sdmmc_print_cis(struct sdmmc_function *);
@@ -392,4 +393,6 @@
 int    sdmmc_mem_discard(struct sdmmc_function *, uint32_t, uint32_t);
 int    sdmmc_mem_flush_cache(struct sdmmc_function *, bool);
 
+void   sdmmc_pause(u_int, kmutex_t *);
+
 #endif /* _SDMMCVAR_H_ */



Home | Main Index | Thread Index | Old Index