1 /* $NetBSD: sdmmc_io.c,v 1.2 2009/12/05 22:34:43 pooka Exp $ */ 2 /* $OpenBSD: sdmmc_io.c,v 1.10 2007/09/17 01:33:33 krw 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 /* Routines for SD I/O cards. */ 21 22 #include <sys/cdefs.h> 23 __KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.2 2009/12/05 22:34:43 pooka Exp $"); 24 25 #include <sys/param.h> 26 #include <sys/kernel.h> 27 #include <sys/malloc.h> 28 #include <sys/proc.h> 29 #include <sys/systm.h> 30 31 #include <dev/sdmmc/sdmmc_ioreg.h> 32 #include <dev/sdmmc/sdmmcchip.h> 33 #include <dev/sdmmc/sdmmcreg.h> 34 #include <dev/sdmmc/sdmmcvar.h> 35 36 #ifdef SDMMC_DEBUG 37 #define DPRINTF(s) do { printf s; } while (0) 38 #else 39 #define DPRINTF(s) do {} while (0) 40 #endif 41 42 struct sdmmc_intr_handler { 43 struct sdmmc_softc *ih_softc; 44 char *ih_name; 45 int (*ih_fun)(void *); 46 void *ih_arg; 47 TAILQ_ENTRY(sdmmc_intr_handler) entry; 48 }; 49 50 static int sdmmc_io_rw_direct(struct sdmmc_softc *, 51 struct sdmmc_function *, int, u_char *, int); 52 static int sdmmc_io_rw_extended(struct sdmmc_softc *, 53 struct sdmmc_function *, int, u_char *, int, int); 54 #if 0 55 static int sdmmc_io_xchg(struct sdmmc_softc *, struct sdmmc_function *, 56 int, u_char *); 57 #endif 58 static void sdmmc_io_reset(struct sdmmc_softc *); 59 static int sdmmc_io_send_op_cond(struct sdmmc_softc *, uint32_t, 60 uint32_t *); 61 62 /* 63 * Initialize SD I/O card functions (before memory cards). The host 64 * system and controller must support card interrupts in order to use 65 * I/O functions. 66 */ 67 int 68 sdmmc_io_enable(struct sdmmc_softc *sc) 69 { 70 uint32_t host_ocr; 71 uint32_t card_ocr; 72 int error; 73 74 SDMMC_LOCK(sc); 75 76 /* Set host mode to SD "combo" card. */ 77 SET(sc->sc_flags, SMF_SD_MODE|SMF_IO_MODE|SMF_MEM_MODE); 78 79 /* Reset I/O functions. */ 80 sdmmc_io_reset(sc); 81 82 /* 83 * Read the I/O OCR value, determine the number of I/O 84 * functions and whether memory is also present (a "combo 85 * card") by issuing CMD5. SD memory-only and MMC cards 86 * do not respond to CMD5. 87 */ 88 error = sdmmc_io_send_op_cond(sc, 0, &card_ocr); 89 if (error) { 90 /* No SDIO card; switch to SD memory-only mode. */ 91 CLR(sc->sc_flags, SMF_IO_MODE); 92 error = 0; 93 goto out; 94 } 95 96 /* Parse the additional bits in the I/O OCR value. */ 97 if (!ISSET(card_ocr, SD_IO_OCR_MEM_PRESENT)) { 98 /* SDIO card without memory (not a "combo card"). */ 99 DPRINTF(("%s: no memory present\n", SDMMCDEVNAME(sc))); 100 CLR(sc->sc_flags, SMF_MEM_MODE); 101 } 102 sc->sc_function_count = SD_IO_OCR_NUM_FUNCTIONS(card_ocr); 103 if (sc->sc_function_count == 0) { 104 /* Useless SDIO card without any I/O functions. */ 105 DPRINTF(("%s: no I/O functions\n", SDMMCDEVNAME(sc))); 106 CLR(sc->sc_flags, SMF_IO_MODE); 107 error = 0; 108 goto out; 109 } 110 card_ocr &= SD_IO_OCR_MASK; 111 112 /* Set the lowest voltage supported by the card and host. */ 113 host_ocr = sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch); 114 error = sdmmc_set_bus_power(sc, host_ocr, card_ocr); 115 if (error) { 116 aprint_error_dev(sc->sc_dev, 117 "couldn't supply voltage requested by card\n"); 118 goto out; 119 } 120 121 /* Reset I/O functions (again). */ 122 sdmmc_io_reset(sc); 123 124 /* Send the new OCR value until all cards are ready. */ 125 error = sdmmc_io_send_op_cond(sc, host_ocr, NULL); 126 if (error) { 127 aprint_error_dev(sc->sc_dev, "couldn't send I/O OCR\n"); 128 goto out; 129 } 130 131 out: 132 SDMMC_UNLOCK(sc); 133 134 return error; 135 } 136 137 /* 138 * Allocate sdmmc_function structures for SD card I/O function 139 * (including function 0). 140 */ 141 void 142 sdmmc_io_scan(struct sdmmc_softc *sc) 143 { 144 struct sdmmc_function *sf0, *sf; 145 int error; 146 int i; 147 148 SDMMC_LOCK(sc); 149 150 sf0 = sdmmc_function_alloc(sc); 151 sf0->number = 0; 152 error = sdmmc_set_relative_addr(sc, sf0); 153 if (error) { 154 aprint_error_dev(sc->sc_dev, "couldn't set I/O RCA\n"); 155 SET(sf0->flags, SFF_ERROR); 156 goto out; 157 } 158 sc->sc_fn0 = sf0; 159 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf0, sf_list); 160 161 /* Verify that the RCA has been set by selecting the card. */ 162 error = sdmmc_select_card(sc, sf0); 163 if (error) { 164 aprint_error_dev(sc->sc_dev, "couldn't select I/O RCA %d\n", 165 sf0->rca); 166 SET(sf0->flags, SFF_ERROR); 167 goto out; 168 } 169 170 for (i = 1; i <= sc->sc_function_count; i++) { 171 sf = sdmmc_function_alloc(sc); 172 sf->number = i; 173 sf->rca = sf0->rca; 174 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list); 175 } 176 177 out: 178 SDMMC_UNLOCK(sc); 179 } 180 181 /* 182 * Initialize SDIO card functions. 183 */ 184 int 185 sdmmc_io_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) 186 { 187 int error = 0; 188 189 SDMMC_LOCK(sc); 190 191 if (sf->number == 0) { 192 sdmmc_io_write_1(sf, SD_IO_CCCR_BUS_WIDTH, CCCR_BUS_WIDTH_1); 193 194 error = sdmmc_read_cis(sf, &sf->cis); 195 if (error) { 196 aprint_error_dev(sc->sc_dev, "couldn't read CIS\n"); 197 SET(sf->flags, SFF_ERROR); 198 goto out; 199 } 200 201 sdmmc_check_cis_quirks(sf); 202 203 #ifdef SDMMC_DEBUG 204 if (sdmmcdebug) 205 sdmmc_print_cis(sf); 206 #endif 207 } 208 209 out: 210 SDMMC_UNLOCK(sc); 211 212 return error; 213 } 214 215 /* 216 * Indicate whether the function is ready to operate. 217 */ 218 static int 219 sdmmc_io_function_ready(struct sdmmc_function *sf) 220 { 221 struct sdmmc_softc *sc = sf->sc; 222 struct sdmmc_function *sf0 = sc->sc_fn0; 223 uint8_t reg; 224 225 if (sf->number == 0) 226 return 1; /* FN0 is always ready */ 227 228 SDMMC_LOCK(sc); 229 reg = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_IOREADY); 230 SDMMC_UNLOCK(sc); 231 return (reg & (1 << sf->number)) != 0; 232 } 233 234 int 235 sdmmc_io_function_enable(struct sdmmc_function *sf) 236 { 237 struct sdmmc_softc *sc = sf->sc; 238 struct sdmmc_function *sf0 = sc->sc_fn0; 239 uint8_t reg; 240 int retry; 241 242 if (sf->number == 0) 243 return 0; /* FN0 is always enabled */ 244 245 SDMMC_LOCK(sc); 246 reg = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE); 247 SET(reg, (1U << sf->number)); 248 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, reg); 249 SDMMC_UNLOCK(sc); 250 251 retry = 5; 252 while (!sdmmc_io_function_ready(sf) && retry-- > 0) 253 kpause("pause", false, hz, NULL); 254 return (retry >= 0) ? 0 : ETIMEDOUT; 255 } 256 257 /* 258 * Disable the I/O function. Return zero if the function was 259 * disabled successfully. 260 */ 261 void 262 sdmmc_io_function_disable(struct sdmmc_function *sf) 263 { 264 struct sdmmc_softc *sc = sf->sc; 265 struct sdmmc_function *sf0 = sc->sc_fn0; 266 uint8_t reg; 267 268 if (sf->number == 0) 269 return; /* FN0 is always enabled */ 270 271 SDMMC_LOCK(sc); 272 reg = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE); 273 CLR(reg, (1U << sf->number)); 274 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, reg); 275 SDMMC_UNLOCK(sc); 276 } 277 278 static int 279 sdmmc_io_rw_direct(struct sdmmc_softc *sc, struct sdmmc_function *sf, 280 int reg, u_char *datap, int arg) 281 { 282 struct sdmmc_command cmd; 283 int error; 284 285 /* Don't lock */ 286 287 /* Make sure the card is selected. */ 288 error = sdmmc_select_card(sc, sf); 289 if (error) 290 return error; 291 292 arg |= ((sf == NULL ? 0 : sf->number) & SD_ARG_CMD52_FUNC_MASK) << 293 SD_ARG_CMD52_FUNC_SHIFT; 294 arg |= (reg & SD_ARG_CMD52_REG_MASK) << 295 SD_ARG_CMD52_REG_SHIFT; 296 arg |= (*datap & SD_ARG_CMD52_DATA_MASK) << 297 SD_ARG_CMD52_DATA_SHIFT; 298 299 memset(&cmd, 0, sizeof cmd); 300 cmd.c_opcode = SD_IO_RW_DIRECT; 301 cmd.c_arg = arg; 302 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5; 303 304 error = sdmmc_mmc_command(sc, &cmd); 305 *datap = SD_R5_DATA(cmd.c_resp); 306 307 return error; 308 } 309 310 /* 311 * Useful values of `arg' to pass in are either SD_ARG_CMD53_READ or 312 * SD_ARG_CMD53_WRITE. SD_ARG_CMD53_INCREMENT may be ORed into `arg' 313 * to access successive register locations instead of accessing the 314 * same register many times. 315 */ 316 static int 317 sdmmc_io_rw_extended(struct sdmmc_softc *sc, struct sdmmc_function *sf, 318 int reg, u_char *datap, int datalen, int arg) 319 { 320 struct sdmmc_command cmd; 321 int error; 322 323 /* Don't lock */ 324 325 #if 0 326 /* Make sure the card is selected. */ 327 error = sdmmc_select_card(sc, sf); 328 if (error) 329 return error; 330 #endif 331 332 arg |= (((sf == NULL) ? 0 : sf->number) & SD_ARG_CMD53_FUNC_MASK) << 333 SD_ARG_CMD53_FUNC_SHIFT; 334 arg |= (reg & SD_ARG_CMD53_REG_MASK) << 335 SD_ARG_CMD53_REG_SHIFT; 336 arg |= (datalen & SD_ARG_CMD53_LENGTH_MASK) << 337 SD_ARG_CMD53_LENGTH_SHIFT; 338 339 memset(&cmd, 0, sizeof cmd); 340 cmd.c_opcode = SD_IO_RW_EXTENDED; 341 cmd.c_arg = arg; 342 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5; 343 cmd.c_data = datap; 344 cmd.c_datalen = datalen; 345 cmd.c_blklen = MIN(datalen, 346 sdmmc_chip_host_maxblklen(sc->sc_sct,sc->sc_sch)); 347 if (!ISSET(arg, SD_ARG_CMD53_WRITE)) 348 cmd.c_flags |= SCF_CMD_READ; 349 350 error = sdmmc_mmc_command(sc, &cmd); 351 352 return error; 353 } 354 355 uint8_t 356 sdmmc_io_read_1(struct sdmmc_function *sf, int reg) 357 { 358 uint8_t data = 0; 359 360 /* Don't lock */ 361 362 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, 363 SD_ARG_CMD52_READ); 364 return data; 365 } 366 367 void 368 sdmmc_io_write_1(struct sdmmc_function *sf, int reg, uint8_t data) 369 { 370 371 /* Don't lock */ 372 373 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, 374 SD_ARG_CMD52_WRITE); 375 } 376 377 uint16_t 378 sdmmc_io_read_2(struct sdmmc_function *sf, int reg) 379 { 380 uint16_t data = 0; 381 382 /* Don't lock */ 383 384 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2, 385 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT); 386 return data; 387 } 388 389 void 390 sdmmc_io_write_2(struct sdmmc_function *sf, int reg, uint16_t data) 391 { 392 393 /* Don't lock */ 394 395 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2, 396 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT); 397 } 398 399 uint32_t 400 sdmmc_io_read_4(struct sdmmc_function *sf, int reg) 401 { 402 uint32_t data = 0; 403 404 /* Don't lock */ 405 406 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4, 407 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT); 408 return data; 409 } 410 411 void 412 sdmmc_io_write_4(struct sdmmc_function *sf, int reg, uint32_t data) 413 { 414 415 /* Don't lock */ 416 417 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4, 418 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT); 419 } 420 421 422 int 423 sdmmc_io_read_multi_1(struct sdmmc_function *sf, int reg, u_char *data, 424 int datalen) 425 { 426 int error; 427 428 /* Don't lock */ 429 430 while (datalen > SD_ARG_CMD53_LENGTH_MAX) { 431 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, 432 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_READ); 433 if (error) 434 goto error; 435 data += SD_ARG_CMD53_LENGTH_MAX; 436 datalen -= SD_ARG_CMD53_LENGTH_MAX; 437 } 438 439 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen, 440 SD_ARG_CMD53_READ); 441 error: 442 return error; 443 } 444 445 int 446 sdmmc_io_write_multi_1(struct sdmmc_function *sf, int reg, u_char *data, 447 int datalen) 448 { 449 int error; 450 451 /* Don't lock */ 452 453 while (datalen > SD_ARG_CMD53_LENGTH_MAX) { 454 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, 455 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_WRITE); 456 if (error) 457 goto error; 458 data += SD_ARG_CMD53_LENGTH_MAX; 459 datalen -= SD_ARG_CMD53_LENGTH_MAX; 460 } 461 462 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen, 463 SD_ARG_CMD53_WRITE); 464 error: 465 return error; 466 } 467 468 #if 0 469 static int 470 sdmmc_io_xchg(struct sdmmc_softc *sc, struct sdmmc_function *sf, 471 int reg, u_char *datap) 472 { 473 474 /* Don't lock */ 475 476 return sdmmc_io_rw_direct(sc, sf, reg, datap, 477 SD_ARG_CMD52_WRITE|SD_ARG_CMD52_EXCHANGE); 478 } 479 #endif 480 481 /* 482 * Reset the I/O functions of the card. 483 */ 484 static void 485 sdmmc_io_reset(struct sdmmc_softc *sc) 486 { 487 488 /* Don't lock */ 489 #if 0 /* XXX command fails */ 490 (void)sdmmc_io_write(sc, NULL, SD_IO_REG_CCCR_CTL, CCCR_CTL_RES); 491 sdmmc_delay(100000); 492 #endif 493 } 494 495 /* 496 * Get or set the card's I/O OCR value (SDIO). 497 */ 498 static int 499 sdmmc_io_send_op_cond(struct sdmmc_softc *sc, u_int32_t ocr, u_int32_t *ocrp) 500 { 501 struct sdmmc_command cmd; 502 int error; 503 int retry; 504 505 DPRINTF(("sdmmc_io_send_op_cond: ocr = %#x\n", ocr)); 506 507 /* Don't lock */ 508 509 /* 510 * If we change the OCR value, retry the command until the OCR 511 * we receive in response has the "CARD BUSY" bit set, meaning 512 * that all cards are ready for identification. 513 */ 514 for (retry = 0; retry < 100; retry++) { 515 memset(&cmd, 0, sizeof cmd); 516 cmd.c_opcode = SD_IO_SEND_OP_COND; 517 cmd.c_arg = ocr; 518 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R4; 519 520 error = sdmmc_mmc_command(sc, &cmd); 521 if (error) 522 break; 523 if (ISSET(MMC_R4(cmd.c_resp), SD_IO_OCR_MEM_READY) || ocr == 0) 524 break; 525 526 error = ETIMEDOUT; 527 sdmmc_delay(10000); 528 } 529 if (error == 0 && ocrp != NULL) 530 *ocrp = MMC_R4(cmd.c_resp); 531 532 DPRINTF(("sdmmc_io_send_op_cond: error = %d\n", error)); 533 534 return error; 535 } 536 537 /* 538 * Card interrupt handling 539 */ 540 541 void 542 sdmmc_intr_enable(struct sdmmc_function *sf) 543 { 544 struct sdmmc_softc *sc = sf->sc; 545 struct sdmmc_function *sf0 = sc->sc_fn0; 546 uint8_t reg; 547 548 SDMMC_LOCK(sc); 549 reg = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_INTEN); 550 reg |= 1 << sf->number; 551 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_INTEN, reg); 552 SDMMC_UNLOCK(sc); 553 } 554 555 void 556 sdmmc_intr_disable(struct sdmmc_function *sf) 557 { 558 struct sdmmc_softc *sc = sf->sc; 559 struct sdmmc_function *sf0 = sc->sc_fn0; 560 uint8_t reg; 561 562 SDMMC_LOCK(sc); 563 reg = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_INTEN); 564 reg &= ~(1 << sf->number); 565 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_INTEN, reg); 566 SDMMC_UNLOCK(sc); 567 } 568 569 /* 570 * Establish a handler for the SDIO card interrupt. Because the 571 * interrupt may be shared with different SDIO functions, multiple 572 * handlers can be established. 573 */ 574 void * 575 sdmmc_intr_establish(device_t dev, int (*fun)(void *), void *arg, 576 const char *name) 577 { 578 struct sdmmc_softc *sc = device_private(dev); 579 struct sdmmc_intr_handler *ih; 580 int s; 581 582 if (sc->sc_sct->card_enable_intr == NULL) 583 return NULL; 584 585 ih = malloc(sizeof *ih, M_DEVBUF, M_WAITOK|M_CANFAIL|M_ZERO); 586 if (ih == NULL) 587 return NULL; 588 589 ih->ih_name = malloc(strlen(name) + 1, M_DEVBUF, 590 M_WAITOK|M_CANFAIL|M_ZERO); 591 if (ih->ih_name == NULL) { 592 free(ih, M_DEVBUF); 593 return NULL; 594 } 595 strlcpy(ih->ih_name, name, strlen(name)); 596 ih->ih_softc = sc; 597 ih->ih_fun = fun; 598 ih->ih_arg = arg; 599 600 s = splhigh(); 601 if (TAILQ_EMPTY(&sc->sc_intrq)) { 602 sdmmc_intr_enable(sc->sc_fn0); 603 sdmmc_chip_card_enable_intr(sc->sc_sct, sc->sc_sch, 1); 604 } 605 TAILQ_INSERT_TAIL(&sc->sc_intrq, ih, entry); 606 splx(s); 607 608 return ih; 609 } 610 611 /* 612 * Disestablish the given handler. 613 */ 614 void 615 sdmmc_intr_disestablish(void *cookie) 616 { 617 struct sdmmc_intr_handler *ih = cookie; 618 struct sdmmc_softc *sc = ih->ih_softc; 619 int s; 620 621 if (sc->sc_sct->card_enable_intr == NULL) 622 return; 623 624 s = splhigh(); 625 TAILQ_REMOVE(&sc->sc_intrq, ih, entry); 626 if (TAILQ_EMPTY(&sc->sc_intrq)) { 627 sdmmc_chip_card_enable_intr(sc->sc_sct, sc->sc_sch, 0); 628 sdmmc_intr_disable(sc->sc_fn0); 629 } 630 splx(s); 631 632 free(ih->ih_name, M_DEVBUF); 633 free(ih, M_DEVBUF); 634 } 635 636 /* 637 * Call established SDIO card interrupt handlers. The host controller 638 * must call this function from its own interrupt handler to handle an 639 * SDIO interrupt from the card. 640 */ 641 void 642 sdmmc_card_intr(device_t dev) 643 { 644 struct sdmmc_softc *sc = device_private(dev); 645 646 if (sc->sc_sct->card_enable_intr) { 647 mutex_enter(&sc->sc_intr_task_mtx); 648 if (!sdmmc_task_pending(&sc->sc_intr_task)) 649 sdmmc_add_task(sc, &sc->sc_intr_task); 650 mutex_exit(&sc->sc_intr_task_mtx); 651 } 652 } 653 654 void 655 sdmmc_intr_task(void *arg) 656 { 657 struct sdmmc_softc *sc = (struct sdmmc_softc *)arg; 658 struct sdmmc_intr_handler *ih; 659 int s; 660 661 s = splsdmmc(); 662 TAILQ_FOREACH(ih, &sc->sc_intrq, entry) { 663 splx(s); 664 /* XXX examine return value and do evcount stuff*/ 665 (void)(*ih->ih_fun)(ih->ih_arg); 666 s = splsdmmc(); 667 } 668 sdmmc_chip_card_intr_ack(sc->sc_sct, sc->sc_sch); 669 splx(s); 670 } 671