1 /* $OpenBSD: sdmmc_io.c,v 1.27 2016/09/11 10:22:16 mglocker Exp $ */ 2 3 /* 4 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* Routines for SD I/O cards. */ 20 21 #include <sys/param.h> 22 #include <sys/device.h> 23 #include <sys/kernel.h> 24 #include <sys/malloc.h> 25 #include <sys/systm.h> 26 27 #include <dev/sdmmc/sdmmc_ioreg.h> 28 #include <dev/sdmmc/sdmmcchip.h> 29 #include <dev/sdmmc/sdmmcvar.h> 30 31 struct sdmmc_intr_handler { 32 struct sdmmc_softc *ih_softc; 33 const char *ih_name; 34 int (*ih_fun)(void *); 35 void *ih_arg; 36 TAILQ_ENTRY(sdmmc_intr_handler) entry; 37 }; 38 39 int sdmmc_submatch(struct device *, void *, void *); 40 int sdmmc_print(void *, const char *); 41 int sdmmc_io_rw_direct(struct sdmmc_softc *, struct sdmmc_function *, 42 int, u_char *, int); 43 int sdmmc_io_rw_extended(struct sdmmc_softc *, struct sdmmc_function *, 44 int, u_char *, int, int); 45 int sdmmc_io_xchg(struct sdmmc_softc *, struct sdmmc_function *, 46 int, u_char *); 47 void sdmmc_io_reset(struct sdmmc_softc *); 48 int sdmmc_io_send_op_cond(struct sdmmc_softc *, u_int32_t, u_int32_t *); 49 50 #ifdef SDMMC_DEBUG 51 #define DPRINTF(s) printf s 52 #else 53 #define DPRINTF(s) /**/ 54 #endif 55 56 #ifdef SDMMC_DEBUG 57 int sdmmc_verbose = 1; 58 #else 59 int sdmmc_verbose = 0; 60 #endif 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 u_int32_t host_ocr; 71 u_int32_t card_ocr; 72 73 rw_assert_wrlock(&sc->sc_lock); 74 75 /* Set host mode to SD "combo" card. */ 76 SET(sc->sc_flags, SMF_SD_MODE|SMF_IO_MODE|SMF_MEM_MODE); 77 78 /* Reset I/O functions. */ 79 sdmmc_io_reset(sc); 80 81 /* 82 * Read the I/O OCR value, determine the number of I/O 83 * functions and whether memory is also present (a "combo 84 * card") by issuing CMD5. SD memory-only and MMC cards 85 * do not respond to CMD5. 86 */ 87 if (sdmmc_io_send_op_cond(sc, 0, &card_ocr) != 0) { 88 /* No SDIO card; switch to SD memory-only mode. */ 89 CLR(sc->sc_flags, SMF_IO_MODE); 90 return 0; 91 } 92 93 /* Parse the additional bits in the I/O OCR value. */ 94 if (!ISSET(card_ocr, SD_IO_OCR_MEM_PRESENT)) { 95 /* SDIO card without memory (not a "combo card"). */ 96 DPRINTF(("%s: no memory present\n", DEVNAME(sc))); 97 CLR(sc->sc_flags, SMF_MEM_MODE); 98 } 99 sc->sc_function_count = SD_IO_OCR_NUM_FUNCTIONS(card_ocr); 100 if (sc->sc_function_count == 0) { 101 /* Useless SDIO card without any I/O functions. */ 102 DPRINTF(("%s: no I/O functions\n", DEVNAME(sc))); 103 CLR(sc->sc_flags, SMF_IO_MODE); 104 return 0; 105 } 106 card_ocr &= SD_IO_OCR_MASK; 107 108 /* Set the lowest voltage supported by the card and host. */ 109 host_ocr = sdmmc_chip_host_ocr(sc->sct, sc->sch); 110 if (sdmmc_set_bus_power(sc, host_ocr, card_ocr) != 0) { 111 printf("%s: can't supply voltage requested by card\n", 112 DEVNAME(sc)); 113 return 1; 114 } 115 116 /* Send the new OCR value until all cards are ready. */ 117 if (sdmmc_io_send_op_cond(sc, host_ocr, NULL) != 0) { 118 printf("%s: can't send I/O OCR\n", DEVNAME(sc)); 119 return 1; 120 } 121 return 0; 122 } 123 124 /* 125 * Allocate sdmmc_function structures for SD card I/O function 126 * (including function 0). 127 */ 128 void 129 sdmmc_io_scan(struct sdmmc_softc *sc) 130 { 131 struct sdmmc_function *sf0, *sf; 132 int i; 133 134 rw_assert_wrlock(&sc->sc_lock); 135 136 sf0 = sdmmc_function_alloc(sc); 137 sf0->number = 0; 138 if (sdmmc_set_relative_addr(sc, sf0) != 0) { 139 printf("%s: can't set I/O RCA\n", DEVNAME(sc)); 140 SET(sf0->flags, SFF_ERROR); 141 return; 142 } 143 sc->sc_fn0 = sf0; 144 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf0, sf_list); 145 146 /* Verify that the RCA has been set by selecting the card. */ 147 if (sdmmc_select_card(sc, sf0) != 0) { 148 printf("%s: can't select I/O RCA %d\n", DEVNAME(sc), 149 sf0->rca); 150 SET(sf0->flags, SFF_ERROR); 151 return; 152 } 153 154 for (i = 1; i <= sc->sc_function_count; i++) { 155 sf = sdmmc_function_alloc(sc); 156 sf->number = i; 157 sf->rca = sf0->rca; 158 159 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list); 160 } 161 } 162 163 /* 164 * Initialize SDIO card functions. 165 */ 166 int 167 sdmmc_io_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) 168 { 169 rw_assert_wrlock(&sc->sc_lock); 170 171 if (sdmmc_read_cis(sf, &sf->cis) != 0) { 172 printf("%s: can't read CIS\n", DEVNAME(sc)); 173 SET(sf->flags, SFF_ERROR); 174 return 1; 175 } 176 177 sdmmc_check_cis_quirks(sf); 178 179 if (sdmmc_verbose) 180 sdmmc_print_cis(sf); 181 182 if (sf->number == 0) { 183 /* XXX respect host and card capabilities */ 184 (void)sdmmc_chip_bus_clock(sc->sct, sc->sch, 185 25000, SDMMC_TIMING_LEGACY); 186 } 187 188 return 0; 189 } 190 191 /* 192 * Indicate whether the function is ready to operate. 193 */ 194 int 195 sdmmc_io_function_ready(struct sdmmc_function *sf) 196 { 197 struct sdmmc_softc *sc = sf->sc; 198 struct sdmmc_function *sf0 = sc->sc_fn0; 199 u_int8_t rv; 200 201 rw_assert_wrlock(&sc->sc_lock); 202 203 if (sf->number == 0) 204 return 1; /* FN0 is always ready */ 205 206 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_READY); 207 208 return (rv & (1 << sf->number)) != 0; 209 } 210 211 /* 212 * Enable the I/O function. Return zero if the function was 213 * enabled successfully. 214 */ 215 int 216 sdmmc_io_function_enable(struct sdmmc_function *sf) 217 { 218 struct sdmmc_softc *sc = sf->sc; 219 struct sdmmc_function *sf0 = sc->sc_fn0; 220 u_int8_t rv; 221 int retry = 5; 222 223 if (sf->number == 0) 224 return 0; /* FN0 is always enabled */ 225 226 rw_enter_write(&sc->sc_lock); 227 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE); 228 rv |= (1<<sf->number); 229 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, rv); 230 rw_exit(&sc->sc_lock); 231 232 while (!sdmmc_io_function_ready(sf) && retry-- > 0) 233 tsleep(&lbolt, PPAUSE, "pause", 0); 234 return (retry >= 0) ? 0 : ETIMEDOUT; 235 } 236 237 /* 238 * Disable the I/O function. Return zero if the function was 239 * disabled successfully. 240 */ 241 void 242 sdmmc_io_function_disable(struct sdmmc_function *sf) 243 { 244 struct sdmmc_softc *sc = sf->sc; 245 struct sdmmc_function *sf0 = sc->sc_fn0; 246 u_int8_t rv; 247 248 rw_assert_wrlock(&sc->sc_lock); 249 250 if (sf->number == 0) 251 return; /* FN0 is always enabled */ 252 253 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE); 254 rv &= ~(1<<sf->number); 255 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, rv); 256 } 257 258 void 259 sdmmc_io_attach(struct sdmmc_softc *sc) 260 { 261 struct sdmmc_function *sf; 262 struct sdmmc_attach_args saa; 263 264 rw_assert_wrlock(&sc->sc_lock); 265 266 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) { 267 if (sf->number < 1) 268 continue; 269 270 bzero(&saa, sizeof saa); 271 saa.sf = sf; 272 273 sf->child = config_found_sm(&sc->sc_dev, &saa, sdmmc_print, 274 sdmmc_submatch); 275 } 276 } 277 278 int 279 sdmmc_submatch(struct device *parent, void *match, void *aux) 280 { 281 struct cfdata *cf = match; 282 283 /* Skip the scsibus, it is configured directly. */ 284 if (strcmp(cf->cf_driver->cd_name, "scsibus") == 0) 285 return 0; 286 287 return cf->cf_attach->ca_match(parent, cf, aux); 288 } 289 290 int 291 sdmmc_print(void *aux, const char *pnp) 292 { 293 struct sdmmc_attach_args *sa = aux; 294 struct sdmmc_function *sf = sa->sf; 295 struct sdmmc_cis *cis = &sf->sc->sc_fn0->cis; 296 int i; 297 298 if (pnp) { 299 if (sf->number == 0) 300 return QUIET; 301 302 for (i = 0; i < 4 && cis->cis1_info[i]; i++) 303 printf("%s%s", i ? ", " : "\"", cis->cis1_info[i]); 304 if (i != 0) 305 printf("\""); 306 307 if (cis->manufacturer != SDMMC_VENDOR_INVALID && 308 cis->product != SDMMC_PRODUCT_INVALID) { 309 printf("%s(", i ? " " : ""); 310 if (cis->manufacturer != SDMMC_VENDOR_INVALID) 311 printf("manufacturer 0x%x%s", 312 cis->manufacturer, 313 cis->product == SDMMC_PRODUCT_INVALID ? 314 "" : ", "); 315 if (cis->product != SDMMC_PRODUCT_INVALID) 316 printf("product 0x%x", cis->product); 317 printf(")"); 318 } 319 printf("%sat %s", i ? " " : "", pnp); 320 } 321 printf(" function %d", sf->number); 322 323 if (!pnp) { 324 for (i = 0; i < 3 && cis->cis1_info[i]; i++) 325 printf("%s%s", i ? ", " : " \"", cis->cis1_info[i]); 326 if (i != 0) 327 printf("\""); 328 } 329 return UNCONF; 330 } 331 332 void 333 sdmmc_io_detach(struct sdmmc_softc *sc) 334 { 335 struct sdmmc_function *sf; 336 337 rw_assert_wrlock(&sc->sc_lock); 338 339 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) { 340 if (sf->child != NULL) { 341 config_detach(sf->child, DETACH_FORCE); 342 sf->child = NULL; 343 } 344 } 345 346 KASSERT(TAILQ_EMPTY(&sc->sc_intrq)); 347 } 348 349 int 350 sdmmc_io_rw_direct(struct sdmmc_softc *sc, struct sdmmc_function *sf, 351 int reg, u_char *datap, int arg) 352 { 353 struct sdmmc_command cmd; 354 int error; 355 356 rw_assert_wrlock(&sc->sc_lock); 357 358 /* Make sure the card is selected. */ 359 if ((error = sdmmc_select_card(sc, sf)) != 0) { 360 rw_exit(&sc->sc_lock); 361 return error; 362 } 363 364 arg |= ((sf == NULL ? 0 : sf->number) & SD_ARG_CMD52_FUNC_MASK) << 365 SD_ARG_CMD52_FUNC_SHIFT; 366 arg |= (reg & SD_ARG_CMD52_REG_MASK) << 367 SD_ARG_CMD52_REG_SHIFT; 368 arg |= (*datap & SD_ARG_CMD52_DATA_MASK) << 369 SD_ARG_CMD52_DATA_SHIFT; 370 371 bzero(&cmd, sizeof cmd); 372 cmd.c_opcode = SD_IO_RW_DIRECT; 373 cmd.c_arg = arg; 374 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5; 375 376 error = sdmmc_mmc_command(sc, &cmd); 377 *datap = SD_R5_DATA(cmd.c_resp); 378 379 return error; 380 } 381 382 /* 383 * Useful values of `arg' to pass in are either SD_ARG_CMD53_READ or 384 * SD_ARG_CMD53_WRITE. SD_ARG_CMD53_INCREMENT may be ORed into `arg' 385 * to access successive register locations instead of accessing the 386 * same register many times. 387 */ 388 int 389 sdmmc_io_rw_extended(struct sdmmc_softc *sc, struct sdmmc_function *sf, 390 int reg, u_char *datap, int datalen, int arg) 391 { 392 struct sdmmc_command cmd; 393 int error; 394 395 rw_assert_wrlock(&sc->sc_lock); 396 397 #if 0 398 /* Make sure the card is selected. */ 399 if ((error = sdmmc_select_card(sc, sf)) != 0) { 400 rw_exit(&sc->sc_lock); 401 return error; 402 } 403 #endif 404 405 arg |= ((sf == NULL ? 0 : sf->number) & SD_ARG_CMD53_FUNC_MASK) << 406 SD_ARG_CMD53_FUNC_SHIFT; 407 arg |= (reg & SD_ARG_CMD53_REG_MASK) << 408 SD_ARG_CMD53_REG_SHIFT; 409 arg |= (datalen & SD_ARG_CMD53_LENGTH_MASK) << 410 SD_ARG_CMD53_LENGTH_SHIFT; 411 412 bzero(&cmd, sizeof cmd); 413 cmd.c_opcode = SD_IO_RW_EXTENDED; 414 cmd.c_arg = arg; 415 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5; 416 cmd.c_data = datap; 417 cmd.c_datalen = datalen; 418 cmd.c_blklen = MIN(datalen, sdmmc_chip_host_maxblklen(sc->sct, sc->sch)); 419 420 if (!ISSET(arg, SD_ARG_CMD53_WRITE)) 421 cmd.c_flags |= SCF_CMD_READ; 422 423 error = sdmmc_mmc_command(sc, &cmd); 424 425 return error; 426 } 427 428 u_int8_t 429 sdmmc_io_read_1(struct sdmmc_function *sf, int reg) 430 { 431 u_int8_t data = 0; 432 433 rw_assert_wrlock(&sf->sc->sc_lock); 434 435 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, 436 SD_ARG_CMD52_READ); 437 return data; 438 } 439 440 void 441 sdmmc_io_write_1(struct sdmmc_function *sf, int reg, u_int8_t data) 442 { 443 rw_assert_wrlock(&sf->sc->sc_lock); 444 445 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, 446 SD_ARG_CMD52_WRITE); 447 } 448 449 u_int16_t 450 sdmmc_io_read_2(struct sdmmc_function *sf, int reg) 451 { 452 u_int16_t data = 0; 453 454 rw_assert_wrlock(&sf->sc->sc_lock); 455 456 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2, 457 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT); 458 return data; 459 } 460 461 void 462 sdmmc_io_write_2(struct sdmmc_function *sf, int reg, u_int16_t data) 463 { 464 rw_assert_wrlock(&sf->sc->sc_lock); 465 466 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2, 467 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT); 468 } 469 470 u_int32_t 471 sdmmc_io_read_4(struct sdmmc_function *sf, int reg) 472 { 473 u_int32_t data = 0; 474 475 rw_assert_wrlock(&sf->sc->sc_lock); 476 477 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4, 478 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT); 479 return data; 480 } 481 482 void 483 sdmmc_io_write_4(struct sdmmc_function *sf, int reg, u_int32_t data) 484 { 485 rw_assert_wrlock(&sf->sc->sc_lock); 486 487 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4, 488 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT); 489 } 490 491 int 492 sdmmc_io_read_multi_1(struct sdmmc_function *sf, int reg, u_char *data, 493 int datalen) 494 { 495 int error; 496 497 rw_assert_wrlock(&sf->sc->sc_lock); 498 499 while (datalen > SD_ARG_CMD53_LENGTH_MAX) { 500 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, 501 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_READ); 502 if (error) 503 return error; 504 data += SD_ARG_CMD53_LENGTH_MAX; 505 datalen -= SD_ARG_CMD53_LENGTH_MAX; 506 } 507 508 return sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen, 509 SD_ARG_CMD53_READ); 510 } 511 512 int 513 sdmmc_io_write_multi_1(struct sdmmc_function *sf, int reg, u_char *data, 514 int datalen) 515 { 516 int error; 517 518 rw_assert_wrlock(&sf->sc->sc_lock); 519 520 while (datalen > SD_ARG_CMD53_LENGTH_MAX) { 521 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, 522 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_WRITE); 523 if (error) 524 return error; 525 data += SD_ARG_CMD53_LENGTH_MAX; 526 datalen -= SD_ARG_CMD53_LENGTH_MAX; 527 } 528 529 return sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen, 530 SD_ARG_CMD53_WRITE); 531 } 532 533 int 534 sdmmc_io_xchg(struct sdmmc_softc *sc, struct sdmmc_function *sf, 535 int reg, u_char *datap) 536 { 537 538 rw_assert_wrlock(&sc->sc_lock); 539 540 return sdmmc_io_rw_direct(sc, sf, reg, datap, 541 SD_ARG_CMD52_WRITE|SD_ARG_CMD52_EXCHANGE); 542 } 543 544 /* 545 * Reset the I/O functions of the card. 546 */ 547 void 548 sdmmc_io_reset(struct sdmmc_softc *sc) 549 { 550 u_int8_t data = CCCR_CTL_RES; 551 552 rw_assert_wrlock(&sc->sc_lock); 553 554 if (sdmmc_io_rw_direct(sc, NULL, SD_IO_CCCR_CTL, (u_char *)&data, 555 SD_ARG_CMD52_WRITE) == 0) 556 sdmmc_delay(100000); 557 } 558 559 /* 560 * Get or set the card's I/O OCR value (SDIO). 561 */ 562 int 563 sdmmc_io_send_op_cond(struct sdmmc_softc *sc, u_int32_t ocr, u_int32_t *ocrp) 564 { 565 struct sdmmc_command cmd; 566 int error; 567 int i; 568 569 rw_assert_wrlock(&sc->sc_lock); 570 571 /* 572 * If we change the OCR value, retry the command until the OCR 573 * we receive in response has the "CARD BUSY" bit set, meaning 574 * that all cards are ready for identification. 575 */ 576 for (i = 0; i < 100; i++) { 577 bzero(&cmd, sizeof cmd); 578 cmd.c_opcode = SD_IO_SEND_OP_COND; 579 cmd.c_arg = ocr; 580 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R4; 581 582 error = sdmmc_mmc_command(sc, &cmd); 583 if (error != 0) 584 break; 585 if (ISSET(MMC_R4(cmd.c_resp), SD_IO_OCR_MEM_READY) || 586 ocr == 0) 587 break; 588 error = ETIMEDOUT; 589 sdmmc_delay(10000); 590 } 591 if (error == 0 && ocrp != NULL) 592 *ocrp = MMC_R4(cmd.c_resp); 593 594 return error; 595 } 596 597 /* 598 * Card interrupt handling 599 */ 600 601 void 602 sdmmc_intr_enable(struct sdmmc_function *sf) 603 { 604 struct sdmmc_softc *sc = sf->sc; 605 struct sdmmc_function *sf0 = sc->sc_fn0; 606 u_int8_t imask; 607 608 rw_enter_write(&sc->sc_lock); 609 imask = sdmmc_io_read_1(sf0, SD_IO_CCCR_INT_ENABLE); 610 imask |= 1 << sf->number; 611 sdmmc_io_write_1(sf0, SD_IO_CCCR_INT_ENABLE, imask); 612 rw_exit(&sc->sc_lock); 613 } 614 615 void 616 sdmmc_intr_disable(struct sdmmc_function *sf) 617 { 618 struct sdmmc_softc *sc = sf->sc; 619 struct sdmmc_function *sf0 = sc->sc_fn0; 620 u_int8_t imask; 621 622 rw_enter_write(&sc->sc_lock); 623 imask = sdmmc_io_read_1(sf0, SD_IO_CCCR_INT_ENABLE); 624 imask &= ~(1 << sf->number); 625 sdmmc_io_write_1(sf0, SD_IO_CCCR_INT_ENABLE, imask); 626 rw_exit(&sc->sc_lock); 627 } 628 629 /* 630 * Establish a handler for the SDIO card interrupt. Because the 631 * interrupt may be shared with different SDIO functions, multiple 632 * handlers can be established. 633 */ 634 void * 635 sdmmc_intr_establish(struct device *sdmmc, int (*fun)(void *), 636 void *arg, const char *name) 637 { 638 struct sdmmc_softc *sc = (struct sdmmc_softc *)sdmmc; 639 struct sdmmc_intr_handler *ih; 640 int s; 641 642 if (sc->sct->card_intr_mask == NULL) 643 return NULL; 644 645 ih = malloc(sizeof *ih, M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO); 646 if (ih == NULL) 647 return NULL; 648 649 ih->ih_name = name; 650 ih->ih_softc = sc; 651 ih->ih_fun = fun; 652 ih->ih_arg = arg; 653 654 s = splhigh(); 655 if (TAILQ_EMPTY(&sc->sc_intrq)) { 656 sdmmc_intr_enable(sc->sc_fn0); 657 sdmmc_chip_card_intr_mask(sc->sct, sc->sch, 1); 658 } 659 TAILQ_INSERT_TAIL(&sc->sc_intrq, ih, entry); 660 splx(s); 661 return ih; 662 } 663 664 /* 665 * Disestablish the given handler. 666 */ 667 void 668 sdmmc_intr_disestablish(void *cookie) 669 { 670 struct sdmmc_intr_handler *ih = cookie; 671 struct sdmmc_softc *sc = ih->ih_softc; 672 int s; 673 674 if (sc->sct->card_intr_mask == NULL) 675 return; 676 677 s = splhigh(); 678 TAILQ_REMOVE(&sc->sc_intrq, ih, entry); 679 if (TAILQ_EMPTY(&sc->sc_intrq)) { 680 sdmmc_chip_card_intr_mask(sc->sct, sc->sch, 0); 681 sdmmc_intr_disable(sc->sc_fn0); 682 } 683 splx(s); 684 685 free(ih, M_DEVBUF, 0); 686 } 687 688 /* 689 * Call established SDIO card interrupt handlers. The host controller 690 * must call this function from its own interrupt handler to handle an 691 * SDIO interrupt from the card. 692 */ 693 void 694 sdmmc_card_intr(struct device *sdmmc) 695 { 696 struct sdmmc_softc *sc = (struct sdmmc_softc *)sdmmc; 697 698 if (sc->sct->card_intr_mask == NULL) 699 return; 700 701 if (!sdmmc_task_pending(&sc->sc_intr_task)) 702 sdmmc_add_task(sc, &sc->sc_intr_task); 703 } 704 705 void 706 sdmmc_intr_task(void *arg) 707 { 708 struct sdmmc_softc *sc = arg; 709 struct sdmmc_intr_handler *ih; 710 int s; 711 712 s = splhigh(); 713 TAILQ_FOREACH(ih, &sc->sc_intrq, entry) { 714 splx(s); 715 716 /* XXX examine return value and do evcount stuff*/ 717 (void)ih->ih_fun(ih->ih_arg); 718 719 s = splhigh(); 720 } 721 sdmmc_chip_card_intr_ack(sc->sct, sc->sch); 722 splx(s); 723 } 724