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