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