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_ */

Reply via email to