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