CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sun Aug 8 16:23:37 UTC 2021 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.h Log Message: Fixup bwfm(4) register bit regarding SDIO device suspend/resume. >From OpenBSD if_bwfm_sdio.h r1.3 To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/sdmmc/if_bwfm_sdio.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/if_bwfm_sdio.h diff -u src/sys/dev/sdmmc/if_bwfm_sdio.h:1.2 src/sys/dev/sdmmc/if_bwfm_sdio.h:1.3 --- src/sys/dev/sdmmc/if_bwfm_sdio.h:1.2 Thu Oct 3 10:53:34 2019 +++ src/sys/dev/sdmmc/if_bwfm_sdio.h Sun Aug 8 16:23:37 2021 @@ -79,7 +79,7 @@ #define BWFM_SDIO_FUNC1_WAKEUPCTRL_HTWAIT (1 << 1) #define BWFM_SDIO_FUNC1_SLEEPCSR 0x1001F #define BWFM_SDIO_FUNC1_SLEEPCSR_KSO (1 << 0) -#define BWFM_SDIO_FUNC1_SLEEPCSR_DEVON (1 << 2) +#define BWFM_SDIO_FUNC1_SLEEPCSR_DEVON (1 << 1) #define BWFM_SDIO_SB_OFT_ADDR_PAGE 0x08000 #define BWFM_SDIO_SB_OFT_ADDR_MASK 0x07FFF
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sun Aug 8 11:11:29 UTC 2021 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Use SMBIOS system product instead of the string "netbsd,generic-acpi" for firmware loading on ACPI systems. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.26 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.27 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.26 Mon Jun 21 03:17:59 2021 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Sun Aug 8 11:11:29 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.26 2021/06/21 03:17:59 christos Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.27 2021/08/08 11:11:29 jmcneill Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -592,10 +592,17 @@ bwfm_fdt_find_phandle(device_t self, dev static const char * bwfm_fdt_get_model(void) { + const char *model; int phandle; phandle = OF_finddevice("/"); - return fdtbus_get_string_index(phandle, "compatible", 0); + model = fdtbus_get_string_index(phandle, "compatible", 0); + if (model == NULL || + (model != NULL && strcmp(model, "netbsd,generic-acpi") == 0)) { + model = pmf_get_platform("system-product"); + } + + return model; } static int
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: msaitoh Date: Tue Aug 3 07:54:39 UTC 2021 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: Use unsigned to avoid undefined behavior in sdmmc_mem_sd_switch(). Found by kUBSan. To generate a diff of this commit: cvs rdiff -u -r1.73 -r1.74 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.73 src/sys/dev/sdmmc/sdmmc_mem.c:1.74 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.73 Sun Jun 13 09:50:02 2021 +++ src/sys/dev/sdmmc/sdmmc_mem.c Tue Aug 3 07:54:39 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.73 2021/06/13 09:50:02 mlelstv Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.74 2021/08/03 07:54:39 msaitoh 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.73 2021/06/13 09:50:02 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.74 2021/08/03 07:54:39 msaitoh Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1604,8 +1604,8 @@ sdmmc_mem_sd_switch(struct sdmmc_functio cmd.c_datalen = statlen; cmd.c_blklen = statlen; cmd.c_opcode = SD_SEND_SWITCH_FUNC; - cmd.c_arg = - (!!mode << 31) | (function << gsft) | (0x00ff & ~(0xf << gsft)); + cmd.c_arg = ((uint32_t)!!mode << 31) | + (function << gsft) | (0x00ff & ~(0xf << gsft)); cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1 | SCF_RSP_SPI_R1; if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) cmd.c_dmamap = sc->sc_dmap;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: christos Date: Mon Jun 21 03:18:00 UTC 2021 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: fix proplib deprecation To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.25 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.26 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.25 Tue Jan 26 22:10:21 2021 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Sun Jun 20 23:17:59 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.25 2021/01/27 03:10:21 thorpej Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.26 2021/06/21 03:17:59 christos Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -565,7 +565,7 @@ bwfm_fdt_find_phandle(device_t self, dev /* locate in FDT */ dict = device_properties(self); - if (prop_dictionary_get_cstring_nocopy(dict, "fdt-path", &str)) { + if (prop_dictionary_get_string(dict, "fdt-path", &str)) { /* search in FDT */ phandle = OF_finddevice(str); } else { @@ -576,7 +576,7 @@ bwfm_fdt_find_phandle(device_t self, dev return -1; /* locate in FDT */ dict = device_properties(dev); - if (!prop_dictionary_get_cstring_nocopy(dict, "fdt-path", &str)) + if (!prop_dictionary_get_string(dict, "fdt-path", &str)) return -1; /* are we the only FDT child ? */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sun Jun 13 09:58:28 UTC 2021 Modified Files: src/sys/dev/sdmmc: sdmmc.c Log Message: Don't crash on detach where interlock == NULL. To generate a diff of this commit: cvs rdiff -u -r1.41 -r1.42 src/sys/dev/sdmmc/sdmmc.c 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.41 src/sys/dev/sdmmc/sdmmc.c:1.42 --- src/sys/dev/sdmmc/sdmmc.c:1.41 Sat Apr 24 23:36:59 2021 +++ src/sys/dev/sdmmc/sdmmc.c Sun Jun 13 09:58:28 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc.c,v 1.41 2021/04/24 23:36:59 thorpej Exp $ */ +/* $NetBSD: sdmmc.c,v 1.42 2021/06/13 09:58:28 mlelstv Exp $ */ /* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */ /* @@ -49,7 +49,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.41 2021/04/24 23:36:59 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.42 2021/06/13 09:58:28 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -300,14 +300,16 @@ sdmmc_del_task(struct sdmmc_softc *sc, s } else { KASSERT(task->sc == NULL); KASSERT(!task->onqueue); - mutex_exit(interlock); + if (interlock != NULL) + mutex_exit(interlock); while (sc->sc_curtask == task) { KASSERT(curlwp != sc->sc_tskq_lwp); cv_wait(&sc->sc_tskq_cv, &sc->sc_tskq_mtx); } - if (!mutex_tryenter(interlock)) { + if (interlock == NULL || !mutex_tryenter(interlock)) { mutex_exit(&sc->sc_tskq_mtx); - mutex_enter(interlock); + if (interlock != NULL) +mutex_enter(interlock); mutex_enter(&sc->sc_tskq_mtx); } cancelled = false;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sun Jun 13 09:50:02 UTC 2021 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: Be less verbose normally and more when debugging. To generate a diff of this commit: cvs rdiff -u -r1.72 -r1.73 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.72 src/sys/dev/sdmmc/sdmmc_mem.c:1.73 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.72 Mon May 11 09:51:47 2020 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sun Jun 13 09:50:02 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.72 2020/05/11 09:51:47 jdc Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.73 2021/06/13 09:50:02 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.72 2020/05/11 09:51:47 jdc Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.73 2021/06/13 09:50:02 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -255,8 +255,11 @@ mmc_mode: } error = sdmmc_mem_signal_voltage(sc, SDMMC_SIGNAL_VOLTAGE_180); - if (error) + if (error) { + DPRINTF(("%s: voltage change on host failed\n", + SDMMCDEVNAME(sc))); goto out; + } SET(sc->sc_flags, SMF_UHS_MODE); } @@ -264,10 +267,6 @@ mmc_mode: out: SDMMC_UNLOCK(sc); - if (error) - printf("%s: %s failed with error %d\n", SDMMCDEVNAME(sc), - __func__, error); - return error; }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: msaitoh Date: Thu May 13 05:54:15 UTC 2021 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: Use unsigned to avoid undefined behavior in hwrite[12](). Found by kUBSan. To generate a diff of this commit: cvs rdiff -u -r1.109 -r1.110 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.109 src/sys/dev/sdmmc/sdhc.c:1.110 --- src/sys/dev/sdmmc/sdhc.c:1.109 Sat Apr 24 23:36:59 2021 +++ src/sys/dev/sdmmc/sdhc.c Thu May 13 05:54:14 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.109 2021/04/24 23:36:59 thorpej Exp $ */ +/* $NetBSD: sdhc.c,v 1.110 2021/05/13 05:54:14 msaitoh Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.109 2021/04/24 23:36:59 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.110 2021/05/13 05:54:14 msaitoh Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -138,7 +138,7 @@ hwrite1(struct sdhc_host *hp, bus_size_t const size_t shift = 8 * (o & 3); o &= -4; uint32_t tmp = bus_space_read_4(hp->iot, hp->ioh, o); - tmp = (val << shift) | (tmp & ~(0xff << shift)); + tmp = (val << shift) | (tmp & ~(0xffU << shift)); bus_space_write_4(hp->iot, hp->ioh, o, tmp); } } @@ -153,7 +153,7 @@ hwrite2(struct sdhc_host *hp, bus_size_t const size_t shift = 8 * (o & 2); o &= -4; uint32_t tmp = bus_space_read_4(hp->iot, hp->ioh, o); - tmp = (val << shift) | (tmp & ~(0x << shift)); + tmp = (val << shift) | (tmp & ~(0xU << shift)); bus_space_write_4(hp->iot, hp->ioh, o, tmp); } }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sat Mar 13 23:26:47 UTC 2021 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: Enable block count only for count > 0. Don't enable autostop when command sets new flag SCF_NO_STOP. To generate a diff of this commit: cvs rdiff -u -r1.107 -r1.108 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.107 src/sys/dev/sdmmc/sdhc.c:1.108 --- src/sys/dev/sdmmc/sdhc.c:1.107 Wed Jul 15 15:57:52 2020 +++ src/sys/dev/sdmmc/sdhc.c Sat Mar 13 23:26:47 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.107 2020/07/15 15:57:52 msaitoh Exp $ */ +/* $NetBSD: sdhc.c,v 1.108 2021/03/13 23:26:47 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.107 2020/07/15 15:57:52 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.108 2021/03/13 23:26:47 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -389,6 +389,8 @@ sdhc_host_found(struct sdhc_softc *sc, b } } + aprint_verbose(", caps <%08x/%08x>", caps, caps2); + const u_int retuning_mode = (caps2 >> SDHC_RETUNING_MODES_SHIFT) & SDHC_RETUNING_MODES_MASK; if (retuning_mode == SDHC_RETUNING_MODE_1) { @@ -1724,14 +1726,17 @@ sdhc_start_command(struct sdhc_host *hp, } /* Prepare transfer mode register value. (2.2.5) */ - mode = SDHC_BLOCK_COUNT_ENABLE; + mode = 0; if (ISSET(cmd->c_flags, SCF_CMD_READ)) mode |= SDHC_READ_MODE; - if (blkcount > 1) { - mode |= SDHC_MULTI_BLOCK_MODE; - /* XXX only for memory commands? */ - if (!ISSET(sc->sc_flags, SDHC_FLAG_NO_AUTO_STOP)) - mode |= SDHC_AUTO_CMD12_ENABLE; + if (blkcount > 0) { + mode |= SDHC_BLOCK_COUNT_ENABLE; + if (blkcount > 1) { + mode |= SDHC_MULTI_BLOCK_MODE; + if (!ISSET(sc->sc_flags, SDHC_FLAG_NO_AUTO_STOP) + && !ISSET(cmd->c_flags, SCF_NO_STOP)) +mode |= SDHC_AUTO_CMD12_ENABLE; + } } if (cmd->c_dmamap != NULL && cmd->c_datalen > 0 && ISSET(hp->flags, SHF_MODE_DMAEN)) {
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sat Mar 13 23:22:44 UTC 2021 Modified Files: src/sys/dev/sdmmc: sdmmcvar.h Log Message: define NO_STOP flag To generate a diff of this commit: cvs rdiff -u -r1.35 -r1.36 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/sdmmcvar.h diff -u src/sys/dev/sdmmc/sdmmcvar.h:1.35 src/sys/dev/sdmmc/sdmmcvar.h:1.36 --- src/sys/dev/sdmmc/sdmmcvar.h:1.35 Sun May 24 17:26:18 2020 +++ src/sys/dev/sdmmc/sdmmcvar.h Sat Mar 13 23:22:44 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcvar.h,v 1.35 2020/05/24 17:26:18 riastradh Exp $ */ +/* $NetBSD: sdmmcvar.h,v 1.36 2021/03/13 23:22:44 mlelstv Exp $ */ /* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -125,6 +125,7 @@ struct sdmmc_command { #define SCF_XFER_SDHC (1U << 15) /* card is SDHC */ #define SCF_POLL (1U << 16) /* polling required */ #define SCF_NEED_BOUNCE (1U << 17) /* (driver) transfer requires bounce buffer */ +#define SCF_NO_STOP (1U << 18) /* don't enable automatic stop CMD12 */ /* response types */ #define SCF_RSP_R0 0 /* none */ #define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Tue Nov 3 09:26:41 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Continue parsing frames after empty payload. Add diagnostic messages. To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.23 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.24 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.23 Wed Jul 22 17:23:12 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Tue Nov 3 09:26:41 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.23 2020/07/22 17:23:12 riastradh Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.24 2020/11/03 09:26:41 mlelstv Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -1478,6 +1478,8 @@ bwfm_sdio_task1(struct bwfm_sdio_softc * DPRINTF(("%s: hostint 0x%" PRIx32 "\n", DEVNAME(sc), hostint)); bwfm_sdio_dev_write(sc, SDPCMD_TOSBMAILBOX, SDPCMD_TOSBMAILBOX_INT_ACK); + if (hostint & SDPCMD_TOHOSTMAILBOXDATA_FWHALT) + printf("%s: firmware halted\n", DEVNAME(sc)); if (hostint & SDPCMD_TOHOSTMAILBOXDATA_NAKHANDLED) sc->sc_rxskip = false; if (hostint & SDPCMD_TOHOSTMAILBOXDATA_DEVREADY || @@ -1726,6 +1728,8 @@ bwfm_sdio_rx_frames(struct bwfm_sdio_sof flen = hwhdr->frmlen - (sizeof(*hwhdr) + sizeof(*swhdr)); if (flen == 0) { + DPRINTF(("%s: empty payload (frmlen=%u)\n", + DEVNAME(sc), hwhdr->frmlen)); nextlen = swhdr->nextlen << 4; continue; } @@ -1794,11 +1798,10 @@ bwfm_sdio_rx_frames(struct bwfm_sdio_sof } m_adj(m, hoff); /* don't pass empty packet to stack */ - if (m->m_len == 0) { + if (m->m_len > 0) +bwfm_rx(&sc->sc_sc, m); + else m_freem(m); -break; - } - bwfm_rx(&sc->sc_sc, m); nextlen = swhdr->nextlen << 4; break; case BWFM_SDIO_SWHDR_CHANNEL_GLOM:
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sat Oct 17 09:36:45 UTC 2020 Modified Files: src/sys/dev/sdmmc: sdmmc_io.c Log Message: Fix error message. No functional change, both commands use the same bit to select read or write mode. To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/dev/sdmmc/sdmmc_io.c 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_io.c diff -u src/sys/dev/sdmmc/sdmmc_io.c:1.20 src/sys/dev/sdmmc/sdmmc_io.c:1.21 --- src/sys/dev/sdmmc/sdmmc_io.c:1.20 Sun May 24 17:26:18 2020 +++ src/sys/dev/sdmmc/sdmmc_io.c Sat Oct 17 09:36:45 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_io.c,v 1.20 2020/05/24 17:26:18 riastradh Exp $ */ +/* $NetBSD: sdmmc_io.c,v 1.21 2020/10/17 09:36:45 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.20 2020/05/24 17:26:18 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.21 2020/10/17 09:36:45 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -375,7 +375,7 @@ sdmmc_io_rw_direct(struct sdmmc_softc *s 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"); + ISSET(arg, SD_ARG_CMD52_WRITE) ? "write" : "read"); } return error;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: riastradh Date: Wed Jul 22 17:23:12 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Sort includes. Nix trailing whitespace. No functional change intended. To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.22 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.23 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.22 Wed Jul 22 17:22:43 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Wed Jul 22 17:23:12 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.22 2020/07/22 17:22:43 riastradh Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.23 2020/07/22 17:23:12 riastradh Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -18,36 +18,36 @@ */ #include -#include +#include + #include +#include #include #include +#include #include -#include +#include #include #include -#include -#include +#include #include #include #include -#include #include +#include #include -#include -#include - #include -#include -#include - +#include #include #include +#include #include +#include +#include #ifdef BWFM_DEBUG #define DPRINTF(x) do { if (bwfm_debug > 0) printf x; } while (0)
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: riastradh Date: Wed Jul 22 17:22:43 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Need for kmem_*. Currently accidentally side-loaded by . To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.21 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.22 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.21 Mon Jul 20 06:47:02 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Wed Jul 22 17:22:43 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.21 2020/07/20 06:47:02 mrg Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.22 2020/07/22 17:22:43 riastradh Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -27,6 +27,7 @@ #include #include #include +#include #include #include
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mrg Date: Mon Jul 20 06:47:03 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: clear all interrupts, not just those we expect from the hostintmask. this removes the final hard hang i have seen in pinebookpro wifi, though one may still need to 'ifconfig bwfm0 down up' occasionally, so we still have bugs to fix here (the hang is usually associated with 'checksum error' from bwfm/sdio.) To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.20 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.21 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.20 Mon Jul 20 06:44:55 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Mon Jul 20 06:47:02 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.20 2020/07/20 06:44:55 mrg Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.21 2020/07/20 06:47:02 mrg Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -1466,7 +1466,6 @@ bwfm_sdio_task1(struct bwfm_sdio_softc * intstat = bwfm_sdio_dev_read(sc, BWFM_SDPCMD_INTSTATUS); DPRINTF(("%s: intstat 0x%" PRIx32 "\n", DEVNAME(sc), intstat)); - intstat &= (SDPCMD_INTSTATUS_HMB_SW_MASK|SDPCMD_INTSTATUS_CHIPACTIVE); if (intstat) bwfm_sdio_dev_write(sc, BWFM_SDPCMD_INTSTATUS, intstat);
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mrg Date: Mon Jul 20 06:44:55 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: only ask for SDPCMD_INTSTATUS_HMB_SW_MASK and SDPCMD_INTSTATUS_CHIPACTIVE interrupts, not all of them. we only ack these ones. mostly fixes pinebookpro wifi hard hangs. still is problematic and can trigger interrupt storm that appears as a hard hang without NET_MPSAFE, and a follow up, less clearly right, change will reduce that to a soft hang of the interface that can be cleared with 'ifconfig bwfm0 down up', and even often recovers itself now. To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.19 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.20 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.19 Tue Jun 23 10:09:33 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Mon Jul 20 06:44:55 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.19 2020/06/23 10:09:33 martin Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.20 2020/07/20 06:44:55 mrg Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -505,9 +505,8 @@ bwfm_sdio_attachhook(device_t self) goto err; } -// bwfm_sdio_dev_write(sc, SDPCMD_HOSTINTMASK, -// SDPCMD_INTSTATUS_HMB_SW_MASK | SDPCMD_INTSTATUS_CHIPACTIVE); - bwfm_sdio_dev_write(sc, SDPCMD_HOSTINTMASK, 0x); + bwfm_sdio_dev_write(sc, SDPCMD_HOSTINTMASK, + SDPCMD_INTSTATUS_HMB_SW_MASK | SDPCMD_INTSTATUS_CHIPACTIVE); bwfm_sdio_write_1(sc, BWFM_SDIO_WATERMARK, 8); if (bwfm_chip_sr_capable(bwfm)) {
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: msaitoh Date: Wed Jul 15 15:57:52 UTC 2020 Modified Files: src/sys/dev/sdmmc: sdhc.c sdhcreg.h Log Message: Identify SDHC 4.1 and 4.2. From {DragonFly,Free}BSD. To generate a diff of this commit: cvs rdiff -u -r1.106 -r1.107 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.20 -r1.21 src/sys/dev/sdmmc/sdhcreg.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.106 src/sys/dev/sdmmc/sdhc.c:1.107 --- src/sys/dev/sdmmc/sdhc.c:1.106 Mon Oct 28 18:11:15 2019 +++ src/sys/dev/sdmmc/sdhc.c Wed Jul 15 15:57:52 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.106 2019/10/28 18:11:15 joerg Exp $ */ +/* $NetBSD: sdhc.c,v 1.107 2020/07/15 15:57:52 msaitoh Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.106 2019/10/28 18:11:15 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.107 2020/07/15 15:57:52 msaitoh Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -324,6 +324,12 @@ sdhc_host_found(struct sdhc_softc *sc, b case SDHC_SPEC_VERS_400: aprint_normal("4.0"); break; + case SDHC_SPEC_VERS_410: + aprint_normal("4.1"); + break; + case SDHC_SPEC_VERS_420: + aprint_normal("4.2"); + break; case SDHC_SPEC_NOVERS: hp->specver = -1; aprint_normal("NO-VERS"); Index: src/sys/dev/sdmmc/sdhcreg.h diff -u src/sys/dev/sdmmc/sdhcreg.h:1.20 src/sys/dev/sdmmc/sdhcreg.h:1.21 --- src/sys/dev/sdmmc/sdhcreg.h:1.20 Wed Oct 23 05:20:52 2019 +++ src/sys/dev/sdmmc/sdhcreg.h Wed Jul 15 15:57:52 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcreg.h,v 1.20 2019/10/23 05:20:52 hkenken Exp $ */ +/* $NetBSD: sdhcreg.h,v 1.21 2020/07/15 15:57:52 msaitoh Exp $ */ /* $OpenBSD: sdhcreg.h,v 1.4 2006/07/30 17:20:40 fgsch Exp $ */ /* @@ -248,6 +248,8 @@ #define SDHC_SPEC_VERS_200 0x01 #define SDHC_SPEC_VERS_300 0x02 #define SDHC_SPEC_VERS_400 0x03 +#define SDHC_SPEC_VERS_410 0x04 +#define SDHC_SPEC_VERS_420 0x05 #define SDHC_SPEC_NOVERS 0xff /* dummy */ /* SDHC_CAPABILITIES decoding */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: martin Date: Tue Jun 23 10:09:33 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Make this work on big endian machines To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.18 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.19 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.18 Sat May 30 15:55:47 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Tue Jun 23 10:09:33 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.18 2020/05/30 15:55:47 jdolecek Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.19 2020/06/23 10:09:33 martin Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -689,7 +689,7 @@ bwfm_sdio_read_4(struct bwfm_sdio_softc sf = sc->sc_sf[1]; rv = sdmmc_io_read_4(sf, addr); - return rv; + return htole32(rv); } static void @@ -732,7 +732,7 @@ bwfm_sdio_write_4(struct bwfm_sdio_softc else sf = sc->sc_sf[1]; - sdmmc_io_write_4(sf, addr, data); + sdmmc_io_write_4(sf, addr, htole32(data)); } static int
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: riastradh Date: Sun May 24 17:26:18 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c ld_sdmmc.c sdmmc.c sdmmc_io.c sdmmcvar.h Log Message: Fix races in sdmmc tasks and teach ld@sdmmc to abort xfers on detach. - Teach sdmmc_add_task to queue it only if not already queued. - Remove now-redundant logic to avoid repeated queueing elsewhere. - Teach sdmmc_del_task to wait until task has completed. - Call sdmmc_del_task in various needful places. - Replace abuse of pcq by a lock and a tailq. (pcq is multi-producer, _single_-consumer, but there are potentially multiple consumers here and really only one producer.) - Teach ld_sdmmc to abort xfers on detach. (Mechanism is kinda kludgey but it'll do for now; any effort one is tempted to spend overhauling this should be spent overhauling sdmmc to support proper asynchronous commands.) - Make sure ld_sdmmc_discard either returns failure or eventually calls ldenddiscard. XXX Currently ld_sdmmc_detach aborts xfers _before_ ldbegindetach has has committed to detaching or not. This is currently necessary to avoid a deadlock because ldbegindetach waits for xfers to drain -- which strikes me as wrong; ldbegindetach shouldn't wait for anything, and should only make the decision to commit to detaching or not so the caller can decide whether to abort xfers before we actually wait for them in ldenddetach. XXX pullup -- although this changes some kernel symbols (sdmmc_add_task and sdmmc_del_task), it shouldn't affect any existing modules; the only module that uses sdmmc is ld_sdmmc.kmod, which is `.if 0' in the build so there shouldn't be any of them floating around. To generate a diff of this commit: cvs rdiff -u -r1.15 -r1.16 src/sys/dev/sdmmc/if_bwfm_sdio.c cvs rdiff -u -r1.37 -r1.38 src/sys/dev/sdmmc/ld_sdmmc.c cvs rdiff -u -r1.39 -r1.40 src/sys/dev/sdmmc/sdmmc.c cvs rdiff -u -r1.19 -r1.20 src/sys/dev/sdmmc/sdmmc_io.c cvs rdiff -u -r1.34 -r1.35 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.15 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.16 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.15 Thu May 7 11:46:27 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Sun May 24 17:26:18 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.15 2020/05/07 11:46:27 macallan Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.16 2020/05/24 17:26:18 riastradh Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -69,7 +69,6 @@ enum bwfm_sdio_clkstate { struct bwfm_sdio_softc { struct bwfm_softc sc_sc; kmutex_t sc_lock; - kmutex_t sc_intr_lock; bool sc_bwfm_attached; @@ -361,10 +360,8 @@ bwfm_sdio_attach(device_t parent, device mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); cv_init(&sc->sc_rxctl_cv, "bwfmctl"); - mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NONE); sdmmc_init_task(&sc->sc_task, bwfm_sdio_task, sc); - sc->sc_task_queued = false; sc->sc_bounce_size = 64 * 1024; sc->sc_bounce_buf = kmem_alloc(sc->sc_bounce_size, KM_SLEEP); @@ -620,10 +617,11 @@ bwfm_sdio_detach(device_t self, int flag if (sc->sc_bwfm_attached) bwfm_detach(&sc->sc_sc, flags); + sdmmc_del_task(sc->sc_sf[1]->sc, &sc->sc_task, NULL); + kmem_free(sc->sc_sf, sc->sc_sf_size); kmem_free(sc->sc_bounce_buf, sc->sc_bounce_size); - mutex_destroy(&sc->sc_intr_lock); cv_destroy(&sc->sc_rxctl_cv); mutex_destroy(&sc->sc_lock); @@ -1426,11 +1424,7 @@ bwfm_sdio_intr1(void *v, const char *nam DPRINTF(("%s: %s\n", DEVNAME(sc), name)); - mutex_enter(&sc->sc_intr_lock); - if (!sdmmc_task_pending(&sc->sc_task)) - sdmmc_add_task(sc->sc_sf[1]->sc, &sc->sc_task); - sc->sc_task_queued = true; - mutex_exit(&sc->sc_intr_lock); + sdmmc_add_task(sc->sc_sf[1]->sc, &sc->sc_task); return 1; } @@ -1444,33 +1438,13 @@ static void bwfm_sdio_task(void *v) { struct bwfm_sdio_softc *sc = (void *)v; -#ifdef BWFM_DEBUG - unsigned count = 0; -#endif - - mutex_enter(&sc->sc_intr_lock); - while (sc->sc_task_queued) { -#ifdef BWFM_DEBUG - ++count; -#endif - sc->sc_task_queued = false; - mutex_exit(&sc->sc_intr_lock); - - mutex_enter(&sc->sc_lock); - bwfm_sdio_task1(sc); -#ifdef BWFM_DEBUG - bwfm_sdio_debug_console(sc); -#endif - mutex_exit(&sc->sc_lock); - - mutex_enter(&sc->sc_intr_lock); - } - mutex_exit(&sc->sc_intr_lock); + mutex_enter(&sc->sc_lock); + bwfm_sdio_task1(sc); #ifdef BWFM_DEBUG - if (count > 1) - DPRINTF(("%s: finished %u tasks\n", DEVNAME(sc), count)); + bwfm_sdio_debug_console(sc); #endif + mutex_exit(&sc->sc_lock); } static void Index: src/sys/dev/sdmmc/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.37 src/sys/dev/sdmmc/ld_sdmmc.c:1.38 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.37 Mon Oct 28 06:31:39 2019 +++ src/sys/dev
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jdc Date: Mon May 11 09:51:47 UTC 2020 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: If the controller doesn't support switch func (opcode 6) then skip setting this but continue with other settings. This allows us to use a card, albeit at a lower speed. To generate a diff of this commit: cvs rdiff -u -r1.71 -r1.72 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.71 src/sys/dev/sdmmc/sdmmc_mem.c:1.72 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.71 Sat Jan 4 22:28:26 2020 +++ src/sys/dev/sdmmc/sdmmc_mem.c Mon May 11 09:51:47 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.71 2020/01/04 22:28:26 mlelstv Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.72 2020/05/11 09:51:47 jdc 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.71 2020/01/04 22:28:26 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.72 2020/05/11 09:51:47 jdc Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -833,9 +833,14 @@ sdmmc_mem_sd_init(struct sdmmc_softc *sc DPRINTF(("%s: switch func mode 0\n", SDMMCDEVNAME(sc))); error = sdmmc_mem_sd_switch(sf, 0, 1, 0, &status); if (error) { - aprint_error_dev(sc->sc_dev, - "switch func mode 0 failed\n"); - return error; + if (error == ENOTSUP) { +/* Not supported by controller */ +goto skipswitchfuncs; + } else { +aprint_error_dev(sc->sc_dev, +"switch func mode 0 failed\n"); +return error; + } } support_func = SFUNC_STATUS_GROUP(&status, 1); @@ -887,6 +892,7 @@ sdmmc_mem_sd_init(struct sdmmc_softc *sc delay(25); } } +skipswitchfuncs: /* update bus clock */ if (sc->sc_busclk > sf->csd.tran_speed)
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: macallan Date: Thu May 7 11:46:27 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: add entry for BCM43362, found on Cubietruck ok jmcneill@ To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.14 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.15 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.14 Wed Mar 25 03:44:45 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Thu May 7 11:46:27 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.14 2020/03/25 03:44:45 thorpej Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.15 2020/05/07 11:46:27 macallan Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -297,6 +297,11 @@ static const struct bwfm_sdio_product { SDMMC_PRODUCT_BROADCOM_BCM43455, SDMMC_CIS_BROADCOM_BCM43455 }, + { + SDMMC_VENDOR_BROADCOM, + SDMMC_PRODUCT_BROADCOM_BCM43362, + SDMMC_CIS_BROADCOM_BCM43362 + }, }; static const char *compatible[] = {
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: thorpej Date: Wed Jan 29 06:00:27 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Adopt . To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.12 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.13 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.12 Sat Jan 4 14:52:52 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Wed Jan 29 06:00:27 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.12 2020/01/04 14:52:52 mlelstv Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.13 2020/01/29 06:00:27 thorpej Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -1610,7 +1610,7 @@ bwfm_sdio_tx_frames(struct bwfm_sdio_sof bwfm_sdio_tx_ctrlframe(sc, m); else { bwfm_sdio_tx_dataframe(sc, m); - ifp->if_opackets++; + if_statinc(ifp, if_opackets); ifstart = true; }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sat Jan 4 22:28:26 UTC 2020 Modified Files: src/sys/dev/sdmmc: sdmmc_io.c sdmmc_mem.c Log Message: Be less noisy for some commands. To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/sys/dev/sdmmc/sdmmc_io.c cvs rdiff -u -r1.70 -r1.71 src/sys/dev/sdmmc/sdmmc_mem.c 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_io.c diff -u src/sys/dev/sdmmc/sdmmc_io.c:1.18 src/sys/dev/sdmmc/sdmmc_io.c:1.19 --- src/sys/dev/sdmmc/sdmmc_io.c:1.18 Mon Oct 28 06:20:01 2019 +++ src/sys/dev/sdmmc/sdmmc_io.c Sat Jan 4 22:28:26 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_io.c,v 1.18 2019/10/28 06:20:01 mlelstv Exp $ */ +/* $NetBSD: sdmmc_io.c,v 1.19 2020/01/04 22:28:26 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.18 2019/10/28 06:20:01 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.19 2020/01/04 22:28:26 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -52,7 +52,7 @@ struct sdmmc_intr_handler { }; static int sdmmc_io_rw_direct(struct sdmmc_softc *, - struct sdmmc_function *, int, u_char *, int); + struct sdmmc_function *, int, u_char *, int, bool); static int sdmmc_io_rw_extended(struct sdmmc_softc *, struct sdmmc_function *, int, u_char *, int, int); #if 0 @@ -341,7 +341,7 @@ sdmmc_io_function_disable(struct sdmmc_f static int sdmmc_io_rw_direct(struct sdmmc_softc *sc, struct sdmmc_function *sf, -int reg, u_char *datap, int arg) +int reg, u_char *datap, int arg, bool toutok) { struct sdmmc_command cmd; int error; @@ -364,12 +364,14 @@ sdmmc_io_rw_direct(struct sdmmc_softc *s cmd.c_opcode = SD_IO_RW_DIRECT; cmd.c_arg = arg; cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5; + if (toutok) + cmd.c_flags |= SCF_TOUT_OK; error = sdmmc_mmc_command(sc, &cmd); if (error == 0) *datap = SD_R5_DATA(cmd.c_resp); - if (error) { + if (error && error != ETIMEDOUT) { device_printf(sc->sc_dev, "direct I/O error %d, r=%d p=%p %s\n", error, reg, datap, @@ -439,7 +441,7 @@ sdmmc_io_read_1(struct sdmmc_function *s /* Don't lock */ (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, - SD_ARG_CMD52_READ); + SD_ARG_CMD52_READ, false); return data; } @@ -450,7 +452,7 @@ sdmmc_io_write_1(struct sdmmc_function * /* Don't lock */ (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, - SD_ARG_CMD52_WRITE); + SD_ARG_CMD52_WRITE, false); } uint16_t @@ -622,7 +624,7 @@ sdmmc_io_xchg(struct sdmmc_softc *sc, st /* Don't lock */ return sdmmc_io_rw_direct(sc, sf, reg, datap, - SD_ARG_CMD52_WRITE|SD_ARG_CMD52_EXCHANGE); + SD_ARG_CMD52_WRITE|SD_ARG_CMD52_EXCHANGE, false); } #endif @@ -635,7 +637,7 @@ sdmmc_io_function_abort(struct sdmmc_fun 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); + SD_ARG_CMD52_WRITE, true); } /* @@ -647,7 +649,7 @@ sdmmc_io_reset(struct sdmmc_softc *sc) u_char data = CCCR_CTL_RES; if (sdmmc_io_rw_direct(sc, NULL, SD_IO_CCCR_CTL, &data, - SD_ARG_CMD52_WRITE) == 0) + SD_ARG_CMD52_WRITE, true) == 0) sdmmc_pause(10, NULL); /* XXX SDMMC_LOCK */ } Index: src/sys/dev/sdmmc/sdmmc_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.70 src/sys/dev/sdmmc/sdmmc_mem.c:1.71 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.70 Mon Oct 28 06:31:39 2019 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sat Jan 4 22:28:26 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.70 2019/10/28 06:31:39 mlelstv Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.71 2020/01/04 22:28:26 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.70 2019/10/28 06:31:39 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.71 2020/01/04 22:28:26 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -676,7 +676,7 @@ sdmmc_mem_send_if_cond(struct sdmmc_soft memset(&cmd, 0, sizeof(cmd)); cmd.c_arg = ocr; - cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R7 | SCF_RSP_SPI_R7; + cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R7 | SCF_RSP_SPI_R7 | SCF_TOUT_OK; cmd.c_opcode = SD_SEND_IF_COND; error = sdmmc_mmc_command(sc, &cmd);
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sat Jan 4 14:52:52 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: size check was backwards. To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.11 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.12 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.11 Wed Jan 1 12:17:13 2020 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Sat Jan 4 14:52:52 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.11 2020/01/01 12:17:13 jmcneill Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.12 2020/01/04 14:52:52 mlelstv Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -1728,7 +1728,7 @@ bwfm_sdio_rxctl(struct bwfm_softc *bwfm, if (err) return 1; - if (m->m_len < *lenp) { + if (m->m_len > *lenp) { m_freem(m); return 1; }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Wed Jan 1 12:17:13 UTC 2020 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Use correct firmware for BCM43456 To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.10 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.11 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.10 Mon Dec 30 16:28:14 2019 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Wed Jan 1 12:17:13 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.10 2019/12/30 16:28:14 mlelstv Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.11 2020/01/01 12:17:13 jmcneill Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -234,6 +234,11 @@ static const struct bwfm_sdio_product { SDMMC_PRODUCT_BROADCOM_BCM43430, SDMMC_CIS_BROADCOM_BCM43430 }, + { + SDMMC_VENDOR_BROADCOM, + SDMMC_PRODUCT_BROADCOM_BCM43455, + SDMMC_CIS_BROADCOM_BCM43455 + }, }; static const char *compatible[] = { @@ -397,8 +402,13 @@ bwfm_sdio_attachhook(device_t self) nvname = "brcmfmac4334-sdio.txt"; break; case BRCM_CC_4345_CHIP_ID: - name = "brcmfmac43455-sdio.bin"; - nvname = "brcmfmac43455-sdio.txt"; + if ((0x200 & __BIT(bwfm->sc_chip.ch_chiprev)) != 0) { + name = "brcmfmac43456-sdio.bin"; + nvname = "brcmfmac43456-sdio.txt"; + } else { + name = "brcmfmac43455-sdio.bin"; + nvname = "brcmfmac43455-sdio.txt"; + } break; case BRCM_CC_43340_CHIP_ID: name = "brcmfmac43340-sdio.bin";
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Wed Jan 1 12:15:53 UTC 2020 Modified Files: src/sys/dev/sdmmc: sdmmcdevs Log Message: Add product ID for Broadcom BCM43455 To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/sys/dev/sdmmc/sdmmcdevs 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/sdmmcdevs diff -u src/sys/dev/sdmmc/sdmmcdevs:1.7 src/sys/dev/sdmmc/sdmmcdevs:1.8 --- src/sys/dev/sdmmc/sdmmcdevs:1.7 Mon Oct 28 06:31:39 2019 +++ src/sys/dev/sdmmc/sdmmcdevs Wed Jan 1 12:15:53 2020 @@ -1,4 +1,4 @@ - $NetBSD: sdmmcdevs,v 1.7 2019/10/28 06:31:39 mlelstv Exp $ + $NetBSD: sdmmcdevs,v 1.8 2020/01/01 12:15:53 jmcneill Exp $ /* $OpenBSD: sdmmcdevs,v 1.8 2007/05/11 17:16:16 mglocker Exp $ */ /* @@ -59,6 +59,7 @@ product BROADCOM BCM43340 0xa94c BCM 431 product BROADCOM BCM43341 0xa94d BCM 43141 product BROADCOM BCM43362 0xa962 BCM 43362 product BROADCOM BCM43430 0xa9a6 BCM 43430 +product BROADCOM BCM43455 0xa9bf BCM 43455 /* C-guys, Inc. */ product CGUYS TIACX100 0x0001 TI ACX100 SD-Link11b WiFi Card
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Wed Jan 1 12:16:14 UTC 2020 Modified Files: src/sys/dev/sdmmc: sdmmcdevs.h Log Message: regen To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/sys/dev/sdmmc/sdmmcdevs.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/sdmmcdevs.h diff -u src/sys/dev/sdmmc/sdmmcdevs.h:1.7 src/sys/dev/sdmmc/sdmmcdevs.h:1.8 --- src/sys/dev/sdmmc/sdmmcdevs.h:1.7 Mon Oct 28 06:32:10 2019 +++ src/sys/dev/sdmmc/sdmmcdevs.h Wed Jan 1 12:16:14 2020 @@ -1,10 +1,10 @@ -/* $NetBSD: sdmmcdevs.h,v 1.7 2019/10/28 06:32:10 mlelstv Exp $ */ +/* $NetBSD: sdmmcdevs.h,v 1.8 2020/01/01 12:16:14 jmcneill Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * NetBSD: sdmmcdevs,v 1.7 2019/10/28 06:31:39 mlelstv Exp + * NetBSD: sdmmcdevs,v 1.8 2020/01/01 12:15:53 jmcneill Exp */ /* $OpenBSD: sdmmcdevs,v 1.8 2007/05/11 17:16:16 mglocker Exp $ */ @@ -83,6 +83,8 @@ #define SDMMC_PRODUCT_BROADCOM_BCM43362 0xa962 #define SDMMC_CIS_BROADCOM_BCM43430 { NULL, NULL, NULL, NULL } #define SDMMC_PRODUCT_BROADCOM_BCM43430 0xa9a6 +#define SDMMC_CIS_BROADCOM_BCM43455 { NULL, NULL, NULL, NULL } +#define SDMMC_PRODUCT_BROADCOM_BCM43455 0xa9bf /* C-guys, Inc. */ #define SDMMC_CIS_CGUYS_TIACX100 { NULL, NULL, NULL, NULL }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Mon Dec 30 16:28:15 UTC 2019 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Follow the Linux driver an use the FDT "compatible" property to build a filename for the nvram config file, fall back to the standard filename. E.g. # ofctl -p / [Caching 123 nodes and 1093 properties] #address-cells 0001 1 #size-cells 0001 1 compatible 73696e6f 766f6970 2c627069 2d6d322d "sinovoip,bpi-m2- 0010: 7a65726f 00.. zero" 0015: 616c6c77 696e6e65 722c7375 6e38692d "allwinner,sun8i- 0025: 68322d70 6c757300 h2-plus" interrupt-parent0001 model 42616e61 6e612050 69204250 492d4d32 "Banana Pi BPI-M2 0010: 2d5a6572 6f00 -Zero" name00.. "" serial-number 30326330 30303432 65636431 36376566 02c00042ecd167ef 0010: 00.. . -rw-r--r-- 1 root wheel 875 Nov 2 12:06 brcmfmac43430-sdio.AP6212.txt lrwxr-xr-x 1 root wheel 29 Dec 30 16:19 brcmfmac43430-sdio.sinovoip,bpi-m2-zero.txt -> brcmfmac43430-sdio.AP6212.txt -rw-r--r-- 1 root wheel 874 Jun 30 2019 brcmfmac43430-sdio.raspberrypi,3-model-b.txt -rw-r--r-- 1 root wheel1864 Jun 30 2019 brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt lrwxr-xr-x 1 root wheel 29 Dec 30 11:24 brcmfmac43455-sdio.raspberrypi,4-model-b-plus.txt -> brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.9 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.10 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.9 Mon Oct 28 06:37:52 2019 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Mon Dec 30 16:28:14 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.9 2019/10/28 06:37:52 mlelstv Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.10 2019/12/30 16:28:14 mlelstv Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -116,6 +116,7 @@ static void bwfm_sdio_attach(device_t, d static int bwfm_sdio_detach(device_t, int); static void bwfm_sdio_attachhook(device_t); static int bwfm_fdt_find_phandle(device_t, device_t); +static const char *bwfm_fdt_get_model(void); static void bwfm_sdio_backplane(struct bwfm_sdio_softc *, uint32_t); static uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t); @@ -377,7 +378,8 @@ bwfm_sdio_attachhook(device_t self) struct bwfm_sdio_softc *sc = device_private(self); struct bwfm_softc *bwfm = &sc->sc_sc; firmware_handle_t fwh; - const char *name, *nvname; + const char *name, *nvname, *model; + char *nvnamebuf; u_char *ucode, *nvram; size_t size, nvlen, nvsize; uint32_t reg, clk; @@ -435,6 +437,21 @@ bwfm_sdio_attachhook(device_t self) goto err; } + /* compute a model specific filename for the NV config */ + nvnamebuf = NULL; + model = bwfm_fdt_get_model(); + if (model != NULL) { + /* assume nvname ends in ".txt" */ + nvnamebuf = kmem_asprintf("%.*s.%s.txt", + (int)(strlen(nvname) - 4), + nvname, model); + } + + aprint_verbose_dev(self, "Firmware %s\n", name); + aprint_verbose_dev(self, "Default Config %s\n", nvname); + if (nvnamebuf != NULL) + aprint_verbose_dev(self, "Model Config %s\n", nvnamebuf); + if (firmware_open("if_bwfm", name, &fwh) != 0) { printf("%s: failed firmware_open of file %s\n", DEVNAME(sc), name); @@ -456,7 +473,8 @@ bwfm_sdio_attachhook(device_t self) goto err1; } - if (firmware_open("if_bwfm", nvname, &fwh) != 0) { + if ((nvnamebuf == NULL || firmware_open("if_bwfm", nvnamebuf, &fwh) != 0) + && firmware_open("if_bwfm", nvname, &fwh) != 0) { printf("%s: failed firmware_open of file %s\n", DEVNAME(sc), nvname); goto err1; @@ -492,6 +510,8 @@ bwfm_sdio_attachhook(device_t self) firmware_free(nvram, nvlen); firmware_free(ucode, size); + if (nvnamebuf != NULL) + kmem_free(nvnamebuf, strlen(nvnamebuf)+1); sdmmc_pause(hztoms(1)*1000, NULL); @@ -565,6 +585,8 @@ err2: firmware_free(nvram, nvlen); err1: firmware_free(ucode, size); + if (nvnamebuf != NULL) + kmem_free(nvnamebuf, strlen(nvnamebuf)+1); err: return; } @@ -603,6 +625,15 @@ bwfm_fdt_find_phandle(device_t self, dev return phandle; } +static const char * +bwfm_fdt_get_model(void) +{ + int phandle; + + phandle = OF_finddevice("/"); + return fdtbus_get_string_index(phandle, "compatible", 0); +} + static int bwfm_sdio_detach(de
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: kamil Date: Thu Dec 19 17:24:45 UTC 2019 Modified Files: src/sys/dev/sdmmc: sdmmc_ioreg.h Log Message: Avoid changing signedness bit with << in sdmmc_ioreg.h Reported by To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/dev/sdmmc/sdmmc_ioreg.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_ioreg.h diff -u src/sys/dev/sdmmc/sdmmc_ioreg.h:1.5 src/sys/dev/sdmmc/sdmmc_ioreg.h:1.6 --- src/sys/dev/sdmmc/sdmmc_ioreg.h:1.5 Mon Oct 28 06:26:19 2019 +++ src/sys/dev/sdmmc/sdmmc_ioreg.h Thu Dec 19 17:24:45 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_ioreg.h,v 1.5 2019/10/28 06:26:19 mlelstv Exp $ */ +/* $NetBSD: sdmmc_ioreg.h,v 1.6 2019/12/19 17:24:45 kamil Exp $ */ /* $OpenBSD: sdmmc_ioreg.h,v 1.4 2007/06/02 01:48:37 uwe Exp $ */ /* @@ -39,7 +39,7 @@ /* CMD53 arguments */ #define SD_ARG_CMD53_READ (0<<31) -#define SD_ARG_CMD53_WRITE (1<<31) +#define SD_ARG_CMD53_WRITE (1U<<31) #define SD_ARG_CMD53_FUNC_SHIFT 28 #define SD_ARG_CMD53_FUNC_MASK 0x7 #define SD_ARG_CMD53_BLOCK_MODE (1<<27) @@ -55,7 +55,7 @@ #define MMC_R5(resp) ((resp)[0]) /* SD R4 response (IO OCR) */ -#define SD_IO_OCR_MEM_READY (1<<31) +#define SD_IO_OCR_MEM_READY (1U<<31) #define SD_IO_OCR_NUM_FUNCTIONS(ocr) (((ocr) >> 28) & 0x7) #define SD_IO_OCR_MEM_PRESENT (1<<27) #define SD_IO_OCR_MASK 0x00f0
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: christos Date: Mon Dec 2 19:24:32 UTC 2019 Modified Files: src/sys/dev/sdmmc: devlist2h.awk Log Message: drop my name from the advertising clause. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/sdmmc/devlist2h.awk 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/devlist2h.awk diff -u src/sys/dev/sdmmc/devlist2h.awk:1.2 src/sys/dev/sdmmc/devlist2h.awk:1.3 --- src/sys/dev/sdmmc/devlist2h.awk:1.2 Sat Jun 3 10:46:29 2017 +++ src/sys/dev/sdmmc/devlist2h.awk Mon Dec 2 14:24:32 2019 @@ -1,5 +1,5 @@ #! /usr/bin/awk -f -# $NetBSD: devlist2h.awk,v 1.2 2017/06/03 14:46:29 christos Exp $ +# $NetBSD: devlist2h.awk,v 1.3 2019/12/02 19:24:32 christos Exp $ # $OpenBSD: devlist2h.awk,v 1.2 2006/06/02 21:16:44 uwe Exp $ # NetBSD: devlist2h.awk,v 1.2 1998/07/22 11:47:13 christos Exp # @@ -17,7 +17,6 @@ # 3. All advertising materials mentioning features or use of this software #must display the following acknowledgement: # This product includes software developed by Christopher G. Demetriou. -# This product includes software developed by Christos Zoulas # 4. The name of the author(s) may not be used to endorse or promote products #derived from this software without specific prior written permission # @@ -66,7 +65,7 @@ NR == 1 { VERSION = $0 gsub("\\$", "", VERSION) - printf("/*\t$NetBSD: devlist2h.awk,v 1.2 2017/06/03 14:46:29 christos Exp $\t*/\n\n") > hfile + printf("/*\t$NetBSD: devlist2h.awk,v 1.3 2019/12/02 19:24:32 christos Exp $\t*/\n\n") > hfile printf("/*\n") > hfile printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \ > hfile
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Tue Mar 19 07:08:43 UTC 2019 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Provide CID data (manufacturer/product id/product name) as disk type. To generate a diff of this commit: cvs rdiff -u -r1.35 -r1.36 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.35 src/sys/dev/sdmmc/ld_sdmmc.c:1.36 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.35 Fri Nov 9 14:39:19 2018 +++ src/sys/dev/sdmmc/ld_sdmmc.c Tue Mar 19 07:08:43 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.35 2018/11/09 14:39:19 jmcneill Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.36 2019/03/19 07:08:43 mlelstv Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.35 2018/11/09 14:39:19 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.36 2019/03/19 07:08:43 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -92,6 +92,7 @@ struct ld_sdmmc_softc { struct sdmmc_function *sc_sf; struct ld_sdmmc_task sc_task[LD_SDMMC_MAXTASKCNT]; pcq_t *sc_freeq; + char *sc_typename; struct evcnt sc_ev_discard; /* discard counter */ struct evcnt sc_ev_discarderr; /* discard error counter */ @@ -146,6 +147,9 @@ ld_sdmmc_attach(device_t parent, device_ sa->sf->cid.rev, sa->sf->cid.psn, sa->sf->cid.mdt); aprint_naive("\n"); + sc->sc_typename = kmem_asprintf("0x%02x:0x%04x:%s", + sa->sf->cid.mid, sa->sf->cid.oid, sa->sf->cid.pnm); + evcnt_attach_dynamic(&sc->sc_ev_discard, EVCNT_TYPE_MISC, NULL, device_xname(self), "sdmmc discard count"); evcnt_attach_dynamic(&sc->sc_ev_discarderr, EVCNT_TYPE_MISC, @@ -176,6 +180,7 @@ ld_sdmmc_attach(device_t parent, device_ ld->sc_start = ld_sdmmc_start; ld->sc_discard = ld_sdmmc_discard; ld->sc_ioctl = ld_sdmmc_ioctl; + ld->sc_typename = sc->sc_typename; /* * Defer attachment of ld + disk subsystem to a thread. @@ -242,6 +247,7 @@ ld_sdmmc_detach(device_t dev, int flags) evcnt_detach(&sc->sc_ev_discard); evcnt_detach(&sc->sc_ev_discarderr); evcnt_detach(&sc->sc_ev_discardbusy); + kmem_free(sc->sc_typename, strlen(sc->sc_typename) + 1); return 0; }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Wed Mar 13 12:16:49 UTC 2019 Modified Files: src/sys/dev/sdmmc: sdhc.c sdhcvar.h Log Message: Add vendor callback for post-bus clock ops and add SDHC_FLAG_STOP_WITH_TC flag To generate a diff of this commit: cvs rdiff -u -r1.101 -r1.102 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.29 -r1.30 src/sys/dev/sdmmc/sdhcvar.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.101 src/sys/dev/sdmmc/sdhc.c:1.102 --- src/sys/dev/sdmmc/sdhc.c:1.101 Fri Jun 23 08:43:59 2017 +++ src/sys/dev/sdmmc/sdhc.c Wed Mar 13 12:16:49 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.101 2017/06/23 08:43:59 ryo Exp $ */ +/* $NetBSD: sdhc.c,v 1.102 2019/03/13 12:16:49 jmcneill Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.101 2017/06/23 08:43:59 ryo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.102 2019/03/13 12:16:49 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1236,6 +1236,12 @@ sdhc_bus_clock_ddr(sdmmc_chipset_handle_ HCLR1(hp, SDHC_HOST_CTL, SDHC_HIGH_SPEED); } + if (hp->sc->sc_vendor_bus_clock_post) { + error = (*hp->sc->sc_vendor_bus_clock_post)(hp->sc, freq); + if (error != 0) + goto out; + } + out: mutex_exit(&hp->intr_lock); @@ -1556,6 +1562,11 @@ sdhc_exec_command(sdmmc_chipset_handle_t } } + if (ISSET(hp->sc->sc_flags, SDHC_FLAG_STOP_WITH_TC)) { + if (cmd->c_opcode == MMC_STOP_TRANSMISSION) + SET(cmd->c_flags, SCF_RSP_BSY); + } + /* * Start the MMC command, or mark `cmd' as failed and return. */ Index: src/sys/dev/sdmmc/sdhcvar.h diff -u src/sys/dev/sdmmc/sdhcvar.h:1.29 src/sys/dev/sdmmc/sdhcvar.h:1.30 --- src/sys/dev/sdmmc/sdhcvar.h:1.29 Sat Apr 22 21:49:41 2017 +++ src/sys/dev/sdmmc/sdhcvar.h Wed Mar 13 12:16:49 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcvar.h,v 1.29 2017/04/22 21:49:41 jmcneill Exp $ */ +/* $NetBSD: sdhcvar.h,v 1.30 2019/03/13 12:16:49 jmcneill Exp $ */ /* $OpenBSD: sdhcvar.h,v 1.3 2007/09/06 08:01:01 jsg Exp $ */ /* @@ -61,6 +61,7 @@ struct sdhc_softc { #define SDHC_FLAG_USDHC 0x0080 /* Freescale uSDHC */ #define SDHC_FLAG_NO_AUTO_STOP 0x0100 /* No auto CMD12 */ #define SDHC_FLAG_NO_BUSY_INTR 0x0200 /* No intr when RESP_BUSY */ +#define SDHC_FLAG_STOP_WITH_TC 0x0400 /* CMD12 can set xfer complete w/o SCF_RSP_BSY */ uint32_t sc_clkbase; int sc_clkmsk; /* Mask for SDCLK */ @@ -72,6 +73,7 @@ struct sdhc_softc { int (*sc_vendor_card_detect)(struct sdhc_softc *); int (*sc_vendor_bus_width)(struct sdhc_softc *, int); int (*sc_vendor_bus_clock)(struct sdhc_softc *, int); + int (*sc_vendor_bus_clock_post)(struct sdhc_softc *, int); int (*sc_vendor_transfer_data_dma)(struct sdhc_softc *, struct sdmmc_command *); void (*sc_vendor_hw_reset)(struct sdhc_softc *, struct sdhc_host *); int (*sc_vendor_signal_voltage)(struct sdhc_softc *, int);
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Mon Feb 25 19:28:01 UTC 2019 Modified Files: src/sys/dev/sdmmc: sdmmcvar.h Log Message: Add SCF_NEED_BOUNCE command flag. Can be used by a driver to keep track of which command(s) need data transfers to go through DMA bounce buffers. To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 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/sdmmcvar.h diff -u src/sys/dev/sdmmc/sdmmcvar.h:1.29 src/sys/dev/sdmmc/sdmmcvar.h:1.30 --- src/sys/dev/sdmmc/sdmmcvar.h:1.29 Sun Aug 20 15:58:43 2017 +++ src/sys/dev/sdmmc/sdmmcvar.h Mon Feb 25 19:28:00 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcvar.h,v 1.29 2017/08/20 15:58:43 mlelstv Exp $ */ +/* $NetBSD: sdmmcvar.h,v 1.30 2019/02/25 19:28:00 jmcneill Exp $ */ /* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -126,6 +126,7 @@ struct sdmmc_command { /* Command hints */ #define SCF_XFER_SDHC (1U << 15) /* card is SDHC */ #define SCF_POLL (1U << 16) /* polling required */ +#define SCF_NEED_BOUNCE (1U << 17) /* (driver) transfer requires bounce buffer */ /* response types */ #define SCF_RSP_R0 0 /* none */ #define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: thorpej Date: Sat Dec 29 04:59:33 UTC 2018 Modified Files: src/sys/dev/sdmmc: sdmmcdevs.h Log Message: Regen. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/dev/sdmmc/sdmmcdevs.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/sdmmcdevs.h diff -u src/sys/dev/sdmmc/sdmmcdevs.h:1.3 src/sys/dev/sdmmc/sdmmcdevs.h:1.4 --- src/sys/dev/sdmmc/sdmmcdevs.h:1.3 Thu Jun 28 13:31:57 2018 +++ src/sys/dev/sdmmc/sdmmcdevs.h Sat Dec 29 04:59:33 2018 @@ -1,10 +1,10 @@ -/* $NetBSD: sdmmcdevs.h,v 1.3 2018/06/28 13:31:57 jmcneill Exp $ */ +/* $NetBSD: sdmmcdevs.h,v 1.4 2018/12/29 04:59:33 thorpej Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * NetBSD: sdmmcdevs,v 1.3 2018/06/28 13:31:38 jmcneill Exp + * NetBSD: sdmmcdevs,v 1.4 2018/12/29 04:58:52 thorpej Exp */ /* $OpenBSD: sdmmcdevs,v 1.8 2007/05/11 17:16:16 mglocker Exp $ */ @@ -98,6 +98,8 @@ /* Realtek */ #define SDMMC_CIS_REALTEK_RTL8703BS { NULL, NULL, NULL, NULL } #define SDMMC_PRODUCT_REALTEK_RTL8703BS 0xb703 +#define SDMMC_CIS_REALTEK_RTL8189FTV { NULL, NULL, NULL, NULL } +#define SDMMC_PRODUCT_REALTEK_RTL8189FTV 0xf179 /* Ricoh */ #define SDMMC_CIS_RICOH_MMCREADER { NULL, NULL, NULL, NULL }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: thorpej Date: Sat Dec 29 04:58:52 UTC 2018 Modified Files: src/sys/dev/sdmmc: sdmmcdevs Log Message: Add ReakTek RTL8189FTV SDIO 802.11 interface. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/dev/sdmmc/sdmmcdevs 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/sdmmcdevs diff -u src/sys/dev/sdmmc/sdmmcdevs:1.3 src/sys/dev/sdmmc/sdmmcdevs:1.4 --- src/sys/dev/sdmmc/sdmmcdevs:1.3 Thu Jun 28 13:31:38 2018 +++ src/sys/dev/sdmmc/sdmmcdevs Sat Dec 29 04:58:52 2018 @@ -1,4 +1,4 @@ - $NetBSD: sdmmcdevs,v 1.3 2018/06/28 13:31:38 jmcneill Exp $ + $NetBSD: sdmmcdevs,v 1.4 2018/12/29 04:58:52 thorpej Exp $ /* $OpenBSD: sdmmcdevs,v 1.8 2007/05/11 17:16:16 mglocker Exp $ */ /* @@ -73,6 +73,7 @@ product SOCKETCOM BTCARD 0x00c5 Socket B /* Realtek */ product REALTEK RTL8703BS 0xb703 RTL8703BS Wireless LAN 802.11n SDIO +product REALTEK RTL8189FTV 0xf179 RTL8189FTV Wireless LAN 802.11n SDIO /* Ricoh */ product RICOH MMCREADER 0xe823 MMC card reader
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Fri Nov 9 14:39:20 UTC 2018 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Defer DIOCCACHESYNC to the sdmmc task queue so they are serialized with other requests. To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.34 src/sys/dev/sdmmc/ld_sdmmc.c:1.35 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.34 Sun Aug 20 15:58:43 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Fri Nov 9 14:39:19 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.34 2017/08/20 15:58:43 mlelstv Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.35 2018/11/09 14:39:19 jmcneill Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.34 2017/08/20 15:58:43 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.35 2018/11/09 14:39:19 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -78,6 +78,11 @@ struct ld_sdmmc_task { struct buf *task_bp; int task_retries; /* number of xfer retry */ struct callout task_restart_ch; + + kmutex_t task_lock; + kcondvar_t task_cv; + + uintptr_t task_data; }; struct ld_sdmmc_softc { @@ -91,6 +96,7 @@ struct ld_sdmmc_softc { struct evcnt sc_ev_discard; /* discard counter */ struct evcnt sc_ev_discarderr; /* discard error counter */ struct evcnt sc_ev_discardbusy; /* discard busy counter */ + struct evcnt sc_ev_cachesyncbusy; /* cache sync busy counter */ }; static int ld_sdmmc_match(device_t, cfdata_t, void *); @@ -153,6 +159,8 @@ ld_sdmmc_attach(device_t parent, device_ task = &sc->sc_task[i]; task->task_sc = sc; callout_init(&task->task_restart_ch, CALLOUT_MPSAFE); + mutex_init(&task->task_lock, MUTEX_DEFAULT, IPL_NONE); + cv_init(&task->task_cv, "ldsdmmctask"); pcq_put(sc->sc_freeq, task); } @@ -224,8 +232,11 @@ ld_sdmmc_detach(device_t dev, int flags) return rv; ldenddetach(ld); - for (i = 0; i < __arraycount(sc->sc_task); i++) + for (i = 0; i < __arraycount(sc->sc_task); i++) { callout_destroy(&sc->sc_task[i].task_restart_ch); + mutex_destroy(&sc->sc_task[i].task_lock); + cv_destroy(&sc->sc_task[i].task_cv); + } pcq_destroy(sc->sc_freeq); evcnt_detach(&sc->sc_ev_discard); @@ -379,15 +390,56 @@ ld_sdmmc_discard(struct ld_softc *ld, st return 0; } +static void +ld_sdmmc_docachesync(void *arg) +{ + struct ld_sdmmc_task *task = arg; + struct ld_sdmmc_softc *sc = task->task_sc; + const bool poll = (bool)task->task_data; + + task->task_data = sdmmc_mem_flush_cache(sc->sc_sf, poll); + + mutex_enter(&task->task_lock); + cv_signal(&task->task_cv); + mutex_exit(&task->task_lock); +} + +static int +ld_sdmmc_cachesync(struct ld_softc *ld, bool poll) +{ + struct ld_sdmmc_softc *sc = device_private(ld->sc_dv); + struct ld_sdmmc_task *task = pcq_get(sc->sc_freeq); + int error = 0; + + if (task == NULL) { + sc->sc_ev_cachesyncbusy.ev_count++; + return EBUSY; + } + + sdmmc_init_task(&task->task, ld_sdmmc_docachesync, task); + task->task_data = poll; + + mutex_enter(&task->task_lock); + sdmmc_add_task(sc->sc_sf->sc, &task->task); + error = cv_wait_sig(&task->task_cv, &task->task_lock); + mutex_exit(&task->task_lock); + + if (error == 0) + error = (int)task->task_data; + + pcq_put(sc->sc_freeq, task); + + return error; +} + static int ld_sdmmc_ioctl(struct ld_softc *ld, u_long cmd, void *addr, int32_t flag, bool poll) { - struct ld_sdmmc_softc *sc = device_private(ld->sc_dv); switch (cmd) { case DIOCCACHESYNC: - return sdmmc_mem_flush_cache(sc->sc_sf, poll); + return ld_sdmmc_cachesync(ld, poll); default: return EPASSTHROUGH; }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Fri Nov 9 14:38:37 UTC 2018 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: Wait for data ready after eMMC flush cache commands To generate a diff of this commit: cvs rdiff -u -r1.65 -r1.66 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.65 src/sys/dev/sdmmc/sdmmc_mem.c:1.66 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.65 Mon Sep 3 16:29:33 2018 +++ src/sys/dev/sdmmc/sdmmc_mem.c Fri Nov 9 14:38:36 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.65 2018/09/03 16:29:33 riastradh Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.66 2018/11/09 14:38:36 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.65 2018/09/03 16:29:33 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.66 2018/11/09 14:38:36 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1640,7 +1640,7 @@ sdmmc_mem_mmc_switch(struct sdmmc_functi if (error) return error; - if (index == EXT_CSD_HS_TIMING && value >= 2) { + if (index == EXT_CSD_FLUSH_CACHE || (index == EXT_CSD_HS_TIMING && value >= 2)) { do { memset(&cmd, 0, sizeof(cmd)); cmd.c_opcode = MMC_SEND_STATUS; @@ -1661,7 +1661,7 @@ sdmmc_mem_mmc_switch(struct sdmmc_functi if (error) { aprint_error_dev(sc->sc_dev, - "error waiting for high speed switch: %d\n", + "error waiting for data ready after switch command: %d\n", error); return error; }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Tue Nov 6 16:01:39 UTC 2018 Modified Files: src/sys/dev/sdmmc: sdmmc.c Log Message: Increase kthread priority to PRI_SOFTBIO. To generate a diff of this commit: cvs rdiff -u -r1.35 -r1.36 src/sys/dev/sdmmc/sdmmc.c 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.35 src/sys/dev/sdmmc/sdmmc.c:1.36 --- src/sys/dev/sdmmc/sdmmc.c:1.35 Tue Mar 6 07:41:55 2018 +++ src/sys/dev/sdmmc/sdmmc.c Tue Nov 6 16:01:38 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc.c,v 1.35 2018/03/06 07:41:55 mlelstv Exp $ */ +/* $NetBSD: sdmmc.c,v 1.36 2018/11/06 16:01:38 jmcneill Exp $ */ /* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */ /* @@ -49,7 +49,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.35 2018/03/06 07:41:55 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.36 2018/11/06 16:01:38 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -246,7 +246,7 @@ sdmmc_doattach(device_t dev) { struct sdmmc_softc *sc = device_private(dev); - if (kthread_create(PRI_BIO, 0, NULL, + if (kthread_create(PRI_SOFTBIO, 0, NULL, sdmmc_task_thread, sc, &sc->sc_tskq_lwp, "%s", device_xname(dev))) { aprint_error_dev(dev, "couldn't create task thread\n"); }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Thu Jun 28 13:31:57 UTC 2018 Modified Files: src/sys/dev/sdmmc: sdmmcdevs.h Log Message: Regen To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/sdmmc/sdmmcdevs.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/sdmmcdevs.h diff -u src/sys/dev/sdmmc/sdmmcdevs.h:1.2 src/sys/dev/sdmmc/sdmmcdevs.h:1.3 --- src/sys/dev/sdmmc/sdmmcdevs.h:1.2 Tue Apr 21 03:10:41 2009 +++ src/sys/dev/sdmmc/sdmmcdevs.h Thu Jun 28 13:31:57 2018 @@ -1,10 +1,10 @@ -/* $NetBSD: sdmmcdevs.h,v 1.2 2009/04/21 03:10:41 nonaka Exp $ */ +/* $NetBSD: sdmmcdevs.h,v 1.3 2018/06/28 13:31:57 jmcneill Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * NetBSD: sdmmcdevs,v 1.1 2009/04/21 03:00:31 nonaka Exp + * NetBSD: sdmmcdevs,v 1.3 2018/06/28 13:31:38 jmcneill Exp */ /* $OpenBSD: sdmmcdevs,v 1.8 2007/05/11 17:16:16 mglocker Exp $ */ @@ -30,11 +30,13 @@ #define SDMMC_VENDOR_CGUYS 0x0092 /* C-guys, Inc. */ #define SDMMC_VENDOR_TOSHIBA 0x0098 /* Toshiba */ #define SDMMC_VENDOR_SOCKETCOM 0x0104 /* Socket Communications, Inc. */ +#define SDMMC_VENDOR_REALTEK 0x024c /* Realtek */ #define SDMMC_VENDOR_ATHEROS 0x0271 /* Atheros */ #define SDMMC_VENDOR_SYCHIP 0x02db /* SyChip Inc. */ #define SDMMC_VENDOR_SPECTEC 0x02fe /* Spectec Computer Co., Ltd */ #define SDMMC_VENDOR_MEDIATEK 0x037a /* MediaTek Inc. */ #define SDMMC_VENDOR_GLOBALSAT 0x0501 /* Globalsat Technology Co. */ +#define SDMMC_VENDOR_RICOH 0x1180 /* Ricoh */ #define SDMMC_VENDOR_ABOCOM 0x13d1 /* AboCom Systems, Inc. */ /* @@ -92,3 +94,11 @@ #define SDMMC_PRODUCT_SOCKETCOM_SDSCANNER 0x005e #define SDMMC_CIS_SOCKETCOM_BTCARD { NULL, NULL, NULL, NULL } #define SDMMC_PRODUCT_SOCKETCOM_BTCARD 0x00c5 + +/* Realtek */ +#define SDMMC_CIS_REALTEK_RTL8703BS { NULL, NULL, NULL, NULL } +#define SDMMC_PRODUCT_REALTEK_RTL8703BS 0xb703 + +/* Ricoh */ +#define SDMMC_CIS_RICOH_MMCREADER { NULL, NULL, NULL, NULL } +#define SDMMC_PRODUCT_RICOH_MMCREADER 0xe823
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Thu Jun 28 13:31:38 UTC 2018 Modified Files: src/sys/dev/sdmmc: sdmmcdevs Log Message: Add vendor REALTEK and product RTL8703BS To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/sdmmc/sdmmcdevs 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/sdmmcdevs diff -u src/sys/dev/sdmmc/sdmmcdevs:1.2 src/sys/dev/sdmmc/sdmmcdevs:1.3 --- src/sys/dev/sdmmc/sdmmcdevs:1.2 Sat Oct 19 22:45:12 2013 +++ src/sys/dev/sdmmc/sdmmcdevs Thu Jun 28 13:31:38 2018 @@ -1,4 +1,4 @@ - $NetBSD: sdmmcdevs,v 1.2 2013/10/19 22:45:12 mlelstv Exp $ + $NetBSD: sdmmcdevs,v 1.3 2018/06/28 13:31:38 jmcneill Exp $ /* $OpenBSD: sdmmcdevs,v 1.8 2007/05/11 17:16:16 mglocker Exp $ */ /* @@ -23,6 +23,7 @@ vendor CGUYS 0x0092 C-guys, Inc. vendor TOSHIBA 0x0098 Toshiba vendor SOCKETCOM 0x0104 Socket Communications, Inc. +vendor REALTEK 0x024c Realtek vendor ATHEROS 0x0271 Atheros vendor SYCHIP 0x02db SyChip Inc. vendor SPECTEC 0x02fe Spectec Computer Co., Ltd @@ -70,5 +71,8 @@ product TOSHIBA SDBTCARD3 0x0003 Toshiba product SOCKETCOM SDSCANNER 0x005e Socket SD Scanner product SOCKETCOM BTCARD 0x00c5 Socket BT Card +/* Realtek */ +product REALTEK RTL8703BS 0xb703 RTL8703BS Wireless LAN 802.11n SDIO + /* Ricoh */ product RICOH MMCREADER 0xe823 MMC card reader
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: maxv Date: Wed Apr 18 14:56:35 UTC 2018 Modified Files: src/sys/dev/sdmmc: sbt.c Log Message: m_free -> m_freem, m_copyback could have added mbufs in the chain To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/dev/sdmmc/sbt.c 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/sbt.c diff -u src/sys/dev/sdmmc/sbt.c:1.5 src/sys/dev/sdmmc/sbt.c:1.6 --- src/sys/dev/sdmmc/sbt.c:1.5 Thu Jul 14 04:00:46 2016 +++ src/sys/dev/sdmmc/sbt.c Wed Apr 18 14:56:35 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sbt.c,v 1.5 2016/07/14 04:00:46 msaitoh Exp $ */ +/* $NetBSD: sbt.c,v 1.6 2018/04/18 14:56:35 maxv Exp $ */ /* $OpenBSD: sbt.c,v 1.9 2007/06/19 07:59:57 uwe Exp $ */ /* @@ -20,7 +20,7 @@ /* Driver for Type-A/B SDIO Bluetooth cards */ #include -__KERNEL_RCSID(0, "$NetBSD: sbt.c,v 1.5 2016/07/14 04:00:46 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sbt.c,v 1.6 2018/04/18 14:56:35 maxv Exp $"); #include #include @@ -357,7 +357,7 @@ sbt_intr(void *arg) m->m_len = MIN(MHLEN, m->m_pkthdr.len); } else { DPRINTF(("%s: sbt_intr: m_copyback failed\n", DEVNAME(sc))); - m_free(m); + m_freem(m); m = NULL; } @@ -383,7 +383,7 @@ eoi: DPRINTF(("%s: recv 0x%x packet (%d bytes)\n", DEVNAME(sc), sc->sc_buf[0], m->m_pkthdr.len)); sc->sc_stats.err_rx++; - m_free(m); + m_freem(m); break; } } else
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: khorben Date: Sun Mar 11 00:17:29 UTC 2018 Modified Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Outsource setting the backplane window into a specific function so it can be called and reused in different places. >From OpenBSD. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.1 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.2 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.1 Tue Nov 7 16:30:32 2017 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Sun Mar 11 00:17:28 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.1 2017/11/07 16:30:32 khorben Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.2 2018/03/11 00:17:28 khorben Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -73,6 +73,7 @@ int bwfm_sdio_match(device_t, cfdata_t void bwfm_sdio_attach(device_t, struct device *, void *); int bwfm_sdio_detach(device_t, int); +void bwfm_sdio_backplane(struct bwfm_sdio_softc *, uint32_t); uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t); uint32_t bwfm_sdio_read_4(struct bwfm_sdio_softc *, uint32_t); void bwfm_sdio_write_1(struct bwfm_sdio_softc *, uint32_t, @@ -218,6 +219,21 @@ bwfm_sdio_detach(struct device *self, in return 0; } +void +bwfm_sdio_backplane(struct bwfm_sdio_softc *sc, uint32_t bar0) +{ + if (sc->sc_bar0 == bar0) + return; + + bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW, + (bar0 >> 8) & 0x80); + bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID, + (bar0 >> 16) & 0xff); + bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH, + (bar0 >> 24) & 0xff); + sc->sc_bar0 = bar0; +} + uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *sc, uint32_t addr) { @@ -246,15 +262,7 @@ bwfm_sdio_read_4(struct bwfm_sdio_softc uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK; uint32_t rv; - if (sc->sc_bar0 != bar0) { - bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW, - (bar0 >> 8) & 0x80); - bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID, - (bar0 >> 16) & 0xff); - bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH, - (bar0 >> 24) & 0xff); - sc->sc_bar0 = bar0; - } + bwfm_sdio_backplane(sc, bar0); addr &= BWFM_SDIO_SB_OFT_ADDR_MASK; addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG; @@ -299,15 +307,7 @@ bwfm_sdio_write_4(struct bwfm_sdio_softc struct sdmmc_function *sf; uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK; - if (sc->sc_bar0 != bar0) { - bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW, - (bar0 >> 8) & 0x80); - bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID, - (bar0 >> 16) & 0xff); - bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH, - (bar0 >> 24) & 0xff); - sc->sc_bar0 = bar0; - } + bwfm_sdio_backplane(sc, bar0); addr &= BWFM_SDIO_SB_OFT_ADDR_MASK; addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Tue Mar 6 07:41:55 UTC 2018 Modified Files: src/sys/dev/sdmmc: sdmmc.c Log Message: correct whitespace in attach message To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/dev/sdmmc/sdmmc.c 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.34 src/sys/dev/sdmmc/sdmmc.c:1.35 --- src/sys/dev/sdmmc/sdmmc.c:1.34 Fri Feb 17 10:51:48 2017 +++ src/sys/dev/sdmmc/sdmmc.c Tue Mar 6 07:41:55 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc.c,v 1.34 2017/02/17 10:51:48 nonaka Exp $ */ +/* $NetBSD: sdmmc.c,v 1.35 2018/03/06 07:41:55 mlelstv Exp $ */ /* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */ /* @@ -49,7 +49,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.34 2017/02/17 10:51:48 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.35 2018/03/06 07:41:55 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -524,6 +524,7 @@ sdmmc_print(void *aux, const char *pnp) printf("standard function interface code 0x%x", sf->interface); printf(")"); + i = 1; } printf("%sat %s", i ? " " : "", pnp); }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: bouyer Date: Wed Feb 7 14:42:07 UTC 2018 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: Fix uninitialized variable use: if there is an error, or if we are using a SPI controller, sdmmc_mem_send_op_cond() doens't assign a value to *ocrp, but it is used unconditionally in sdmmc_mem_enable() to see if we can switch to low voltage. In sdmmc_mem_send_op_cond(), if the new ocr is not returned by the card for whatever reason, set *ocrp to the orig value. To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.64 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.63 src/sys/dev/sdmmc/sdmmc_mem.c:1.64 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.63 Tue Sep 12 13:43:37 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Wed Feb 7 14:42:07 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.63 2017/09/12 13:43:37 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.64 2018/02/07 14:42:07 bouyer 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.63 2017/09/12 13:43:37 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.64 2018/02/07 14:42:07 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -644,10 +644,14 @@ sdmmc_mem_send_op_cond(struct sdmmc_soft error = ETIMEDOUT; sdmmc_delay(1); } - if (error == 0 && - ocrp != NULL && - !ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) - *ocrp = MMC_R3(cmd.c_resp); + if (ocrp != NULL) { + if (error == 0 && + !ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) { + *ocrp = MMC_R3(cmd.c_resp); + } else { + *ocrp = ocr; + } + } DPRINTF(("%s: sdmmc_mem_send_op_cond: error=%d, ocr=%#x\n", SDMMCDEVNAME(sc), error, MMC_R3(cmd.c_resp))); return error;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sun Jan 28 14:34:06 UTC 2018 Modified Files: src/sys/dev/sdmmc: sdmmc_cis.c Log Message: Don't print an error when we find a CIS tuple code in the vendor-unique range (80h-8Fh). To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/dev/sdmmc/sdmmc_cis.c 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_cis.c diff -u src/sys/dev/sdmmc/sdmmc_cis.c:1.4 src/sys/dev/sdmmc/sdmmc_cis.c:1.5 --- src/sys/dev/sdmmc/sdmmc_cis.c:1.4 Wed Feb 1 22:34:43 2012 +++ src/sys/dev/sdmmc/sdmmc_cis.c Sun Jan 28 14:34:06 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_cis.c,v 1.4 2012/02/01 22:34:43 matt Exp $ */ +/* $NetBSD: sdmmc_cis.c,v 1.5 2018/01/28 14:34:06 jmcneill Exp $ */ /* $OpenBSD: sdmmc_cis.c,v 1.1 2006/06/01 21:53:41 uwe Exp $ */ /* @@ -20,7 +20,7 @@ /* Routines to decode the Card Information Structure of SD I/O cards */ #include -__KERNEL_RCSID(0, "$NetBSD: sdmmc_cis.c,v 1.4 2012/02/01 22:34:43 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_cis.c,v 1.5 2018/01/28 14:34:06 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -260,9 +260,14 @@ sdmmc_read_cis(struct sdmmc_function *sf break; default: - aprint_error_dev(dev, - "unknown tuple code %#x, length %d\n", - tplcode, tpllen); + /* + * Tuple codes between 80h-8Fh are vendor unique. + * Print a warning about all other codes. + */ + if ((tplcode & 0xf0) != 0x80) +aprint_error_dev(dev, +"unknown tuple code %#x, length %d\n", +tplcode, tpllen); reg += tpllen; break; }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: khorben Date: Tue Nov 7 16:30:32 UTC 2017 Modified Files: src/sys/dev/sdmmc: files.sdmmc Added Files: src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Add driver for Broadcom 802.11a/b/g/n/ac SDIO wireless devices, based on the OpenBSD bwfm(4) driver. I could not test this on any hardware yet, as it does not attach as-is on my Raspberry PI 3. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/dev/sdmmc/files.sdmmc cvs rdiff -u -r0 -r1.1 src/sys/dev/sdmmc/if_bwfm_sdio.c 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/files.sdmmc diff -u src/sys/dev/sdmmc/files.sdmmc:1.4 src/sys/dev/sdmmc/files.sdmmc:1.5 --- src/sys/dev/sdmmc/files.sdmmc:1.4 Thu Oct 2 21:49:22 2014 +++ src/sys/dev/sdmmc/files.sdmmc Tue Nov 7 16:30:32 2017 @@ -1,4 +1,4 @@ -# $NetBSD: files.sdmmc,v 1.4 2014/10/02 21:49:22 jmcneill Exp $ +# $NetBSD: files.sdmmc,v 1.5 2017/11/07 16:30:32 khorben Exp $ # $OpenBSD: files.sdmmc,v 1.2 2006/06/01 21:53:41 uwe Exp $ # # Config file and device description for machine-independent SD/MMC code. @@ -21,3 +21,7 @@ file dev/sdmmc/ld_sdmmc.c ld_sdmmc device sbt: btbus, bluetooth attach sbt at sdmmc file dev/sdmmc/sbt.c sbt + +# Broadcom FullMAC SDIO wireless adapter +attach bwfm at sdmmc with bwfm_sdio +file dev/sdmmc/if_bwfm_sdio.c bwfm_sdio Added files: Index: src/sys/dev/sdmmc/if_bwfm_sdio.c diff -u /dev/null src/sys/dev/sdmmc/if_bwfm_sdio.c:1.1 --- /dev/null Tue Nov 7 16:30:32 2017 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Tue Nov 7 16:30:32 2017 @@ -0,0 +1,444 @@ +/* $NetBSD: if_bwfm_sdio.c,v 1.1 2017/11/07 16:30:32 khorben Exp $ */ +/* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ +/* + * Copyright (c) 2010-2016 Broadcom Corporation + * Copyright (c) 2016,2017 Patrick Wildt + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include + +#define BWFM_SDIO_CCCR_BRCM_CARDCAP 0xf0 +#define BWFM_SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02 +#define BWFM_SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04 +#define BWFM_SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08 +#define BWFM_SDIO_CCCR_BRCM_CARDCTRL 0xf1 +#define BWFM_SDIO_CCCR_BRCM_CARDCTRL_WLANRESET 0x02 +#define BWFM_SDIO_CCCR_BRCM_SEPINT 0xf2 + +#ifdef BWFM_DEBUG +#define DPRINTF(x) do { if (bwfm_debug > 0) printf x; } while (0) +#define DPRINTFN(n, x) do { if (bwfm_debug >= (n)) printf x; } while (0) +static int bwfm_debug = 2; +#else +#define DPRINTF(x) do { ; } while (0) +#define DPRINTFN(n, x) do { ; } while (0) +#endif + +#define DEVNAME(sc) device_xname((sc)->sc_sc.sc_dev) + +struct bwfm_sdio_softc { + struct bwfm_softc sc_sc; + struct sdmmc_function **sc_sf; + uint32_t sc_bar0; +}; + +int bwfm_sdio_match(device_t, cfdata_t, void *); +void bwfm_sdio_attach(device_t, struct device *, void *); +int bwfm_sdio_detach(device_t, int); + +uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t); +uint32_t bwfm_sdio_read_4(struct bwfm_sdio_softc *, uint32_t); +void bwfm_sdio_write_1(struct bwfm_sdio_softc *, uint32_t, + uint8_t); +void bwfm_sdio_write_4(struct bwfm_sdio_softc *, uint32_t, + uint32_t); + +uint32_t bwfm_sdio_buscore_read(struct bwfm_softc *, uint32_t); +void bwfm_sdio_buscore_write(struct bwfm_softc *, uint32_t, + uint32_t); +int bwfm_sdio_buscore_prepare(struct bwfm_softc *); +void bwfm_sdio_buscore_activate(struct bwfm_softc *, uint32_t); + +int bwfm_sdio_txdata(struct bwfm_softc *, struct mbuf *); +int bwfm_sdio_txctl(struct bwfm_softc *, char *, size_t); +int bwfm_sdio_rxctl(struct bwfm_softc *, char *, size_t *); + +struct bwfm_bus_ops bwfm_sdio_bus_ops = { + .bs_init = NULL, + .bs_stop = NULL, + .bs_txdata = bwfm_sdio_txdata, + .bs_txctl = bwfm_sdio_txctl, + .bs_rxctl = bwfm_sdio_rxctl, +}; + +struct bwfm_buscore_ops bwfm_sdio_buscore_ops = { + .bc_read = bwfm_sdio_buscore_read, + .bc_write = bwfm_sdio_buscore_write, + .bc_prepare = bwfm_sdio_busco
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Mon Oct 23 13:47:17 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmc_io.c Log Message: - Get SDIO reset working (from OpenBSD). - After switching bus width, notify the host controller of the change. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/dev/sdmmc/sdmmc_io.c 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_io.c diff -u src/sys/dev/sdmmc/sdmmc_io.c:1.12 src/sys/dev/sdmmc/sdmmc_io.c:1.13 --- src/sys/dev/sdmmc/sdmmc_io.c:1.12 Tue Oct 6 14:32:51 2015 +++ src/sys/dev/sdmmc/sdmmc_io.c Mon Oct 23 13:47:17 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_io.c,v 1.12 2015/10/06 14:32:51 mlelstv Exp $ */ +/* $NetBSD: sdmmc_io.c,v 1.13 2017/10/23 13:47:17 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.12 2015/10/06 14:32:51 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.13 2017/10/23 13:47:17 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -122,9 +122,6 @@ sdmmc_io_enable(struct sdmmc_softc *sc) goto out; } - /* Reset I/O functions (again). */ - sdmmc_io_reset(sc); - /* Send the new OCR value until all cards are ready. */ error = sdmmc_io_send_op_cond(sc, host_ocr, NULL); if (error) { @@ -203,6 +200,11 @@ sdmmc_io_init(struct sdmmc_softc *sc, st sdmmc_io_write_1(sf, SD_IO_CCCR_BUS_WIDTH, CCCR_BUS_WIDTH_4); sf->width = 4; + error = sdmmc_chip_bus_width(sc->sc_sct, sc->sc_sch, + sf->width); + if (error) +aprint_error_dev(sc->sc_dev, +"can't change bus width\n"); } error = sdmmc_read_cis(sf, &sf->cis); @@ -535,12 +537,10 @@ sdmmc_io_xchg(struct sdmmc_softc *sc, st static void sdmmc_io_reset(struct sdmmc_softc *sc) { + u_char data = CCCR_CTL_RES; - /* Don't lock */ -#if 0 /* XXX command fails */ - (void)sdmmc_io_write(sc, NULL, SD_IO_REG_CCCR_CTL, CCCR_CTL_RES); - sdmmc_delay(10); -#endif + if (sdmmc_io_rw_direct(sc, NULL, SD_IO_CCCR_CTL, &data, SD_ARG_CMD52_WRITE) == 0) + sdmmc_delay(10); } /*
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Tue Sep 12 13:43:37 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c sdmmcreg.h Log Message: For SD cards, send the SET_WR_BLK_ERASE_COUNT app command before a multi-block write to improve write performance. To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.63 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.32 -r1.33 src/sys/dev/sdmmc/sdmmcreg.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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.62 src/sys/dev/sdmmc/sdmmc_mem.c:1.63 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.62 Sun Aug 20 15:58:43 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Tue Sep 12 13:43:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.62 2017/08/20 15:58:43 mlelstv Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.63 2017/09/12 13:43:37 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.62 2017/08/20 15:58:43 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.63 2017/09/12 13:43:37 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -2021,6 +2021,18 @@ sdmmc_mem_write_block_subr(struct sdmmc_ goto out; } + const int nblk = howmany(datalen, SDMMC_SECTOR_SIZE); + if (ISSET(sc->sc_flags, SMF_SD_MODE) && nblk > 1) { + /* Set the number of write blocks to be pre-erased */ + memset(&cmd, 0, sizeof(cmd)); + cmd.c_opcode = SD_APP_SET_WR_BLK_ERASE_COUNT; + cmd.c_flags = SCF_RSP_R1 | SCF_RSP_SPI_R1 | SCF_CMD_AC; + cmd.c_arg = nblk; + error = sdmmc_app_command(sc, sf, &cmd); + if (error) + goto out; + } + memset(&cmd, 0, sizeof(cmd)); cmd.c_data = data; cmd.c_datalen = datalen; Index: src/sys/dev/sdmmc/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.32 src/sys/dev/sdmmc/sdmmcreg.h:1.33 --- src/sys/dev/sdmmc/sdmmcreg.h:1.32 Sun Jul 16 17:11:46 2017 +++ src/sys/dev/sdmmc/sdmmcreg.h Tue Sep 12 13:43:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.32 2017/07/16 17:11:46 jmcneill Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.33 2017/09/12 13:43:37 jmcneill Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -67,6 +67,7 @@ /* SD application commands */ /* response type */ #define SD_APP_SET_BUS_WIDTH 6 /* R1 */ #define SD_APP_SD_STATUS 13 /* R1 */ +#define SD_APP_SET_WR_BLK_ERASE_COUNT 23 /* R1 */ #define SD_APP_OP_COND 41 /* R3 */ #define SD_APP_SEND_SCR 51 /* R1 */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Fri Aug 11 18:41:42 UTC 2017 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Defer sdmmc discard operations to the sdmmc task queue. Fixes a panic introduced by ld.c r1.102. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.32 src/sys/dev/sdmmc/ld_sdmmc.c:1.33 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.32 Wed Aug 9 16:44:40 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Fri Aug 11 18:41:42 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.32 2017/08/09 16:44:40 mlelstv Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.33 2017/08/11 18:41:42 jmcneill Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.32 2017/08/09 16:44:40 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.33 2017/08/11 18:41:42 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -65,15 +65,24 @@ __KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v #define LD_SDMMC_IORETRIES 5 /* number of retries before giving up */ #define RECOVERYTIME hz/2 /* time to wait before retrying a cmd */ +#define LD_SDMMC_MAXQUEUECNT 4 /* number of queued bio requests */ +#define LD_SDMMC_MAXTASKCNT 8 /* number of tasks in task pool */ + struct ld_sdmmc_softc; struct ld_sdmmc_task { struct sdmmc_task task; struct ld_sdmmc_softc *task_sc; + + /* bio tasks */ struct buf *task_bp; int task_retries; /* number of xfer retry */ struct callout task_restart_ch; + + /* discard tasks */ + off_t task_pos; + off_t task_len; }; struct ld_sdmmc_softc { @@ -81,9 +90,12 @@ struct ld_sdmmc_softc { int sc_hwunit; struct sdmmc_function *sc_sf; -#define LD_SDMMC_MAXQUEUECNT 4 - struct ld_sdmmc_task sc_task[LD_SDMMC_MAXQUEUECNT]; + struct ld_sdmmc_task sc_task[LD_SDMMC_MAXTASKCNT]; pcq_t *sc_freeq; + + struct evcnt sc_ev_discard; /* discard counter */ + struct evcnt sc_ev_discarderr; /* discard error counter */ + struct evcnt sc_ev_discardbusy; /* discard busy counter */ }; static int ld_sdmmc_match(device_t, cfdata_t, void *); @@ -98,6 +110,7 @@ static int ld_sdmmc_ioctl(struct ld_soft static void ld_sdmmc_doattach(void *); static void ld_sdmmc_dobio(void *); +static void ld_sdmmc_dodiscard(void *); CFATTACH_DECL_NEW(ld_sdmmc, sizeof(struct ld_sdmmc_softc), ld_sdmmc_match, ld_sdmmc_attach, ld_sdmmc_detach, NULL); @@ -132,6 +145,13 @@ ld_sdmmc_attach(device_t parent, device_ sa->sf->cid.rev, sa->sf->cid.psn, sa->sf->cid.mdt); aprint_naive("\n"); + evcnt_attach_dynamic(&sc->sc_ev_discard, EVCNT_TYPE_MISC, + NULL, device_xname(self), "sdmmc discard count"); + evcnt_attach_dynamic(&sc->sc_ev_discarderr, EVCNT_TYPE_MISC, + NULL, device_xname(self), "sdmmc discard errors"); + evcnt_attach_dynamic(&sc->sc_ev_discardbusy, EVCNT_TYPE_MISC, + NULL, device_xname(self), "sdmmc discard busy"); + const int ntask = __arraycount(sc->sc_task); sc->sc_freeq = pcq_create(ntask, KM_SLEEP); for (i = 0; i < ntask; i++) { @@ -213,6 +233,9 @@ ld_sdmmc_detach(device_t dev, int flags) callout_destroy(&sc->sc_task[i].task_restart_ch); pcq_destroy(sc->sc_freeq); + evcnt_detach(&sc->sc_ev_discard); + evcnt_detach(&sc->sc_ev_discarderr); + evcnt_detach(&sc->sc_ev_discardbusy); return 0; } @@ -314,12 +337,44 @@ ld_sdmmc_dump(struct ld_softc *ld, void blkcnt * ld->sc_secsize); } +static void +ld_sdmmc_dodiscard(void *arg) +{ + struct ld_sdmmc_task *task = arg; + struct ld_sdmmc_softc *sc = task->task_sc; + const off_t pos = task->task_pos; + const off_t len = task->task_len; + int error; + + /* An error from discard is non-fatal */ + error = sdmmc_mem_discard(sc->sc_sf, pos, len); + if (error != 0) + sc->sc_ev_discarderr.ev_count++; + else + sc->sc_ev_discard.ev_count++; + + pcq_put(sc->sc_freeq, task); +} + static int ld_sdmmc_discard(struct ld_softc *ld, off_t pos, off_t len) { struct ld_sdmmc_softc *sc = device_private(ld->sc_dv); + struct ld_sdmmc_task *task = pcq_get(sc->sc_freeq); + + if (task == NULL) { + sc->sc_ev_discardbusy.ev_count++; + return 0; + } - return sdmmc_mem_discard(sc->sc_sf, pos, len); + task->task_pos = pos; + task->task_len = len; + + sdmmc_init_task(&task->task, ld_sdmmc_dodiscard, task); + + sdmmc_add_task(sc->sc_sf->sc, &task->task); + + return 0; } static int
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sun Jul 16 17:11:46 UTC 2017 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c sdmmc_mem.c sdmmcreg.h sdmmcvar.h Log Message: Add support for eMMC 4.5's optional cache feature. If a cache is present, and the host controller reports the SMC_CAPS_POLLING capability (needed to flush cache at shutdown), it will be automatically enabled and used. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/sys/dev/sdmmc/ld_sdmmc.c cvs rdiff -u -r1.60 -r1.61 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.31 -r1.32 src/sys/dev/sdmmc/sdmmcreg.h cvs rdiff -u -r1.27 -r1.28 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.30 src/sys/dev/sdmmc/ld_sdmmc.c:1.31 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.30 Mon Jul 10 10:35:07 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Sun Jul 16 17:11:46 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.30 2017/07/10 10:35:07 mlelstv Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.31 2017/07/16 17:11:46 jmcneill Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.30 2017/07/10 10:35:07 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.31 2017/07/16 17:11:46 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -94,6 +94,7 @@ static int ld_sdmmc_dump(struct ld_softc static int ld_sdmmc_start(struct ld_softc *, struct buf *); static void ld_sdmmc_restart(void *); static int ld_sdmmc_discard(struct ld_softc *, off_t, off_t); +static int ld_sdmmc_ioctl(struct ld_softc *, u_long, void *, int32_t, bool); static void ld_sdmmc_doattach(void *); static void ld_sdmmc_dobio(void *); @@ -151,6 +152,7 @@ ld_sdmmc_attach(device_t parent, device_ ld->sc_dump = ld_sdmmc_dump; ld->sc_start = ld_sdmmc_start; ld->sc_discard = ld_sdmmc_discard; + ld->sc_ioctl = ld_sdmmc_ioctl; /* * Defer attachment of ld + disk subsystem to a thread. @@ -174,11 +176,19 @@ ld_sdmmc_doattach(void *arg) struct ld_sdmmc_softc *sc = (struct ld_sdmmc_softc *)arg; struct ld_softc *ld = &sc->sc_ld; struct sdmmc_softc *ssc = device_private(device_parent(ld->sc_dv)); + const u_int cache_size = sc->sc_sf->ext_csd.cache_size; + char buf[sizeof(" KB")]; ldattach(ld, BUFQ_DISK_DEFAULT_STRAT); aprint_normal_dev(ld->sc_dv, "%d-bit width,", sc->sc_sf->width); if (ssc->sc_transfer_mode != NULL) aprint_normal(" %s,", ssc->sc_transfer_mode); + if (cache_size > 0) { + format_bytes(buf, sizeof(buf), cache_size); + aprint_normal(" %s cache%s,", buf, + ISSET(sc->sc_sf->flags, SFF_CACHE_ENABLED) ? "" : + " (disabled)"); + } if ((ssc->sc_busclk / 1000) != 0) aprint_normal(" %u.%03u MHz\n", ssc->sc_busclk / 1000, ssc->sc_busclk % 1000); @@ -312,6 +322,20 @@ ld_sdmmc_discard(struct ld_softc *ld, of return sdmmc_mem_discard(sc->sc_sf, pos, len); } +static int +ld_sdmmc_ioctl(struct ld_softc *ld, u_long cmd, void *addr, int32_t flag, +bool poll) +{ + struct ld_sdmmc_softc *sc = device_private(ld->sc_dv); + + switch (cmd) { + case DIOCCACHESYNC: + return sdmmc_mem_flush_cache(sc->sc_sf, poll); + default: + return EPASSTHROUGH; + } +} + MODULE(MODULE_CLASS_DRIVER, ld_sdmmc, "ld"); #ifdef _MODULE Index: src/sys/dev/sdmmc/sdmmc_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.60 src/sys/dev/sdmmc/sdmmc_mem.c:1.61 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.60 Sat Jun 24 23:25:01 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sun Jul 16 17:11:46 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.60 2017/06/24 23:25:01 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.61 2017/07/16 17:11:46 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.60 2017/06/24 23:25:01 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.61 2017/07/16 17:11:46 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -87,7 +87,7 @@ static int sdmmc_mem_send_cxd_data(struc static int sdmmc_set_bus_width(struct sdmmc_function *, int); static int sdmmc_mem_sd_switch(struct sdmmc_function *, int, int, int, sdmmc_bitfield512_t *); static int sdmmc_mem_mmc_switch(struct sdmmc_function *, uint8_t, uint8_t, -uint8_t); +uint8_t, bool); static int sdmmc_mem_signal_voltage(struct sdmmc_softc *, int); static int sdmmc_mem_spi_read_ocr(struct sdmmc_softc *, uint32_t, uint32_t *); static int sdmmc_mem_single_read_block(struct sdmmc_function *, uint32_t, @@ -981,7 +981,7 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s if (width != 1) { error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, value); + EXT_CSD_BUS_WIDTH, value, false); if (error == 0) error = sdmmc_chip_bus
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Mon Jul 10 10:35:08 UTC 2017 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Decrypt comment about the attach thread. No functional change. To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.29 src/sys/dev/sdmmc/ld_sdmmc.c:1.30 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.29 Sat Jul 8 18:38:57 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Mon Jul 10 10:35:07 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.29 2017/07/08 18:38:57 jmcneill Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.30 2017/07/10 10:35:07 mlelstv Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.29 2017/07/08 18:38:57 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.30 2017/07/10 10:35:07 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -153,8 +153,13 @@ ld_sdmmc_attach(device_t parent, device_ ld->sc_discard = ld_sdmmc_discard; /* - * It is avoided that the error occurs when the card attaches it, - * when wedge is supported. + * Defer attachment of ld + disk subsystem to a thread. + * + * This is necessary because wedge autodiscover needs to + * open and call into the ld driver, which could deadlock + * when the sdmmc driver isn't ready in early bootstrap. + * + * Don't mark thread as MPSAFE to keep aprint output sane. */ config_pending_incr(self); if (kthread_create(PRI_NONE, 0, NULL,
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sat Jul 8 18:38:57 UTC 2017 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: The config_* APIs are not MPSAFE, so make sure the deferred attach thread holds KERNEL_LOCK. To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.28 src/sys/dev/sdmmc/ld_sdmmc.c:1.29 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.28 Sat Jun 24 11:27:33 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Sat Jul 8 18:38:57 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.28 2017/06/24 11:27:33 jmcneill Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.29 2017/07/08 18:38:57 jmcneill Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.28 2017/06/24 11:27:33 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.29 2017/07/08 18:38:57 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -157,7 +157,7 @@ ld_sdmmc_attach(device_t parent, device_ * when wedge is supported. */ config_pending_incr(self); - if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, + if (kthread_create(PRI_NONE, 0, NULL, ld_sdmmc_doattach, sc, &lwp, "%sattach", device_xname(self))) { aprint_error_dev(self, "couldn't create thread\n"); }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sat Jun 24 23:25:01 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c sdmmcvar.h Log Message: Revert part of previous; the SD card spec recommends not to issue a DISCARD command to the file system area. To generate a diff of this commit: cvs rdiff -u -r1.59 -r1.60 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.26 -r1.27 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.59 src/sys/dev/sdmmc/sdmmc_mem.c:1.60 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.59 Sat Jun 24 23:07:35 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sat Jun 24 23:25:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.59 2017/06/24 23:07:35 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.60 2017/06/24 23:25:01 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.59 2017/06/24 23:07:35 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.60 2017/06/24 23:25:01 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1373,7 +1373,6 @@ sdmmc_mem_decode_ssr(struct sdmmc_softc const int uhs_speed_grade = SSR_UHS_SPEED_GRADE(ssr); const int video_speed_class = SSR_VIDEO_SPEED_CLASS(ssr); const int app_perf_class = SSR_APP_PERF_CLASS(ssr); - const int discard_support = SSR_DISCARD_SUPPORT(ssr); switch (speed_class) { case SSR_SPEED_CLASS_0: speed_class_val = 0; break; @@ -1406,16 +1405,8 @@ sdmmc_mem_decode_ssr(struct sdmmc_softc printf(", V%d", video_speed_class); if (app_perf_class) printf(", A%d", app_perf_class); - if (discard_support) - printf(", DISCARD"); printf("\n"); - /* - * Set function flags - */ - if (discard_support) - SET(sf->flags, SFF_DISCARD); - return 0; } @@ -2186,8 +2177,6 @@ sdmmc_mem_discard(struct sdmmc_function /* Start the erase operation */ memset(&cmd, 0, sizeof(cmd)); cmd.c_opcode = MMC_ERASE; - if (ISSET(sf->flags, SFF_DISCARD)) - cmd.c_arg = SD_ERASE_DISCARD; cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B; error = sdmmc_mmc_command(sc, &cmd); if (error) Index: src/sys/dev/sdmmc/sdmmcvar.h diff -u src/sys/dev/sdmmc/sdmmcvar.h:1.26 src/sys/dev/sdmmc/sdmmcvar.h:1.27 --- src/sys/dev/sdmmc/sdmmcvar.h:1.26 Sat Jun 24 23:07:35 2017 +++ src/sys/dev/sdmmc/sdmmcvar.h Sat Jun 24 23:25:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcvar.h,v 1.26 2017/06/24 23:07:35 jmcneill Exp $ */ +/* $NetBSD: sdmmcvar.h,v 1.27 2017/06/24 23:25:01 jmcneill Exp $ */ /* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -185,7 +185,6 @@ struct sdmmc_function { int flags; #define SFF_ERROR 0x0001 /* function is poo; ignore it */ #define SFF_SDHC 0x0002 /* SD High Capacity card */ -#define SFF_DISCARD 0x0004 /* SD card supports discard erase */ SIMPLEQ_ENTRY(sdmmc_function) sf_list; /* SD card I/O function members */ int number; /* I/O function number or -1 */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sat Jun 24 23:07:35 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c sdmmcreg.h sdmmcvar.h Log Message: Read SD status register and print card status when a new SD card is found: sdmmc0: SD card status: 4-bit, C10, U1, V10 If the SD status register reports discard support, set the DISCARD arg to the ERASE operation to let the card know that the host doesn't care if the erase is performed. To generate a diff of this commit: cvs rdiff -u -r1.58 -r1.59 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.30 -r1.31 src/sys/dev/sdmmc/sdmmcreg.h cvs rdiff -u -r1.25 -r1.26 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.58 src/sys/dev/sdmmc/sdmmc_mem.c:1.59 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.58 Sat Jun 24 11:27:33 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sat Jun 24 23:07:35 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.58 2017/06/24 11:27:33 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.59 2017/06/24 23:07:35 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.58 2017/06/24 11:27:33 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.59 2017/06/24 23:07:35 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -79,6 +79,10 @@ static int sdmmc_mem_send_csd(struct sdm static int sdmmc_mem_send_scr(struct sdmmc_softc *, struct sdmmc_function *, uint32_t *scr); static int sdmmc_mem_decode_scr(struct sdmmc_softc *, struct sdmmc_function *); +static int sdmmc_mem_send_ssr(struct sdmmc_softc *, struct sdmmc_function *, +sdmmc_bitfield512_t *); +static int sdmmc_mem_decode_ssr(struct sdmmc_softc *, struct sdmmc_function *, +sdmmc_bitfield512_t *); static int sdmmc_mem_send_cxd_data(struct sdmmc_softc *, int, void *, size_t); static int sdmmc_set_bus_width(struct sdmmc_function *, int); static int sdmmc_mem_sd_switch(struct sdmmc_function *, int, int, int, sdmmc_bitfield512_t *); @@ -778,7 +782,7 @@ static int sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) { int support_func, best_func, bus_clock, error, i; - sdmmc_bitfield512_t status; /* Switch Function Status */ + sdmmc_bitfield512_t status; bool ddr = false; /* change bus clock */ @@ -888,6 +892,15 @@ sdmmc_mem_sd_init(struct sdmmc_softc *sc sc->sc_transfer_mode = switch_group0_functions[best_func].name; sc->sc_busddr = ddr; + /* get card status */ + error = sdmmc_mem_send_ssr(sc, sf, &status); + if (error) { + aprint_error_dev(sc->sc_dev, "can't get SD status: %d\n", + error); + return error; + } + sdmmc_mem_decode_ssr(sc, sf, &status); + /* execute tuning (UHS) */ error = sdmmc_mem_execute_tuning(sc, sf); if (error) { @@ -1270,6 +1283,143 @@ sdmmc_mem_decode_scr(struct sdmmc_softc } static int +sdmmc_mem_send_ssr(struct sdmmc_softc *sc, struct sdmmc_function *sf, +sdmmc_bitfield512_t *ssr) +{ + struct sdmmc_command cmd; + bus_dma_segment_t ds[1]; + void *ptr = NULL; + int datalen = 64; + int rseg; + int error = 0; + + /* Don't lock */ + + if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) { + error = bus_dmamem_alloc(sc->sc_dmat, datalen, PAGE_SIZE, 0, + ds, 1, &rseg, BUS_DMA_NOWAIT); + if (error) + goto out; + error = bus_dmamem_map(sc->sc_dmat, ds, 1, datalen, &ptr, + BUS_DMA_NOWAIT); + if (error) + goto dmamem_free; + error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, ptr, datalen, + NULL, BUS_DMA_NOWAIT|BUS_DMA_STREAMING|BUS_DMA_READ); + if (error) + goto dmamem_unmap; + + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, + BUS_DMASYNC_PREREAD); + } else { + ptr = malloc(datalen, M_DEVBUF, M_NOWAIT | M_ZERO); + if (ptr == NULL) + goto out; + } + + memset(&cmd, 0, sizeof(cmd)); + cmd.c_data = ptr; + cmd.c_datalen = datalen; + cmd.c_blklen = datalen; + cmd.c_arg = 0; + cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1 | SCF_RSP_SPI_R1; + cmd.c_opcode = SD_APP_SD_STATUS; + if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) + cmd.c_dmamap = sc->sc_dmap; + + error = sdmmc_app_command(sc, sf, &cmd); + if (error == 0) { + if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) { + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, + BUS_DMASYNC_POSTREAD); + } + memcpy(ssr, ptr, datalen); + } + +out: + if (ptr != NULL) { + if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) { + bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap); +dmamem_unmap: + bus_dmamem_unmap(sc->sc_dmat, ptr, datalen); +dmamem_free: + bus_dmamem_free(sc->sc_dmat, ds, rseg); + } else { + free(ptr, M_DEVBUF); + } + } + DPRINTF(("%s: sdmem_mem_send_ssr: error = %d\n", SDMMCDEVNAME(sc), + error)); + + if (error == 0) + sdmmc_be512_to_bitfield512(ssr); + +#ifdef SDMMC_DEBUG + i
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sat Jun 24 11:27:33 UTC 2017 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c sdmmc_mem.c sdmmcreg.h sdmmcvar.h Log Message: Add discard support to ld@sdmmc using the ERASE (CMD38) command. To generate a diff of this commit: cvs rdiff -u -r1.27 -r1.28 src/sys/dev/sdmmc/ld_sdmmc.c cvs rdiff -u -r1.57 -r1.58 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.29 -r1.30 src/sys/dev/sdmmc/sdmmcreg.h cvs rdiff -u -r1.24 -r1.25 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.27 src/sys/dev/sdmmc/ld_sdmmc.c:1.28 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.27 Tue Jun 6 21:01:07 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Sat Jun 24 11:27:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.27 2017/06/06 21:01:07 jmcneill Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.28 2017/06/24 11:27:33 jmcneill Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.27 2017/06/06 21:01:07 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.28 2017/06/24 11:27:33 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -93,6 +93,7 @@ static int ld_sdmmc_detach(device_t, int static int ld_sdmmc_dump(struct ld_softc *, void *, int, int); static int ld_sdmmc_start(struct ld_softc *, struct buf *); static void ld_sdmmc_restart(void *); +static int ld_sdmmc_discard(struct ld_softc *, off_t, off_t); static void ld_sdmmc_doattach(void *); static void ld_sdmmc_dobio(void *); @@ -149,6 +150,7 @@ ld_sdmmc_attach(device_t parent, device_ ld->sc_maxqueuecnt = LD_SDMMC_MAXQUEUECNT; ld->sc_dump = ld_sdmmc_dump; ld->sc_start = ld_sdmmc_start; + ld->sc_discard = ld_sdmmc_discard; /* * It is avoided that the error occurs when the card attaches it, @@ -297,6 +299,14 @@ ld_sdmmc_dump(struct ld_softc *ld, void blkcnt * ld->sc_secsize); } +static int +ld_sdmmc_discard(struct ld_softc *ld, off_t pos, off_t len) +{ + struct ld_sdmmc_softc *sc = device_private(ld->sc_dv); + + return sdmmc_mem_discard(sc->sc_sf, pos, len); +} + MODULE(MODULE_CLASS_DRIVER, ld_sdmmc, "ld"); #ifdef _MODULE Index: src/sys/dev/sdmmc/sdmmc_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.57 src/sys/dev/sdmmc/sdmmc_mem.c:1.58 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.57 Sun Jun 4 15:00:02 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sat Jun 24 11:27:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.57 2017/06/04 15:00:02 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.58 2017/06/24 11:27:33 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.57 2017/06/04 15:00:02 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.58 2017/06/24 11:27:33 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1987,3 +1987,68 @@ out: return error; } + +int +sdmmc_mem_discard(struct sdmmc_function *sf, off_t pos, off_t len) +{ + struct sdmmc_softc *sc = sf->sc; + struct sdmmc_command cmd; + int error; + + if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) + return ENODEV; /* XXX not tested */ + + /* Erase what we can in the specified range. */ + const off_t start = roundup(pos, SDMMC_SECTOR_SIZE); + const off_t end = rounddown(pos + len, SDMMC_SECTOR_SIZE) - 1; + if (end < start) + return EINVAL; + const uint32_t sblkno = start / SDMMC_SECTOR_SIZE; + const uint32_t eblkno = end / SDMMC_SECTOR_SIZE; + + SDMMC_LOCK(sc); + mutex_enter(&sc->sc_mtx); + + /* Set the address of the first write block to be erased */ + memset(&cmd, 0, sizeof(cmd)); + cmd.c_opcode = ISSET(sc->sc_flags, SMF_SD_MODE) ? + SD_ERASE_WR_BLK_START : MMC_TAG_ERASE_GROUP_START; + cmd.c_arg = sblkno; + if (!ISSET(sf->flags, SFF_SDHC)) + cmd.c_arg <<= SDMMC_SECTOR_SIZE_SB; + cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1; + error = sdmmc_mmc_command(sc, &cmd); + if (error) + goto out; + + /* Set the address of the last write block to be erased */ + memset(&cmd, 0, sizeof(cmd)); + cmd.c_opcode = ISSET(sc->sc_flags, SMF_SD_MODE) ? + SD_ERASE_WR_BLK_END : MMC_TAG_ERASE_GROUP_END; + cmd.c_arg = eblkno; + if (!ISSET(sf->flags, SFF_SDHC)) + cmd.c_arg <<= SDMMC_SECTOR_SIZE_SB; + cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1; + error = sdmmc_mmc_command(sc, &cmd); + if (error) + goto out; + + /* Start the erase operation */ + memset(&cmd, 0, sizeof(cmd)); + cmd.c_opcode = MMC_ERASE; + cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B; + error = sdmmc_mmc_command(sc, &cmd); + if (error) + goto out; + +out: + mutex_exit(&sc->sc_mtx); + SDMMC_UNLOCK(sc); + +#ifdef SDMMC_DEBUG + device_printf(sc->sc_dev, "discard blk %u-%u error %d\n", + sblkno, eblkno, error); +#endif + + return error; +} Index: src/sys/dev/sdmmc/sdmmcreg.h diff -u src/s
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: ryo Date: Fri Jun 23 08:43:59 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdhc.c sdhcreg.h Log Message: fix problem for ESDHC/USDHC due to change of r1.96 on ESDHC/USDHC, even if the iosize is less than SDHC_HOST_CTL_VERSION, specver must be an appropriate value. To generate a diff of this commit: cvs rdiff -u -r1.100 -r1.101 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.18 -r1.19 src/sys/dev/sdmmc/sdhcreg.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.100 src/sys/dev/sdmmc/sdhc.c:1.101 --- src/sys/dev/sdmmc/sdhc.c:1.100 Sat Apr 22 21:49:41 2017 +++ src/sys/dev/sdmmc/sdhc.c Fri Jun 23 08:43:59 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.100 2017/04/22 21:49:41 jmcneill Exp $ */ +/* $NetBSD: sdhc.c,v 1.101 2017/06/23 08:43:59 ryo Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.100 2017/04/22 21:49:41 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.101 2017/06/23 08:43:59 ryo Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -292,42 +292,41 @@ sdhc_host_found(struct sdhc_softc *sc, b callout_init(&hp->tuning_timer, CALLOUT_MPSAFE); callout_setfunc(&hp->tuning_timer, sdhc_tuning_timer, hp); - if (iosize <= SDHC_HOST_CTL_VERSION) { - aprint_normal_dev(sc->sc_dev, "SDHC NO-VERS"); - hp->specver = -1; + if (ISSET(hp->sc->sc_flags, SDHC_FLAG_USDHC)) { + sdhcver = SDHC_SPEC_VERS_300 << SDHC_SPEC_VERS_SHIFT; + } else if (ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) { + sdhcver = HREAD4(hp, SDHC_ESDHC_HOST_CTL_VERSION); + } else if (iosize <= SDHC_HOST_CTL_VERSION) { + sdhcver = SDHC_SPEC_NOVERS << SDHC_SPEC_VERS_SHIFT; } else { - if (ISSET(hp->sc->sc_flags, SDHC_FLAG_USDHC)) { - sdhcver = SDHC_SPEC_VERS_300 << SDHC_SPEC_VERS_SHIFT; - } else if (ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) { - sdhcver = HREAD4(hp, SDHC_ESDHC_HOST_CTL_VERSION); - } else - sdhcver = HREAD2(hp, SDHC_HOST_CTL_VERSION); - aprint_normal_dev(sc->sc_dev, "SDHC "); - hp->specver = SDHC_SPEC_VERSION(sdhcver); - switch (SDHC_SPEC_VERSION(sdhcver)) { - case SDHC_SPEC_VERS_100: - aprint_normal("1.0"); - break; - - case SDHC_SPEC_VERS_200: - aprint_normal("2.0"); - break; - - case SDHC_SPEC_VERS_300: - aprint_normal("3.0"); - break; - - case SDHC_SPEC_VERS_400: - aprint_normal("4.0"); - break; - - default: - aprint_normal("unknown version(0x%x)", - SDHC_SPEC_VERSION(sdhcver)); - break; - } - aprint_normal(", rev %u", SDHC_VENDOR_VERSION(sdhcver)); + sdhcver = HREAD2(hp, SDHC_HOST_CTL_VERSION); + } + aprint_normal_dev(sc->sc_dev, "SDHC "); + hp->specver = SDHC_SPEC_VERSION(sdhcver); + switch (SDHC_SPEC_VERSION(sdhcver)) { + case SDHC_SPEC_VERS_100: + aprint_normal("1.0"); + break; + case SDHC_SPEC_VERS_200: + aprint_normal("2.0"); + break; + case SDHC_SPEC_VERS_300: + aprint_normal("3.0"); + break; + case SDHC_SPEC_VERS_400: + aprint_normal("4.0"); + break; + case SDHC_SPEC_NOVERS: + hp->specver = -1; + aprint_normal("NO-VERS"); + break; + default: + aprint_normal("unknown version(0x%x)", + SDHC_SPEC_VERSION(sdhcver)); + break; } + if (SDHC_SPEC_VERSION(sdhcver) != SDHC_SPEC_NOVERS) + aprint_normal(", rev %u", SDHC_VENDOR_VERSION(sdhcver)); /* * Reset the host controller and enable interrupts. Index: src/sys/dev/sdmmc/sdhcreg.h diff -u src/sys/dev/sdmmc/sdhcreg.h:1.18 src/sys/dev/sdmmc/sdhcreg.h:1.19 --- src/sys/dev/sdmmc/sdhcreg.h:1.18 Thu Dec 31 11:53:19 2015 +++ src/sys/dev/sdmmc/sdhcreg.h Fri Jun 23 08:43:59 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcreg.h,v 1.18 2015/12/31 11:53:19 ryo Exp $ */ +/* $NetBSD: sdhcreg.h,v 1.19 2017/06/23 08:43:59 ryo Exp $ */ /* $OpenBSD: sdhcreg.h,v 1.4 2006/07/30 17:20:40 fgsch Exp $ */ /* @@ -246,6 +246,7 @@ #define SDHC_SPEC_VERS_200 0x01 #define SDHC_SPEC_VERS_300 0x02 #define SDHC_SPEC_VERS_400 0x03 +#define SDHC_SPEC_NOVERS 0xff /* dummy */ /* SDHC_CAPABILITIES decoding */ #define SDHC_BASE_V3_FREQ_KHZ(cap) \
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Tue Jun 6 21:01:07 UTC 2017 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Fix a race between ld_sdmmc_start and ld_sdmmc_dobio that could result in tasks getting lost from the task queue. The symptom of this is a NULL deref in ld_sdmmc_start since the code assumes that a task will always be available from the pool. This changes the code to use pcq(9) instead of a TAILQ to manage the free task list. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.26 src/sys/dev/sdmmc/ld_sdmmc.c:1.27 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.26 Sat Apr 22 14:19:36 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Tue Jun 6 21:01:07 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.26 2017/04/22 14:19:36 jmcneill Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.27 2017/06/06 21:01:07 jmcneill Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.26 2017/04/22 14:19:36 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.27 2017/06/06 21:01:07 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v #include #include #include +#include #include @@ -82,7 +83,7 @@ struct ld_sdmmc_softc { struct sdmmc_function *sc_sf; #define LD_SDMMC_MAXQUEUECNT 4 struct ld_sdmmc_task sc_task[LD_SDMMC_MAXQUEUECNT]; - TAILQ_HEAD(, sdmmc_task) sc_freeq; + pcq_t *sc_freeq; }; static int ld_sdmmc_match(device_t, cfdata_t, void *); @@ -129,12 +130,13 @@ ld_sdmmc_attach(device_t parent, device_ sa->sf->cid.rev, sa->sf->cid.psn, sa->sf->cid.mdt); aprint_naive("\n"); - TAILQ_INIT(&sc->sc_freeq); - for (i = 0; i < __arraycount(sc->sc_task); i++) { + const int ntask = __arraycount(sc->sc_task); + sc->sc_freeq = pcq_create(ntask, KM_SLEEP); + for (i = 0; i < ntask; i++) { task = &sc->sc_task[i]; task->task_sc = sc; - callout_init(&task->task_restart_ch, 0); - TAILQ_INSERT_TAIL(&sc->sc_freeq, &task->task, next); + callout_init(&task->task_restart_ch, CALLOUT_MPSAFE); + pcq_put(sc->sc_freeq, task); } sc->sc_hwunit = 0; /* always 0? */ @@ -193,6 +195,8 @@ ld_sdmmc_detach(device_t dev, int flags) for (i = 0; i < __arraycount(sc->sc_task); i++) callout_destroy(&sc->sc_task[i].task_restart_ch); + pcq_destroy(sc->sc_freeq); + return 0; } @@ -200,9 +204,10 @@ static int ld_sdmmc_start(struct ld_softc *ld, struct buf *bp) { struct ld_sdmmc_softc *sc = device_private(ld->sc_dv); - struct ld_sdmmc_task *task = (void *)TAILQ_FIRST(&sc->sc_freeq); + struct ld_sdmmc_task *task = pcq_get(sc->sc_freeq); - TAILQ_REMOVE(&sc->sc_freeq, &task->task, next); + if (task == NULL) + return EAGAIN; task->task_bp = bp; task->task_retries = 0; @@ -278,7 +283,7 @@ ld_sdmmc_dobio(void *arg) } done: - TAILQ_INSERT_TAIL(&sc->sc_freeq, &task->task, next); + pcq_put(sc->sc_freeq, task); lddone(&sc->sc_ld, bp); }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sun Jun 4 15:00:02 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c sdmmcvar.h Log Message: Give a hint to controllers in the command flags if we are performing a transfer with an SDHC capable card. If the controller needs to adjust command args, it can use this hint to understand how it is encoded. To generate a diff of this commit: cvs rdiff -u -r1.56 -r1.57 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.23 -r1.24 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.56 src/sys/dev/sdmmc/sdmmc_mem.c:1.57 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.56 Tue Apr 11 23:26:33 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sun Jun 4 15:00:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.56 2017/04/11 23:26:33 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.57 2017/06/04 15:00:02 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.56 2017/04/11 23:26:33 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.57 2017/06/04 15:00:02 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1641,6 +1641,8 @@ sdmmc_mem_read_block_subr(struct sdmmc_f if (!ISSET(sf->flags, SFF_SDHC)) cmd.c_arg <<= SDMMC_SECTOR_SIZE_SB; cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1 | SCF_RSP_SPI_R1; + if (ISSET(sf->flags, SFF_SDHC)) + cmd.c_flags |= SCF_XFER_SDHC; if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) cmd.c_dmamap = dmap; @@ -1866,6 +1868,8 @@ sdmmc_mem_write_block_subr(struct sdmmc_ if (!ISSET(sf->flags, SFF_SDHC)) cmd.c_arg <<= SDMMC_SECTOR_SIZE_SB; cmd.c_flags = SCF_CMD_ADTC | SCF_RSP_R1; + if (ISSET(sf->flags, SFF_SDHC)) + cmd.c_flags |= SCF_XFER_SDHC; if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) cmd.c_dmamap = dmap; Index: src/sys/dev/sdmmc/sdmmcvar.h diff -u src/sys/dev/sdmmc/sdmmcvar.h:1.23 src/sys/dev/sdmmc/sdmmcvar.h:1.24 --- src/sys/dev/sdmmc/sdmmcvar.h:1.23 Fri Feb 17 10:51:48 2017 +++ src/sys/dev/sdmmc/sdmmcvar.h Sun Jun 4 15:00:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcvar.h,v 1.23 2017/02/17 10:51:48 nonaka Exp $ */ +/* $NetBSD: sdmmcvar.h,v 1.24 2017/06/04 15:00:02 jmcneill Exp $ */ /* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -122,6 +122,8 @@ struct sdmmc_command { #define SCF_RSP_SPI_BSY (1U << 13) /* Probing */ #define SCF_TOUT_OK (1U << 14) /* command timeout expected */ +/* Transfer hints */ +#define SCF_XFER_SDHC (1U << 15) /* card is SDHC */ /* response types */ #define SCF_RSP_R0 0 /* none */ #define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sat Apr 22 21:49:41 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdhc.c sdhcvar.h Log Message: Add a vendor callback for setting signal voltage. To generate a diff of this commit: cvs rdiff -u -r1.99 -r1.100 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.28 -r1.29 src/sys/dev/sdmmc/sdhcvar.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.99 src/sys/dev/sdmmc/sdhc.c:1.100 --- src/sys/dev/sdmmc/sdhc.c:1.99 Fri Feb 17 10:51:48 2017 +++ src/sys/dev/sdmmc/sdhc.c Sat Apr 22 21:49:41 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.99 2017/02/17 10:51:48 nonaka Exp $ */ +/* $NetBSD: sdhc.c,v 1.100 2017/04/22 21:49:41 jmcneill Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.99 2017/02/17 10:51:48 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.100 2017/04/22 21:49:41 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1342,6 +1342,7 @@ static int sdhc_signal_voltage(sdmmc_chipset_handle_t sch, int signal_voltage) { struct sdhc_host *hp = (struct sdhc_host *)sch; + int error = 0; if (hp->specver < SDHC_SPEC_VERS_300) return EINVAL; @@ -1349,19 +1350,32 @@ sdhc_signal_voltage(sdmmc_chipset_handle mutex_enter(&hp->intr_lock); switch (signal_voltage) { case SDMMC_SIGNAL_VOLTAGE_180: + if (hp->sc->sc_vendor_signal_voltage != NULL) { + error = hp->sc->sc_vendor_signal_voltage(hp->sc, + signal_voltage); + if (error != 0) +break; + } if (!ISSET(hp->sc->sc_flags, SDHC_FLAG_USDHC)) HSET2(hp, SDHC_HOST_CTL2, SDHC_1_8V_SIGNAL_EN); break; case SDMMC_SIGNAL_VOLTAGE_330: if (!ISSET(hp->sc->sc_flags, SDHC_FLAG_USDHC)) HCLR2(hp, SDHC_HOST_CTL2, SDHC_1_8V_SIGNAL_EN); + if (hp->sc->sc_vendor_signal_voltage != NULL) { + error = hp->sc->sc_vendor_signal_voltage(hp->sc, + signal_voltage); + if (error != 0) +break; + } break; default: - return EINVAL; + error = EINVAL; + break; } mutex_exit(&hp->intr_lock); - return 0; + return error; } /* Index: src/sys/dev/sdmmc/sdhcvar.h diff -u src/sys/dev/sdmmc/sdhcvar.h:1.28 src/sys/dev/sdmmc/sdhcvar.h:1.29 --- src/sys/dev/sdmmc/sdhcvar.h:1.28 Fri Feb 17 10:51:48 2017 +++ src/sys/dev/sdmmc/sdhcvar.h Sat Apr 22 21:49:41 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcvar.h,v 1.28 2017/02/17 10:51:48 nonaka Exp $ */ +/* $NetBSD: sdhcvar.h,v 1.29 2017/04/22 21:49:41 jmcneill Exp $ */ /* $OpenBSD: sdhcvar.h,v 1.3 2007/09/06 08:01:01 jsg Exp $ */ /* @@ -74,6 +74,7 @@ struct sdhc_softc { int (*sc_vendor_bus_clock)(struct sdhc_softc *, int); int (*sc_vendor_transfer_data_dma)(struct sdhc_softc *, struct sdmmc_command *); void (*sc_vendor_hw_reset)(struct sdhc_softc *, struct sdhc_host *); + int (*sc_vendor_signal_voltage)(struct sdhc_softc *, int); }; /* Host controller functions called by the attachment driver. */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sat Apr 22 14:19:36 UTC 2017 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Ensure that the task is returned to the free task list in an error branch. To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.25 src/sys/dev/sdmmc/ld_sdmmc.c:1.26 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.25 Sat Jan 7 16:24:40 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Sat Apr 22 14:19:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.25 2017/01/07 16:24:40 martin Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.26 2017/04/22 14:19:36 jmcneill Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.25 2017/01/07 16:24:40 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.26 2017/04/22 14:19:36 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -248,8 +248,8 @@ ld_sdmmc_dobio(void *arg) bp->b_rawblkno, sc->sc_sf->csd.capacity); bp->b_error = EINVAL; bp->b_resid = bp->b_bcount; - lddone(&sc->sc_ld, bp); - return; + + goto done; } if (bp->b_flags & B_READ) @@ -277,6 +277,7 @@ ld_sdmmc_dobio(void *arg) bp->b_resid = 0; } +done: TAILQ_INSERT_TAIL(&sc->sc_freeq, &task->task, next); lddone(&sc->sc_ld, bp);
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Tue Apr 11 23:26:33 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: Remove a test that prevents tuning from happening on eMMC devices. To generate a diff of this commit: cvs rdiff -u -r1.55 -r1.56 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.55 src/sys/dev/sdmmc/sdmmc_mem.c:1.56 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.55 Fri Feb 17 10:51:48 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Tue Apr 11 23:26:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.55 2017/02/17 10:51:48 nonaka Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.56 2017/04/11 23:26:33 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.55 2017/02/17 10:51:48 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.56 2017/04/11 23:26:33 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -744,9 +744,6 @@ sdmmc_mem_execute_tuning(struct sdmmc_so { int timing = -1; - if (!ISSET(sc->sc_flags, SMF_UHS_MODE)) - return 0; - if (ISSET(sc->sc_flags, SMF_SD_MODE)) { if (!ISSET(sc->sc_flags, SMF_UHS_MODE)) return 0;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Fri Feb 17 10:50:43 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdhc.c sdmmc_mem.c sdmmcchip.h Log Message: sdhc(4), sdmmc(4): Added MMC HS DDR52 support. To generate a diff of this commit: cvs rdiff -u -r1.97 -r1.98 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.53 -r1.54 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.7 -r1.8 src/sys/dev/sdmmc/sdmmcchip.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.97 src/sys/dev/sdmmc/sdhc.c:1.98 --- src/sys/dev/sdmmc/sdhc.c:1.97 Sat Jan 7 15:05:08 2017 +++ src/sys/dev/sdmmc/sdhc.c Fri Feb 17 10:50:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.97 2017/01/07 15:05:08 kiyohara Exp $ */ +/* $NetBSD: sdhc.c,v 1.98 2017/02/17 10:50:43 nonaka Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.97 2017/01/07 15:05:08 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.98 2017/02/17 10:50:43 nonaka Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1107,7 +1107,13 @@ sdhc_bus_clock_ddr(sdmmc_chipset_handle_ if (freq > 10) { HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR104); } else if (freq > 5) { - HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR50); + if (ddr) { +HSET2(hp, SDHC_HOST_CTL2, +SDHC_UHS_MODE_SELECT_DDR50); + } else { +HSET2(hp, SDHC_HOST_CTL2, +SDHC_UHS_MODE_SELECT_SDR50); + } } else if (freq > 25000) { if (ddr) { HSET2(hp, SDHC_HOST_CTL2, @@ -1335,6 +1341,9 @@ sdhc_signal_voltage(sdmmc_chipset_handle { struct sdhc_host *hp = (struct sdhc_host *)sch; + if (hp->specver < SDHC_SPEC_VERS_300) + return EINVAL; + mutex_enter(&hp->intr_lock); switch (signal_voltage) { case SDMMC_SIGNAL_VOLTAGE_180: Index: src/sys/dev/sdmmc/sdmmc_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.53 src/sys/dev/sdmmc/sdmmc_mem.c:1.54 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.53 Fri Feb 17 10:48:19 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Fri Feb 17 10:50:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.53 2017/02/17 10:48:19 nonaka Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.54 2017/02/17 10:50:43 nonaka 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.53 2017/02/17 10:48:19 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.54 2017/02/17 10:50:43 nonaka Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -907,6 +907,7 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s int width, value, hs_timing, bus_clock, error; uint8_t ext_csd[512]; uint32_t sectors = 0; + bool ddr = false; sc->sc_transfer_mode = NULL; @@ -934,11 +935,15 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s return ENOTSUP; } - sc->sc_transfer_mode = NULL; if (ISSET(sc->sc_caps, SMC_CAPS_MMC_HS200) && ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_HS200_1_8V) { sf->csd.tran_speed = 20; /* 200MHz SDR */ hs_timing = EXT_CSD_HS_TIMING_HS200; + } else if (ISSET(sc->sc_caps, SMC_CAPS_MMC_DDR52) && + ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_DDR52_1_8V) { + sf->csd.tran_speed = 52000; /* 52MHz */ + hs_timing = EXT_CSD_HS_TIMING_HIGHSPEED; + ddr = true; } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_52M) { sf->csd.tran_speed = 52000; /* 52MHz */ hs_timing = EXT_CSD_HS_TIMING_HIGHSPEED; @@ -1022,6 +1027,47 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s } } + /* + * HS_TIMING must be set to “0x1” before setting BUS_WIDTH + * for dual data rate operation + */ + if (ddr && + hs_timing == EXT_CSD_HS_TIMING_HIGHSPEED && + width > 1) { + error = sdmmc_mem_mmc_switch(sf, + EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, + (width == 8) ? EXT_CSD_BUS_WIDTH_8_DDR : + EXT_CSD_BUS_WIDTH_4_DDR); + if (error) { +DPRINTF(("%s: can't switch to DDR" +" (%d bit)\n", SDMMCDEVNAME(sc), width)); +return error; + } + + delay(1); + + error = sdmmc_mem_signal_voltage(sc, + SDMMC_SIGNAL_VOLTAGE_180); + if (error) { +aprint_error_dev(sc->sc_dev, +"can't switch signaling voltage\n"); +return error; + } + + error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, + sc->sc_busclk, ddr); + if (error) { +aprint_error_dev(sc->sc_dev, +"can't change bus clock\n"); +return error; + } + + delay(1); + + sc->sc_transfer_mode = "DDR52"; + sc->sc_busddr = ddr; + } + sectors = ext_csd[EXT_CSD_SEC_COUNT + 0] << 0 | ext_csd[EXT_CSD_SEC_COUNT + 1] << 8 | ext_csd[EXT_CSD_SEC_COUNT + 2] << 16 | @@ -1041,8 +1087,6 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s "can't execute MMC tuning\n");
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Fri Feb 17 10:49:47 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmcvar.h Log Message: sdmmc(4): Add MMC HS DDR52 timing support bit and use __BIT() macro. To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 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/sdmmcvar.h diff -u src/sys/dev/sdmmc/sdmmcvar.h:1.21 src/sys/dev/sdmmc/sdmmcvar.h:1.22 --- src/sys/dev/sdmmc/sdmmcvar.h:1.21 Sun Nov 29 23:38:47 2015 +++ src/sys/dev/sdmmc/sdmmcvar.h Fri Feb 17 10:49:47 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcvar.h,v 1.21 2015/11/29 23:38:47 jmcneill Exp $ */ +/* $NetBSD: sdmmcvar.h,v 1.22 2017/02/17 10:49:47 nonaka Exp $ */ /* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -222,21 +222,25 @@ struct sdmmc_softc { #define SMF_UHS_MODE 0x1 /* host in UHS mode */ uint32_t sc_caps; /* host capability */ -#define SMC_CAPS_AUTO_STOP 0x0001 /* send CMD12 automagically by host */ -#define SMC_CAPS_4BIT_MODE 0x0002 /* 4-bits data bus width */ -#define SMC_CAPS_DMA 0x0004 /* DMA transfer */ -#define SMC_CAPS_SPI_MODE 0x0008 /* SPI mode */ -#define SMC_CAPS_POLL_CARD_DET 0x0010 /* Polling card detect */ -#define SMC_CAPS_SINGLE_ONLY 0x0020 /* only single read/write */ -#define SMC_CAPS_8BIT_MODE 0x0040 /* 8-bits data bus width */ -#define SMC_CAPS_MULTI_SEG_DMA 0x0080 /* multiple segment DMA transfer */ -#define SMC_CAPS_SD_HIGHSPEED 0x0100 /* SD high-speed timing */ -#define SMC_CAPS_MMC_HIGHSPEED 0x0200 /* MMC high-speed timing */ -#define SMC_CAPS_UHS_SDR50 0x1000 /* UHS SDR50 timing */ -#define SMC_CAPS_UHS_SDR104 0x2000 /* UHS SDR104 timing */ -#define SMC_CAPS_UHS_DDR50 0x4000 /* UHS DDR50 timing */ -#define SMC_CAPS_UHS_MASK 0x7000 -#define SMC_CAPS_MMC_HS200 0x8000 /* eMMC HS200 timing */ +#define SMC_CAPS_AUTO_STOP __BIT(0) /* send CMD12 automagically by host */ +#define SMC_CAPS_4BIT_MODE __BIT(1) /* 4-bits data bus width */ +#define SMC_CAPS_DMA __BIT(2) /* DMA transfer */ +#define SMC_CAPS_SPI_MODE __BIT(3) /* SPI mode */ +#define SMC_CAPS_POLL_CARD_DET __BIT(4) /* Polling card detect */ +#define SMC_CAPS_SINGLE_ONLY __BIT(5) /* only single read/write */ +#define SMC_CAPS_8BIT_MODE __BIT(6) /* 8-bits data bus width */ +#define SMC_CAPS_MULTI_SEG_DMA __BIT(7) /* multiple segment DMA transfer */ +#define SMC_CAPS_SD_HIGHSPEED __BIT(8) /* SD high-speed timing */ +#define SMC_CAPS_MMC_HIGHSPEED __BIT(9) /* MMC high-speed timing */ +#define SMC_CAPS_MMC_DDR52 __BIT(10) /* MMC HS DDR52 timing */ +/*__BIT(11) */ +#define SMC_CAPS_UHS_SDR50 __BIT(12) /* UHS SDR50 timing */ +#define SMC_CAPS_UHS_SDR104 __BIT(13) /* UHS SDR104 timing */ +#define SMC_CAPS_UHS_DDR50 __BIT(14) /* UHS DDR50 timing */ +#define SMC_CAPS_UHS_MASK (SMC_CAPS_UHS_SDR50 \ +| SMC_CAPS_UHS_SDR104 \ +| SMC_CAPS_UHS_DDR50) +#define SMC_CAPS_MMC_HS200 __BIT(15) /* eMMC HS200 timing */ /* function */ int sc_function_count; /* number of I/O functions (SDIO) */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Fri Feb 17 10:48:19 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: sdmmc(4): Use EXT_CSD[HS_TIMING] definitions. To generate a diff of this commit: cvs rdiff -u -r1.52 -r1.53 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.52 src/sys/dev/sdmmc/sdmmc_mem.c:1.53 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.52 Thu Aug 11 01:33:25 2016 +++ src/sys/dev/sdmmc/sdmmc_mem.c Fri Feb 17 10:48:19 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.52 2016/08/11 01:33:25 nonaka Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.53 2017/02/17 10:48:19 nonaka 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.52 2016/08/11 01:33:25 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.53 2017/02/17 10:48:19 nonaka Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -938,13 +938,13 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s if (ISSET(sc->sc_caps, SMC_CAPS_MMC_HS200) && ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_HS200_1_8V) { sf->csd.tran_speed = 20; /* 200MHz SDR */ - hs_timing = 2; + hs_timing = EXT_CSD_HS_TIMING_HS200; } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_52M) { sf->csd.tran_speed = 52000; /* 52MHz */ - hs_timing = 1; + hs_timing = EXT_CSD_HS_TIMING_HIGHSPEED; } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_26M) { sf->csd.tran_speed = 26000; /* 26MHz */ - hs_timing = 0; + hs_timing = EXT_CSD_HS_TIMING_LEGACY; } else { aprint_error_dev(sc->sc_dev, "unknown CARD_TYPE: 0x%x\n", @@ -980,11 +980,11 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s } sf->width = width; - if (hs_timing == 1 && + if (hs_timing == EXT_CSD_HS_TIMING_HIGHSPEED && !ISSET(sc->sc_caps, SMC_CAPS_MMC_HIGHSPEED)) { - hs_timing = 0; + hs_timing = EXT_CSD_HS_TIMING_LEGACY; } - if (hs_timing) { + if (hs_timing != EXT_CSD_HS_TIMING_LEGACY) { error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, hs_timing); if (error) { @@ -1007,7 +1007,7 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s } } - if (hs_timing) { + if (hs_timing != EXT_CSD_HS_TIMING_LEGACY) { error = sdmmc_mem_send_cxd_data(sc, MMC_SEND_EXT_CSD, ext_csd, sizeof(ext_csd)); if (error) { @@ -1031,7 +1031,7 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s sf->csd.capacity = sectors; } - if (hs_timing == 2) { + if (hs_timing == EXT_CSD_HS_TIMING_HS200) { sc->sc_transfer_mode = "HS200"; /* execute tuning (HS200) */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Fri Feb 17 10:47:09 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmcreg.h Log Message: sdmmc(4): Added EXT_CSD[HS_TIMING] definitions. To generate a diff of this commit: cvs rdiff -u -r1.27 -r1.28 src/sys/dev/sdmmc/sdmmcreg.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/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.27 src/sys/dev/sdmmc/sdmmcreg.h:1.28 --- src/sys/dev/sdmmc/sdmmcreg.h:1.27 Fri Feb 17 10:46:20 2017 +++ src/sys/dev/sdmmc/sdmmcreg.h Fri Feb 17 10:47:09 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.27 2017/02/17 10:46:20 nonaka Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.28 2017/02/17 10:47:09 nonaka Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -134,6 +134,12 @@ #define EXT_CSD_BUS_WIDTH_4_DDR 5 /* 4 bit mode (DDR) */ #define EXT_CSD_BUS_WIDTH_8_DDR 6 /* 8 bit mode (DDR) */ +/* EXT_CSD_HS_TIMING */ +#define EXT_CSD_HS_TIMING_LEGACY 0 +#define EXT_CSD_HS_TIMING_HIGHSPEED 1 +#define EXT_CSD_HS_TIMING_HS200 2 +#define EXT_CSD_HS_TIMING_HS400 3 + /* EXT_CSD_STRUCTURE */ #define EXT_CSD_STRUCTURE_VER_1_0 0 /* CSD Version No.1.0 */ #define EXT_CSD_STRUCTURE_VER_1_1 1 /* CSD Version No.1.1 */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Fri Feb 17 10:46:21 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmcreg.h Log Message: sdmmc(4): Change EXT_CSD[CARD_TYPE] HS DDR 52 MHz definition. Because it has been difficult to understand from the definition is DDR. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/dev/sdmmc/sdmmcreg.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/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.26 src/sys/dev/sdmmc/sdmmcreg.h:1.27 --- src/sys/dev/sdmmc/sdmmcreg.h:1.26 Fri Feb 17 10:45:23 2017 +++ src/sys/dev/sdmmc/sdmmcreg.h Fri Feb 17 10:46:20 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.26 2017/02/17 10:45:23 nonaka Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.27 2017/02/17 10:46:20 nonaka Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -142,8 +142,8 @@ /* EXT_CSD_CARD_TYPE */ #define EXT_CSD_CARD_TYPE_F_26M (1 << 0) /* HS 26 MHz */ #define EXT_CSD_CARD_TYPE_F_52M (1 << 1) /* HS 52 MHz */ -#define EXT_CSD_CARD_TYPE_F_52M_1_8V (1 << 2) /* HS DDR 52 MHz 1.8V or 3V */ -#define EXT_CSD_CARD_TYPE_F_52M_1_2V (1 << 3) /* HS DDR 52 MHz 1.2V */ +#define EXT_CSD_CARD_TYPE_F_DDR52_1_8V (1 << 2) /* HS DDR 52 MHz 1.8V or 3V */ +#define EXT_CSD_CARD_TYPE_F_DDR52_1_2V (1 << 3) /* HS DDR 52 MHz 1.2V */ #define EXT_CSD_CARD_TYPE_F_HS200_1_8V (1 << 4) /* HS200 SDR 200 MHz 1.8V */ #define EXT_CSD_CARD_TYPE_F_HS200_1_2V (1 << 5) /* HS200 SDR 200 MHz 1.2V */ #define EXT_CSD_CARD_TYPE_F_HS400_1_8V (1 << 6) /* HS400 DDR 200 MHz 1.8V */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Fri Feb 17 10:45:23 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmcreg.h Log Message: sdmmc(4): Remove unused EXT_CSD[CARD_TYPE] definitions. To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/dev/sdmmc/sdmmcreg.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/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.25 src/sys/dev/sdmmc/sdmmcreg.h:1.26 --- src/sys/dev/sdmmc/sdmmcreg.h:1.25 Fri Feb 17 10:44:31 2017 +++ src/sys/dev/sdmmc/sdmmcreg.h Fri Feb 17 10:45:23 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.25 2017/02/17 10:44:31 nonaka Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.26 2017/02/17 10:45:23 nonaka Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -148,11 +148,6 @@ #define EXT_CSD_CARD_TYPE_F_HS200_1_2V (1 << 5) /* HS200 SDR 200 MHz 1.2V */ #define EXT_CSD_CARD_TYPE_F_HS400_1_8V (1 << 6) /* HS400 DDR 200 MHz 1.8V */ #define EXT_CSD_CARD_TYPE_F_HS400_1_2V (1 << 7) /* HS400 DDR 200 MHz 1.2V */ -#define EXT_CSD_CARD_TYPE_26M 0x01 -#define EXT_CSD_CARD_TYPE_52M 0x03 -#define EXT_CSD_CARD_TYPE_52M_V18 0x07 -#define EXT_CSD_CARD_TYPE_52M_V12 0x0b -#define EXT_CSD_CARD_TYPE_52M_V12_18 0x0f /* MMC_SWITCH access mode */ #define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Fri Feb 17 10:44:31 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmcreg.h Log Message: sdmmc(4): Added comments at EXT_CSD[CARD_TYPE] definitions. To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.25 src/sys/dev/sdmmc/sdmmcreg.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/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.24 src/sys/dev/sdmmc/sdmmcreg.h:1.25 --- src/sys/dev/sdmmc/sdmmcreg.h:1.24 Fri Feb 17 10:43:47 2017 +++ src/sys/dev/sdmmc/sdmmcreg.h Fri Feb 17 10:44:31 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.24 2017/02/17 10:43:47 nonaka Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.25 2017/02/17 10:44:31 nonaka Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -140,14 +140,14 @@ #define EXT_CSD_STRUCTURE_VER_1_2 2 /* Version 4.1-4.2-4.3 */ /* EXT_CSD_CARD_TYPE */ -#define EXT_CSD_CARD_TYPE_F_26M (1 << 0) -#define EXT_CSD_CARD_TYPE_F_52M (1 << 1) -#define EXT_CSD_CARD_TYPE_F_52M_1_8V (1 << 2) -#define EXT_CSD_CARD_TYPE_F_52M_1_2V (1 << 3) -#define EXT_CSD_CARD_TYPE_F_HS200_1_8V (1 << 4) -#define EXT_CSD_CARD_TYPE_F_HS200_1_2V (1 << 5) -#define EXT_CSD_CARD_TYPE_F_HS400_1_8V (1 << 6) -#define EXT_CSD_CARD_TYPE_F_HS400_1_2V (1 << 7) +#define EXT_CSD_CARD_TYPE_F_26M (1 << 0) /* HS 26 MHz */ +#define EXT_CSD_CARD_TYPE_F_52M (1 << 1) /* HS 52 MHz */ +#define EXT_CSD_CARD_TYPE_F_52M_1_8V (1 << 2) /* HS DDR 52 MHz 1.8V or 3V */ +#define EXT_CSD_CARD_TYPE_F_52M_1_2V (1 << 3) /* HS DDR 52 MHz 1.2V */ +#define EXT_CSD_CARD_TYPE_F_HS200_1_8V (1 << 4) /* HS200 SDR 200 MHz 1.8V */ +#define EXT_CSD_CARD_TYPE_F_HS200_1_2V (1 << 5) /* HS200 SDR 200 MHz 1.2V */ +#define EXT_CSD_CARD_TYPE_F_HS400_1_8V (1 << 6) /* HS400 DDR 200 MHz 1.8V */ +#define EXT_CSD_CARD_TYPE_F_HS400_1_2V (1 << 7) /* HS400 DDR 200 MHz 1.2V */ #define EXT_CSD_CARD_TYPE_26M 0x01 #define EXT_CSD_CARD_TYPE_52M 0x03 #define EXT_CSD_CARD_TYPE_52M_V18 0x07
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Fri Feb 17 10:43:47 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmcreg.h Log Message: sdmmc(4): Added 4 and 8 bit mode DDR definitions at EXT_CSD[BUS_WIDTH]. To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/sys/dev/sdmmc/sdmmcreg.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/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.23 src/sys/dev/sdmmc/sdmmcreg.h:1.24 --- src/sys/dev/sdmmc/sdmmcreg.h:1.23 Fri Feb 17 10:43:03 2017 +++ src/sys/dev/sdmmc/sdmmcreg.h Fri Feb 17 10:43:47 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.23 2017/02/17 10:43:03 nonaka Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.24 2017/02/17 10:43:47 nonaka Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -131,6 +131,8 @@ #define EXT_CSD_BUS_WIDTH_1 0 /* 1 bit mode */ #define EXT_CSD_BUS_WIDTH_4 1 /* 4 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* 8 bit mode */ +#define EXT_CSD_BUS_WIDTH_4_DDR 5 /* 4 bit mode (DDR) */ +#define EXT_CSD_BUS_WIDTH_8_DDR 6 /* 8 bit mode (DDR) */ /* EXT_CSD_STRUCTURE */ #define EXT_CSD_STRUCTURE_VER_1_0 0 /* CSD Version No.1.0 */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Fri Feb 17 10:43:03 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdmmcreg.h Log Message: sdmmc(4): Fix cell type in comments. >From JEDEC Standard No.84-B51, 7.4. Extended CSD register. To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/dev/sdmmc/sdmmcreg.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/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.22 src/sys/dev/sdmmc/sdmmcreg.h:1.23 --- src/sys/dev/sdmmc/sdmmcreg.h:1.22 Wed Aug 10 04:24:17 2016 +++ src/sys/dev/sdmmc/sdmmcreg.h Fri Feb 17 10:43:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.22 2016/08/10 04:24:17 nonaka Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.23 2017/02/17 10:43:03 nonaka Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -115,12 +115,12 @@ #define SD_ARG_BUS_WIDTH_4 2 /* EXT_CSD fields */ -#define EXT_CSD_BUS_WIDTH 183 /* WO */ -#define EXT_CSD_HS_TIMING 185 /* R/W */ -#define EXT_CSD_REV 192 /* RO */ -#define EXT_CSD_STRUCTURE 194 /* RO */ -#define EXT_CSD_CARD_TYPE 196 /* RO */ -#define EXT_CSD_SEC_COUNT 212 /* RO */ +#define EXT_CSD_BUS_WIDTH 183 /* W/E_P */ +#define EXT_CSD_HS_TIMING 185 /* R/W/E_P */ +#define EXT_CSD_REV 192 /* R */ +#define EXT_CSD_STRUCTURE 194 /* R */ +#define EXT_CSD_CARD_TYPE 196 /* R */ +#define EXT_CSD_SEC_COUNT 212 /* R */ /* EXT_CSD field definitions */ #define EXT_CSD_CMD_SET_NORMAL (1U << 0)
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: martin Date: Sat Jan 7 16:24:40 UTC 2017 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Add missing includes To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.25 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.24 src/sys/dev/sdmmc/ld_sdmmc.c:1.25 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.24 Sat Jan 7 14:49:53 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Sat Jan 7 16:24:40 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.24 2017/01/07 14:49:53 kiyohara Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.25 2017/01/07 16:24:40 martin Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.24 2017/01/07 14:49:53 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.25 2017/01/07 16:24:40 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -44,7 +44,9 @@ __KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v #include #include #include +#include #include +#include #include #include
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: kiyohara Date: Sat Jan 7 15:05:08 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdhc.c sdhcvar.h Log Message: Add flags SDHC_FLAG_NO_AUTO_STOP and SDHC_FLAG_NO_BUSY_INTR. To generate a diff of this commit: cvs rdiff -u -r1.96 -r1.97 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.26 -r1.27 src/sys/dev/sdmmc/sdhcvar.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.96 src/sys/dev/sdmmc/sdhc.c:1.97 --- src/sys/dev/sdmmc/sdhc.c:1.96 Sat Jan 7 15:00:38 2017 +++ src/sys/dev/sdmmc/sdhc.c Sat Jan 7 15:05:08 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.96 2017/01/07 15:00:38 kiyohara Exp $ */ +/* $NetBSD: sdhc.c,v 1.97 2017/01/07 15:05:08 kiyohara Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.96 2017/01/07 15:00:38 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.97 2017/01/07 15:05:08 kiyohara Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -595,7 +595,9 @@ adma_done: saa.saa_clkmin = hp->clkbase / 0x3ff; else saa.saa_clkmin = hp->clkbase / 256; - saa.saa_caps = SMC_CAPS_4BIT_MODE|SMC_CAPS_AUTO_STOP; + if (!ISSET(sc->sc_flags, SDHC_FLAG_NO_AUTO_STOP)) + saa.saa_caps |= SMC_CAPS_AUTO_STOP; + saa.saa_caps |= SMC_CAPS_4BIT_MODE; if (ISSET(sc->sc_flags, SDHC_FLAG_8BIT_MODE)) saa.saa_caps |= SMC_CAPS_8BIT_MODE; if (ISSET(caps, SDHC_HIGH_SPEED_SUPP)) @@ -1572,7 +1574,8 @@ sdhc_exec_command(sdmmc_chipset_handle_t if (cmd->c_error == 0 && cmd->c_data != NULL) sdhc_transfer_data(hp, cmd); else if (ISSET(cmd->c_flags, SCF_RSP_BSY)) { - if (!sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE, hz * 10, false)) { + if (!ISSET(hp->sc->sc_flags, SDHC_FLAG_NO_BUSY_INTR) && + !sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE, hz * 10, false)) { DPRINTF(1,("%s: sdhc_exec_command: RSP_BSY\n", HDEVNAME(hp))); cmd->c_error = ETIMEDOUT; @@ -1588,6 +1591,10 @@ out: } SET(cmd->c_flags, SCF_ITSDONE); + if (ISSET(hp->sc->sc_flags, SDHC_FLAG_NO_AUTO_STOP) && + cmd->c_opcode == MMC_STOP_TRANSMISSION) + (void)sdhc_soft_reset(hp, SDHC_RESET_CMD|SDHC_RESET_DAT); + mutex_exit(&hp->intr_lock); DPRINTF(1,("%s: cmd %d %s (flags=%08x error=%d)\n", HDEVNAME(hp), @@ -1642,7 +1649,8 @@ sdhc_start_command(struct sdhc_host *hp, if (blkcount > 1) { mode |= SDHC_MULTI_BLOCK_MODE; /* XXX only for memory commands? */ - mode |= SDHC_AUTO_CMD12_ENABLE; + if (!ISSET(sc->sc_flags, SDHC_FLAG_NO_AUTO_STOP)) + mode |= SDHC_AUTO_CMD12_ENABLE; } if (cmd->c_dmamap != NULL && cmd->c_datalen > 0 && ISSET(hp->flags, SHF_MODE_DMAEN)) { Index: src/sys/dev/sdmmc/sdhcvar.h diff -u src/sys/dev/sdmmc/sdhcvar.h:1.26 src/sys/dev/sdmmc/sdhcvar.h:1.27 --- src/sys/dev/sdmmc/sdhcvar.h:1.26 Thu Dec 31 11:53:19 2015 +++ src/sys/dev/sdmmc/sdhcvar.h Sat Jan 7 15:05:08 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcvar.h,v 1.26 2015/12/31 11:53:19 ryo Exp $ */ +/* $NetBSD: sdhcvar.h,v 1.27 2017/01/07 15:05:08 kiyohara Exp $ */ /* $OpenBSD: sdhcvar.h,v 1.3 2007/09/06 08:01:01 jsg Exp $ */ /* @@ -59,6 +59,8 @@ struct sdhc_softc { #define SDHC_FLAG_POLL_CARD_DET 0x0020 /* polling card detect */ #define SDHC_FLAG_SLOW_SDR50 0x0040 /* reduce SDR50 speed */ #define SDHC_FLAG_USDHC 0x0080 /* Freescale uSDHC */ +#define SDHC_FLAG_NO_AUTO_STOP 0x0100 /* No auto CMD12 */ +#define SDHC_FLAG_NO_BUSY_INTR 0x0200 /* No intr when RESP_BUSY */ uint32_t sc_clkbase; int sc_clkmsk; /* Mask for SDCLK */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: kiyohara Date: Sat Jan 7 15:00:38 UTC 2017 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: Don't access SDHC_HOST_CTL_VERSION, if iosize less than this. To generate a diff of this commit: cvs rdiff -u -r1.95 -r1.96 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.95 src/sys/dev/sdmmc/sdhc.c:1.96 --- src/sys/dev/sdmmc/sdhc.c:1.95 Wed Aug 10 04:24:17 2016 +++ src/sys/dev/sdmmc/sdhc.c Sat Jan 7 15:00:38 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.95 2016/08/10 04:24:17 nonaka Exp $ */ +/* $NetBSD: sdhc.c,v 1.96 2017/01/07 15:00:38 kiyohara Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.95 2016/08/10 04:24:17 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.96 2017/01/07 15:00:38 kiyohara Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -290,38 +290,42 @@ sdhc_host_found(struct sdhc_softc *sc, b callout_init(&hp->tuning_timer, CALLOUT_MPSAFE); callout_setfunc(&hp->tuning_timer, sdhc_tuning_timer, hp); - if (ISSET(hp->sc->sc_flags, SDHC_FLAG_USDHC)) { - sdhcver = SDHC_SPEC_VERS_300 << SDHC_SPEC_VERS_SHIFT; - } else if (ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) { - sdhcver = HREAD4(hp, SDHC_ESDHC_HOST_CTL_VERSION); + if (iosize <= SDHC_HOST_CTL_VERSION) { + aprint_normal_dev(sc->sc_dev, "SDHC NO-VERS"); + hp->specver = -1; } else { - sdhcver = HREAD2(hp, SDHC_HOST_CTL_VERSION); - } - aprint_normal_dev(sc->sc_dev, "SDHC "); - hp->specver = SDHC_SPEC_VERSION(sdhcver); - switch (SDHC_SPEC_VERSION(sdhcver)) { - case SDHC_SPEC_VERS_100: - aprint_normal("1.0"); - break; + if (ISSET(hp->sc->sc_flags, SDHC_FLAG_USDHC)) { + sdhcver = SDHC_SPEC_VERS_300 << SDHC_SPEC_VERS_SHIFT; + } else if (ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) { + sdhcver = HREAD4(hp, SDHC_ESDHC_HOST_CTL_VERSION); + } else + sdhcver = HREAD2(hp, SDHC_HOST_CTL_VERSION); + aprint_normal_dev(sc->sc_dev, "SDHC "); + hp->specver = SDHC_SPEC_VERSION(sdhcver); + switch (SDHC_SPEC_VERSION(sdhcver)) { + case SDHC_SPEC_VERS_100: + aprint_normal("1.0"); + break; - case SDHC_SPEC_VERS_200: - aprint_normal("2.0"); - break; + case SDHC_SPEC_VERS_200: + aprint_normal("2.0"); + break; - case SDHC_SPEC_VERS_300: - aprint_normal("3.0"); - break; + case SDHC_SPEC_VERS_300: + aprint_normal("3.0"); + break; - case SDHC_SPEC_VERS_400: - aprint_normal("4.0"); - break; + case SDHC_SPEC_VERS_400: + aprint_normal("4.0"); + break; - default: - aprint_normal("unknown version(0x%x)", - SDHC_SPEC_VERSION(sdhcver)); - break; + default: + aprint_normal("unknown version(0x%x)", + SDHC_SPEC_VERSION(sdhcver)); + break; + } + aprint_normal(", rev %u", SDHC_VENDOR_VERSION(sdhcver)); } - aprint_normal(", rev %u", SDHC_VENDOR_VERSION(sdhcver)); /* * Reset the host controller and enable interrupts.
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: kiyohara Date: Sat Jan 7 14:49:53 UTC 2017 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Support retry when error. like wd(4). To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.23 src/sys/dev/sdmmc/ld_sdmmc.c:1.24 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.23 Tue Sep 27 03:33:33 2016 +++ src/sys/dev/sdmmc/ld_sdmmc.c Sat Jan 7 14:49:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.23 2016/09/27 03:33:33 pgoyette Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.24 2017/01/07 14:49:53 kiyohara Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.23 2016/09/27 03:33:33 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.24 2017/01/07 14:49:53 kiyohara Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -59,6 +59,9 @@ __KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v #define DPRINTF(s) /**/ #endif +#define LD_SDMMC_IORETRIES 5 /* number of retries before giving up */ +#define RECOVERYTIME hz/2 /* time to wait before retrying a cmd */ + struct ld_sdmmc_softc; struct ld_sdmmc_task { @@ -66,6 +69,8 @@ struct ld_sdmmc_task { struct ld_sdmmc_softc *task_sc; struct buf *task_bp; + int task_retries; /* number of xfer retry */ + struct callout task_restart_ch; }; struct ld_sdmmc_softc { @@ -75,7 +80,7 @@ struct ld_sdmmc_softc { struct sdmmc_function *sc_sf; #define LD_SDMMC_MAXQUEUECNT 4 struct ld_sdmmc_task sc_task[LD_SDMMC_MAXQUEUECNT]; - int sc_nexttask; + TAILQ_HEAD(, sdmmc_task) sc_freeq; }; static int ld_sdmmc_match(device_t, cfdata_t, void *); @@ -84,6 +89,7 @@ static int ld_sdmmc_detach(device_t, int static int ld_sdmmc_dump(struct ld_softc *, void *, int, int); static int ld_sdmmc_start(struct ld_softc *, struct buf *); +static void ld_sdmmc_restart(void *); static void ld_sdmmc_doattach(void *); static void ld_sdmmc_dobio(void *); @@ -110,7 +116,9 @@ ld_sdmmc_attach(device_t parent, device_ struct ld_sdmmc_softc *sc = device_private(self); struct sdmmc_attach_args *sa = aux; struct ld_softc *ld = &sc->sc_ld; + struct ld_sdmmc_task *task; struct lwp *lwp; + int i; ld->sc_dv = self; @@ -119,7 +127,13 @@ ld_sdmmc_attach(device_t parent, device_ sa->sf->cid.rev, sa->sf->cid.psn, sa->sf->cid.mdt); aprint_naive("\n"); - sc->sc_nexttask = 0; + TAILQ_INIT(&sc->sc_freeq); + for (i = 0; i < __arraycount(sc->sc_task); i++) { + task = &sc->sc_task[i]; + task->task_sc = sc; + callout_init(&task->task_restart_ch, 0); + TAILQ_INSERT_TAIL(&sc->sc_freeq, &task->task, next); + } sc->sc_hwunit = 0; /* always 0? */ sc->sc_sf = sa->sf; @@ -168,12 +182,15 @@ ld_sdmmc_detach(device_t dev, int flags) { struct ld_sdmmc_softc *sc = device_private(dev); struct ld_softc *ld = &sc->sc_ld; - int rv; + int rv, i; if ((rv = ldbegindetach(ld, flags)) != 0) return rv; ldenddetach(ld); + for (i = 0; i < __arraycount(sc->sc_task); i++) + callout_destroy(&sc->sc_task[i].task_restart_ch); + return 0; } @@ -181,12 +198,12 @@ static int ld_sdmmc_start(struct ld_softc *ld, struct buf *bp) { struct ld_sdmmc_softc *sc = device_private(ld->sc_dv); - struct ld_sdmmc_task *task = &sc->sc_task[sc->sc_nexttask]; + struct ld_sdmmc_task *task = (void *)TAILQ_FIRST(&sc->sc_freeq); - sc->sc_nexttask = (sc->sc_nexttask + 1) % LD_SDMMC_MAXQUEUECNT; + TAILQ_REMOVE(&sc->sc_freeq, &task->task, next); - task->task_sc = sc; task->task_bp = bp; + task->task_retries = 0; sdmmc_init_task(&task->task, ld_sdmmc_dobio, task); sdmmc_add_task(sc->sc_sf->sc, &task->task); @@ -195,6 +212,18 @@ ld_sdmmc_start(struct ld_softc *ld, stru } static void +ld_sdmmc_restart(void *arg) +{ + struct ld_sdmmc_task *task = (struct ld_sdmmc_task *)arg; + struct ld_sdmmc_softc *sc = task->task_sc; + struct buf *bp = task->task_bp; + + bp->b_resid = bp->b_bcount; + + sdmmc_add_task(sc->sc_sf->sc, &task->task); +} + +static void ld_sdmmc_dobio(void *arg) { struct ld_sdmmc_task *task = (struct ld_sdmmc_task *)arg; @@ -228,14 +257,26 @@ ld_sdmmc_dobio(void *arg) error = sdmmc_mem_write_block(sc->sc_sf, bp->b_rawblkno, bp->b_data, bp->b_bcount); if (error) { - DPRINTF(("%s: error %d\n", device_xname(sc->sc_ld.sc_dv), - error)); + if (task->task_retries < LD_SDMMC_IORETRIES) { + struct dk_softc *dksc = &sc->sc_ld.sc_dksc; + struct cfdriver *cd = device_cfdriver(dksc->sc_dev); + + diskerr(bp, cd->cd_name, "error", LOG_PRINTF, 0, +dksc->sc_dkdev.dk_label); + printf(", retrying\n"); + task->task_retries++; + callout_reset(&task->task_restart_ch, RECOVERYTIME, + ld_sdmmc_restart, task); + return; + } bp->b_error = error; bp->b_resid = bp->b_bcount; } el
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Thu Aug 11 01:33:25 UTC 2016 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: Fix incorrect sector counts with MMC. To generate a diff of this commit: cvs rdiff -u -r1.51 -r1.52 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.51 src/sys/dev/sdmmc/sdmmc_mem.c:1.52 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.51 Sun Mar 13 09:12:16 2016 +++ src/sys/dev/sdmmc/sdmmc_mem.c Thu Aug 11 01:33:25 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.51 2016/03/13 09:12:16 tsutsui Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.52 2016/08/11 01:33:25 nonaka 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.51 2016/03/13 09:12:16 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.52 2016/08/11 01:33:25 nonaka Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -905,7 +905,7 @@ static int sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) { int width, value, hs_timing, bus_clock, error; - char ext_csd[512]; + uint8_t ext_csd[512]; uint32_t sectors = 0; sc->sc_transfer_mode = NULL;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: nonaka Date: Wed Aug 10 04:24:17 UTC 2016 Modified Files: src/sys/dev/sdmmc: sdhc.c sdmmcreg.h Log Message: Use 1.65-1.95 voltage window for 1.8V support. To generate a diff of this commit: cvs rdiff -u -r1.94 -r1.95 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.21 -r1.22 src/sys/dev/sdmmc/sdmmcreg.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.94 src/sys/dev/sdmmc/sdhc.c:1.95 --- src/sys/dev/sdmmc/sdhc.c:1.94 Sun Jul 3 11:55:27 2016 +++ src/sys/dev/sdmmc/sdhc.c Wed Aug 10 04:24:17 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.94 2016/07/03 11:55:27 kiyohara Exp $ */ +/* $NetBSD: sdhc.c,v 1.95 2016/08/10 04:24:17 nonaka Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.94 2016/07/03 11:55:27 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.95 2016/08/10 04:24:17 nonaka Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -484,7 +484,7 @@ sdhc_host_found(struct sdhc_softc *sc, b aprint_normal(" SDR104 HS200"); } if (ISSET(caps, SDHC_VOLTAGE_SUPP_1_8V)) { - SET(hp->ocr, MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V); + SET(hp->ocr, MMC_OCR_1_65V_1_95V); aprint_normal(" 1.8V"); } if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_0V)) { @@ -910,7 +910,7 @@ sdhc_bus_power(sdmmc_chipset_handle_t sc * Select the lowest voltage according to capabilities. */ ocr &= hp->ocr; - if (ISSET(ocr, MMC_OCR_1_7V_1_8V|MMC_OCR_1_8V_1_9V)) { + if (ISSET(ocr, MMC_OCR_1_65V_1_95V)) { vdd = SDHC_VOLTAGE_1_8V; } else if (ISSET(ocr, MMC_OCR_2_9V_3_0V|MMC_OCR_3_0V_3_1V)) { vdd = SDHC_VOLTAGE_3_0V; Index: src/sys/dev/sdmmc/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.21 src/sys/dev/sdmmc/sdmmcreg.h:1.22 --- src/sys/dev/sdmmc/sdmmcreg.h:1.21 Thu Oct 29 22:37:15 2015 +++ src/sys/dev/sdmmc/sdmmcreg.h Wed Aug 10 04:24:17 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.21 2015/10/29 22:37:15 jmcneill Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.22 2016/08/10 04:24:17 nonaka Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -91,10 +91,7 @@ #define MMC_OCR_2_2V_2_3V (1<<10) #define MMC_OCR_2_1V_2_2V (1<<9) #define MMC_OCR_2_0V_2_1V (1<<8) -#define MMC_OCR_1_9V_2_0V (1<<7) -#define MMC_OCR_1_8V_1_9V (1<<6) -#define MMC_OCR_1_7V_1_8V (1<<5) -#define MMC_OCR_1_6V_1_7V (1<<4) +#define MMC_OCR_1_65V_1_95V (1<<7) /* R1 response type bits */ #define MMC_R1_READY_FOR_DATA (1<<8) /* ready for next transfer */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: kiyohara Date: Sun Jul 3 11:55:27 UTC 2016 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: Please more delay, if timeout in sdhc_wait_intr(). To generate a diff of this commit: cvs rdiff -u -r1.93 -r1.94 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.93 src/sys/dev/sdmmc/sdhc.c:1.94 --- src/sys/dev/sdmmc/sdhc.c:1.93 Thu Dec 31 11:53:19 2015 +++ src/sys/dev/sdmmc/sdhc.c Sun Jul 3 11:55:27 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.93 2015/12/31 11:53:19 ryo Exp $ */ +/* $NetBSD: sdhc.c,v 1.94 2016/07/03 11:55:27 kiyohara Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.93 2015/12/31 11:53:19 ryo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.94 2016/07/03 11:55:27 kiyohara Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1532,6 +1532,7 @@ sdhc_exec_command(sdmmc_chipset_handle_t probing = (cmd->c_flags & SCF_TOUT_OK) != 0; if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE, SDHC_COMMAND_TIMEOUT, probing)) { DPRINTF(1,("%s: timeout for command\n", __func__)); + sdmmc_delay(50); cmd->c_error = ETIMEDOUT; goto out; }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: tsutsui Date: Sun Mar 13 09:12:16 UTC 2016 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: Call the second sdmmc_mem_send_if_cond() only where it's necessary. This makes SMC_CAPS_SPI_MODE devices (currently evbsh3 only) work again. "Maybe ok" from nonaka@. To generate a diff of this commit: cvs rdiff -u -r1.50 -r1.51 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.50 src/sys/dev/sdmmc/sdmmc_mem.c:1.51 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.50 Tue Dec 22 09:56:06 2015 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sun Mar 13 09:12:16 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.50 2015/12/22 09:56:06 mlelstv Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.51 2016/03/13 09:12:16 tsutsui 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.50 2015/12/22 09:56:06 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.51 2016/03/13 09:12:16 tsutsui Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -198,15 +198,14 @@ mmc_mode: goto out; } - /* Tell the card(s) to enter the idle state (again). */ - sdmmc_go_idle_state(sc); - DPRINTF(("%s: host_ocr 0x%08x\n", SDMMCDEVNAME(sc), host_ocr)); DPRINTF(("%s: card_ocr 0x%08x\n", SDMMCDEVNAME(sc), card_ocr)); host_ocr &= card_ocr; /* only allow the common voltages */ if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) { if (ISSET(sc->sc_flags, SMF_SD_MODE)) { + /* Tell the card(s) to enter the idle state (again). */ + sdmmc_go_idle_state(sc); /* Check SD Ver.2 */ error = sdmmc_mem_send_if_cond(sc, 0x1aa, &card_ocr); if (error == 0 && card_ocr == 0x1aa)
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: ryo Date: Mon Dec 28 16:47:11 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: fix typo. use pmask for SDHC_PRESENT_STATE. To generate a diff of this commit: cvs rdiff -u -r1.91 -r1.92 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.91 src/sys/dev/sdmmc/sdhc.c:1.92 --- src/sys/dev/sdmmc/sdhc.c:1.91 Tue Nov 3 07:59:29 2015 +++ src/sys/dev/sdmmc/sdhc.c Mon Dec 28 16:47:11 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.91 2015/11/03 07:59:29 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.92 2015/12/28 16:47:11 ryo Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.91 2015/11/03 07:59:29 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.92 2015/12/28 16:47:11 ryo Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1832,7 +1832,7 @@ sdhc_transfer_data_pio(struct sdhc_host KASSERT(HREAD2(hp, SDHC_NINTR_SIGNAL_EN) & SDHC_TRANSFER_COMPLETE); while (datalen > 0) { - if (!ISSET(HREAD4(hp, SDHC_PRESENT_STATE), imask)) { + if (!ISSET(HREAD4(hp, SDHC_PRESENT_STATE), pmask)) { if (ISSET(hp->sc->sc_flags, SDHC_FLAG_32BIT_ACCESS)) { HSET4(hp, SDHC_NINTR_SIGNAL_EN, imask); } else {
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Tue Dec 22 09:56:06 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c Log Message: Be graceful about command timeouts when probing. To generate a diff of this commit: cvs rdiff -u -r1.49 -r1.50 src/sys/dev/sdmmc/sdmmc_mem.c 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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.49 src/sys/dev/sdmmc/sdmmc_mem.c:1.50 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.49 Sun Nov 29 23:38:47 2015 +++ src/sys/dev/sdmmc/sdmmc_mem.c Tue Dec 22 09:56:06 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.49 2015/11/29 23:38:47 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.50 2015/12/22 09:56:06 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.49 2015/11/29 23:38:47 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.50 2015/12/22 09:56:06 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -616,7 +616,8 @@ sdmmc_mem_send_op_cond(struct sdmmc_soft memset(&cmd, 0, sizeof(cmd)); cmd.c_arg = !ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE) ? ocr : (ocr & MMC_OCR_HCS); - cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R3 | SCF_RSP_SPI_R1; + cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R3 | SCF_RSP_SPI_R1 + | SCF_TOUT_OK; if (ISSET(sc->sc_flags, SMF_SD_MODE)) { cmd.c_opcode = SD_APP_OP_COND;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Tue Dec 22 09:55:38 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdmmc.c Log Message: ignore timeouts for APP_CMD prefix as for the application command itself. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/sys/dev/sdmmc/sdmmc.c 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.32 src/sys/dev/sdmmc/sdmmc.c:1.33 --- src/sys/dev/sdmmc/sdmmc.c:1.32 Sun Nov 29 23:38:47 2015 +++ src/sys/dev/sdmmc/sdmmc.c Tue Dec 22 09:55:38 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc.c,v 1.32 2015/11/29 23:38:47 jmcneill Exp $ */ +/* $NetBSD: sdmmc.c,v 1.33 2015/12/22 09:55:38 mlelstv Exp $ */ /* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */ /* @@ -49,7 +49,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.32 2015/11/29 23:38:47 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.33 2015/12/22 09:55:38 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -798,7 +798,7 @@ sdmmc_app_command(struct sdmmc_softc *sc memset(&acmd, 0, sizeof(acmd)); acmd.c_opcode = MMC_APP_CMD; acmd.c_arg = (sf != NULL) ? (sf->rca << 16) : 0; - acmd.c_flags = SCF_CMD_AC | SCF_RSP_R1 | SCF_RSP_SPI_R1; + acmd.c_flags = SCF_CMD_AC | SCF_RSP_R1 | SCF_RSP_SPI_R1 | (cmd->c_flags & SCF_TOUT_OK); error = sdmmc_mmc_command(sc, &acmd); if (error == 0) {
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sun Nov 29 23:38:47 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdmmc.c sdmmc_mem.c sdmmcvar.h Log Message: Add some event counters to track transfer sizes. To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.32 src/sys/dev/sdmmc/sdmmc.c cvs rdiff -u -r1.48 -r1.49 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.20 -r1.21 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.31 src/sys/dev/sdmmc/sdmmc.c:1.32 --- src/sys/dev/sdmmc/sdmmc.c:1.31 Sun Aug 9 13:18:46 2015 +++ src/sys/dev/sdmmc/sdmmc.c Sun Nov 29 23:38:47 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc.c,v 1.31 2015/08/09 13:18:46 mlelstv Exp $ */ +/* $NetBSD: sdmmc.c,v 1.32 2015/11/29 23:38:47 jmcneill Exp $ */ /* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */ /* @@ -49,7 +49,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.31 2015/08/09 13:18:46 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.32 2015/11/29 23:38:47 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -154,6 +154,29 @@ sdmmc_attach(device_t parent, device_t s mutex_init(&sc->sc_intr_task_mtx, MUTEX_DEFAULT, IPL_SDMMC); cv_init(&sc->sc_tskq_cv, "mmctaskq"); + evcnt_attach_dynamic(&sc->sc_ev_xfer, EVCNT_TYPE_MISC, NULL, + device_xname(self), "xfer"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_aligned[0], EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer 512"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_aligned[1], EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer 1024"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_aligned[2], EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer 2048"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_aligned[3], EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer 4096"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_aligned[4], EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer 8192"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_aligned[5], EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer 16384"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_aligned[6], EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer 32768"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_aligned[7], EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer 65536"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_unaligned, EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer unaligned"); + evcnt_attach_dynamic(&sc->sc_ev_xfer_error, EVCNT_TYPE_MISC, + &sc->sc_ev_xfer, device_xname(self), "xfer error"); + if (ISSET(sc->sc_caps, SMC_CAPS_POLL_CARD_DET)) { callout_init(&sc->sc_card_detect_ch, 0); callout_reset(&sc->sc_card_detect_ch, hz, @@ -178,7 +201,7 @@ static int sdmmc_detach(device_t self, int flags) { struct sdmmc_softc *sc = device_private(self); - int error; + int error, i; mutex_enter(&sc->sc_tskq_mtx); sc->sc_dying = 1; @@ -209,6 +232,12 @@ sdmmc_detach(device_t self, int flags) mutex_destroy(&sc->sc_tskq_mtx); mutex_destroy(&sc->sc_mtx); + evcnt_detach(&sc->sc_ev_xfer_error); + evcnt_detach(&sc->sc_ev_xfer_unaligned); + for (i = 0; i < __arraycount(sc->sc_ev_xfer_aligned); i++) + evcnt_detach(&sc->sc_ev_xfer_aligned[i]); + evcnt_detach(&sc->sc_ev_xfer); + return 0; } Index: src/sys/dev/sdmmc/sdmmc_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.48 src/sys/dev/sdmmc/sdmmc_mem.c:1.49 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.48 Thu Oct 29 22:37:15 2015 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sun Nov 29 23:38:47 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.48 2015/10/29 22:37:15 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.49 2015/11/29 23:38:47 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.48 2015/10/29 22:37:15 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.49 2015/11/29 23:38:47 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -56,6 +56,8 @@ __KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c, #include #include #include +#include +#include #include #include @@ -1595,9 +1597,20 @@ sdmmc_mem_read_block_subr(struct sdmmc_f if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) cmd.c_dmamap = dmap; + sc->sc_ev_xfer.ev_count++; + error = sdmmc_mmc_command(sc, &cmd); - if (error) + if (error) { + sc->sc_ev_xfer_error.ev_count++; goto out; + } + + const u_int counter = __builtin_ctz(cmd.c_datalen); + if (counter >= 9 && counter <= 16) { + sc->sc_ev_xfer_aligned[counter - 9].ev_count++; + } else { + sc->sc_ev_xfer_unaligned.ev_count++; + } if (!ISSET(sc->sc_caps, SMC_CAPS_AUTO_STOP)) { if (cmd.c_opcode == MMC_READ_BLOCK_MULTIPLE) { @@ -1809,9 +1822,20 @@ sdmmc_mem_write_block_sub
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Tue Nov 3 07:59:29 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: Also wait for DAT when sending RSP_BSY commands. Fixes PR 50388. To generate a diff of this commit: cvs rdiff -u -r1.90 -r1.91 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.90 src/sys/dev/sdmmc/sdhc.c:1.91 --- src/sys/dev/sdmmc/sdhc.c:1.90 Tue Nov 3 06:49:39 2015 +++ src/sys/dev/sdmmc/sdhc.c Tue Nov 3 07:59:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.90 2015/11/03 06:49:39 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.91 2015/11/03 07:59:29 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.90 2015/11/03 06:49:39 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.91 2015/11/03 07:59:29 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1596,7 +1596,7 @@ sdhc_start_command(struct sdhc_host *hp, /* Wait until command and optionally data inhibit bits are clear. (1.5) */ pmask = SDHC_CMD_INHIBIT_CMD; - if (cmd->c_flags & SCF_CMD_ADTC) + if (cmd->c_flags & (SCF_CMD_ADTC|SCF_RSP_BSY)) pmask |= SDHC_CMD_INHIBIT_DAT; error = sdhc_wait_state(hp, pmask, 0); if (error) {
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Tue Nov 3 06:49:39 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: fix timeout path in soft reset when building with SDHC_DEBUG To generate a diff of this commit: cvs rdiff -u -r1.89 -r1.90 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.89 src/sys/dev/sdmmc/sdhc.c:1.90 --- src/sys/dev/sdmmc/sdhc.c:1.89 Mon Nov 2 22:18:45 2015 +++ src/sys/dev/sdmmc/sdhc.c Tue Nov 3 06:49:39 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.89 2015/11/02 22:18:45 jmcneill Exp $ */ +/* $NetBSD: sdhc.c,v 1.90 2015/11/03 06:49:39 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.89 2015/11/02 22:18:45 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.90 2015/11/03 06:49:39 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -2043,9 +2043,10 @@ sdhc_soft_reset(struct sdhc_host *hp, in /* Short delay because I worry we may miss it... */ sdmmc_delay(1); } - if (timo == 0) + if (timo == 0) { DPRINTF(1,("%s: timeout for reset on\n", __func__)); return ETIMEDOUT; + } } /*
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Mon Nov 2 22:18:45 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c sdhcvar.h Log Message: allow vendor specific code to hook into bus width changes To generate a diff of this commit: cvs rdiff -u -r1.88 -r1.89 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.24 -r1.25 src/sys/dev/sdmmc/sdhcvar.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.88 src/sys/dev/sdmmc/sdhc.c:1.89 --- src/sys/dev/sdmmc/sdhc.c:1.88 Tue Oct 6 14:32:51 2015 +++ src/sys/dev/sdmmc/sdhc.c Mon Nov 2 22:18:45 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.88 2015/10/06 14:32:51 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.89 2015/11/02 22:18:45 jmcneill Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.88 2015/10/06 14:32:51 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.89 2015/11/02 22:18:45 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1182,6 +1182,12 @@ sdhc_bus_width(sdmmc_chipset_handle_t sc return 1; } + if (hp->sc->sc_vendor_bus_width) { + const int error = hp->sc->sc_vendor_bus_width(hp->sc, width); + if (error != 0) + return error; + } + mutex_enter(&hp->intr_lock); reg = HREAD1(hp, SDHC_HOST_CTL); Index: src/sys/dev/sdmmc/sdhcvar.h diff -u src/sys/dev/sdmmc/sdhcvar.h:1.24 src/sys/dev/sdmmc/sdhcvar.h:1.25 --- src/sys/dev/sdmmc/sdhcvar.h:1.24 Sun Aug 9 13:24:39 2015 +++ src/sys/dev/sdmmc/sdhcvar.h Mon Nov 2 22:18:45 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcvar.h,v 1.24 2015/08/09 13:24:39 mlelstv Exp $ */ +/* $NetBSD: sdhcvar.h,v 1.25 2015/11/02 22:18:45 jmcneill Exp $ */ /* $OpenBSD: sdhcvar.h,v 1.3 2007/09/06 08:01:01 jsg Exp $ */ /* @@ -67,6 +67,7 @@ struct sdhc_softc { int (*sc_vendor_rod)(struct sdhc_softc *, int); int (*sc_vendor_write_protect)(struct sdhc_softc *); int (*sc_vendor_card_detect)(struct sdhc_softc *); + int (*sc_vendor_bus_width)(struct sdhc_softc *, int); int (*sc_vendor_bus_clock)(struct sdhc_softc *, int); int (*sc_vendor_transfer_data_dma)(struct sdhc_softc *, struct sdmmc_command *); };
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Thu Oct 29 22:37:15 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c sdmmcreg.h Log Message: After setting HS_TIMING value for HS200 or later, send repeated SEND_STATUS command until the device is no longer busy or the SWITCH_ERROR bit is set. To generate a diff of this commit: cvs rdiff -u -r1.47 -r1.48 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.20 -r1.21 src/sys/dev/sdmmc/sdmmcreg.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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.47 src/sys/dev/sdmmc/sdmmc_mem.c:1.48 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.47 Tue Oct 6 14:32:51 2015 +++ src/sys/dev/sdmmc/sdmmc_mem.c Thu Oct 29 22:37:15 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.47 2015/10/06 14:32:51 mlelstv Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.48 2015/10/29 22:37:15 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.47 2015/10/06 14:32:51 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.48 2015/10/29 22:37:15 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1414,6 +1414,7 @@ sdmmc_mem_mmc_switch(struct sdmmc_functi { struct sdmmc_softc *sc = sf->sc; struct sdmmc_command cmd; + int error; memset(&cmd, 0, sizeof(cmd)); cmd.c_opcode = MMC_SWITCH; @@ -1421,7 +1422,36 @@ sdmmc_mem_mmc_switch(struct sdmmc_functi (index << 16) | (value << 8) | set; cmd.c_flags = SCF_RSP_SPI_R1B | SCF_RSP_R1B | SCF_CMD_AC; - return sdmmc_mmc_command(sc, &cmd); + error = sdmmc_mmc_command(sc, &cmd); + if (error) + return error; + + if (index == EXT_CSD_HS_TIMING && value >= 2) { + do { + memset(&cmd, 0, sizeof(cmd)); + cmd.c_opcode = MMC_SEND_STATUS; + if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) +cmd.c_arg = MMC_ARG_RCA(sf->rca); + cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1 | SCF_RSP_SPI_R2; + error = sdmmc_mmc_command(sc, &cmd); + if (error) +break; + if (ISSET(MMC_R1(cmd.c_resp), MMC_R1_SWITCH_ERROR)) { +aprint_error_dev(sc->sc_dev, "switch error\n"); +return EINVAL; + } + /* XXX time out */ + } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)); + + if (error) { + aprint_error_dev(sc->sc_dev, + "error waiting for high speed switch: %d\n", + error); + return error; + } + } + + return 0; } /* Index: src/sys/dev/sdmmc/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.20 src/sys/dev/sdmmc/sdmmcreg.h:1.21 --- src/sys/dev/sdmmc/sdmmcreg.h:1.20 Sat Aug 8 10:50:55 2015 +++ src/sys/dev/sdmmc/sdmmcreg.h Thu Oct 29 22:37:15 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.20 2015/08/08 10:50:55 jmcneill Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.21 2015/10/29 22:37:15 jmcneill Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -98,6 +98,7 @@ /* R1 response type bits */ #define MMC_R1_READY_FOR_DATA (1<<8) /* ready for next transfer */ +#define MMC_R1_SWITCH_ERROR (1<<7) /* switch command failed */ #define MMC_R1_APP_CMD (1<<5) /* app. commands supported */ /* 48-bit response decoding (32 bits w/o CRC) */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Tue Oct 6 14:32:51 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c sdmmc_io.c sdmmc_mem.c sdmmcvar.h Log Message: support hiding command timeout messages with a new command flag and use this when probing for cards. Should fix PR 50302. To generate a diff of this commit: cvs rdiff -u -r1.87 -r1.88 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.11 -r1.12 src/sys/dev/sdmmc/sdmmc_io.c cvs rdiff -u -r1.46 -r1.47 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.19 -r1.20 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.87 src/sys/dev/sdmmc/sdhc.c:1.88 --- src/sys/dev/sdmmc/sdhc.c:1.87 Wed Sep 9 08:09:28 2015 +++ src/sys/dev/sdmmc/sdhc.c Tue Oct 6 14:32:51 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.87 2015/09/09 08:09:28 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.88 2015/10/06 14:32:51 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.87 2015/09/09 08:09:28 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.88 2015/10/06 14:32:51 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -195,7 +195,7 @@ static void sdhc_tuning_timer(void *); static int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *); static int sdhc_wait_state(struct sdhc_host *, uint32_t, uint32_t); static int sdhc_soft_reset(struct sdhc_host *, int); -static int sdhc_wait_intr(struct sdhc_host *, int, int); +static int sdhc_wait_intr(struct sdhc_host *, int, int, bool); static void sdhc_transfer_data(struct sdhc_host *, struct sdmmc_command *); static int sdhc_transfer_data_dma(struct sdhc_host *, struct sdmmc_command *); static int sdhc_transfer_data_pio(struct sdhc_host *, struct sdmmc_command *); @@ -1331,7 +1331,7 @@ sdhc_execute_tuning1(struct sdhc_host *h break; if (!sdhc_wait_intr(hp, SDHC_BUFFER_READ_READY, - SDHC_TUNING_TIMEOUT)) { + SDHC_TUNING_TIMEOUT, false)) { break; } @@ -1409,6 +1409,7 @@ sdhc_exec_command(sdmmc_chipset_handle_t { struct sdhc_host *hp = (struct sdhc_host *)sch; int error; + bool probing; mutex_enter(&hp->intr_lock); @@ -1451,7 +1452,8 @@ sdhc_exec_command(sdmmc_chipset_handle_t * Wait until the command phase is done, or until the command * is marked done for any other reason. */ - if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE, SDHC_COMMAND_TIMEOUT)) { + probing = (cmd->c_flags & SCF_TOUT_OK) != 0; + if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE, SDHC_COMMAND_TIMEOUT, probing)) { DPRINTF(1,("%s: timeout for command\n", __func__)); cmd->c_error = ETIMEDOUT; goto out; @@ -1488,7 +1490,7 @@ sdhc_exec_command(sdmmc_chipset_handle_t if (cmd->c_error == 0 && cmd->c_data != NULL) sdhc_transfer_data(hp, cmd); else if (ISSET(cmd->c_flags, SCF_RSP_BSY)) { - if (!sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE, hz * 10)) { + if (!sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE, hz * 10, false)) { DPRINTF(1,("%s: sdhc_exec_command: RSP_BSY\n", HDEVNAME(hp))); cmd->c_error = ETIMEDOUT; @@ -1707,7 +1709,7 @@ sdhc_transfer_data(struct sdhc_host *hp, if (hp->sc->sc_vendor_transfer_data_dma != NULL) { error = hp->sc->sc_vendor_transfer_data_dma(sc, cmd); if (error == 0 && !sdhc_wait_intr(hp, - SDHC_TRANSFER_COMPLETE, SDHC_DMA_TIMEOUT)) { + SDHC_TRANSFER_COMPLETE, SDHC_DMA_TIMEOUT, false)) { DPRINTF(1,("%s: timeout\n", __func__)); error = ETIMEDOUT; } @@ -1744,7 +1746,7 @@ sdhc_transfer_data_dma(struct sdhc_host for (;;) { status = sdhc_wait_intr(hp, SDHC_DMA_INTERRUPT|SDHC_TRANSFER_COMPLETE, - SDHC_DMA_TIMEOUT); + SDHC_DMA_TIMEOUT, false); if (status & SDHC_TRANSFER_COMPLETE) { break; @@ -1830,7 +1832,7 @@ sdhc_transfer_data_pio(struct sdhc_host } else { HSET2(hp, SDHC_NINTR_SIGNAL_EN, imask); } - if (!sdhc_wait_intr(hp, imask, SDHC_BUFFER_TIMEOUT)) { + if (!sdhc_wait_intr(hp, imask, SDHC_BUFFER_TIMEOUT, false)) { DPRINTF(1,("%s: timeout\n", __func__)); error = ETIMEDOUT; break; @@ -1851,7 +1853,7 @@ sdhc_transfer_data_pio(struct sdhc_host } if (error == 0 && !sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE, - SDHC_TRANSFER_TIMEOUT)) { + SDHC_TRANSFER_TIMEOUT, false)) { DPRINTF(1,("%s: timeout for transfer\n", __func__)); error = ETIMEDOUT; } @@ -2063,7 +2065,7 @@ sdhc_soft_reset(struct sdhc_host *hp, in } static int -sdhc_wait_intr(struct sdhc_host *hp, int mask, int timo) +sdhc_wait_intr(struct sdhc_host *hp, int mask, int timo, bool probing) { int status, error, nointr; @@ -2110,8 +2112,14 @@ sdhc_wait_intr(struct sdhc_host *hp, int device_printf(hp->sc->sc_dev,"cmd end bit error\n"); if (ISSET(error, SDHC_CMD_CRC_ERROR)) device_print
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Wed Sep 9 08:09:28 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: The iMX uSDHC controller doesn't have an interrupt error status flag, the bit position is reserved and reads as value 0. - Fake the flag if any of the error bits is set. - uSDHC supports the 32bit access, the 16bit path doesn't need that quirk. To generate a diff of this commit: cvs rdiff -u -r1.86 -r1.87 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.86 src/sys/dev/sdmmc/sdhc.c:1.87 --- src/sys/dev/sdmmc/sdhc.c:1.86 Wed Sep 9 08:06:47 2015 +++ src/sys/dev/sdmmc/sdhc.c Wed Sep 9 08:09:28 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.86 2015/09/09 08:06:47 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.87 2015/09/09 08:09:28 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.86 2015/09/09 08:06:47 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.87 2015/09/09 08:09:28 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -2163,6 +2163,10 @@ sdhc_intr(void *arg) uint32_t xstatus = HREAD4(hp, SDHC_NINTR_STATUS); status = xstatus; error = xstatus >> 16; + if (ISSET(sc->sc_flags, SDHC_FLAG_ENHANCED)) { +if ((error & SDHC_NINTR_STATUS_MASK) != 0) + SET(status, SDHC_ERROR_INTERRUPT); + } if (error) xstatus |= SDHC_ERROR_INTERRUPT; else if (!ISSET(status, SDHC_NINTR_STATUS_MASK))
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Wed Sep 9 08:06:47 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: Don't test flags from error value in status value. Instead test the error interrupt status. To generate a diff of this commit: cvs rdiff -u -r1.85 -r1.86 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.85 src/sys/dev/sdmmc/sdhc.c:1.86 --- src/sys/dev/sdmmc/sdhc.c:1.85 Wed Sep 9 08:04:33 2015 +++ src/sys/dev/sdmmc/sdhc.c Wed Sep 9 08:06:47 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.85 2015/09/09 08:04:33 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.86 2015/09/09 08:06:47 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.85 2015/09/09 08:04:33 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.86 2015/09/09 08:06:47 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -2223,8 +2223,7 @@ sdhc_intr(void *arg) * Wake up the blocking process to service command * related interrupt(s). */ - if (ISSET(status, SDHC_COMMAND_COMPLETE| - SDHC_CMD_TIMEOUT_ERROR|SDHC_DATA_TIMEOUT_ERROR| + if (ISSET(status, SDHC_COMMAND_COMPLETE|SDHC_ERROR_INTERRUPT| SDHC_BUFFER_READ_READY|SDHC_BUFFER_WRITE_READY| SDHC_TRANSFER_COMPLETE|SDHC_DMA_INTERRUPT)) { hp->intr_error_status |= error;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Wed Sep 9 08:04:33 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: fix DPRINTF parameters To generate a diff of this commit: cvs rdiff -u -r1.84 -r1.85 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.84 src/sys/dev/sdmmc/sdhc.c:1.85 --- src/sys/dev/sdmmc/sdhc.c:1.84 Sun Aug 9 13:46:50 2015 +++ src/sys/dev/sdmmc/sdhc.c Wed Sep 9 08:04:33 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.84 2015/08/09 13:46:50 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.85 2015/09/09 08:04:33 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.84 2015/08/09 13:46:50 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.85 2015/09/09 08:04:33 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1489,7 +1489,8 @@ sdhc_exec_command(sdmmc_chipset_handle_t sdhc_transfer_data(hp, cmd); else if (ISSET(cmd->c_flags, SCF_RSP_BSY)) { if (!sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE, hz * 10)) { - DPRINTF(1,(hp->sc->sc_dev,"sdhc_exec_command: RSP_BSY\n")); + DPRINTF(1,("%s: sdhc_exec_command: RSP_BSY\n", + HDEVNAME(hp))); cmd->c_error = ETIMEDOUT; goto out; }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Fri Aug 28 06:04:43 UTC 2015 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: remove unused include sys/rndsource.h To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.20 src/sys/dev/sdmmc/ld_sdmmc.c:1.21 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.20 Sun Aug 9 13:49:18 2015 +++ src/sys/dev/sdmmc/ld_sdmmc.c Fri Aug 28 06:04:43 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.20 2015/08/09 13:49:18 mlelstv Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.21 2015/08/28 06:04:43 mlelstv Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.20 2015/08/09 13:49:18 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.21 2015/08/28 06:04:43 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -45,7 +45,6 @@ __KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v #include #include #include -#include #include
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sun Aug 9 13:49:19 UTC 2015 Modified Files: src/sys/dev/sdmmc: ld_sdmmc.c Log Message: Add small command queue to reduce latency between ld driver and sdmmc I/O thread. To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/sys/dev/sdmmc/ld_sdmmc.c 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/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.19 src/sys/dev/sdmmc/ld_sdmmc.c:1.20 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.19 Mon Aug 3 10:09:08 2015 +++ src/sys/dev/sdmmc/ld_sdmmc.c Sun Aug 9 13:49:18 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.19 2015/08/03 10:09:08 jmcneill Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.20 2015/08/09 13:49:18 mlelstv Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.19 2015/08/03 10:09:08 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.20 2015/08/09 13:49:18 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -71,7 +71,9 @@ struct ld_sdmmc_softc { int sc_hwunit; struct sdmmc_function *sc_sf; - struct ld_sdmmc_task sc_task; +#define LD_SDMMC_MAXQUEUECNT 4 + struct ld_sdmmc_task sc_task[LD_SDMMC_MAXQUEUECNT]; + int sc_nexttask; }; static int ld_sdmmc_match(device_t, cfdata_t, void *); @@ -115,6 +117,8 @@ ld_sdmmc_attach(device_t parent, device_ sa->sf->cid.rev, sa->sf->cid.psn, sa->sf->cid.mdt); aprint_naive("\n"); + sc->sc_nexttask = 0; + sc->sc_hwunit = 0; /* always 0? */ sc->sc_sf = sa->sf; @@ -122,7 +126,7 @@ ld_sdmmc_attach(device_t parent, device_ ld->sc_secperunit = sc->sc_sf->csd.capacity; ld->sc_secsize = SDMMC_SECTOR_SIZE; ld->sc_maxxfer = MAXPHYS; - ld->sc_maxqueuecnt = 1; + ld->sc_maxqueuecnt = LD_SDMMC_MAXQUEUECNT; ld->sc_dump = ld_sdmmc_dump; ld->sc_start = ld_sdmmc_start; @@ -175,7 +179,9 @@ static int ld_sdmmc_start(struct ld_softc *ld, struct buf *bp) { struct ld_sdmmc_softc *sc = device_private(ld->sc_dv); - struct ld_sdmmc_task *task = &sc->sc_task; + struct ld_sdmmc_task *task = &sc->sc_task[sc->sc_nexttask]; + + sc->sc_nexttask = (sc->sc_nexttask + 1) % LD_SDMMC_MAXQUEUECNT; task->task_sc = sc; task->task_bp = bp;
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sun Aug 9 13:46:50 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: Ignore data inhibit for commands that do not use the DAT line. Do a soft reset when the inhibit condition persists for better error recovery. Simplify interrupt handling and print errors reported by the controller. Add more specific debug messages for timeout errors. To generate a diff of this commit: cvs rdiff -u -r1.83 -r1.84 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.83 src/sys/dev/sdmmc/sdhc.c:1.84 --- src/sys/dev/sdmmc/sdhc.c:1.83 Sun Aug 9 13:39:18 2015 +++ src/sys/dev/sdmmc/sdhc.c Sun Aug 9 13:46:50 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.83 2015/08/09 13:39:18 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.84 2015/08/09 13:46:50 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.83 2015/08/09 13:39:18 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.84 2015/08/09 13:46:50 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1117,6 +1117,7 @@ sdhc_bus_clock_ddr(sdmmc_chipset_handle_ } if (timo == 0) { error = ETIMEDOUT; + DPRINTF(1,("%s: timeout\n", __func__)); goto out; } } @@ -1451,6 +1452,7 @@ sdhc_exec_command(sdmmc_chipset_handle_t * is marked done for any other reason. */ if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE, SDHC_COMMAND_TIMEOUT)) { + DPRINTF(1,("%s: timeout for command\n", __func__)); cmd->c_error = ETIMEDOUT; goto out; } @@ -1487,6 +1489,7 @@ sdhc_exec_command(sdmmc_chipset_handle_t sdhc_transfer_data(hp, cmd); else if (ISSET(cmd->c_flags, SCF_RSP_BSY)) { if (!sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE, hz * 10)) { + DPRINTF(1,(hp->sc->sc_dev,"sdhc_exec_command: RSP_BSY\n")); cmd->c_error = ETIMEDOUT; goto out; } @@ -1515,6 +1518,7 @@ sdhc_start_command(struct sdhc_host *hp, uint16_t blkcount = 0; uint16_t mode; uint16_t command; + uint32_t pmask; int error; KASSERT(mutex_owned(&hp->intr_lock)); @@ -1581,10 +1585,14 @@ sdhc_start_command(struct sdhc_host *hp, else command |= SDHC_RESP_LEN_48; - /* Wait until command and data inhibit bits are clear. (1.5) */ - error = sdhc_wait_state(hp, SDHC_CMD_INHIBIT_MASK, 0); + /* Wait until command and optionally data inhibit bits are clear. (1.5) */ + pmask = SDHC_CMD_INHIBIT_CMD; + if (cmd->c_flags & SCF_CMD_ADTC) + pmask |= SDHC_CMD_INHIBIT_DAT; + error = sdhc_wait_state(hp, pmask, 0); if (error) { - aprint_error_dev(sc->sc_dev, "command or data phase inhibited\n"); + (void) sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD); + device_printf(sc->sc_dev, "command or data phase inhibited\n"); return error; } @@ -1699,6 +1707,7 @@ sdhc_transfer_data(struct sdhc_host *hp, error = hp->sc->sc_vendor_transfer_data_dma(sc, cmd); if (error == 0 && !sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE, SDHC_DMA_TIMEOUT)) { +DPRINTF(1,("%s: timeout\n", __func__)); error = ETIMEDOUT; } } else { @@ -1740,6 +1749,7 @@ sdhc_transfer_data_dma(struct sdhc_host break; } if (!status) { + DPRINTF(1,("%s: timeout\n", __func__)); error = ETIMEDOUT; break; } @@ -1820,6 +1830,7 @@ sdhc_transfer_data_pio(struct sdhc_host HSET2(hp, SDHC_NINTR_SIGNAL_EN, imask); } if (!sdhc_wait_intr(hp, imask, SDHC_BUFFER_TIMEOUT)) { +DPRINTF(1,("%s: timeout\n", __func__)); error = ETIMEDOUT; break; } @@ -1839,8 +1850,10 @@ sdhc_transfer_data_pio(struct sdhc_host } if (error == 0 && !sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE, - SDHC_TRANSFER_TIMEOUT)) + SDHC_TRANSFER_TIMEOUT)) { + DPRINTF(1,("%s: timeout for transfer\n", __func__)); error = ETIMEDOUT; + } return error; } @@ -2022,6 +2035,7 @@ sdhc_soft_reset(struct sdhc_host *hp, in sdmmc_delay(1); } if (timo == 0) + DPRINTF(1,("%s: timeout for reset on\n", __func__)); return ETIMEDOUT; } @@ -2050,33 +2064,73 @@ sdhc_soft_reset(struct sdhc_host *hp, in static int sdhc_wait_intr(struct sdhc_host *hp, int mask, int timo) { - int status; + int status, error, nointr; KASSERT(mutex_owned(&hp->intr_lock)); mask |= SDHC_ERROR_INTERRUPT; + nointr = 0; status = hp->intr_status & mask; while (status == 0) { if (cv_timedwait(&hp->intr_cv, &hp->intr_lock, timo) == EWOULDBLOCK) { - status |= SDHC_ERROR_INTERRUPT; + nointr = 1; break; } status = hp->intr_status & mask; } - hp->intr_status &= ~status; + error = hp->intr_error_status; DPRINTF(2,("%s: intr status %#x error %#x\n", HDEVNAME(hp), status, - hp->intr_error_status)); + error)); + + hp->intr_status &= ~status; + hp->intr_error_status &= ~error; - /* Command timeo
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sun Aug 9 13:39:18 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: Protect the whole tuning operation including the register setup. To generate a diff of this commit: cvs rdiff -u -r1.82 -r1.83 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.82 src/sys/dev/sdmmc/sdhc.c:1.83 --- src/sys/dev/sdmmc/sdhc.c:1.82 Sun Aug 9 13:24:39 2015 +++ src/sys/dev/sdmmc/sdhc.c Sun Aug 9 13:39:18 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.82 2015/08/09 13:24:39 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.83 2015/08/09 13:39:18 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.82 2015/08/09 13:24:39 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.83 2015/08/09 13:39:18 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -189,6 +189,7 @@ static void sdhc_card_intr_ack(sdmmc_chi static void sdhc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *); static int sdhc_signal_voltage(sdmmc_chipset_handle_t, int); +static int sdhc_execute_tuning1(struct sdhc_host *, int); static int sdhc_execute_tuning(sdmmc_chipset_handle_t, int); static void sdhc_tuning_timer(void *); static int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *); @@ -1273,13 +1274,14 @@ sdhc_signal_voltage(sdmmc_chipset_handle * Sampling clock tuning procedure (UHS) */ static int -sdhc_execute_tuning(sdmmc_chipset_handle_t sch, int timing) +sdhc_execute_tuning1(struct sdhc_host *hp, int timing) { - struct sdhc_host *hp = (struct sdhc_host *)sch; struct sdmmc_command cmd; uint8_t hostctl; int opcode, error, retry = 40; + KASSERT(mutex_owned(&hp->intr_lock)); + hp->tuning_timing = timing; switch (timing) { @@ -1312,7 +1314,6 @@ sdhc_execute_tuning(sdmmc_chipset_handle /* start of tuning */ HWRITE2(hp, SDHC_HOST_CTL2, SDHC_EXECUTE_TUNING); - mutex_enter(&hp->intr_lock); do { memset(&cmd, 0, sizeof(cmd)); cmd.c_opcode = opcode; @@ -1335,7 +1336,6 @@ sdhc_execute_tuning(sdmmc_chipset_handle delay(1000); } while (HREAD2(hp, SDHC_HOST_CTL2) & SDHC_EXECUTE_TUNING && --retry); - mutex_exit(&hp->intr_lock); /* disable buffer read ready interrupt */ HCLR2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_BUFFER_READ_READY); @@ -1367,6 +1367,18 @@ sdhc_execute_tuning(sdmmc_chipset_handle return 0; /* tuning completed */ } +static int +sdhc_execute_tuning(sdmmc_chipset_handle_t sch, int timing) +{ + struct sdhc_host *hp = (struct sdhc_host *)sch; + int error; + + mutex_enter(&hp->intr_lock); + error = sdhc_execute_tuning1(hp, timing); + mutex_exit(&hp->intr_lock); + return error; +} + static void sdhc_tuning_timer(void *arg) { @@ -1397,12 +1409,12 @@ sdhc_exec_command(sdmmc_chipset_handle_t struct sdhc_host *hp = (struct sdhc_host *)sch; int error; + mutex_enter(&hp->intr_lock); + if (atomic_cas_uint(&hp->tuning_timer_pending, 1, 0) == 1) { - (void)sdhc_execute_tuning(hp, hp->tuning_timing); + (void)sdhc_execute_tuning1(hp, hp->tuning_timing); } - mutex_enter(&hp->intr_lock); - if (cmd->c_data && ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) { const uint16_t ready = SDHC_BUFFER_READ_READY | SDHC_BUFFER_WRITE_READY; if (ISSET(hp->flags, SHF_USE_DMA)) {
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sun Aug 9 13:24:39 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c sdhcvar.h Log Message: Add a quirk for Ricoh 5U823 controller. Operation with a 100MHz bus clock for SDR50 seems to be unstable, reduce frequency one notch (effectively down to 66MHz with divisor = 3). To generate a diff of this commit: cvs rdiff -u -r1.81 -r1.82 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.23 -r1.24 src/sys/dev/sdmmc/sdhcvar.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.81 src/sys/dev/sdmmc/sdhc.c:1.82 --- src/sys/dev/sdmmc/sdhc.c:1.81 Thu Aug 6 09:30:55 2015 +++ src/sys/dev/sdmmc/sdhc.c Sun Aug 9 13:24:39 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.81 2015/08/06 09:30:55 jmcneill Exp $ */ +/* $NetBSD: sdhc.c,v 1.82 2015/08/09 13:24:39 mlelstv Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.81 2015/08/06 09:30:55 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.82 2015/08/09 13:24:39 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1072,6 +1072,15 @@ sdhc_bus_clock_ddr(sdmmc_chipset_handle_ } /* + * Slow down Ricoh 5U823 controller that isn't reliable + * at 100MHz bus clock. + */ + if (ISSET(hp->sc->sc_flags, SDHC_FLAG_SLOW_SDR50)) { + if (freq == 10) + --freq; + } + + /* * Set the minimum base clock frequency divisor. */ if (!sdhc_clock_divisor(hp, freq, &div)) { Index: src/sys/dev/sdmmc/sdhcvar.h diff -u src/sys/dev/sdmmc/sdhcvar.h:1.23 src/sys/dev/sdmmc/sdhcvar.h:1.24 --- src/sys/dev/sdmmc/sdhcvar.h:1.23 Mon Aug 3 12:11:36 2015 +++ src/sys/dev/sdmmc/sdhcvar.h Sun Aug 9 13:24:39 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcvar.h,v 1.23 2015/08/03 12:11:36 jmcneill Exp $ */ +/* $NetBSD: sdhcvar.h,v 1.24 2015/08/09 13:24:39 mlelstv Exp $ */ /* $OpenBSD: sdhcvar.h,v 1.3 2007/09/06 08:01:01 jsg Exp $ */ /* @@ -57,6 +57,7 @@ struct sdhc_softc { #define SDHC_FLAG_NO_TIMEOUT 0x0008 /* ignore timeout interrupts */ #define SDHC_FLAG_USE_ADMA2 0x0010 #define SDHC_FLAG_POLL_CARD_DET 0x0020 /* polling card detect */ +#define SDHC_FLAG_SLOW_SDR50 0x0040 /* reduce SDR50 speed */ uint32_t sc_clkbase; int sc_clkmsk; /* Mask for SDCLK */
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sun Aug 9 13:18:46 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdmmc.c sdmmcvar.h Log Message: Send an explicit CMD12 (stop transmission) when there was an error in multi-sector I/O. The SDHC spec has a complex flowchart describing when an explicit CMD12 is necessary, so we probably use it too often. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/sys/dev/sdmmc/sdmmc.c cvs rdiff -u -r1.18 -r1.19 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.30 src/sys/dev/sdmmc/sdmmc.c:1.31 --- src/sys/dev/sdmmc/sdmmc.c:1.30 Sun Aug 9 13:14:11 2015 +++ src/sys/dev/sdmmc/sdmmc.c Sun Aug 9 13:18:46 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc.c,v 1.30 2015/08/09 13:14:11 mlelstv Exp $ */ +/* $NetBSD: sdmmc.c,v 1.31 2015/08/09 13:18:46 mlelstv Exp $ */ /* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */ /* @@ -49,7 +49,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.30 2015/08/09 13:14:11 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.31 2015/08/09 13:18:46 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -817,10 +817,35 @@ sdmmc_mmc_command(struct sdmmc_softc *sc DPRINTF(1,("sdmmc_mmc_command: error=%d\n", error)); + if (error && + (cmd->c_opcode == MMC_READ_BLOCK_MULTIPLE || + cmd->c_opcode == MMC_WRITE_BLOCK_MULTIPLE)) { + sdmmc_stop_transmission(sc); + } + return error; } /* + * Send the "STOP TRANSMISSION" command + */ +void +sdmmc_stop_transmission(struct sdmmc_softc *sc) +{ + struct sdmmc_command cmd; + + DPRINTF(1,("sdmmc_stop_transmission\n")); + + /* Don't lock */ + + memset(&cmd, 0, sizeof(cmd)); + cmd.c_opcode = MMC_STOP_TRANSMISSION; + cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B | SCF_RSP_SPI_R1B; + + (void)sdmmc_mmc_command(sc, &cmd); +} + +/* * Send the "GO IDLE STATE" command. */ void Index: src/sys/dev/sdmmc/sdmmcvar.h diff -u src/sys/dev/sdmmc/sdmmcvar.h:1.18 src/sys/dev/sdmmc/sdmmcvar.h:1.19 --- src/sys/dev/sdmmc/sdmmcvar.h:1.18 Mon Aug 3 10:08:51 2015 +++ src/sys/dev/sdmmc/sdmmcvar.h Sun Aug 9 13:18:46 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcvar.h,v 1.18 2015/08/03 10:08:51 jmcneill Exp $ */ +/* $NetBSD: sdmmcvar.h,v 1.19 2015/08/09 13:18:46 mlelstv Exp $ */ /* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -306,6 +306,7 @@ int sdmmc_set_bus_power(struct sdmmc_sof int sdmmc_mmc_command(struct sdmmc_softc *, struct sdmmc_command *); int sdmmc_app_command(struct sdmmc_softc *, struct sdmmc_function *, struct sdmmc_command *); +void sdmmc_stop_transmission(struct sdmmc_softc *); void sdmmc_go_idle_state(struct sdmmc_softc *); int sdmmc_select_card(struct sdmmc_softc *, struct sdmmc_function *); int sdmmc_set_relative_addr(struct sdmmc_softc *, struct sdmmc_function *);
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: mlelstv Date: Sun Aug 9 13:14:11 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdmmc.c Log Message: protect card detection with mutex. To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/sys/dev/sdmmc/sdmmc.c 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.29 src/sys/dev/sdmmc/sdmmc.c:1.30 --- src/sys/dev/sdmmc/sdmmc.c:1.29 Mon Aug 3 10:08:51 2015 +++ src/sys/dev/sdmmc/sdmmc.c Sun Aug 9 13:14:11 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc.c,v 1.29 2015/08/03 10:08:51 jmcneill Exp $ */ +/* $NetBSD: sdmmc.c,v 1.30 2015/08/09 13:14:11 mlelstv Exp $ */ /* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */ /* @@ -49,7 +49,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.29 2015/08/03 10:08:51 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.30 2015/08/09 13:14:11 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -315,19 +315,28 @@ static void sdmmc_discover_task(void *arg) { struct sdmmc_softc *sc = (struct sdmmc_softc *)arg; + int card_detect, card_present; - if (sdmmc_chip_card_detect(sc->sc_sct, sc->sc_sch)) { - if (!ISSET(sc->sc_flags, SMF_CARD_PRESENT)) { - SET(sc->sc_flags, SMF_CARD_PRESENT); + mutex_enter(&sc->sc_discover_task_mtx); + card_detect = sdmmc_chip_card_detect(sc->sc_sct, sc->sc_sch); + card_present = ISSET(sc->sc_flags, SMF_CARD_PRESENT); + if (card_detect) + SET(sc->sc_flags, SMF_CARD_PRESENT); + else + CLR(sc->sc_flags, SMF_CARD_PRESENT); + mutex_exit(&sc->sc_discover_task_mtx); + + if (card_detect) { + if (!card_present) { sdmmc_card_attach(sc); + mutex_enter(&sc->sc_discover_task_mtx); if (!ISSET(sc->sc_flags, SMF_CARD_ATTACHED)) CLR(sc->sc_flags, SMF_CARD_PRESENT); + mutex_exit(&sc->sc_discover_task_mtx); } } else { - if (ISSET(sc->sc_flags, SMF_CARD_PRESENT)) { - CLR(sc->sc_flags, SMF_CARD_PRESENT); + if (card_present) sdmmc_card_detach(sc, DETACH_FORCE); - } } } @@ -335,20 +344,15 @@ static void sdmmc_polling_card(void *arg) { struct sdmmc_softc *sc = (struct sdmmc_softc *)arg; - int card_detect; + int card_detect, card_present; - mutex_enter(&sc->sc_mtx); + mutex_enter(&sc->sc_discover_task_mtx); card_detect = sdmmc_chip_card_detect(sc->sc_sct, sc->sc_sch); - if (card_detect) { - if (!ISSET(sc->sc_flags, SMF_CARD_PRESENT)) { - sdmmc_needs_discover(sc->sc_dev); - } - } else { - if (ISSET(sc->sc_flags, SMF_CARD_PRESENT)) { - sdmmc_needs_discover(sc->sc_dev); - } - } - mutex_exit(&sc->sc_mtx); + card_present = ISSET(sc->sc_flags, SMF_CARD_PRESENT); + mutex_exit(&sc->sc_discover_task_mtx); + + if (card_detect != card_present) + sdmmc_needs_discover(sc->sc_dev); callout_schedule(&sc->sc_card_detect_ch, hz); }
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Sat Aug 8 10:50:55 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdmmc_mem.c sdmmcreg.h Log Message: eMMC fixes To generate a diff of this commit: cvs rdiff -u -r1.45 -r1.46 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.19 -r1.20 src/sys/dev/sdmmc/sdmmcreg.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_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.45 src/sys/dev/sdmmc/sdmmc_mem.c:1.46 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.45 Wed Aug 5 10:29:37 2015 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sat Aug 8 10:50:55 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.45 2015/08/05 10:29:37 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.46 2015/08/08 10:50:55 jmcneill 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 -__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.45 2015/08/05 10:29:37 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.46 2015/08/08 10:50:55 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -204,13 +204,17 @@ mmc_mode: host_ocr &= card_ocr; /* only allow the common voltages */ if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) { - /* Check SD Ver.2 */ - error = sdmmc_mem_send_if_cond(sc, 0x1aa, &card_ocr); - if (error == 0 && card_ocr == 0x1aa) - SET(ocr, MMC_OCR_HCS); + if (ISSET(sc->sc_flags, SMF_SD_MODE)) { + /* Check SD Ver.2 */ + error = sdmmc_mem_send_if_cond(sc, 0x1aa, &card_ocr); + if (error == 0 && card_ocr == 0x1aa) +SET(ocr, MMC_OCR_HCS); - if (sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch) & MMC_OCR_S18A) - SET(ocr, MMC_OCR_S18A); + if (sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch) & MMC_OCR_S18A) +SET(ocr, MMC_OCR_S18A); + } else { + SET(ocr, MMC_OCR_ACCESS_MODE_SECTOR); + } } host_ocr |= ocr; @@ -221,7 +225,7 @@ mmc_mode: goto out; } - if (ISSET(new_ocr, MMC_OCR_S18A) && sc->sc_sct->signal_voltage) { + if (ISSET(sc->sc_flags, SMF_SD_MODE) && ISSET(new_ocr, MMC_OCR_S18A)) { /* * Card and host support low voltage mode, begin switch * sequence. @@ -946,13 +950,6 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s return ENOTSUP; } - if (hs_timing == 2) { - error = sdmmc_chip_signal_voltage(sc->sc_sct, - sc->sc_sch, SDMMC_SIGNAL_VOLTAGE_180); - if (error) -hs_timing = 1; - } - if (ISSET(sc->sc_caps, SMC_CAPS_8BIT_MODE)) { width = 8; value = EXT_CSD_BUS_WIDTH_8; @@ -977,6 +974,7 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s } /* : need bus test? (using by CMD14 & CMD19) */ + delay(1); } sf->width = width; @@ -989,7 +987,8 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s EXT_CSD_HS_TIMING, hs_timing); if (error) { aprint_error_dev(sc->sc_dev, -"can't change high speed\n"); +"can't change high speed %d, error %d\n", +hs_timing, error); return error; } } Index: src/sys/dev/sdmmc/sdmmcreg.h diff -u src/sys/dev/sdmmc/sdmmcreg.h:1.19 src/sys/dev/sdmmc/sdmmcreg.h:1.20 --- src/sys/dev/sdmmc/sdmmcreg.h:1.19 Wed Aug 5 10:29:37 2015 +++ src/sys/dev/sdmmc/sdmmcreg.h Sat Aug 8 10:50:55 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcreg.h,v 1.19 2015/08/05 10:29:37 jmcneill Exp $ */ +/* $NetBSD: sdmmcreg.h,v 1.20 2015/08/08 10:50:55 jmcneill Exp $ */ /* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ /* @@ -70,7 +70,10 @@ /* OCR bits */ #define MMC_OCR_MEM_READY (1U<<31)/* memory power-up status bit */ -#define MMC_OCR_HCS (1<<30) +#define MMC_OCR_HCS (1<<30) /* SD only */ +#define MMC_OCR_ACCESS_MODE_MASK (3<<29) /* MMC only */ +#define MMC_OCR_ACCESS_MODE_BYTE (0<<29) /* MMC only */ +#define MMC_OCR_ACCESS_MODE_SECTOR (2<<29) /* MMC only */ #define MMC_OCR_S18A (1<<24) #define MMC_OCR_3_5V_3_6V (1<<23) #define MMC_OCR_3_4V_3_5V (1<<22)
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Thu Aug 6 09:30:55 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c Log Message: don't hold intr_lock while calling sdhc_execute_tuning To generate a diff of this commit: cvs rdiff -u -r1.80 -r1.81 src/sys/dev/sdmmc/sdhc.c 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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.80 src/sys/dev/sdmmc/sdhc.c:1.81 --- src/sys/dev/sdmmc/sdhc.c:1.80 Wed Aug 5 12:28:47 2015 +++ src/sys/dev/sdmmc/sdhc.c Thu Aug 6 09:30:55 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.80 2015/08/05 12:28:47 jmcneill Exp $ */ +/* $NetBSD: sdhc.c,v 1.81 2015/08/06 09:30:55 jmcneill Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.80 2015/08/05 12:28:47 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.81 2015/08/06 09:30:55 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -1388,12 +1388,12 @@ sdhc_exec_command(sdmmc_chipset_handle_t struct sdhc_host *hp = (struct sdhc_host *)sch; int error; - mutex_enter(&hp->intr_lock); - if (atomic_cas_uint(&hp->tuning_timer_pending, 1, 0) == 1) { (void)sdhc_execute_tuning(hp, hp->tuning_timing); } + mutex_enter(&hp->intr_lock); + if (cmd->c_data && ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) { const uint16_t ready = SDHC_BUFFER_READ_READY | SDHC_BUFFER_WRITE_READY; if (ISSET(hp->flags, SHF_USE_DMA)) {
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Wed Aug 5 12:28:47 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c sdhcreg.h Log Message: support re-tuning modes 1 and 2 To generate a diff of this commit: cvs rdiff -u -r1.79 -r1.80 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.16 -r1.17 src/sys/dev/sdmmc/sdhcreg.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.79 src/sys/dev/sdmmc/sdhc.c:1.80 --- src/sys/dev/sdmmc/sdhc.c:1.79 Wed Aug 5 10:30:25 2015 +++ src/sys/dev/sdmmc/sdhc.c Wed Aug 5 12:28:47 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.79 2015/08/05 10:30:25 jmcneill Exp $ */ +/* $NetBSD: sdhc.c,v 1.80 2015/08/05 12:28:47 jmcneill Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.79 2015/08/05 10:30:25 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.80 2015/08/05 12:28:47 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -36,6 +36,7 @@ __KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.7 #include #include #include +#include #include #include @@ -78,6 +79,11 @@ struct sdhc_host { kmutex_t intr_lock; kcondvar_t intr_cv; + callout_t tuning_timer; + int tuning_timing; + u_int tuning_timer_count; + u_int tuning_timer_pending; + int specver; /* spec. version */ uint32_t flags; /* flags for this host */ @@ -184,6 +190,7 @@ static void sdhc_exec_command(sdmmc_chip struct sdmmc_command *); static int sdhc_signal_voltage(sdmmc_chipset_handle_t, int); static int sdhc_execute_tuning(sdmmc_chipset_handle_t, int); +static void sdhc_tuning_timer(void *); static int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *); static int sdhc_wait_state(struct sdhc_host *, uint32_t, uint32_t); static int sdhc_soft_reset(struct sdhc_host *, int); @@ -279,6 +286,8 @@ sdhc_host_found(struct sdhc_softc *sc, b mutex_init(&hp->intr_lock, MUTEX_DEFAULT, IPL_SDMMC); cv_init(&hp->intr_cv, "sdhcintr"); + callout_init(&hp->tuning_timer, CALLOUT_MPSAFE); + callout_setfunc(&hp->tuning_timer, sdhc_tuning_timer, hp); if (ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) { sdhcver = HREAD4(hp, SDHC_ESDHC_HOST_CTL_VERSION); @@ -329,6 +338,18 @@ sdhc_host_found(struct sdhc_softc *sc, b } } + const u_int retuning_mode = (caps2 >> SDHC_RETUNING_MODES_SHIFT) & + SDHC_RETUNING_MODES_MASK; + if (retuning_mode == SDHC_RETUNING_MODE_1) { + hp->tuning_timer_count = (caps2 >> SDHC_TIMER_COUNT_SHIFT) & + SDHC_TIMER_COUNT_MASK; + if (hp->tuning_timer_count == 0xf) + hp->tuning_timer_count = 0; + if (hp->tuning_timer_count) + hp->tuning_timer_count = + 1 << (hp->tuning_timer_count - 1); + } + /* * Use DMA if the host system and the controller support it. * Suports integrated or external DMA egine, with or without @@ -442,6 +463,11 @@ sdhc_host_found(struct sdhc_softc *sc, b SET(hp->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V); aprint_normal(" 3.3V"); } + if (hp->specver >= SDHC_SPEC_VERS_300) { + aprint_normal(", re-tuning mode %d", retuning_mode + 1); + if (hp->tuning_timer_count) + aprint_normal(" (%us timer)", hp->tuning_timer_count); + } /* * Determine the maximum block length supported by the host @@ -560,6 +586,7 @@ adma_done: return 0; err: + callout_destroy(&hp->tuning_timer); cv_destroy(&hp->intr_cv); mutex_destroy(&hp->intr_lock); free(hp, M_DEVBUF); @@ -595,6 +622,8 @@ sdhc_detach(struct sdhc_softc *sc, int f sdhc_soft_reset(hp, SDHC_RESET_ALL); mutex_exit(&hp->intr_lock); } + callout_halt(&hp->tuning_timer, NULL); + callout_destroy(&hp->tuning_timer); cv_destroy(&hp->intr_cv); mutex_destroy(&hp->intr_lock); if (hp->ios > 0) { @@ -841,6 +870,7 @@ sdhc_bus_power(sdmmc_chipset_handle_t sc /* If power is disabled, reset the host and return now. */ if (ocr == 0) { (void)sdhc_host_reset1(hp); + callout_halt(&hp->tuning_timer, &hp->intr_lock); goto out; } @@ -1241,6 +1271,8 @@ sdhc_execute_tuning(sdmmc_chipset_handle uint8_t hostctl; int opcode, error, retry = 40; + hp->tuning_timing = timing; + switch (timing) { case SDMMC_TIMING_MMC_HS200: opcode = MMC_SEND_TUNING_BLOCK_HS200; @@ -1318,9 +1350,22 @@ sdhc_execute_tuning(sdmmc_chipset_handle return EIO; /* tuning failed */ } + if (hp->tuning_timer_count) { + callout_schedule(&hp->tuning_timer, + hz * hp->tuning_timer_count); + } + return 0; /* tuning completed */ } +static void +sdhc_tuning_timer(void *arg) +{ + struct sdhc_host *hp = arg; + + atomic_swap_uint(&hp->tuning_timer_pending, 1); +} + static int sdhc_wait_state(struct sdhc_host *hp, uint32_t mask, uint32_t value) { @@ -1345,6 +1390,10 @@ sdhc_exec_command(sdmmc_chipset_handle_t mutex_enter(&hp->intr_lock); + if (atomic_cas_uint(&hp->tuning_timer_p
CVS commit: src/sys/dev/sdmmc
Module Name:src Committed By: jmcneill Date: Wed Aug 5 10:30:25 UTC 2015 Modified Files: src/sys/dev/sdmmc: sdhc.c sdhcreg.h Log Message: Implement SDHC sampling clock tuning procedure. To generate a diff of this commit: cvs rdiff -u -r1.78 -r1.79 src/sys/dev/sdmmc/sdhc.c cvs rdiff -u -r1.15 -r1.16 src/sys/dev/sdmmc/sdhcreg.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/sdhc.c diff -u src/sys/dev/sdmmc/sdhc.c:1.78 src/sys/dev/sdmmc/sdhc.c:1.79 --- src/sys/dev/sdmmc/sdhc.c:1.78 Wed Aug 5 07:31:52 2015 +++ src/sys/dev/sdmmc/sdhc.c Wed Aug 5 10:30:25 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.78 2015/08/05 07:31:52 mlelstv Exp $ */ +/* $NetBSD: sdhc.c,v 1.79 2015/08/05 10:30:25 jmcneill Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.78 2015/08/05 07:31:52 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.79 2015/08/05 10:30:25 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -55,6 +55,7 @@ void sdhc_dump_regs(struct sdhc_host *); #define SDHC_BUFFER_TIMEOUT hz #define SDHC_TRANSFER_TIMEOUT hz #define SDHC_DMA_TIMEOUT (hz*3) +#define SDHC_TUNING_TIMEOUT hz struct sdhc_host { struct sdhc_softc *sc; /* host controller device */ @@ -182,6 +183,7 @@ static void sdhc_card_intr_ack(sdmmc_chi static void sdhc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *); static int sdhc_signal_voltage(sdmmc_chipset_handle_t, int); +static int sdhc_execute_tuning(sdmmc_chipset_handle_t, int); static int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *); static int sdhc_wait_state(struct sdhc_host *, uint32_t, uint32_t); static int sdhc_soft_reset(struct sdhc_host *, int); @@ -224,6 +226,7 @@ static struct sdmmc_chip_functions sdhc_ /* UHS functions */ .signal_voltage = sdhc_signal_voltage, .bus_clock_ddr = sdhc_bus_clock_ddr, + .execute_tuning = sdhc_execute_tuning, }; static int @@ -318,11 +321,11 @@ sdhc_host_found(struct sdhc_softc *sc, b caps = sc->sc_caps; caps2 = sc->sc_caps2; } else { - caps = HREAD4(hp, SDHC_CAPABILITIES); + caps = sc->sc_caps = HREAD4(hp, SDHC_CAPABILITIES); if (hp->specver >= SDHC_SPEC_VERS_300) { - caps2 = HREAD4(hp, SDHC_CAPABILITIES2); + caps2 = sc->sc_caps2 = HREAD4(hp, SDHC_CAPABILITIES2); } else { - caps2 = 0; + caps2 = sc->sc_caps2 = 0; } } @@ -1227,6 +1230,97 @@ sdhc_signal_voltage(sdmmc_chipset_handle return 0; } +/* + * Sampling clock tuning procedure (UHS) + */ +static int +sdhc_execute_tuning(sdmmc_chipset_handle_t sch, int timing) +{ + struct sdhc_host *hp = (struct sdhc_host *)sch; + struct sdmmc_command cmd; + uint8_t hostctl; + int opcode, error, retry = 40; + + switch (timing) { + case SDMMC_TIMING_MMC_HS200: + opcode = MMC_SEND_TUNING_BLOCK_HS200; + break; + case SDMMC_TIMING_UHS_SDR50: + if (!ISSET(hp->sc->sc_caps2, SDHC_TUNING_SDR50)) + return 0; + /* FALLTHROUGH */ + case SDMMC_TIMING_UHS_SDR104: + opcode = MMC_SEND_TUNING_BLOCK; + break; + default: + return EINVAL; + } + + hostctl = HREAD1(hp, SDHC_HOST_CTL); + + /* enable buffer read ready interrupt */ + HSET2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_BUFFER_READ_READY); + HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_BUFFER_READ_READY); + + /* disable DMA */ + HCLR1(hp, SDHC_HOST_CTL, SDHC_DMA_SELECT); + + /* reset tuning circuit */ + HCLR2(hp, SDHC_HOST_CTL2, SDHC_SAMPLING_CLOCK_SEL); + + /* start of tuning */ + HWRITE2(hp, SDHC_HOST_CTL2, SDHC_EXECUTE_TUNING); + + mutex_enter(&hp->intr_lock); + do { + memset(&cmd, 0, sizeof(cmd)); + cmd.c_opcode = opcode; + cmd.c_arg = 0; + cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1; + if (ISSET(hostctl, SDHC_8BIT_MODE)) { + cmd.c_blklen = cmd.c_datalen = 128; + } else { + cmd.c_blklen = cmd.c_datalen = 64; + } + + error = sdhc_start_command(hp, &cmd); + if (error) + break; + + if (!sdhc_wait_intr(hp, SDHC_BUFFER_READ_READY, + SDHC_TUNING_TIMEOUT)) { + break; + } + + delay(1000); + } while (HREAD2(hp, SDHC_HOST_CTL2) & SDHC_EXECUTE_TUNING && --retry); + mutex_exit(&hp->intr_lock); + + /* disable buffer read ready interrupt */ + HCLR2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_BUFFER_READ_READY); + HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_BUFFER_READ_READY); + + if (HREAD2(hp, SDHC_HOST_CTL2) & SDHC_EXECUTE_TUNING) { + HCLR2(hp, SDHC_HOST_CTL2, + SDHC_SAMPLING_CLOCK_SEL|SDHC_EXECUTE_TUNING); + sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD); + aprint_error_dev(hp->sc->sc_dev, + "tuning did not complete, using fixed sampling clock\n"); + return EIO; /* tuning did not complete */ + } + + if ((HREAD2(hp, SDHC_HOST_CTL2) & SDHC_SAMPLING_CLOCK_SEL) == 0) { + HCLR2(hp, SDHC_HOST_CTL2, + SDHC_SAMPLING_CLOCK_SEL|SDHC_EXECUTE_TUNING); + sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD); + aprint_error_dev(hp