Sat Dec 15 00:03:01 2012 UTC ()
Correctly read the 512-bit-wide big-endian Switch Function Status register.
Some of this could/will also be useful for the SD Status register.


(jakllsch)
diff -r1.25 -r1.26 src/sys/dev/sdmmc/sdmmc_mem.c
diff -r1.12 -r1.13 src/sys/dev/sdmmc/sdmmcreg.h

cvs diff -r1.25 -r1.26 src/sys/dev/sdmmc/sdmmc_mem.c (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdmmc_mem.c 2012/12/14 23:22:21 1.25
+++ src/sys/dev/sdmmc/sdmmc_mem.c 2012/12/15 00:03:00 1.26
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sdmmc_mem.c,v 1.25 2012/12/14 23:22:21 jakllsch Exp $ */ 1/* $NetBSD: sdmmc_mem.c,v 1.26 2012/12/15 00:03:00 jakllsch Exp $ */
2/* $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg Exp $ */ 2/* $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg 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
@@ -35,59 +35,61 @@ @@ -35,59 +35,61 @@
35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
36 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 36 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
37 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 37 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
39 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
40 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
42 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */ 43 */
44 44
45/* Routines for SD/MMC memory cards. */ 45/* Routines for SD/MMC memory cards. */
46 46
47#include <sys/cdefs.h> 47#include <sys/cdefs.h>
48__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.25 2012/12/14 23:22:21 jakllsch Exp $"); 48__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.26 2012/12/15 00:03:00 jakllsch Exp $");
49 49
50#ifdef _KERNEL_OPT 50#ifdef _KERNEL_OPT
51#include "opt_sdmmc.h" 51#include "opt_sdmmc.h"
52#endif 52#endif
53 53
54#include <sys/param.h> 54#include <sys/param.h>
55#include <sys/kernel.h> 55#include <sys/kernel.h>
56#include <sys/malloc.h> 56#include <sys/malloc.h>
57#include <sys/systm.h> 57#include <sys/systm.h>
58#include <sys/device.h> 58#include <sys/device.h>
59 59
60#include <dev/sdmmc/sdmmcchip.h> 60#include <dev/sdmmc/sdmmcchip.h>
61#include <dev/sdmmc/sdmmcreg.h> 61#include <dev/sdmmc/sdmmcreg.h>
62#include <dev/sdmmc/sdmmcvar.h> 62#include <dev/sdmmc/sdmmcvar.h>
63 63
64#ifdef SDMMC_DEBUG 64#ifdef SDMMC_DEBUG
65#define DPRINTF(s) do { printf s; } while (/*CONSTCOND*/0) 65#define DPRINTF(s) do { printf s; } while (/*CONSTCOND*/0)
66#else 66#else
67#define DPRINTF(s) do {} while (/*CONSTCOND*/0) 67#define DPRINTF(s) do {} while (/*CONSTCOND*/0)
68#endif 68#endif
69 69
 70typedef struct { uint32_t _bits[512/32]; } __packed __aligned(4) sdmmc_bitfield512_t;
 71
70static int sdmmc_mem_sd_init(struct sdmmc_softc *, struct sdmmc_function *); 72static int sdmmc_mem_sd_init(struct sdmmc_softc *, struct sdmmc_function *);
71static int sdmmc_mem_mmc_init(struct sdmmc_softc *, struct sdmmc_function *); 73static int sdmmc_mem_mmc_init(struct sdmmc_softc *, struct sdmmc_function *);
72static int sdmmc_mem_send_cid(struct sdmmc_softc *, sdmmc_response *); 74static int sdmmc_mem_send_cid(struct sdmmc_softc *, sdmmc_response *);
73static int sdmmc_mem_send_csd(struct sdmmc_softc *, struct sdmmc_function *, 75static int sdmmc_mem_send_csd(struct sdmmc_softc *, struct sdmmc_function *,
74 sdmmc_response *); 76 sdmmc_response *);
75static int sdmmc_mem_send_scr(struct sdmmc_softc *, struct sdmmc_function *, 77static int sdmmc_mem_send_scr(struct sdmmc_softc *, struct sdmmc_function *,
76 uint32_t scr[2]); 78 uint32_t scr[2]);
77static int sdmmc_mem_decode_scr(struct sdmmc_softc *, struct sdmmc_function *); 79static int sdmmc_mem_decode_scr(struct sdmmc_softc *, struct sdmmc_function *);
78static int sdmmc_mem_send_cxd_data(struct sdmmc_softc *, int, void *, size_t); 80static int sdmmc_mem_send_cxd_data(struct sdmmc_softc *, int, void *, size_t);
79static int sdmmc_set_bus_width(struct sdmmc_function *, int); 81static int sdmmc_set_bus_width(struct sdmmc_function *, int);
80static int sdmmc_mem_sd_switch(struct sdmmc_function *, int, int, int, void *); 82static int sdmmc_mem_sd_switch(struct sdmmc_function *, int, int, int, sdmmc_bitfield512_t *);
81static int sdmmc_mem_mmc_switch(struct sdmmc_function *, uint8_t, uint8_t, 83static int sdmmc_mem_mmc_switch(struct sdmmc_function *, uint8_t, uint8_t,
82 uint8_t); 84 uint8_t);
83static int sdmmc_mem_spi_read_ocr(struct sdmmc_softc *, uint32_t, uint32_t *); 85static int sdmmc_mem_spi_read_ocr(struct sdmmc_softc *, uint32_t, uint32_t *);
84static int sdmmc_mem_single_read_block(struct sdmmc_function *, uint32_t, 86static int sdmmc_mem_single_read_block(struct sdmmc_function *, uint32_t,
85 u_char *, size_t); 87 u_char *, size_t);
86static int sdmmc_mem_single_write_block(struct sdmmc_function *, uint32_t, 88static int sdmmc_mem_single_write_block(struct sdmmc_function *, uint32_t,
87 u_char *, size_t); 89 u_char *, size_t);
88static int sdmmc_mem_read_block_subr(struct sdmmc_function *, uint32_t, 90static int sdmmc_mem_read_block_subr(struct sdmmc_function *, uint32_t,
89 u_char *, size_t); 91 u_char *, size_t);
90static int sdmmc_mem_write_block_subr(struct sdmmc_function *, uint32_t, 92static int sdmmc_mem_write_block_subr(struct sdmmc_function *, uint32_t,
91 u_char *, size_t); 93 u_char *, size_t);
92 94
93/* 95/*
@@ -564,100 +566,114 @@ sdmmc_mem_set_blocklen(struct sdmmc_soft @@ -564,100 +566,114 @@ sdmmc_mem_set_blocklen(struct sdmmc_soft
564 memset(&cmd, 0, sizeof(cmd)); 566 memset(&cmd, 0, sizeof(cmd));
565 cmd.c_opcode = MMC_SET_BLOCKLEN; 567 cmd.c_opcode = MMC_SET_BLOCKLEN;
566 cmd.c_arg = SDMMC_SECTOR_SIZE; 568 cmd.c_arg = SDMMC_SECTOR_SIZE;
567 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1 | SCF_RSP_SPI_R1; 569 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1 | SCF_RSP_SPI_R1;
568 570
569 error = sdmmc_mmc_command(sc, &cmd); 571 error = sdmmc_mmc_command(sc, &cmd);
570 572
571 DPRINTF(("%s: sdmmc_mem_set_blocklen: read_bl_len=%d sector_size=%d\n", 573 DPRINTF(("%s: sdmmc_mem_set_blocklen: read_bl_len=%d sector_size=%d\n",
572 SDMMCDEVNAME(sc), 1 << sf->csd.read_bl_len, SDMMC_SECTOR_SIZE)); 574 SDMMCDEVNAME(sc), 1 << sf->csd.read_bl_len, SDMMC_SECTOR_SIZE));
573 575
574 return error; 576 return error;
575} 577}
576 578
 579/* make 512-bit BE quantity __bitfield()-compatible */
 580static void
 581sdmmc_be512_to_bitfield512(sdmmc_bitfield512_t *buf) {
 582 size_t i;
 583 uint32_t tmp0, tmp1;
 584 const size_t bitswords = __arraycount(buf->_bits);
 585 for (i = 0; i < bitswords/2; i++) {
 586 tmp0 = buf->_bits[i];
 587 tmp1 = buf->_bits[bitswords - 1 - i];
 588 buf->_bits[i] = be32toh(tmp1);
 589 buf->_bits[bitswords - 1 - i] = be32toh(tmp0);
 590 }
 591}
 592
577static int 593static int
578sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) 594sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
579{ 595{
580 static const struct { 596 static const struct {
581 int v; 597 int v;
582 int freq; 598 int freq;
583 } switch_group0_functions[] = { 599 } switch_group0_functions[] = {
584 /* Default/SDR12 */ 600 /* Default/SDR12 */
585 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V | 601 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V |
586 MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V, 25000 }, 602 MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V, 25000 },
587 603
588 /* High-Speed/SDR25 */ 604 /* High-Speed/SDR25 */
589 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V | 605 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V |
590 MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V, 50000 }, 606 MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V, 50000 },
591 607
592 /* SDR50 */ 608 /* SDR50 */
593 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V, 100000 }, 609 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V, 100000 },
594 610
595 /* SDR104 */ 611 /* SDR104 */
596 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V, 208000 }, 612 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V, 208000 },
597 613
598 /* DDR50 */ 614 /* DDR50 */
599 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V, 50000 }, 615 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V, 50000 },
600 }; 616 };
601 int host_ocr, support_func, best_func, error, g, i; 617 int host_ocr, support_func, best_func, error, g, i;
602 char status[64]; 618 sdmmc_bitfield512_t status; /* Switch Function Status */
603 619
604 error = sdmmc_mem_send_scr(sc, sf, sf->raw_scr); 620 error = sdmmc_mem_send_scr(sc, sf, sf->raw_scr);
605 if (error) { 621 if (error) {
606 aprint_error_dev(sc->sc_dev, "SD_SEND_SCR send failed.\n"); 622 aprint_error_dev(sc->sc_dev, "SD_SEND_SCR send failed.\n");
607 return error; 623 return error;
608 } 624 }
609 error = sdmmc_mem_decode_scr(sc, sf); 625 error = sdmmc_mem_decode_scr(sc, sf);
610 if (error) 626 if (error)
611 return error; 627 return error;
612 628
613 if (ISSET(sc->sc_caps, SMC_CAPS_4BIT_MODE) && 629 if (ISSET(sc->sc_caps, SMC_CAPS_4BIT_MODE) &&
614 ISSET(sf->scr.bus_width, SCR_SD_BUS_WIDTHS_4BIT)) { 630 ISSET(sf->scr.bus_width, SCR_SD_BUS_WIDTHS_4BIT)) {
615 DPRINTF(("%s: change bus width\n", SDMMCDEVNAME(sc))); 631 DPRINTF(("%s: change bus width\n", SDMMCDEVNAME(sc)));
616 error = sdmmc_set_bus_width(sf, 4); 632 error = sdmmc_set_bus_width(sf, 4);
617 if (error) { 633 if (error) {
618 aprint_error_dev(sc->sc_dev, 634 aprint_error_dev(sc->sc_dev,
619 "can't change bus width (%d bit)\n", 4); 635 "can't change bus width (%d bit)\n", 4);
620 return error; 636 return error;
621 } 637 }
622 sf->width = 4; 638 sf->width = 4;
623 } 639 }
624 640
625 if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 && 641 if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 &&
626 ISSET(sf->csd.ccc, SD_CSD_CCC_SWITCH)) { 642 ISSET(sf->csd.ccc, SD_CSD_CCC_SWITCH)) {
627 DPRINTF(("%s: switch func mode 0\n", SDMMCDEVNAME(sc))); 643 DPRINTF(("%s: switch func mode 0\n", SDMMCDEVNAME(sc)));
628 error = sdmmc_mem_sd_switch(sf, 0, 1, 0, status); 644 error = sdmmc_mem_sd_switch(sf, 0, 1, 0, &status);
629 if (error) { 645 if (error) {
630 aprint_error_dev(sc->sc_dev, 646 aprint_error_dev(sc->sc_dev,
631 "switch func mode 0 failed\n"); 647 "switch func mode 0 failed\n");
632 return error; 648 return error;
633 } 649 }
634 650
635 host_ocr = sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch); 651 host_ocr = sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch);
636 support_func = SFUNC_STATUS_GROUP(status, 1); 652 support_func = SFUNC_STATUS_GROUP(&status, 1);
637 best_func = 0; 653 best_func = 0;
638 for (i = 0, g = 1; 654 for (i = 0, g = 1;
639 i < __arraycount(switch_group0_functions); i++, g <<= 1) { 655 i < __arraycount(switch_group0_functions); i++, g <<= 1) {
640 if (!(switch_group0_functions[i].v & host_ocr)) 656 if (!(switch_group0_functions[i].v & host_ocr))
641 continue; 657 continue;
642 if (g & support_func) 658 if (g & support_func)
643 best_func = i; 659 best_func = i;
644 } 660 }
645 if (ISSET(sc->sc_caps, SMC_CAPS_SD_HIGHSPEED) && 661 if (ISSET(sc->sc_caps, SMC_CAPS_SD_HIGHSPEED) &&
646 best_func != 0) { 662 best_func != 0) {
647 DPRINTF(("%s: switch func mode 1(func=%d)\n", 663 DPRINTF(("%s: switch func mode 1(func=%d)\n",
648 SDMMCDEVNAME(sc), best_func)); 664 SDMMCDEVNAME(sc), best_func));
649 error = 665 error =
650 sdmmc_mem_sd_switch(sf, 1, 1, best_func, status); 666 sdmmc_mem_sd_switch(sf, 1, 1, best_func, &status);
651 if (error) { 667 if (error) {
652 aprint_error_dev(sc->sc_dev, 668 aprint_error_dev(sc->sc_dev,
653 "switch func mode 1 failed:" 669 "switch func mode 1 failed:"
654 " group 1 function %d(0x%2x)\n", 670 " group 1 function %d(0x%2x)\n",
655 best_func, support_func); 671 best_func, support_func);
656 return error; 672 return error;
657 } 673 }
658 sf->csd.tran_speed = 674 sf->csd.tran_speed =
659 switch_group0_functions[best_func].freq; 675 switch_group0_functions[best_func].freq;
660 676
661 /* Wait 400KHz x 8 clock (2.5us * 8 + slop) */ 677 /* Wait 400KHz x 8 clock (2.5us * 8 + slop) */
662 delay(25); 678 delay(25);
663 } 679 }
@@ -1049,27 +1065,27 @@ sdmmc_set_bus_width(struct sdmmc_functio @@ -1049,27 +1065,27 @@ sdmmc_set_bus_width(struct sdmmc_functio
1049 1065
1050 default: 1066 default:
1051 return EINVAL; 1067 return EINVAL;
1052 } 1068 }
1053 1069
1054 error = sdmmc_app_command(sc, sf, &cmd); 1070 error = sdmmc_app_command(sc, sf, &cmd);
1055 if (error == 0) 1071 if (error == 0)
1056 error = sdmmc_chip_bus_width(sc->sc_sct, sc->sc_sch, width); 1072 error = sdmmc_chip_bus_width(sc->sc_sct, sc->sc_sch, width);
1057 return error; 1073 return error;
1058} 1074}
1059 1075
1060static int 1076static int
1061sdmmc_mem_sd_switch(struct sdmmc_function *sf, int mode, int group, 1077sdmmc_mem_sd_switch(struct sdmmc_function *sf, int mode, int group,
1062 int function, void *status) 1078 int function, sdmmc_bitfield512_t *status)
1063{ 1079{
1064 struct sdmmc_softc *sc = sf->sc; 1080 struct sdmmc_softc *sc = sf->sc;
1065 struct sdmmc_command cmd; 1081 struct sdmmc_command cmd;
1066 bus_dma_segment_t ds[1]; 1082 bus_dma_segment_t ds[1];
1067 void *ptr = NULL; 1083 void *ptr = NULL;
1068 int gsft, rseg, error = 0; 1084 int gsft, rseg, error = 0;
1069 const int statlen = 64; 1085 const int statlen = 64;
1070 1086
1071 if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 && 1087 if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 &&
1072 !ISSET(sf->csd.ccc, SD_CSD_CCC_SWITCH)) 1088 !ISSET(sf->csd.ccc, SD_CSD_CCC_SWITCH))
1073 return EINVAL; 1089 return EINVAL;
1074 1090
1075 if (group <= 0 || group > 6 || 1091 if (group <= 0 || group > 6 ||
@@ -1122,26 +1138,30 @@ sdmmc_mem_sd_switch(struct sdmmc_functio @@ -1122,26 +1138,30 @@ sdmmc_mem_sd_switch(struct sdmmc_functio
1122 1138
1123out: 1139out:
1124 if (ptr != NULL) { 1140 if (ptr != NULL) {
1125 if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) { 1141 if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) {
1126 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap); 1142 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap);
1127dmamem_unmap: 1143dmamem_unmap:
1128 bus_dmamem_unmap(sc->sc_dmat, ptr, statlen); 1144 bus_dmamem_unmap(sc->sc_dmat, ptr, statlen);
1129dmamem_free: 1145dmamem_free:
1130 bus_dmamem_free(sc->sc_dmat, ds, rseg); 1146 bus_dmamem_free(sc->sc_dmat, ds, rseg);
1131 } else { 1147 } else {
1132 free(ptr, M_DEVBUF); 1148 free(ptr, M_DEVBUF);
1133 } 1149 }
1134 } 1150 }
 1151
 1152 if (error == 0)
 1153 sdmmc_be512_to_bitfield512(status);
 1154
1135 return error; 1155 return error;
1136} 1156}
1137 1157
1138static int 1158static int
1139sdmmc_mem_mmc_switch(struct sdmmc_function *sf, uint8_t set, uint8_t index, 1159sdmmc_mem_mmc_switch(struct sdmmc_function *sf, uint8_t set, uint8_t index,
1140 uint8_t value) 1160 uint8_t value)
1141{ 1161{
1142 struct sdmmc_softc *sc = sf->sc; 1162 struct sdmmc_softc *sc = sf->sc;
1143 struct sdmmc_command cmd; 1163 struct sdmmc_command cmd;
1144 1164
1145 memset(&cmd, 0, sizeof(cmd)); 1165 memset(&cmd, 0, sizeof(cmd));
1146 cmd.c_opcode = MMC_SWITCH; 1166 cmd.c_opcode = MMC_SWITCH;
1147 cmd.c_arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | 1167 cmd.c_arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |

cvs diff -r1.12 -r1.13 src/sys/dev/sdmmc/sdmmcreg.h (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdmmcreg.h 2012/07/28 18:38:03 1.12
+++ src/sys/dev/sdmmc/sdmmcreg.h 2012/12/15 00:03:00 1.13
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sdmmcreg.h,v 1.12 2012/07/28 18:38:03 matt Exp $ */ 1/* $NetBSD: sdmmcreg.h,v 1.13 2012/12/15 00:03:00 jakllsch Exp $ */
2/* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ 2/* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg 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
@@ -308,34 +308,34 @@ @@ -308,34 +308,34 @@
308#define SCR_SD_SECURITY_1_0_2 2 /* security protocol 1.0 */ 308#define SCR_SD_SECURITY_1_0_2 2 /* security protocol 1.0 */
309#define SCR_SD_BUS_WIDTHS(scr) MMC_RSP_BITS((scr), 48, 4) 309#define SCR_SD_BUS_WIDTHS(scr) MMC_RSP_BITS((scr), 48, 4)
310#define SCR_SD_BUS_WIDTHS_1BIT (1 << 0) /* 1bit (DAT0) */ 310#define SCR_SD_BUS_WIDTHS_1BIT (1 << 0) /* 1bit (DAT0) */
311#define SCR_SD_BUS_WIDTHS_4BIT (1 << 2) /* 4bit (DAT0-3) */ 311#define SCR_SD_BUS_WIDTHS_4BIT (1 << 2) /* 4bit (DAT0-3) */
312#define SCR_SD_SPEC3(scr) MMC_RSP_BITS((scr), 47, 1) 312#define SCR_SD_SPEC3(scr) MMC_RSP_BITS((scr), 47, 1)
313#define SCR_EX_SECURITY(scr) MMC_RSP_BITS((scr), 43, 4) 313#define SCR_EX_SECURITY(scr) MMC_RSP_BITS((scr), 43, 4)
314#define SCR_RESERVED(scr) MMC_RSP_BITS((scr), 34, 9) 314#define SCR_RESERVED(scr) MMC_RSP_BITS((scr), 34, 9)
315#define SCR_CMD_SUPPORT_CMD23(scr) MMC_RSP_BITS((scr), 33, 1) 315#define SCR_CMD_SUPPORT_CMD23(scr) MMC_RSP_BITS((scr), 33, 1)
316#define SCR_CMD_SUPPORT_CMD20(scr) MMC_RSP_BITS((scr), 32, 1) 316#define SCR_CMD_SUPPORT_CMD20(scr) MMC_RSP_BITS((scr), 32, 1)
317#define SCR_RESERVED2(scr) MMC_RSP_BITS((scr), 0, 32) 317#define SCR_RESERVED2(scr) MMC_RSP_BITS((scr), 0, 32)
318 318
319/* Status of Switch Function */ 319/* Status of Switch Function */
320#define SFUNC_STATUS_GROUP(status, group) \ 320#define SFUNC_STATUS_GROUP(status, group) \
321 be16toh(__bitfield((uint32_t *)(status), (7 - (group)) << 4, 16)) 321 (__bitfield((uint32_t *)(status), 400 + (group - 1) * 16, 16))
322 322
323/* This assumes the response fields are in host byte order in 32-bit units. */ 323/* This assumes the response fields are in host byte order in 32-bit units. */
324#define MMC_RSP_BITS(resp, start, len) __bitfield((resp), (start)-8, (len)) 324#define MMC_RSP_BITS(resp, start, len) __bitfield((resp), (start)-8, (len))
325static inline uint32_t 325static inline uint32_t
326__bitfield(const uint32_t *src, size_t start, size_t len) 326__bitfield(const uint32_t *src, size_t start, size_t len)
327{ 327{
328 if (start + len > 128 || len == 0 || len > 32) 328 if (start + len > 512 || len == 0 || len > 32)
329 return 0; 329 return 0;
330 330
331 src += start / 32; 331 src += start / 32;
332 start %= 32; 332 start %= 32;
333 333
334 uint32_t dst = src[0] >> start; 334 uint32_t dst = src[0] >> start;
335 335
336 if (__predict_false((start + len - 1) / 32 != start / 32)) { 336 if (__predict_false((start + len - 1) / 32 != start / 32)) {
337 dst |= src[1] << (32 - start); 337 dst |= src[1] << (32 - start);
338 } 338 }
339 339
340 return dst & (__BIT(len) - 1); 340 return dst & (__BIT(len) - 1);
341} 341}