Sun May 24 12:59:54 2009 UTC ()
SDHC card was able to be used.


(nonaka)
diff -r1.1 -r1.2 src/sys/dev/sdmmc/sdmmc_mem.c

cvs diff -r1.1 -r1.2 src/sys/dev/sdmmc/sdmmc_mem.c (switch to unified diff)

--- src/sys/dev/sdmmc/sdmmc_mem.c 2009/04/21 03:00:30 1.1
+++ src/sys/dev/sdmmc/sdmmc_mem.c 2009/05/24 12:59:54 1.2
@@ -1,730 +1,731 @@ @@ -1,730 +1,731 @@
1/* $NetBSD: sdmmc_mem.c,v 1.1 2009/04/21 03:00:30 nonaka Exp $ */ 1/* $NetBSD: sdmmc_mem.c,v 1.2 2009/05/24 12:59:54 nonaka 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
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 * Copyright (c) 2007-2009 NONAKA Kimihiro <nonaka@netbsd.org> 21 * Copyright (c) 2007-2009 NONAKA Kimihiro <nonaka@netbsd.org>
22 * All rights reserved. 22 * All rights reserved.
23 * 23 *
24 * Redistribution and use in source and binary forms, with or without 24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions 25 * modification, are permitted provided that the following conditions
26 * are met: 26 * are met:
27 * 1. Redistributions of source code must retain the above copyright 27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer. 28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright 29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the 30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution. 31 * documentation and/or other materials provided with the distribution.
32 * 32 *
33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE. 43 * SUCH DAMAGE.
44 */ 44 */
45 45
46/* Routines for SD/MMC memory cards. */ 46/* Routines for SD/MMC memory cards. */
47 47
48#include <sys/cdefs.h> 48#include <sys/cdefs.h>
49__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.1 2009/04/21 03:00:30 nonaka Exp $"); 49__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.2 2009/05/24 12:59:54 nonaka Exp $");
50 50
51#include <sys/param.h> 51#include <sys/param.h>
52#include <sys/kernel.h> 52#include <sys/kernel.h>
53#include <sys/malloc.h> 53#include <sys/malloc.h>
54#include <sys/systm.h> 54#include <sys/systm.h>
55#include <sys/device.h> 55#include <sys/device.h>
56 56
57#include <uvm/uvm_extern.h> 57#include <uvm/uvm_extern.h>
58 58
59#include <dev/sdmmc/sdmmcchip.h> 59#include <dev/sdmmc/sdmmcchip.h>
60#include <dev/sdmmc/sdmmcreg.h> 60#include <dev/sdmmc/sdmmcreg.h>
61#include <dev/sdmmc/sdmmcvar.h> 61#include <dev/sdmmc/sdmmcvar.h>
62 62
63#ifdef SDMMC_DEBUG 63#ifdef SDMMC_DEBUG
64#define DPRINTF(s) do { printf s; } while (/*CONSTCOND*/0) 64#define DPRINTF(s) do { printf s; } while (/*CONSTCOND*/0)
65#else 65#else
66#define DPRINTF(s) do {} while (/*CONSTCOND*/0) 66#define DPRINTF(s) do {} while (/*CONSTCOND*/0)
67#endif 67#endif
68 68
69static int sdmmc_mem_send_op_cond(struct sdmmc_softc *, uint32_t, uint32_t *); 69static int sdmmc_mem_send_op_cond(struct sdmmc_softc *, uint32_t, uint32_t *);
70static int sdmmc_mem_send_if_cond(struct sdmmc_softc *, uint32_t, uint32_t *); 70static int sdmmc_mem_send_if_cond(struct sdmmc_softc *, uint32_t, uint32_t *);
71static int sdmmc_mem_set_blocklen(struct sdmmc_softc *, 71static int sdmmc_mem_set_blocklen(struct sdmmc_softc *,
72 struct sdmmc_function *); 72 struct sdmmc_function *);
73#ifdef SDMMC_DUMP_CSD 73#ifdef SDMMC_DUMP_CSD
74static void sdmmc_print_csd(sdmmc_response, struct sdmmc_csd *); 74static void sdmmc_print_csd(sdmmc_response, struct sdmmc_csd *);
75#endif 75#endif
76static int sdmmc_mem_read_block_subr(struct sdmmc_function *, uint32_t, 76static int sdmmc_mem_read_block_subr(struct sdmmc_function *, uint32_t,
77 u_char *, size_t); 77 u_char *, size_t);
78static int sdmmc_mem_write_block_subr(struct sdmmc_function *, uint32_t, 78static int sdmmc_mem_write_block_subr(struct sdmmc_function *, uint32_t,
79 u_char *, size_t); 79 u_char *, size_t);
80 80
81/* 81/*
82 * Initialize SD/MMC memory cards and memory in SDIO "combo" cards. 82 * Initialize SD/MMC memory cards and memory in SDIO "combo" cards.
83 */ 83 */
84int 84int
85sdmmc_mem_enable(struct sdmmc_softc *sc) 85sdmmc_mem_enable(struct sdmmc_softc *sc)
86{ 86{
87 uint32_t host_ocr; 87 uint32_t host_ocr;
88 uint32_t card_ocr; 88 uint32_t card_ocr;
89 int error; 89 int error;
90 90
91 SDMMC_LOCK(sc); 91 SDMMC_LOCK(sc);
92 92
93 /* Set host mode to SD "combo" card or SD memory-only. */ 93 /* Set host mode to SD "combo" card or SD memory-only. */
94 SET(sc->sc_flags, SMF_SD_MODE|SMF_MEM_MODE); 94 SET(sc->sc_flags, SMF_SD_MODE|SMF_MEM_MODE);
95 95
96 /* Reset memory (*must* do that before CMD55 or CMD1). */ 96 /* Reset memory (*must* do that before CMD55 or CMD1). */
97 sdmmc_go_idle_state(sc); 97 sdmmc_go_idle_state(sc);
98 98
99 /* 99 /*
100 * Read the SD/MMC memory OCR value by issuing CMD55 followed 100 * Read the SD/MMC memory OCR value by issuing CMD55 followed
101 * by ACMD41 to read the OCR value from memory-only SD cards. 101 * by ACMD41 to read the OCR value from memory-only SD cards.
102 * MMC cards will not respond to CMD55 or ACMD41 and this is 102 * MMC cards will not respond to CMD55 or ACMD41 and this is
103 * how we distinguish them from SD cards. 103 * how we distinguish them from SD cards.
104 */ 104 */
105mmc_mode: 105mmc_mode:
106 error = sdmmc_mem_send_op_cond(sc, 0, &card_ocr); 106 error = sdmmc_mem_send_op_cond(sc, 0, &card_ocr);
107 if (error) { 107 if (error) {
108 if (ISSET(sc->sc_flags, SMF_SD_MODE) && 108 if (ISSET(sc->sc_flags, SMF_SD_MODE) &&
109 !ISSET(sc->sc_flags, SMF_IO_MODE)) { 109 !ISSET(sc->sc_flags, SMF_IO_MODE)) {
110 /* Not a SD card, switch to MMC mode. */ 110 /* Not a SD card, switch to MMC mode. */
111 DPRINTF(("%s: switch to MMC mode\n", SDMMCDEVNAME(sc))); 111 DPRINTF(("%s: switch to MMC mode\n", SDMMCDEVNAME(sc)));
112 CLR(sc->sc_flags, SMF_SD_MODE); 112 CLR(sc->sc_flags, SMF_SD_MODE);
113 goto mmc_mode; 113 goto mmc_mode;
114 } 114 }
115 if (!ISSET(sc->sc_flags, SMF_SD_MODE)) { 115 if (!ISSET(sc->sc_flags, SMF_SD_MODE)) {
116 DPRINTF(("%s: couldn't read memory OCR\n", 116 DPRINTF(("%s: couldn't read memory OCR\n",
117 SDMMCDEVNAME(sc))); 117 SDMMCDEVNAME(sc)));
118 goto out; 118 goto out;
119 } else { 119 } else {
120 /* Not a "combo" card. */ 120 /* Not a "combo" card. */
121 CLR(sc->sc_flags, SMF_MEM_MODE); 121 CLR(sc->sc_flags, SMF_MEM_MODE);
122 error = 0; 122 error = 0;
123 goto out; 123 goto out;
124 } 124 }
125 } 125 }
126 126
127 /* Set the lowest voltage supported by the card and host. */ 127 /* Set the lowest voltage supported by the card and host. */
128 host_ocr = sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch); 128 host_ocr = sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch);
129 error = sdmmc_set_bus_power(sc, host_ocr, card_ocr); 129 error = sdmmc_set_bus_power(sc, host_ocr, card_ocr);
130 if (error) { 130 if (error) {
131 DPRINTF(("%s: couldn't supply voltage requested by card\n", 131 DPRINTF(("%s: couldn't supply voltage requested by card\n",
132 SDMMCDEVNAME(sc))); 132 SDMMCDEVNAME(sc)));
133 goto out; 133 goto out;
134 } 134 }
135 135
136 /* Tell the card(s) to enter the idle state (again). */ 136 /* Tell the card(s) to enter the idle state (again). */
137 sdmmc_go_idle_state(sc); 137 sdmmc_go_idle_state(sc);
138 138
139 error = sdmmc_mem_send_if_cond(sc, 0x1aa, &card_ocr); 139 error = sdmmc_mem_send_if_cond(sc, 0x1aa, &card_ocr);
140 if (error == 0 && card_ocr == 0x1aa) 140 if (error == 0 && card_ocr == 0x1aa)
141 SET(host_ocr, MMC_OCR_HCS); 141 SET(host_ocr, MMC_OCR_HCS);
142 142
143 /* Send the new OCR value until all cards are ready. */ 143 /* Send the new OCR value until all cards are ready. */
144 error = sdmmc_mem_send_op_cond(sc, host_ocr, NULL); 144 error = sdmmc_mem_send_op_cond(sc, host_ocr, NULL);
145 if (error) { 145 if (error) {
146 DPRINTF(("%s: couldn't send memory OCR\n", SDMMCDEVNAME(sc))); 146 DPRINTF(("%s: couldn't send memory OCR\n", SDMMCDEVNAME(sc)));
147 goto out; 147 goto out;
148 } 148 }
149 149
150out: 150out:
151 SDMMC_UNLOCK(sc); 151 SDMMC_UNLOCK(sc);
152 152
153 return error; 153 return error;
154} 154}
155 155
156/* 156/*
157 * Read the CSD and CID from all cards and assign each card a unique 157 * Read the CSD and CID from all cards and assign each card a unique
158 * relative card address (RCA). CMD2 is ignored by SDIO-only cards. 158 * relative card address (RCA). CMD2 is ignored by SDIO-only cards.
159 */ 159 */
160void 160void
161sdmmc_mem_scan(struct sdmmc_softc *sc) 161sdmmc_mem_scan(struct sdmmc_softc *sc)
162{ 162{
163 struct sdmmc_command cmd; 163 struct sdmmc_command cmd;
164 struct sdmmc_function *sf; 164 struct sdmmc_function *sf;
165 uint16_t next_rca; 165 uint16_t next_rca;
166 int error; 166 int error;
167 int retry; 167 int retry;
168 168
169 SDMMC_LOCK(sc); 169 SDMMC_LOCK(sc);
170 170
171 /* 171 /*
172 * CMD2 is a broadcast command understood by SD cards and MMC 172 * CMD2 is a broadcast command understood by SD cards and MMC
173 * cards. All cards begin to respond to the command, but back 173 * cards. All cards begin to respond to the command, but back
174 * off if another card drives the CMD line to a different level. 174 * off if another card drives the CMD line to a different level.
175 * Only one card will get its entire response through. That 175 * Only one card will get its entire response through. That
176 * card remains silent once it has been assigned a RCA. 176 * card remains silent once it has been assigned a RCA.
177 */ 177 */
178 for (retry = 0; retry < 100; retry++) { 178 for (retry = 0; retry < 100; retry++) {
179 memset(&cmd, 0, sizeof cmd); 179 memset(&cmd, 0, sizeof cmd);
180 cmd.c_opcode = MMC_ALL_SEND_CID; 180 cmd.c_opcode = MMC_ALL_SEND_CID;
181 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R2; 181 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R2;
182 182
183 error = sdmmc_mmc_command(sc, &cmd); 183 error = sdmmc_mmc_command(sc, &cmd);
184 if (error == ETIMEDOUT) { 184 if (error == ETIMEDOUT) {
185 /* No more cards there. */ 185 /* No more cards there. */
186 break; 186 break;
187 } else if (error) { 187 } else if (error) {
188 DPRINTF(("%s: couldn't read CID\n", SDMMCDEVNAME(sc))); 188 DPRINTF(("%s: couldn't read CID\n", SDMMCDEVNAME(sc)));
189 break; 189 break;
190 } 190 }
191 191
192 /* In MMC mode, find the next available RCA. */ 192 /* In MMC mode, find the next available RCA. */
193 next_rca = 1; 193 next_rca = 1;
194 if (!ISSET(sc->sc_flags, SMF_SD_MODE)) { 194 if (!ISSET(sc->sc_flags, SMF_SD_MODE)) {
195 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) 195 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list)
196 next_rca++; 196 next_rca++;
197 } 197 }
198 198
199 /* Allocate a sdmmc_function structure. */ 199 /* Allocate a sdmmc_function structure. */
200 sf = sdmmc_function_alloc(sc); 200 sf = sdmmc_function_alloc(sc);
201 sf->rca = next_rca; 201 sf->rca = next_rca;
202 202
203 /* 203 /*
204 * Remember the CID returned in the CMD2 response for 204 * Remember the CID returned in the CMD2 response for
205 * later decoding. 205 * later decoding.
206 */ 206 */
207 memcpy(sf->raw_cid, cmd.c_resp, sizeof(sf->raw_cid)); 207 memcpy(sf->raw_cid, cmd.c_resp, sizeof(sf->raw_cid));
208 208
209 /* 209 /*
210 * Silence the card by assigning it a unique RCA, or 210 * Silence the card by assigning it a unique RCA, or
211 * querying it for its RCA in the case of SD. 211 * querying it for its RCA in the case of SD.
212 */ 212 */
213 if (sdmmc_set_relative_addr(sc, sf) != 0) { 213 if (sdmmc_set_relative_addr(sc, sf) != 0) {
214 aprint_error_dev(sc->sc_dev, "couldn't set mem RCA\n"); 214 aprint_error_dev(sc->sc_dev, "couldn't set mem RCA\n");
215 sdmmc_function_free(sf); 215 sdmmc_function_free(sf);
216 break; 216 break;
217 } 217 }
218 218
219#if 0 219#if 0
220 /* Verify that the RCA has been set by selecting the card. */ 220 /* Verify that the RCA has been set by selecting the card. */
221 if (sdmmc_select_card(sc, sf) != 0) { 221 if (sdmmc_select_card(sc, sf) != 0) {
222 printf("%s: can't select mem RCA %d (verify)\n", 222 printf("%s: can't select mem RCA %d (verify)\n",
223 SDMMCDEVNAME(sc), sf->rca); 223 SDMMCDEVNAME(sc), sf->rca);
224 sdmmc_function_free(sf); 224 sdmmc_function_free(sf);
225 break; 225 break;
226 } 226 }
227 227
228 /* Deselect. */ 228 /* Deselect. */
229 (void)sdmmc_select_card(sc, NULL); 229 (void)sdmmc_select_card(sc, NULL);
230#endif 230#endif
231 231
232 /* 232 /*
233 * If this is a memory-only card, the card responding 233 * If this is a memory-only card, the card responding
234 * first becomes an alias for SDIO function 0. 234 * first becomes an alias for SDIO function 0.
235 */ 235 */
236 if (sc->sc_fn0 == NULL) 236 if (sc->sc_fn0 == NULL)
237 sc->sc_fn0 = sf; 237 sc->sc_fn0 = sf;
238 238
239 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list); 239 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list);
240 } 240 }
241 241
242 /* 242 /*
243 * All cards are either inactive or awaiting further commands. 243 * All cards are either inactive or awaiting further commands.
244 * Read the CSDs and decode the raw CID for each card. 244 * Read the CSDs and decode the raw CID for each card.
245 */ 245 */
246 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) { 246 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
247 memset(&cmd, 0, sizeof cmd); 247 memset(&cmd, 0, sizeof cmd);
248 cmd.c_opcode = MMC_SEND_CSD; 248 cmd.c_opcode = MMC_SEND_CSD;
249 cmd.c_arg = MMC_ARG_RCA(sf->rca); 249 cmd.c_arg = MMC_ARG_RCA(sf->rca);
250 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R2; 250 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R2;
251 251
252 if (sdmmc_mmc_command(sc, &cmd) != 0) { 252 if (sdmmc_mmc_command(sc, &cmd) != 0) {
253 SET(sf->flags, SFF_ERROR); 253 SET(sf->flags, SFF_ERROR);
254 continue; 254 continue;
255 } 255 }
256 256
257 if (sdmmc_decode_csd(sc, cmd.c_resp, sf) != 0 || 257 if (sdmmc_decode_csd(sc, cmd.c_resp, sf) != 0 ||
258 sdmmc_decode_cid(sc, sf->raw_cid, sf) != 0) { 258 sdmmc_decode_cid(sc, sf->raw_cid, sf) != 0) {
259 SET(sf->flags, SFF_ERROR); 259 SET(sf->flags, SFF_ERROR);
260 continue; 260 continue;
261 } 261 }
262 262
263#ifdef SDMMC_DEBUG 263#ifdef SDMMC_DEBUG
264 printf("%s: CID: ", SDMMCDEVNAME(sc)); 264 printf("%s: CID: ", SDMMCDEVNAME(sc));
265 sdmmc_print_cid(&sf->cid); 265 sdmmc_print_cid(&sf->cid);
266#endif 266#endif
267 } 267 }
268 268
269 SDMMC_UNLOCK(sc); 269 SDMMC_UNLOCK(sc);
270} 270}
271 271
272int 272int
273sdmmc_decode_csd(struct sdmmc_softc *sc, sdmmc_response resp, 273sdmmc_decode_csd(struct sdmmc_softc *sc, sdmmc_response resp,
274 struct sdmmc_function *sf) 274 struct sdmmc_function *sf)
275{ 275{
276 /* TRAN_SPEED(2:0): transfer rate exponent */ 276 /* TRAN_SPEED(2:0): transfer rate exponent */
277 static const int speed_exponent[8] = { 277 static const int speed_exponent[8] = {
278 100 * 1, /* 100 Kbits/s */ 278 100 * 1, /* 100 Kbits/s */
279 1 * 1000, /* 1 Mbits/s */ 279 1 * 1000, /* 1 Mbits/s */
280 10 * 1000, /* 10 Mbits/s */ 280 10 * 1000, /* 10 Mbits/s */
281 100 * 1000, /* 100 Mbits/s */ 281 100 * 1000, /* 100 Mbits/s */
282 0, 282 0,
283 0, 283 0,
284 0, 284 0,
285 0, 285 0,
286 }; 286 };
287 /* TRAN_SPEED(6:3): time mantissa */ 287 /* TRAN_SPEED(6:3): time mantissa */
288 static const int speed_mantissa[16] = { 288 static const int speed_mantissa[16] = {
289 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 289 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80,
290 }; 290 };
291 struct sdmmc_csd *csd = &sf->csd; 291 struct sdmmc_csd *csd = &sf->csd;
292 int e, m; 292 int e, m;
293 293
294 if (ISSET(sc->sc_flags, SMF_SD_MODE)) { 294 if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
295 /* 295 /*
296 * CSD version 1.0 corresponds to SD system 296 * CSD version 1.0 corresponds to SD system
297 * specification version 1.0 - 1.10. (SanDisk, 3.5.3) 297 * specification version 1.0 - 1.10. (SanDisk, 3.5.3)
298 */ 298 */
299 csd->csdver = SD_CSD_CSDVER(resp); 299 csd->csdver = SD_CSD_CSDVER(resp);
300 switch (csd->csdver) { 300 switch (csd->csdver) {
301 case SD_CSD_CSDVER_2_0: 301 case SD_CSD_CSDVER_2_0:
302 DPRINTF(("%s: SD Ver.2.0\n", SDMMCDEVNAME(sc))); 302 DPRINTF(("%s: SD Ver.2.0\n", SDMMCDEVNAME(sc)));
 303 SET(sf->flags, SFF_SDHC);
303 csd->capacity = SD_CSD_V2_CAPACITY(resp); 304 csd->capacity = SD_CSD_V2_CAPACITY(resp);
304 csd->read_bl_len = SD_CSD_V2_BL_LEN; 305 csd->read_bl_len = SD_CSD_V2_BL_LEN;
305 break; 306 break;
306 307
307 case SD_CSD_CSDVER_1_0: 308 case SD_CSD_CSDVER_1_0:
308 DPRINTF(("%s: SD Ver.1.0\n", SDMMCDEVNAME(sc))); 309 DPRINTF(("%s: SD Ver.1.0\n", SDMMCDEVNAME(sc)));
309 csd->capacity = SD_CSD_CAPACITY(resp); 310 csd->capacity = SD_CSD_CAPACITY(resp);
310 csd->read_bl_len = SD_CSD_READ_BL_LEN(resp); 311 csd->read_bl_len = SD_CSD_READ_BL_LEN(resp);
311 break; 312 break;
312 313
313 default: 314 default:
314 aprint_error_dev(sc->sc_dev, 315 aprint_error_dev(sc->sc_dev,
315 "unknown SD CSD structure version 0x%x\n", 316 "unknown SD CSD structure version 0x%x\n",
316 csd->csdver); 317 csd->csdver);
317 return 1; 318 return 1;
318 } 319 }
319 320
320 csd->mmcver = SD_CSD_MMCVER(resp); 321 csd->mmcver = SD_CSD_MMCVER(resp);
321 csd->write_bl_len = SD_CSD_WRITE_BL_LEN(resp); 322 csd->write_bl_len = SD_CSD_WRITE_BL_LEN(resp);
322 csd->r2w_factor = SD_CSD_R2W_FACTOR(resp); 323 csd->r2w_factor = SD_CSD_R2W_FACTOR(resp);
323 e = SD_CSD_SPEED_EXP(resp); 324 e = SD_CSD_SPEED_EXP(resp);
324 m = SD_CSD_SPEED_MANT(resp); 325 m = SD_CSD_SPEED_MANT(resp);
325 csd->tran_speed = speed_exponent[e] * speed_mantissa[m] / 10; 326 csd->tran_speed = speed_exponent[e] * speed_mantissa[m] / 10;
326 } else { 327 } else {
327 csd->csdver = MMC_CSD_CSDVER(resp); 328 csd->csdver = MMC_CSD_CSDVER(resp);
328 if (csd->csdver != MMC_CSD_CSDVER_1_0 && 329 if (csd->csdver != MMC_CSD_CSDVER_1_0 &&
329 csd->csdver != MMC_CSD_CSDVER_2_0) { 330 csd->csdver != MMC_CSD_CSDVER_2_0) {
330 aprint_error_dev(sc->sc_dev, 331 aprint_error_dev(sc->sc_dev,
331 "unknown MMC CSD structure version 0x%x\n", 332 "unknown MMC CSD structure version 0x%x\n",
332 csd->csdver); 333 csd->csdver);
333 return 1; 334 return 1;
334 } 335 }
335 336
336 csd->mmcver = MMC_CSD_MMCVER(resp); 337 csd->mmcver = MMC_CSD_MMCVER(resp);
337 csd->capacity = MMC_CSD_CAPACITY(resp); 338 csd->capacity = MMC_CSD_CAPACITY(resp);
338 csd->read_bl_len = MMC_CSD_READ_BL_LEN(resp); 339 csd->read_bl_len = MMC_CSD_READ_BL_LEN(resp);
339 csd->write_bl_len = MMC_CSD_WRITE_BL_LEN(resp); 340 csd->write_bl_len = MMC_CSD_WRITE_BL_LEN(resp);
340 csd->r2w_factor = MMC_CSD_R2W_FACTOR(resp); 341 csd->r2w_factor = MMC_CSD_R2W_FACTOR(resp);
341 e = MMC_CSD_TRAN_SPEED_EXP(resp); 342 e = MMC_CSD_TRAN_SPEED_EXP(resp);
342 m = MMC_CSD_TRAN_SPEED_MANT(resp); 343 m = MMC_CSD_TRAN_SPEED_MANT(resp);
343 csd->tran_speed = speed_exponent[e] * speed_mantissa[m] / 10; 344 csd->tran_speed = speed_exponent[e] * speed_mantissa[m] / 10;
344 } 345 }
345 csd->sector_size = MIN((1 << csd->read_bl_len), 346 csd->sector_size = MIN((1 << csd->read_bl_len),
346 sdmmc_chip_host_maxblklen(sc->sc_sct, sc->sc_sch)); 347 sdmmc_chip_host_maxblklen(sc->sc_sct, sc->sc_sch));
347 if (csd->sector_size < (1 << csd->read_bl_len)) 348 if (csd->sector_size < (1 << csd->read_bl_len))
348 csd->capacity *= (1 << csd->read_bl_len) / csd->sector_size; 349 csd->capacity *= (1 << csd->read_bl_len) / csd->sector_size;
349 csd->sector_size_sb = ffs(csd->sector_size) - 1; 350 csd->sector_size_sb = ffs(csd->sector_size) - 1;
350 351
351 if (sc->sc_busclk > csd->tran_speed) 352 if (sc->sc_busclk > csd->tran_speed)
352 sc->sc_busclk = csd->tran_speed; 353 sc->sc_busclk = csd->tran_speed;
353 354
354#ifdef SDMMC_DUMP_CSD 355#ifdef SDMMC_DUMP_CSD
355 sdmmc_print_csd(resp, csd); 356 sdmmc_print_csd(resp, csd);
356#endif 357#endif
357 358
358 return 0; 359 return 0;
359} 360}
360 361
361int 362int
362sdmmc_decode_cid(struct sdmmc_softc *sc, sdmmc_response resp, 363sdmmc_decode_cid(struct sdmmc_softc *sc, sdmmc_response resp,
363 struct sdmmc_function *sf) 364 struct sdmmc_function *sf)
364{ 365{
365 struct sdmmc_cid *cid = &sf->cid; 366 struct sdmmc_cid *cid = &sf->cid;
366 367
367 if (ISSET(sc->sc_flags, SMF_SD_MODE)) { 368 if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
368 cid->mid = SD_CID_MID(resp); 369 cid->mid = SD_CID_MID(resp);
369 cid->oid = SD_CID_OID(resp); 370 cid->oid = SD_CID_OID(resp);
370 SD_CID_PNM_CPY(resp, cid->pnm); 371 SD_CID_PNM_CPY(resp, cid->pnm);
371 cid->rev = SD_CID_REV(resp); 372 cid->rev = SD_CID_REV(resp);
372 cid->psn = SD_CID_PSN(resp); 373 cid->psn = SD_CID_PSN(resp);
373 cid->mdt = SD_CID_MDT(resp); 374 cid->mdt = SD_CID_MDT(resp);
374 } else { 375 } else {
375 switch(sf->csd.mmcver) { 376 switch(sf->csd.mmcver) {
376 case MMC_CSD_MMCVER_1_0: 377 case MMC_CSD_MMCVER_1_0:
377 case MMC_CSD_MMCVER_1_4: 378 case MMC_CSD_MMCVER_1_4:
378 cid->mid = MMC_CID_MID_V1(resp); 379 cid->mid = MMC_CID_MID_V1(resp);
379 MMC_CID_PNM_V1_CPY(resp, cid->pnm); 380 MMC_CID_PNM_V1_CPY(resp, cid->pnm);
380 cid->rev = MMC_CID_REV_V1(resp); 381 cid->rev = MMC_CID_REV_V1(resp);
381 cid->psn = MMC_CID_PSN_V1(resp); 382 cid->psn = MMC_CID_PSN_V1(resp);
382 cid->mdt = MMC_CID_MDT_V1(resp); 383 cid->mdt = MMC_CID_MDT_V1(resp);
383 break; 384 break;
384 case MMC_CSD_MMCVER_2_0: 385 case MMC_CSD_MMCVER_2_0:
385 case MMC_CSD_MMCVER_3_1: 386 case MMC_CSD_MMCVER_3_1:
386 case MMC_CSD_MMCVER_4_0: 387 case MMC_CSD_MMCVER_4_0:
387 cid->mid = MMC_CID_MID_V2(resp); 388 cid->mid = MMC_CID_MID_V2(resp);
388 cid->oid = MMC_CID_OID_V2(resp); 389 cid->oid = MMC_CID_OID_V2(resp);
389 MMC_CID_PNM_V2_CPY(resp, cid->pnm); 390 MMC_CID_PNM_V2_CPY(resp, cid->pnm);
390 cid->psn = MMC_CID_PSN_V2(resp); 391 cid->psn = MMC_CID_PSN_V2(resp);
391 break; 392 break;
392 default: 393 default:
393 aprint_error_dev(sc->sc_dev, "unknown MMC version %d\n", 394 aprint_error_dev(sc->sc_dev, "unknown MMC version %d\n",
394 sf->csd.mmcver); 395 sf->csd.mmcver);
395 return 1; 396 return 1;
396 } 397 }
397 } 398 }
398 return 0; 399 return 0;
399} 400}
400 401
401void 402void
402sdmmc_print_cid(struct sdmmc_cid *cid) 403sdmmc_print_cid(struct sdmmc_cid *cid)
403{ 404{
404 405
405 printf("mid=0x%02x oid=0x%04x pnm=\"%s\" rev=0x%02x psn=0x%08x" 406 printf("mid=0x%02x oid=0x%04x pnm=\"%s\" rev=0x%02x psn=0x%08x"
406 " mdt=%03x\n", cid->mid, cid->oid, cid->pnm, cid->rev, cid->psn, 407 " mdt=%03x\n", cid->mid, cid->oid, cid->pnm, cid->rev, cid->psn,
407 cid->mdt); 408 cid->mdt);
408} 409}
409 410
410#ifdef SDMMC_DUMP_CSD 411#ifdef SDMMC_DUMP_CSD
411static void 412static void
412sdmmc_print_csd(sdmmc_response resp, struct sdmmc_csd *csd) 413sdmmc_print_csd(sdmmc_response resp, struct sdmmc_csd *csd)
413{ 414{
414 415
415 printf("csdver = %d\n", csd->csdver); 416 printf("csdver = %d\n", csd->csdver);
416 printf("mmcver = %d\n", csd->mmcver); 417 printf("mmcver = %d\n", csd->mmcver);
417 printf("capacity = %08x\n", csd->capacity); 418 printf("capacity = %08x\n", csd->capacity);
418 printf("read_bl_len = %d\n", csd->read_bl_len); 419 printf("read_bl_len = %d\n", csd->read_bl_len);
419 printf("write_cl_len = %d\n", csd->write_bl_len); 420 printf("write_cl_len = %d\n", csd->write_bl_len);
420 printf("r2w_factor = %d\n", csd->r2w_factor); 421 printf("r2w_factor = %d\n", csd->r2w_factor);
421 printf("tran_speed = %d\n", csd->tran_speed); 422 printf("tran_speed = %d\n", csd->tran_speed);
422 printf("sector_size = %d\n", csd->sector_size); 423 printf("sector_size = %d\n", csd->sector_size);
423} 424}
424#endif 425#endif
425 426
426/* 427/*
427 * Initialize a SD/MMC memory card. 428 * Initialize a SD/MMC memory card.
428 */ 429 */
429int 430int
430sdmmc_mem_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) 431sdmmc_mem_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
431{ 432{
432 int error; 433 int error;
433 434
434 SDMMC_LOCK(sc); 435 SDMMC_LOCK(sc);
435 436
436 error = sdmmc_select_card(sc, sf); 437 error = sdmmc_select_card(sc, sf);
437 if (error) 438 if (error)
438 goto out; 439 goto out;
439 440
440 if (!ISSET(sf->flags, SFF_SDHC)) { 441 if (!ISSET(sf->flags, SFF_SDHC)) {
441 error = sdmmc_mem_set_blocklen(sc, sf); 442 error = sdmmc_mem_set_blocklen(sc, sf);
442 if (error) 443 if (error)
443 goto out; 444 goto out;
444 } 445 }
445 446
446out: 447out:
447 SDMMC_UNLOCK(sc); 448 SDMMC_UNLOCK(sc);
448 449
449 return error; 450 return error;
450} 451}
451 452
452/* 453/*
453 * Get or set the card's memory OCR value (SD or MMC). 454 * Get or set the card's memory OCR value (SD or MMC).
454 */ 455 */
455static int 456static int
456sdmmc_mem_send_op_cond(struct sdmmc_softc *sc, uint32_t ocr, uint32_t *ocrp) 457sdmmc_mem_send_op_cond(struct sdmmc_softc *sc, uint32_t ocr, uint32_t *ocrp)
457{ 458{
458 struct sdmmc_command cmd; 459 struct sdmmc_command cmd;
459 int error; 460 int error;
460 int retry; 461 int retry;
461 462
462 /* Don't lock */ 463 /* Don't lock */
463 464
464 /* 465 /*
465 * If we change the OCR value, retry the command until the OCR 466 * If we change the OCR value, retry the command until the OCR
466 * we receive in response has the "CARD BUSY" bit set, meaning 467 * we receive in response has the "CARD BUSY" bit set, meaning
467 * that all cards are ready for identification. 468 * that all cards are ready for identification.
468 */ 469 */
469 for (retry = 0; retry < 100; retry++) { 470 for (retry = 0; retry < 100; retry++) {
470 memset(&cmd, 0, sizeof(cmd)); 471 memset(&cmd, 0, sizeof(cmd));
471 cmd.c_arg = ocr; 472 cmd.c_arg = ocr;
472 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R3; 473 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R3;
473 474
474 if (ISSET(sc->sc_flags, SMF_SD_MODE)) { 475 if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
475 cmd.c_opcode = SD_APP_OP_COND; 476 cmd.c_opcode = SD_APP_OP_COND;
476 error = sdmmc_app_command(sc, &cmd); 477 error = sdmmc_app_command(sc, &cmd);
477 } else { 478 } else {
478 cmd.c_opcode = MMC_SEND_OP_COND; 479 cmd.c_opcode = MMC_SEND_OP_COND;
479 error = sdmmc_mmc_command(sc, &cmd); 480 error = sdmmc_mmc_command(sc, &cmd);
480 } 481 }
481 if (error) 482 if (error)
482 break; 483 break;
483 if (ISSET(MMC_R3(cmd.c_resp), MMC_OCR_MEM_READY) || ocr == 0) 484 if (ISSET(MMC_R3(cmd.c_resp), MMC_OCR_MEM_READY) || ocr == 0)
484 break; 485 break;
485 486
486 error = ETIMEDOUT; 487 error = ETIMEDOUT;
487 sdmmc_delay(10000); 488 sdmmc_delay(10000);
488 } 489 }
489 if (error == 0 && ocrp != NULL) 490 if (error == 0 && ocrp != NULL)
490 *ocrp = MMC_R3(cmd.c_resp); 491 *ocrp = MMC_R3(cmd.c_resp);
491 492
492 return error; 493 return error;
493} 494}
494 495
495static int 496static int
496sdmmc_mem_send_if_cond(struct sdmmc_softc *sc, uint32_t ocr, uint32_t *ocrp) 497sdmmc_mem_send_if_cond(struct sdmmc_softc *sc, uint32_t ocr, uint32_t *ocrp)
497{ 498{
498 struct sdmmc_command cmd; 499 struct sdmmc_command cmd;
499 int error; 500 int error;
500 501
501 /* Don't lock */ 502 /* Don't lock */
502 503
503 memset(&cmd, 0, sizeof(cmd)); 504 memset(&cmd, 0, sizeof(cmd));
504 cmd.c_arg = ocr; 505 cmd.c_arg = ocr;
505 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R7; 506 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R7;
506 cmd.c_opcode = SD_SEND_IF_COND; 507 cmd.c_opcode = SD_SEND_IF_COND;
507 508
508 error = sdmmc_mmc_command(sc, &cmd); 509 error = sdmmc_mmc_command(sc, &cmd);
509 if (error == 0 && ocrp != NULL) 510 if (error == 0 && ocrp != NULL)
510 *ocrp = MMC_R7(cmd.c_resp); 511 *ocrp = MMC_R7(cmd.c_resp);
511 return error; 512 return error;
512} 513}
513 514
514/* 515/*
515 * Set the read block length appropriately for this card, according to 516 * Set the read block length appropriately for this card, according to
516 * the card CSD register value. 517 * the card CSD register value.
517 */ 518 */
518static int 519static int
519sdmmc_mem_set_blocklen(struct sdmmc_softc *sc, struct sdmmc_function *sf) 520sdmmc_mem_set_blocklen(struct sdmmc_softc *sc, struct sdmmc_function *sf)
520{ 521{
521 struct sdmmc_command cmd; 522 struct sdmmc_command cmd;
522 int error; 523 int error;
523 524
524 /* Don't lock */ 525 /* Don't lock */
525 526
526 memset(&cmd, 0, sizeof(cmd)); 527 memset(&cmd, 0, sizeof(cmd));
527 cmd.c_opcode = MMC_SET_BLOCKLEN; 528 cmd.c_opcode = MMC_SET_BLOCKLEN;
528 cmd.c_arg = sf->csd.sector_size; 529 cmd.c_arg = sf->csd.sector_size;
529 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1; 530 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
530 531
531 error = sdmmc_mmc_command(sc, &cmd); 532 error = sdmmc_mmc_command(sc, &cmd);
532 533
533 DPRINTF(("%s: sdmmc_mem_set_blocklen: read_bl_len=%d sector_size=%d\n", 534 DPRINTF(("%s: sdmmc_mem_set_blocklen: read_bl_len=%d sector_size=%d\n",
534 SDMMCDEVNAME(sc), 1 << sf->csd.read_bl_len, sf->csd.sector_size)); 535 SDMMCDEVNAME(sc), 1 << sf->csd.read_bl_len, sf->csd.sector_size));
535 536
536 return error; 537 return error;
537} 538}
538 539
539static int 540static int
540sdmmc_mem_read_block_subr(struct sdmmc_function *sf, uint32_t blkno, 541sdmmc_mem_read_block_subr(struct sdmmc_function *sf, uint32_t blkno,
541 u_char *data, size_t datalen) 542 u_char *data, size_t datalen)
542{ 543{
543 struct sdmmc_softc *sc = sf->sc; 544 struct sdmmc_softc *sc = sf->sc;
544 struct sdmmc_command cmd; 545 struct sdmmc_command cmd;
545 int error; 546 int error;
546 547
547 error = sdmmc_select_card(sc, sf); 548 error = sdmmc_select_card(sc, sf);
548 if (error) 549 if (error)
549 goto out; 550 goto out;
550 551
551 memset(&cmd, 0, sizeof(cmd)); 552 memset(&cmd, 0, sizeof(cmd));
552 cmd.c_data = data; 553 cmd.c_data = data;
553 cmd.c_datalen = datalen; 554 cmd.c_datalen = datalen;
554 cmd.c_blklen = sf->csd.sector_size; 555 cmd.c_blklen = sf->csd.sector_size;
555 cmd.c_opcode = (cmd.c_datalen / cmd.c_blklen) > 1 ? 556 cmd.c_opcode = (cmd.c_datalen / cmd.c_blklen) > 1 ?
556 MMC_READ_BLOCK_MULTIPLE : MMC_READ_BLOCK_SINGLE; 557 MMC_READ_BLOCK_MULTIPLE : MMC_READ_BLOCK_SINGLE;
557 cmd.c_arg = blkno; 558 cmd.c_arg = blkno;
558 if (!ISSET(sf->flags, SFF_SDHC)) 559 if (!ISSET(sf->flags, SFF_SDHC))
559 cmd.c_arg <<= sf->csd.sector_size_sb; 560 cmd.c_arg <<= sf->csd.sector_size_sb;
560 cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1; 561 cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1;
561 if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) 562 if (ISSET(sc->sc_caps, SMC_CAPS_DMA))
562 cmd.c_dmamap = sc->sc_dmap; 563 cmd.c_dmamap = sc->sc_dmap;
563 564
564 error = sdmmc_mmc_command(sc, &cmd); 565 error = sdmmc_mmc_command(sc, &cmd);
565 if (error) 566 if (error)
566 goto out; 567 goto out;
567 568
568 if (!ISSET(sc->sc_caps, SMC_CAPS_AUTO_STOP)) { 569 if (!ISSET(sc->sc_caps, SMC_CAPS_AUTO_STOP)) {
569 if (cmd.c_opcode == MMC_READ_BLOCK_MULTIPLE) { 570 if (cmd.c_opcode == MMC_READ_BLOCK_MULTIPLE) {
570 memset(&cmd, 0, sizeof cmd); 571 memset(&cmd, 0, sizeof cmd);
571 cmd.c_opcode = MMC_STOP_TRANSMISSION; 572 cmd.c_opcode = MMC_STOP_TRANSMISSION;
572 cmd.c_arg = MMC_ARG_RCA(sf->rca); 573 cmd.c_arg = MMC_ARG_RCA(sf->rca);
573 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B; 574 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B;
574 error = sdmmc_mmc_command(sc, &cmd); 575 error = sdmmc_mmc_command(sc, &cmd);
575 if (error) 576 if (error)
576 goto out; 577 goto out;
577 } 578 }
578 } 579 }
579 580
580 do { 581 do {
581 memset(&cmd, 0, sizeof(cmd)); 582 memset(&cmd, 0, sizeof(cmd));
582 cmd.c_opcode = MMC_SEND_STATUS; 583 cmd.c_opcode = MMC_SEND_STATUS;
583 cmd.c_arg = MMC_ARG_RCA(sf->rca); 584 cmd.c_arg = MMC_ARG_RCA(sf->rca);
584 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1; 585 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
585 error = sdmmc_mmc_command(sc, &cmd); 586 error = sdmmc_mmc_command(sc, &cmd);
586 if (error) 587 if (error)
587 break; 588 break;
588 /* XXX time out */ 589 /* XXX time out */
589 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)); 590 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA));
590 591
591out: 592out:
592 return error; 593 return error;
593} 594}
594 595
595int 596int
596sdmmc_mem_read_block(struct sdmmc_function *sf, uint32_t blkno, u_char *data, 597sdmmc_mem_read_block(struct sdmmc_function *sf, uint32_t blkno, u_char *data,
597 size_t datalen) 598 size_t datalen)
598{ 599{
599 struct sdmmc_softc *sc = sf->sc; 600 struct sdmmc_softc *sc = sf->sc;
600 int error; 601 int error;
601 602
602 SDMMC_LOCK(sc); 603 SDMMC_LOCK(sc);
603 604
604 if (!ISSET(sc->sc_caps, SMC_CAPS_DMA)) { 605 if (!ISSET(sc->sc_caps, SMC_CAPS_DMA)) {
605 error = sdmmc_mem_read_block_subr(sf, blkno, data, datalen); 606 error = sdmmc_mem_read_block_subr(sf, blkno, data, datalen);
606 goto out; 607 goto out;
607 } 608 }
608 609
609 /* DMA transfer */ 610 /* DMA transfer */
610 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, data, datalen, NULL, 611 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, data, datalen, NULL,
611 BUS_DMA_NOWAIT|BUS_DMA_STREAMING|BUS_DMA_READ); 612 BUS_DMA_NOWAIT|BUS_DMA_STREAMING|BUS_DMA_READ);
612 if (error) 613 if (error)
613 goto out; 614 goto out;
614 615
615 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, 616 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen,
616 BUS_DMASYNC_PREREAD); 617 BUS_DMASYNC_PREREAD);
617 618
618 error = sdmmc_mem_read_block_subr(sf, blkno, data, datalen); 619 error = sdmmc_mem_read_block_subr(sf, blkno, data, datalen);
619 if (error) 620 if (error)
620 goto unload; 621 goto unload;
621 622
622 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, 623 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen,
623 BUS_DMASYNC_POSTREAD); 624 BUS_DMASYNC_POSTREAD);
624unload: 625unload:
625 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap); 626 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap);
626 627
627out: 628out:
628 SDMMC_UNLOCK(sc); 629 SDMMC_UNLOCK(sc);
629 630
630 return error; 631 return error;
631} 632}
632 633
633static int 634static int
634sdmmc_mem_write_block_subr(struct sdmmc_function *sf, uint32_t blkno, 635sdmmc_mem_write_block_subr(struct sdmmc_function *sf, uint32_t blkno,
635 u_char *data, size_t datalen) 636 u_char *data, size_t datalen)
636{ 637{
637 struct sdmmc_softc *sc = sf->sc; 638 struct sdmmc_softc *sc = sf->sc;
638 struct sdmmc_command cmd; 639 struct sdmmc_command cmd;
639 int error; 640 int error;
640 641
641 error = sdmmc_select_card(sc, sf); 642 error = sdmmc_select_card(sc, sf);
642 if (error) 643 if (error)
643 goto out; 644 goto out;
644 645
645 memset(&cmd, 0, sizeof(cmd)); 646 memset(&cmd, 0, sizeof(cmd));
646 cmd.c_data = data; 647 cmd.c_data = data;
647 cmd.c_datalen = datalen; 648 cmd.c_datalen = datalen;
648 cmd.c_blklen = sf->csd.sector_size; 649 cmd.c_blklen = sf->csd.sector_size;
649 cmd.c_opcode = (cmd.c_datalen / cmd.c_blklen) > 1 ? 650 cmd.c_opcode = (cmd.c_datalen / cmd.c_blklen) > 1 ?
650 MMC_WRITE_BLOCK_MULTIPLE : MMC_WRITE_BLOCK_SINGLE; 651 MMC_WRITE_BLOCK_MULTIPLE : MMC_WRITE_BLOCK_SINGLE;
651 cmd.c_arg = blkno; 652 cmd.c_arg = blkno;
652 if (!ISSET(sf->flags, SFF_SDHC)) 653 if (!ISSET(sf->flags, SFF_SDHC))
653 cmd.c_arg <<= sf->csd.sector_size_sb; 654 cmd.c_arg <<= sf->csd.sector_size_sb;
654 cmd.c_flags = SCF_CMD_ADTC | SCF_RSP_R1; 655 cmd.c_flags = SCF_CMD_ADTC | SCF_RSP_R1;
655 if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) 656 if (ISSET(sc->sc_caps, SMC_CAPS_DMA))
656 cmd.c_dmamap = sc->sc_dmap; 657 cmd.c_dmamap = sc->sc_dmap;
657 658
658 error = sdmmc_mmc_command(sc, &cmd); 659 error = sdmmc_mmc_command(sc, &cmd);
659 if (error) 660 if (error)
660 goto out; 661 goto out;
661 662
662 if (!ISSET(sc->sc_caps, SMC_CAPS_AUTO_STOP)) { 663 if (!ISSET(sc->sc_caps, SMC_CAPS_AUTO_STOP)) {
663 if (cmd.c_opcode == MMC_WRITE_BLOCK_MULTIPLE) { 664 if (cmd.c_opcode == MMC_WRITE_BLOCK_MULTIPLE) {
664 memset(&cmd, 0, sizeof(cmd)); 665 memset(&cmd, 0, sizeof(cmd));
665 cmd.c_opcode = MMC_STOP_TRANSMISSION; 666 cmd.c_opcode = MMC_STOP_TRANSMISSION;
666 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B; 667 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B;
667 error = sdmmc_mmc_command(sc, &cmd); 668 error = sdmmc_mmc_command(sc, &cmd);
668 if (error) 669 if (error)
669 goto out; 670 goto out;
670 } 671 }
671 } 672 }
672 673
673 do { 674 do {
674 memset(&cmd, 0, sizeof(cmd)); 675 memset(&cmd, 0, sizeof(cmd));
675 cmd.c_opcode = MMC_SEND_STATUS; 676 cmd.c_opcode = MMC_SEND_STATUS;
676 cmd.c_arg = MMC_ARG_RCA(sf->rca); 677 cmd.c_arg = MMC_ARG_RCA(sf->rca);
677 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1; 678 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
678 error = sdmmc_mmc_command(sc, &cmd); 679 error = sdmmc_mmc_command(sc, &cmd);
679 if (error) 680 if (error)
680 break; 681 break;
681 /* XXX time out */ 682 /* XXX time out */
682 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)); 683 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA));
683 684
684out: 685out:
685 return error; 686 return error;
686} 687}
687 688
688int 689int
689sdmmc_mem_write_block(struct sdmmc_function *sf, uint32_t blkno, u_char *data, 690sdmmc_mem_write_block(struct sdmmc_function *sf, uint32_t blkno, u_char *data,
690 size_t datalen) 691 size_t datalen)
691{ 692{
692 struct sdmmc_softc *sc = sf->sc; 693 struct sdmmc_softc *sc = sf->sc;
693 int error; 694 int error;
694 695
695 SDMMC_LOCK(sc); 696 SDMMC_LOCK(sc);
696 697
697 if (sdmmc_chip_write_protect(sc->sc_sct, sc->sc_sch)) { 698 if (sdmmc_chip_write_protect(sc->sc_sct, sc->sc_sch)) {
698 aprint_normal_dev(sc->sc_dev, "write-protected\n"); 699 aprint_normal_dev(sc->sc_dev, "write-protected\n");
699 error = EIO; 700 error = EIO;
700 goto out; 701 goto out;
701 } 702 }
702 703
703 if (!ISSET(sc->sc_caps, SMC_CAPS_DMA)) { 704 if (!ISSET(sc->sc_caps, SMC_CAPS_DMA)) {
704 error = sdmmc_mem_write_block_subr(sf, blkno, data, datalen); 705 error = sdmmc_mem_write_block_subr(sf, blkno, data, datalen);
705 goto out; 706 goto out;
706 } 707 }
707 708
708 /* DMA transfer */ 709 /* DMA transfer */
709 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, data, datalen, NULL, 710 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, data, datalen, NULL,
710 BUS_DMA_NOWAIT|BUS_DMA_STREAMING|BUS_DMA_WRITE); 711 BUS_DMA_NOWAIT|BUS_DMA_STREAMING|BUS_DMA_WRITE);
711 if (error) 712 if (error)
712 goto out; 713 goto out;
713 714
714 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, 715 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen,
715 BUS_DMASYNC_PREWRITE); 716 BUS_DMASYNC_PREWRITE);
716 717
717 error = sdmmc_mem_write_block_subr(sf, blkno, data, datalen); 718 error = sdmmc_mem_write_block_subr(sf, blkno, data, datalen);
718 if (error) 719 if (error)
719 goto unload; 720 goto unload;
720 721
721 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, 722 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen,
722 BUS_DMASYNC_POSTWRITE); 723 BUS_DMASYNC_POSTWRITE);
723unload: 724unload:
724 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap); 725 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap);
725 726
726out: 727out:
727 SDMMC_UNLOCK(sc); 728 SDMMC_UNLOCK(sc);
728 729
729 return error; 730 return error;
730} 731}