Sat Mar 13 23:26:47 2021 UTC ()
Enable block count only for count > 0.
Don't enable autostop when command sets new flag SCF_NO_STOP.


(mlelstv)
diff -r1.107 -r1.108 src/sys/dev/sdmmc/sdhc.c

cvs diff -r1.107 -r1.108 src/sys/dev/sdmmc/sdhc.c (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdhc.c 2020/07/15 15:57:52 1.107
+++ src/sys/dev/sdmmc/sdhc.c 2021/03/13 23:26:47 1.108
@@ -1,39 +1,39 @@ @@ -1,39 +1,39 @@
1/* $NetBSD: sdhc.c,v 1.107 2020/07/15 15:57:52 msaitoh Exp $ */ 1/* $NetBSD: sdhc.c,v 1.108 2021/03/13 23:26:47 mlelstv Exp $ */
2/* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ 2/* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */ 18 */
19 19
20/* 20/*
21 * SD Host Controller driver based on the SD Host Controller Standard 21 * SD Host Controller driver based on the SD Host Controller Standard
22 * Simplified Specification Version 1.00 (www.sdcard.com). 22 * Simplified Specification Version 1.00 (www.sdcard.com).
23 */ 23 */
24 24
25#include <sys/cdefs.h> 25#include <sys/cdefs.h>
26__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.107 2020/07/15 15:57:52 msaitoh Exp $"); 26__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.108 2021/03/13 23:26:47 mlelstv Exp $");
27 27
28#ifdef _KERNEL_OPT 28#ifdef _KERNEL_OPT
29#include "opt_sdmmc.h" 29#include "opt_sdmmc.h"
30#endif 30#endif
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/device.h> 33#include <sys/device.h>
34#include <sys/kernel.h> 34#include <sys/kernel.h>
35#include <sys/malloc.h> 35#include <sys/malloc.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/mutex.h> 37#include <sys/mutex.h>
38#include <sys/condvar.h> 38#include <sys/condvar.h>
39#include <sys/atomic.h> 39#include <sys/atomic.h>
@@ -379,26 +379,28 @@ sdhc_host_found(struct sdhc_softc *sc, b @@ -379,26 +379,28 @@ sdhc_host_found(struct sdhc_softc *sc, b
379 caps |= SDHC_ADMA2_SUPP; 379 caps |= SDHC_ADMA2_SUPP;
380 sc->sc_caps = caps; 380 sc->sc_caps = caps;
381 /* uSDHC has no SDHC_CAPABILITIES2 register */ 381 /* uSDHC has no SDHC_CAPABILITIES2 register */
382 caps2 = sc->sc_caps2 = SDHC_SDR50_SUPP | SDHC_DDR50_SUPP; 382 caps2 = sc->sc_caps2 = SDHC_SDR50_SUPP | SDHC_DDR50_SUPP;
383 } else { 383 } else {
384 caps = sc->sc_caps = HREAD4(hp, SDHC_CAPABILITIES); 384 caps = sc->sc_caps = HREAD4(hp, SDHC_CAPABILITIES);
385 if (hp->specver >= SDHC_SPEC_VERS_300) { 385 if (hp->specver >= SDHC_SPEC_VERS_300) {
386 caps2 = sc->sc_caps2 = HREAD4(hp, SDHC_CAPABILITIES2); 386 caps2 = sc->sc_caps2 = HREAD4(hp, SDHC_CAPABILITIES2);
387 } else { 387 } else {
388 caps2 = sc->sc_caps2 = 0; 388 caps2 = sc->sc_caps2 = 0;
389 } 389 }
390 } 390 }
391 391
 392 aprint_verbose(", caps <%08x/%08x>", caps, caps2);
 393
392 const u_int retuning_mode = (caps2 >> SDHC_RETUNING_MODES_SHIFT) & 394 const u_int retuning_mode = (caps2 >> SDHC_RETUNING_MODES_SHIFT) &
393 SDHC_RETUNING_MODES_MASK; 395 SDHC_RETUNING_MODES_MASK;
394 if (retuning_mode == SDHC_RETUNING_MODE_1) { 396 if (retuning_mode == SDHC_RETUNING_MODE_1) {
395 hp->tuning_timer_count = (caps2 >> SDHC_TIMER_COUNT_SHIFT) & 397 hp->tuning_timer_count = (caps2 >> SDHC_TIMER_COUNT_SHIFT) &
396 SDHC_TIMER_COUNT_MASK; 398 SDHC_TIMER_COUNT_MASK;
397 if (hp->tuning_timer_count == 0xf) 399 if (hp->tuning_timer_count == 0xf)
398 hp->tuning_timer_count = 0; 400 hp->tuning_timer_count = 0;
399 if (hp->tuning_timer_count) 401 if (hp->tuning_timer_count)
400 hp->tuning_timer_count = 402 hp->tuning_timer_count =
401 1 << (hp->tuning_timer_count - 1); 403 1 << (hp->tuning_timer_count - 1);
402 } 404 }
403 405
404 /* 406 /*
@@ -1714,34 +1716,37 @@ sdhc_start_command(struct sdhc_host *hp, @@ -1714,34 +1716,37 @@ sdhc_start_command(struct sdhc_host *hp,
1714 aprint_error_dev(sc->sc_dev, 1716 aprint_error_dev(sc->sc_dev,
1715 "data not a multiple of %u bytes\n", blksize); 1717 "data not a multiple of %u bytes\n", blksize);
1716 return EINVAL; 1718 return EINVAL;
1717 } 1719 }
1718 } 1720 }
1719 1721
1720 /* Check limit imposed by 9-bit block count. (1.7.2) */ 1722 /* Check limit imposed by 9-bit block count. (1.7.2) */
1721 if (blkcount > SDHC_BLOCK_COUNT_MAX) { 1723 if (blkcount > SDHC_BLOCK_COUNT_MAX) {
1722 aprint_error_dev(sc->sc_dev, "too much data\n"); 1724 aprint_error_dev(sc->sc_dev, "too much data\n");
1723 return EINVAL; 1725 return EINVAL;
1724 } 1726 }
1725 1727
1726 /* Prepare transfer mode register value. (2.2.5) */ 1728 /* Prepare transfer mode register value. (2.2.5) */
1727 mode = SDHC_BLOCK_COUNT_ENABLE; 1729 mode = 0;
1728 if (ISSET(cmd->c_flags, SCF_CMD_READ)) 1730 if (ISSET(cmd->c_flags, SCF_CMD_READ))
1729 mode |= SDHC_READ_MODE; 1731 mode |= SDHC_READ_MODE;
1730 if (blkcount > 1) { 1732 if (blkcount > 0) {
1731 mode |= SDHC_MULTI_BLOCK_MODE; 1733 mode |= SDHC_BLOCK_COUNT_ENABLE;
1732 /* XXX only for memory commands? */ 1734 if (blkcount > 1) {
1733 if (!ISSET(sc->sc_flags, SDHC_FLAG_NO_AUTO_STOP)) 1735 mode |= SDHC_MULTI_BLOCK_MODE;
1734 mode |= SDHC_AUTO_CMD12_ENABLE; 1736 if (!ISSET(sc->sc_flags, SDHC_FLAG_NO_AUTO_STOP)
 1737 && !ISSET(cmd->c_flags, SCF_NO_STOP))
 1738 mode |= SDHC_AUTO_CMD12_ENABLE;
 1739 }
1735 } 1740 }
1736 if (cmd->c_dmamap != NULL && cmd->c_datalen > 0 && 1741 if (cmd->c_dmamap != NULL && cmd->c_datalen > 0 &&
1737 ISSET(hp->flags, SHF_MODE_DMAEN)) { 1742 ISSET(hp->flags, SHF_MODE_DMAEN)) {
1738 mode |= SDHC_DMA_ENABLE; 1743 mode |= SDHC_DMA_ENABLE;
1739 } 1744 }
1740 1745
1741 /* 1746 /*
1742 * Prepare command register value. (2.2.6) 1747 * Prepare command register value. (2.2.6)
1743 */ 1748 */
1744 command = (cmd->c_opcode & SDHC_COMMAND_INDEX_MASK) << SDHC_COMMAND_INDEX_SHIFT; 1749 command = (cmd->c_opcode & SDHC_COMMAND_INDEX_MASK) << SDHC_COMMAND_INDEX_SHIFT;
1745 1750
1746 if (ISSET(cmd->c_flags, SCF_RSP_CRC)) 1751 if (ISSET(cmd->c_flags, SCF_RSP_CRC))
1747 command |= SDHC_CRC_CHECK_ENABLE; 1752 command |= SDHC_CRC_CHECK_ENABLE;