1 /* $NetBSD: sdmmc_mem.c,v 1.3 2009/11/28 10:00:24 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.3 2009/11/28 10:00:24 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 if ((1 << csd->read_bl_len) > SDMMC_SECTOR_SIZE) 347 csd->capacity *= (1 << csd->read_bl_len) / SDMMC_SECTOR_SIZE; 348 349 if (sc->sc_busclk > csd->tran_speed) 350 sc->sc_busclk = csd->tran_speed; 351 352 #ifdef SDMMC_DUMP_CSD 353 sdmmc_print_csd(resp, csd); 354 #endif 355 356 return 0; 357 } 358 359 int 360 sdmmc_decode_cid(struct sdmmc_softc *sc, sdmmc_response resp, 361 struct sdmmc_function *sf) 362 { 363 struct sdmmc_cid *cid = &sf->cid; 364 365 if (ISSET(sc->sc_flags, SMF_SD_MODE)) { 366 cid->mid = SD_CID_MID(resp); 367 cid->oid = SD_CID_OID(resp); 368 SD_CID_PNM_CPY(resp, cid->pnm); 369 cid->rev = SD_CID_REV(resp); 370 cid->psn = SD_CID_PSN(resp); 371 cid->mdt = SD_CID_MDT(resp); 372 } else { 373 switch(sf->csd.mmcver) { 374 case MMC_CSD_MMCVER_1_0: 375 case MMC_CSD_MMCVER_1_4: 376 cid->mid = MMC_CID_MID_V1(resp); 377 MMC_CID_PNM_V1_CPY(resp, cid->pnm); 378 cid->rev = MMC_CID_REV_V1(resp); 379 cid->psn = MMC_CID_PSN_V1(resp); 380 cid->mdt = MMC_CID_MDT_V1(resp); 381 break; 382 case MMC_CSD_MMCVER_2_0: 383 case MMC_CSD_MMCVER_3_1: 384 case MMC_CSD_MMCVER_4_0: 385 cid->mid = MMC_CID_MID_V2(resp); 386 cid->oid = MMC_CID_OID_V2(resp); 387 MMC_CID_PNM_V2_CPY(resp, cid->pnm); 388 cid->psn = MMC_CID_PSN_V2(resp); 389 break; 390 default: 391 aprint_error_dev(sc->sc_dev, "unknown MMC version %d\n", 392 sf->csd.mmcver); 393 return 1; 394 } 395 } 396 return 0; 397 } 398 399 void 400 sdmmc_print_cid(struct sdmmc_cid *cid) 401 { 402 403 printf("mid=0x%02x oid=0x%04x pnm=\"%s\" rev=0x%02x psn=0x%08x" 404 " mdt=%03x\n", cid->mid, cid->oid, cid->pnm, cid->rev, cid->psn, 405 cid->mdt); 406 } 407 408 #ifdef SDMMC_DUMP_CSD 409 static void 410 sdmmc_print_csd(sdmmc_response resp, struct sdmmc_csd *csd) 411 { 412 413 printf("csdver = %d\n", csd->csdver); 414 printf("mmcver = %d\n", csd->mmcver); 415 printf("capacity = %08x\n", csd->capacity); 416 printf("read_bl_len = %d\n", csd->read_bl_len); 417 printf("write_cl_len = %d\n", csd->write_bl_len); 418 printf("r2w_factor = %d\n", csd->r2w_factor); 419 printf("tran_speed = %d\n", csd->tran_speed); 420 } 421 #endif 422 423 /* 424 * Initialize a SD/MMC memory card. 425 */ 426 int 427 sdmmc_mem_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) 428 { 429 int error; 430 431 SDMMC_LOCK(sc); 432 433 error = sdmmc_select_card(sc, sf); 434 if (error) 435 goto out; 436 437 if (!ISSET(sf->flags, SFF_SDHC)) { 438 error = sdmmc_mem_set_blocklen(sc, sf); 439 if (error) 440 goto out; 441 } 442 443 out: 444 SDMMC_UNLOCK(sc); 445 446 return error; 447 } 448 449 /* 450 * Get or set the card's memory OCR value (SD or MMC). 451 */ 452 static int 453 sdmmc_mem_send_op_cond(struct sdmmc_softc *sc, uint32_t ocr, uint32_t *ocrp) 454 { 455 struct sdmmc_command cmd; 456 int error; 457 int retry; 458 459 /* Don't lock */ 460 461 /* 462 * If we change the OCR value, retry the command until the OCR 463 * we receive in response has the "CARD BUSY" bit set, meaning 464 * that all cards are ready for identification. 465 */ 466 for (retry = 0; retry < 100; retry++) { 467 memset(&cmd, 0, sizeof(cmd)); 468 cmd.c_arg = ocr; 469 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R3; 470 471 if (ISSET(sc->sc_flags, SMF_SD_MODE)) { 472 cmd.c_opcode = SD_APP_OP_COND; 473 error = sdmmc_app_command(sc, &cmd); 474 } else { 475 cmd.c_opcode = MMC_SEND_OP_COND; 476 error = sdmmc_mmc_command(sc, &cmd); 477 } 478 if (error) 479 break; 480 if (ISSET(MMC_R3(cmd.c_resp), MMC_OCR_MEM_READY) || ocr == 0) 481 break; 482 483 error = ETIMEDOUT; 484 sdmmc_delay(10000); 485 } 486 if (error == 0 && ocrp != NULL) 487 *ocrp = MMC_R3(cmd.c_resp); 488 489 return error; 490 } 491 492 static int 493 sdmmc_mem_send_if_cond(struct sdmmc_softc *sc, uint32_t ocr, uint32_t *ocrp) 494 { 495 struct sdmmc_command cmd; 496 int error; 497 498 /* Don't lock */ 499 500 memset(&cmd, 0, sizeof(cmd)); 501 cmd.c_arg = ocr; 502 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R7; 503 cmd.c_opcode = SD_SEND_IF_COND; 504 505 error = sdmmc_mmc_command(sc, &cmd); 506 if (error == 0 && ocrp != NULL) 507 *ocrp = MMC_R7(cmd.c_resp); 508 return error; 509 } 510 511 /* 512 * Set the read block length appropriately for this card, according to 513 * the card CSD register value. 514 */ 515 static int 516 sdmmc_mem_set_blocklen(struct sdmmc_softc *sc, struct sdmmc_function *sf) 517 { 518 struct sdmmc_command cmd; 519 int error; 520 521 /* Don't lock */ 522 523 memset(&cmd, 0, sizeof(cmd)); 524 cmd.c_opcode = MMC_SET_BLOCKLEN; 525 cmd.c_arg = SDMMC_SECTOR_SIZE; 526 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1; 527 528 error = sdmmc_mmc_command(sc, &cmd); 529 530 DPRINTF(("%s: sdmmc_mem_set_blocklen: read_bl_len=%d sector_size=%d\n", 531 SDMMCDEVNAME(sc), 1 << sf->csd.read_bl_len, SDMMC_SECTOR_SIZE)); 532 533 return error; 534 } 535 536 static int 537 sdmmc_mem_read_block_subr(struct sdmmc_function *sf, uint32_t blkno, 538 u_char *data, size_t datalen) 539 { 540 struct sdmmc_softc *sc = sf->sc; 541 struct sdmmc_command cmd; 542 int error; 543 544 error = sdmmc_select_card(sc, sf); 545 if (error) 546 goto out; 547 548 memset(&cmd, 0, sizeof(cmd)); 549 cmd.c_data = data; 550 cmd.c_datalen = datalen; 551 cmd.c_blklen = SDMMC_SECTOR_SIZE; 552 cmd.c_opcode = (cmd.c_datalen / cmd.c_blklen) > 1 ? 553 MMC_READ_BLOCK_MULTIPLE : MMC_READ_BLOCK_SINGLE; 554 cmd.c_arg = blkno; 555 if (!ISSET(sf->flags, SFF_SDHC)) 556 cmd.c_arg <<= SDMMC_SECTOR_SIZE_SB; 557 cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1; 558 if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) 559 cmd.c_dmamap = sc->sc_dmap; 560 561 error = sdmmc_mmc_command(sc, &cmd); 562 if (error) 563 goto out; 564 565 if (!ISSET(sc->sc_caps, SMC_CAPS_AUTO_STOP)) { 566 if (cmd.c_opcode == MMC_READ_BLOCK_MULTIPLE) { 567 memset(&cmd, 0, sizeof cmd); 568 cmd.c_opcode = MMC_STOP_TRANSMISSION; 569 cmd.c_arg = MMC_ARG_RCA(sf->rca); 570 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B; 571 error = sdmmc_mmc_command(sc, &cmd); 572 if (error) 573 goto out; 574 } 575 } 576 577 do { 578 memset(&cmd, 0, sizeof(cmd)); 579 cmd.c_opcode = MMC_SEND_STATUS; 580 cmd.c_arg = MMC_ARG_RCA(sf->rca); 581 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1; 582 error = sdmmc_mmc_command(sc, &cmd); 583 if (error) 584 break; 585 /* XXX time out */ 586 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)); 587 588 out: 589 return error; 590 } 591 592 int 593 sdmmc_mem_read_block(struct sdmmc_function *sf, uint32_t blkno, u_char *data, 594 size_t datalen) 595 { 596 struct sdmmc_softc *sc = sf->sc; 597 int error; 598 599 SDMMC_LOCK(sc); 600 601 if (!ISSET(sc->sc_caps, SMC_CAPS_DMA)) { 602 error = sdmmc_mem_read_block_subr(sf, blkno, data, datalen); 603 goto out; 604 } 605 606 /* DMA transfer */ 607 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, data, datalen, NULL, 608 BUS_DMA_NOWAIT|BUS_DMA_STREAMING|BUS_DMA_READ); 609 if (error) 610 goto out; 611 612 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, 613 BUS_DMASYNC_PREREAD); 614 615 error = sdmmc_mem_read_block_subr(sf, blkno, data, datalen); 616 if (error) 617 goto unload; 618 619 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, 620 BUS_DMASYNC_POSTREAD); 621 unload: 622 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap); 623 624 out: 625 SDMMC_UNLOCK(sc); 626 627 return error; 628 } 629 630 static int 631 sdmmc_mem_write_block_subr(struct sdmmc_function *sf, uint32_t blkno, 632 u_char *data, size_t datalen) 633 { 634 struct sdmmc_softc *sc = sf->sc; 635 struct sdmmc_command cmd; 636 int error; 637 638 error = sdmmc_select_card(sc, sf); 639 if (error) 640 goto out; 641 642 memset(&cmd, 0, sizeof(cmd)); 643 cmd.c_data = data; 644 cmd.c_datalen = datalen; 645 cmd.c_blklen = SDMMC_SECTOR_SIZE; 646 cmd.c_opcode = (cmd.c_datalen / cmd.c_blklen) > 1 ? 647 MMC_WRITE_BLOCK_MULTIPLE : MMC_WRITE_BLOCK_SINGLE; 648 cmd.c_arg = blkno; 649 if (!ISSET(sf->flags, SFF_SDHC)) 650 cmd.c_arg <<= SDMMC_SECTOR_SIZE_SB; 651 cmd.c_flags = SCF_CMD_ADTC | SCF_RSP_R1; 652 if (ISSET(sc->sc_caps, SMC_CAPS_DMA)) 653 cmd.c_dmamap = sc->sc_dmap; 654 655 error = sdmmc_mmc_command(sc, &cmd); 656 if (error) 657 goto out; 658 659 if (!ISSET(sc->sc_caps, SMC_CAPS_AUTO_STOP)) { 660 if (cmd.c_opcode == MMC_WRITE_BLOCK_MULTIPLE) { 661 memset(&cmd, 0, sizeof(cmd)); 662 cmd.c_opcode = MMC_STOP_TRANSMISSION; 663 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B; 664 error = sdmmc_mmc_command(sc, &cmd); 665 if (error) 666 goto out; 667 } 668 } 669 670 do { 671 memset(&cmd, 0, sizeof(cmd)); 672 cmd.c_opcode = MMC_SEND_STATUS; 673 cmd.c_arg = MMC_ARG_RCA(sf->rca); 674 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1; 675 error = sdmmc_mmc_command(sc, &cmd); 676 if (error) 677 break; 678 /* XXX time out */ 679 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)); 680 681 out: 682 return error; 683 } 684 685 int 686 sdmmc_mem_write_block(struct sdmmc_function *sf, uint32_t blkno, u_char *data, 687 size_t datalen) 688 { 689 struct sdmmc_softc *sc = sf->sc; 690 int error; 691 692 SDMMC_LOCK(sc); 693 694 if (sdmmc_chip_write_protect(sc->sc_sct, sc->sc_sch)) { 695 aprint_normal_dev(sc->sc_dev, "write-protected\n"); 696 error = EIO; 697 goto out; 698 } 699 700 if (!ISSET(sc->sc_caps, SMC_CAPS_DMA)) { 701 error = sdmmc_mem_write_block_subr(sf, blkno, data, datalen); 702 goto out; 703 } 704 705 /* DMA transfer */ 706 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, data, datalen, NULL, 707 BUS_DMA_NOWAIT|BUS_DMA_STREAMING|BUS_DMA_WRITE); 708 if (error) 709 goto out; 710 711 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, 712 BUS_DMASYNC_PREWRITE); 713 714 error = sdmmc_mem_write_block_subr(sf, blkno, data, datalen); 715 if (error) 716 goto unload; 717 718 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen, 719 BUS_DMASYNC_POSTWRITE); 720 unload: 721 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap); 722 723 out: 724 SDMMC_UNLOCK(sc); 725 726 return error; 727 } 728