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