Module Name: src
Committed By: mlelstv
Date: Mon Oct 28 06:16:46 UTC 2019
Modified Files:
src/sys/dev/sdmmc: sdmmc.c sdmmc_io.c sdmmc_mem.c sdmmcvar.h
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.39 src/sys/dev/sdmmc/sdmmc.c
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/sdmmc/sdmmc_io.c
cvs rdiff -u -r1.68 -r1.69 src/sys/dev/sdmmc/sdmmc_mem.c
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/sdmmc/sdmmcvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/sdmmc/sdmmc.c
diff -u src/sys/dev/sdmmc/sdmmc.c:1.38 src/sys/dev/sdmmc/sdmmc.c:1.39
--- src/sys/dev/sdmmc/sdmmc.c:1.38 Wed Oct 23 05:20:52 2019
+++ src/sys/dev/sdmmc/sdmmc.c Mon Oct 28 06:16:46 2019
@@ -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 @@ sdmmc_enable(struct sdmmc_softc *sc)
}
/* 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 @@ sdmmc_delay(u_int usecs)
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 @@ sdmmc_set_relative_addr(struct sdmmc_sof
/* 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 @@ sdmmc_select_card(struct sdmmc_softc *sc
/* 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 @@ sdmmc_select_card(struct sdmmc_softc *sc
if (error == 0 || sf == NULL)
sc->sc_card = sf;
+ if (error) {
+ device_printf(sc->sc_dev,
+ "sdmmc_select_card: error %d", error);
+ }
+
return error;
}
Index: src/sys/dev/sdmmc/sdmmc_io.c
diff -u src/sys/dev/sdmmc/sdmmc_io.c:1.16 src/sys/dev/sdmmc/sdmmc_io.c:1.17
--- src/sys/dev/sdmmc/sdmmc_io.c:1.16 Mon Sep 2 11:09:42 2019
+++ src/sys/dev/sdmmc/sdmmc_io.c Mon Oct 28 06:16:46 2019
@@ -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 @@ sdmmc_io_init(struct sdmmc_softc *sc, st
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 @@ sdmmc_io_init(struct sdmmc_softc *sc, st
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 @@ sdmmc_io_rw_direct(struct sdmmc_softc *s
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 @@ sdmmc_io_rw_extended(struct sdmmc_softc
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 @@ sdmmc_io_xchg(struct sdmmc_softc *sc, st
#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 @@ sdmmc_io_reset(struct sdmmc_softc *sc)
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 @@ sdmmc_io_send_op_cond(struct sdmmc_softc
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 @@ err:
return error;
}
+
Index: src/sys/dev/sdmmc/sdmmc_mem.c
diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.68 src/sys/dev/sdmmc/sdmmc_mem.c:1.69
--- src/sys/dev/sdmmc/sdmmc_mem.c:1.68 Thu Jun 6 20:50:46 2019
+++ src/sys/dev/sdmmc/sdmmc_mem.c Mon Oct 28 06:16:46 2019
@@ -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 @@ sdmmc_mem_send_op_cond(struct sdmmc_soft
}
error = ETIMEDOUT;
- sdmmc_delay(10000);
+ sdmmc_pause(10000, NULL);
}
if (ocrp != NULL) {
if (error == 0 &&
@@ -1057,7 +1057,7 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s
}
/*
- * 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 &&
Index: src/sys/dev/sdmmc/sdmmcvar.h
diff -u src/sys/dev/sdmmc/sdmmcvar.h:1.32 src/sys/dev/sdmmc/sdmmcvar.h:1.33
--- src/sys/dev/sdmmc/sdmmcvar.h:1.32 Wed Oct 23 05:20:52 2019
+++ src/sys/dev/sdmmc/sdmmcvar.h Mon Oct 28 06:16:46 2019
@@ -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_multi_1(struct sdmmc_
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_write_block(struct sdmmc_f
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_ */