1 /* $OpenBSD: sdmmc_io.c,v 1.13 2009/04/07 16:35:52 blambert 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/kernel.h> 23 #include <sys/malloc.h> 24 #include <sys/proc.h> 25 #include <sys/systm.h> 26 27 #include <dev/sdmmc/sdmmc_ioreg.h> 28 #include <dev/sdmmc/sdmmcchip.h> 29 #include <dev/sdmmc/sdmmcreg.h> 30 #include <dev/sdmmc/sdmmcvar.h> 31 32 struct sdmmc_intr_handler { 33 struct sdmmc_softc *ih_softc; 34 char *ih_name; 35 int (*ih_fun)(void *); 36 void *ih_arg; 37 TAILQ_ENTRY(sdmmc_intr_handler) entry; 38 }; 39 40 int sdmmc_submatch(struct device *, void *, void *); 41 int sdmmc_print(void *, const char *); 42 int sdmmc_io_rw_direct(struct sdmmc_softc *, struct sdmmc_function *, 43 int, u_char *, int); 44 int sdmmc_io_rw_extended(struct sdmmc_softc *, struct sdmmc_function *, 45 int, u_char *, int, int); 46 int sdmmc_io_xchg(struct sdmmc_softc *, struct sdmmc_function *, 47 int, u_char *); 48 void sdmmc_io_reset(struct sdmmc_softc *); 49 int sdmmc_io_send_op_cond(struct sdmmc_softc *, u_int32_t, u_int32_t *); 50 51 #ifdef SDMMC_DEBUG 52 #define DPRINTF(s) printf s 53 #else 54 #define DPRINTF(s) /**/ 55 #endif 56 57 #ifdef SDMMC_DEBUG 58 int sdmmc_verbose = 1; 59 #else 60 int sdmmc_verbose = 0; 61 #endif 62 63 /* 64 * Initialize SD I/O card functions (before memory cards). The host 65 * system and controller must support card interrupts in order to use 66 * I/O functions. 67 */ 68 int 69 sdmmc_io_enable(struct sdmmc_softc *sc) 70 { 71 u_int32_t host_ocr; 72 u_int32_t card_ocr; 73 74 SDMMC_ASSERT_LOCKED(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 if (sdmmc_io_send_op_cond(sc, 0, &card_ocr) != 0) { 89 /* No SDIO card; switch to SD memory-only mode. */ 90 CLR(sc->sc_flags, SMF_IO_MODE); 91 return 0; 92 } 93 94 /* Parse the additional bits in the I/O OCR value. */ 95 if (!ISSET(card_ocr, SD_IO_OCR_MEM_PRESENT)) { 96 /* SDIO card without memory (not a "combo card"). */ 97 DPRINTF(("%s: no memory present\n", SDMMCDEVNAME(sc))); 98 CLR(sc->sc_flags, SMF_MEM_MODE); 99 } 100 sc->sc_function_count = SD_IO_OCR_NUM_FUNCTIONS(card_ocr); 101 if (sc->sc_function_count == 0) { 102 /* Useless SDIO card without any I/O functions. */ 103 DPRINTF(("%s: no I/O functions\n", SDMMCDEVNAME(sc))); 104 CLR(sc->sc_flags, SMF_IO_MODE); 105 return 0; 106 } 107 card_ocr &= SD_IO_OCR_MASK; 108 109 /* Set the lowest voltage supported by the card and host. */ 110 host_ocr = sdmmc_chip_host_ocr(sc->sct, sc->sch); 111 if (sdmmc_set_bus_power(sc, host_ocr, card_ocr) != 0) { 112 printf("%s: can't supply voltage requested by card\n", 113 SDMMCDEVNAME(sc)); 114 return 1; 115 } 116 117 /* Reset I/O functions (again). */ 118 sdmmc_io_reset(sc); 119 120 /* Send the new OCR value until all cards are ready. */ 121 if (sdmmc_io_send_op_cond(sc, host_ocr, NULL) != 0) { 122 printf("%s: can't send I/O OCR\n", SDMMCDEVNAME(sc)); 123 return 1; 124 } 125 return 0; 126 } 127 128 /* 129 * Allocate sdmmc_function structures for SD card I/O function 130 * (including function 0). 131 */ 132 void 133 sdmmc_io_scan(struct sdmmc_softc *sc) 134 { 135 struct sdmmc_function *sf0, *sf; 136 int i; 137 138 SDMMC_ASSERT_LOCKED(sc); 139 140 sf0 = sdmmc_function_alloc(sc); 141 sf0->number = 0; 142 if (sdmmc_set_relative_addr(sc, sf0) != 0) { 143 printf("%s: can't set I/O RCA\n", SDMMCDEVNAME(sc)); 144 SET(sf0->flags, SFF_ERROR); 145 return; 146 } 147 sc->sc_fn0 = sf0; 148 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf0, sf_list); 149 150 /* Verify that the RCA has been set by selecting the card. */ 151 if (sdmmc_select_card(sc, sf0) != 0) { 152 printf("%s: can't select I/O RCA %d\n", SDMMCDEVNAME(sc), 153 sf0->rca); 154 SET(sf0->flags, SFF_ERROR); 155 return; 156 } 157 158 for (i = 1; i <= sc->sc_function_count; i++) { 159 sf = sdmmc_function_alloc(sc); 160 sf->number = i; 161 sf->rca = sf0->rca; 162 163 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list); 164 } 165 } 166 167 /* 168 * Initialize SDIO card functions. 169 */ 170 int 171 sdmmc_io_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) 172 { 173 SDMMC_ASSERT_LOCKED(sc); 174 175 if (sf->number == 0) { 176 sdmmc_io_write_1(sf, SD_IO_CCCR_BUS_WIDTH, 177 CCCR_BUS_WIDTH_1); 178 179 if (sdmmc_read_cis(sf, &sf->cis) != 0) { 180 printf("%s: can't read CIS\n", SDMMCDEVNAME(sc)); 181 SET(sf->flags, SFF_ERROR); 182 return 1; 183 } 184 185 sdmmc_check_cis_quirks(sf); 186 187 if (sdmmc_verbose) 188 sdmmc_print_cis(sf); 189 } 190 return 0; 191 } 192 193 /* 194 * Indicate whether the function is ready to operate. 195 */ 196 int 197 sdmmc_io_function_ready(struct sdmmc_function *sf) 198 { 199 struct sdmmc_softc *sc = sf->sc; 200 struct sdmmc_function *sf0 = sc->sc_fn0; 201 u_int8_t rv; 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 return (rv & (1 << sf->number)) != 0; 208 } 209 210 /* 211 * Enable the I/O function. Return zero if the function was 212 * enabled successfully. 213 */ 214 int 215 sdmmc_io_function_enable(struct sdmmc_function *sf) 216 { 217 struct sdmmc_softc *sc = sf->sc; 218 struct sdmmc_function *sf0 = sc->sc_fn0; 219 u_int8_t rv; 220 int retry = 5; 221 222 if (sf->number == 0) 223 return 0; /* FN0 is always enabled */ 224 225 SDMMC_LOCK(sc); 226 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE); 227 rv |= (1<<sf->number); 228 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, rv); 229 SDMMC_UNLOCK(sc); 230 231 while (!sdmmc_io_function_ready(sf) && retry-- > 0) 232 tsleep(&lbolt, PPAUSE, "pause", 0); 233 return (retry >= 0) ? 0 : ETIMEDOUT; 234 } 235 236 /* 237 * Disable the I/O function. Return zero if the function was 238 * disabled successfully. 239 */ 240 void 241 sdmmc_io_function_disable(struct sdmmc_function *sf) 242 { 243 struct sdmmc_softc *sc = sf->sc; 244 struct sdmmc_function *sf0 = sc->sc_fn0; 245 u_int8_t rv; 246 247 if (sf->number == 0) 248 return; /* FN0 is always enabled */ 249 250 SDMMC_LOCK(sc); 251 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE); 252 rv &= ~(1<<sf->number); 253 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, rv); 254 SDMMC_UNLOCK(sc); 255 } 256 257 void 258 sdmmc_io_attach(struct sdmmc_softc *sc) 259 { 260 struct sdmmc_function *sf; 261 struct sdmmc_attach_args saa; 262 263 SDMMC_ASSERT_LOCKED(sc); 264 265 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) { 266 if (sf->number < 1) 267 continue; 268 269 bzero(&saa, sizeof saa); 270 saa.sf = sf; 271 272 sf->child = config_found_sm(&sc->sc_dev, &saa, sdmmc_print, 273 sdmmc_submatch); 274 } 275 } 276 277 int 278 sdmmc_submatch(struct device *parent, void *match, void *aux) 279 { 280 struct cfdata *cf = match; 281 282 /* Skip the scsibus, it is configured directly. */ 283 if (strcmp(cf->cf_driver->cd_name, "scsibus") == 0) 284 return 0; 285 286 return cf->cf_attach->ca_match(parent, cf, aux); 287 } 288 289 int 290 sdmmc_print(void *aux, const char *pnp) 291 { 292 struct sdmmc_attach_args *sa = aux; 293 struct sdmmc_function *sf = sa->sf; 294 struct sdmmc_cis *cis = &sf->sc->sc_fn0->cis; 295 int i; 296 297 if (pnp) { 298 if (sf->number == 0) 299 return QUIET; 300 301 for (i = 0; i < 4 && cis->cis1_info[i]; i++) 302 printf("%s%s", i ? ", " : "\"", cis->cis1_info[i]); 303 if (i != 0) 304 printf("\""); 305 306 if (cis->manufacturer != SDMMC_VENDOR_INVALID && 307 cis->product != SDMMC_PRODUCT_INVALID) { 308 printf("%s(", i ? " " : ""); 309 if (cis->manufacturer != SDMMC_VENDOR_INVALID) 310 printf("manufacturer 0x%x%s", 311 cis->manufacturer, 312 cis->product == SDMMC_PRODUCT_INVALID ? 313 "" : ", "); 314 if (cis->product != SDMMC_PRODUCT_INVALID) 315 printf("product 0x%x", cis->product); 316 printf(")"); 317 } 318 printf("%sat %s", i ? " " : "", pnp); 319 } 320 printf(" function %d", sf->number); 321 322 if (!pnp) { 323 for (i = 0; i < 3 && cis->cis1_info[i]; i++) 324 printf("%s%s", i ? ", " : " \"", cis->cis1_info[i]); 325 if (i != 0) 326 printf("\""); 327 } 328 return UNCONF; 329 } 330 331 void 332 sdmmc_io_detach(struct sdmmc_softc *sc) 333 { 334 struct sdmmc_function *sf; 335 336 SDMMC_ASSERT_LOCKED(sc); 337 338 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) { 339 if (sf->child != NULL) { 340 config_detach(sf->child, DETACH_FORCE); 341 sf->child = NULL; 342 } 343 } 344 345 KASSERT(TAILQ_EMPTY(&sc->sc_intrq)); 346 } 347 348 int 349 sdmmc_io_rw_direct(struct sdmmc_softc *sc, struct sdmmc_function *sf, 350 int reg, u_char *datap, int arg) 351 { 352 struct sdmmc_command cmd; 353 int error; 354 355 SDMMC_LOCK(sc); 356 357 /* Make sure the card is selected. */ 358 if ((error = sdmmc_select_card(sc, sf)) != 0) { 359 SDMMC_UNLOCK(sc); 360 return error; 361 } 362 363 arg |= ((sf == NULL ? 0 : sf->number) & SD_ARG_CMD52_FUNC_MASK) << 364 SD_ARG_CMD52_FUNC_SHIFT; 365 arg |= (reg & SD_ARG_CMD52_REG_MASK) << 366 SD_ARG_CMD52_REG_SHIFT; 367 arg |= (*datap & SD_ARG_CMD52_DATA_MASK) << 368 SD_ARG_CMD52_DATA_SHIFT; 369 370 bzero(&cmd, sizeof cmd); 371 cmd.c_opcode = SD_IO_RW_DIRECT; 372 cmd.c_arg = arg; 373 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5; 374 375 error = sdmmc_mmc_command(sc, &cmd); 376 *datap = SD_R5_DATA(cmd.c_resp); 377 378 SDMMC_UNLOCK(sc); 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 SDMMC_LOCK(sc); 396 397 #if 0 398 /* Make sure the card is selected. */ 399 if ((error = sdmmc_select_card(sc, sf)) != 0) { 400 SDMMC_UNLOCK(sc); 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 SDMMC_UNLOCK(sc); 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 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, 434 SD_ARG_CMD52_READ); 435 return data; 436 } 437 438 void 439 sdmmc_io_write_1(struct sdmmc_function *sf, int reg, u_int8_t data) 440 { 441 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, 442 SD_ARG_CMD52_WRITE); 443 } 444 445 u_int16_t 446 sdmmc_io_read_2(struct sdmmc_function *sf, int reg) 447 { 448 u_int16_t data = 0; 449 450 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2, 451 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT); 452 return data; 453 } 454 455 void 456 sdmmc_io_write_2(struct sdmmc_function *sf, int reg, u_int16_t data) 457 { 458 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2, 459 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT); 460 } 461 462 u_int32_t 463 sdmmc_io_read_4(struct sdmmc_function *sf, int reg) 464 { 465 u_int32_t data = 0; 466 467 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4, 468 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT); 469 return data; 470 } 471 472 void 473 sdmmc_io_write_4(struct sdmmc_function *sf, int reg, u_int32_t data) 474 { 475 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4, 476 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT); 477 } 478 479 int 480 sdmmc_io_read_multi_1(struct sdmmc_function *sf, int reg, u_char *data, 481 int datalen) 482 { 483 int error; 484 485 while (datalen > SD_ARG_CMD53_LENGTH_MAX) { 486 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, 487 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_READ); 488 if (error) 489 return error; 490 data += SD_ARG_CMD53_LENGTH_MAX; 491 datalen -= SD_ARG_CMD53_LENGTH_MAX; 492 } 493 494 return sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen, 495 SD_ARG_CMD53_READ); 496 } 497 498 int 499 sdmmc_io_write_multi_1(struct sdmmc_function *sf, int reg, u_char *data, 500 int datalen) 501 { 502 int error; 503 504 while (datalen > SD_ARG_CMD53_LENGTH_MAX) { 505 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, 506 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_WRITE); 507 if (error) 508 return error; 509 data += SD_ARG_CMD53_LENGTH_MAX; 510 datalen -= SD_ARG_CMD53_LENGTH_MAX; 511 } 512 513 return sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen, 514 SD_ARG_CMD53_WRITE); 515 } 516 517 int 518 sdmmc_io_xchg(struct sdmmc_softc *sc, struct sdmmc_function *sf, 519 int reg, u_char *datap) 520 { 521 return sdmmc_io_rw_direct(sc, sf, reg, datap, 522 SD_ARG_CMD52_WRITE|SD_ARG_CMD52_EXCHANGE); 523 } 524 525 /* 526 * Reset the I/O functions of the card. 527 */ 528 void 529 sdmmc_io_reset(struct sdmmc_softc *sc) 530 { 531 #if 0 /* XXX command fails */ 532 (void)sdmmc_io_write(sc, NULL, SD_IO_REG_CCCR_CTL, CCCR_CTL_RES); 533 sdmmc_delay(100000); 534 #endif 535 } 536 537 /* 538 * Get or set the card's I/O OCR value (SDIO). 539 */ 540 int 541 sdmmc_io_send_op_cond(struct sdmmc_softc *sc, u_int32_t ocr, u_int32_t *ocrp) 542 { 543 struct sdmmc_command cmd; 544 int error; 545 int i; 546 547 SDMMC_ASSERT_LOCKED(sc); 548 549 /* 550 * If we change the OCR value, retry the command until the OCR 551 * we receive in response has the "CARD BUSY" bit set, meaning 552 * that all cards are ready for identification. 553 */ 554 for (i = 0; i < 100; i++) { 555 bzero(&cmd, sizeof cmd); 556 cmd.c_opcode = SD_IO_SEND_OP_COND; 557 cmd.c_arg = ocr; 558 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R4; 559 560 error = sdmmc_mmc_command(sc, &cmd); 561 if (error != 0) 562 break; 563 if (ISSET(MMC_R4(cmd.c_resp), SD_IO_OCR_MEM_READY) || 564 ocr == 0) 565 break; 566 error = ETIMEDOUT; 567 sdmmc_delay(10000); 568 } 569 if (error == 0 && ocrp != NULL) 570 *ocrp = MMC_R4(cmd.c_resp); 571 572 return error; 573 } 574 575 /* 576 * Card interrupt handling 577 */ 578 579 void 580 sdmmc_intr_enable(struct sdmmc_function *sf) 581 { 582 struct sdmmc_softc *sc = sf->sc; 583 struct sdmmc_function *sf0 = sc->sc_fn0; 584 u_int8_t imask; 585 586 SDMMC_LOCK(sc); 587 imask = sdmmc_io_read_1(sf0, SD_IO_CCCR_INT_ENABLE); 588 imask |= 1 << sf->number; 589 sdmmc_io_write_1(sf0, SD_IO_CCCR_INT_ENABLE, imask); 590 SDMMC_UNLOCK(sc); 591 } 592 593 void 594 sdmmc_intr_disable(struct sdmmc_function *sf) 595 { 596 struct sdmmc_softc *sc = sf->sc; 597 struct sdmmc_function *sf0 = sc->sc_fn0; 598 u_int8_t imask; 599 600 SDMMC_LOCK(sc); 601 imask = sdmmc_io_read_1(sf0, SD_IO_CCCR_INT_ENABLE); 602 imask &= ~(1 << sf->number); 603 sdmmc_io_write_1(sf0, SD_IO_CCCR_INT_ENABLE, imask); 604 SDMMC_UNLOCK(sc); 605 } 606 607 /* 608 * Establish a handler for the SDIO card interrupt. Because the 609 * interrupt may be shared with different SDIO functions, multiple 610 * handlers can be established. 611 */ 612 void * 613 sdmmc_intr_establish(struct device *sdmmc, int (*fun)(void *), 614 void *arg, const char *name) 615 { 616 struct sdmmc_softc *sc = (struct sdmmc_softc *)sdmmc; 617 struct sdmmc_intr_handler *ih; 618 int s; 619 620 if (sc->sct->card_intr_mask == NULL) 621 return NULL; 622 623 ih = malloc(sizeof *ih, M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO); 624 if (ih == NULL) 625 return NULL; 626 627 ih->ih_name = malloc(strlen(name), M_DEVBUF, M_WAITOK | M_CANFAIL); 628 if (ih->ih_name == NULL) { 629 free(ih, M_DEVBUF); 630 return NULL; 631 } 632 strlcpy(ih->ih_name, name, strlen(name)); 633 ih->ih_softc = sc; 634 ih->ih_fun = fun; 635 ih->ih_arg = arg; 636 637 s = splhigh(); 638 if (TAILQ_EMPTY(&sc->sc_intrq)) { 639 sdmmc_intr_enable(sc->sc_fn0); 640 sdmmc_chip_card_intr_mask(sc->sct, sc->sch, 1); 641 } 642 TAILQ_INSERT_TAIL(&sc->sc_intrq, ih, entry); 643 splx(s); 644 return ih; 645 } 646 647 /* 648 * Disestablish the given handler. 649 */ 650 void 651 sdmmc_intr_disestablish(void *cookie) 652 { 653 struct sdmmc_intr_handler *ih = cookie; 654 struct sdmmc_softc *sc = ih->ih_softc; 655 int s; 656 657 if (sc->sct->card_intr_mask == NULL) 658 return; 659 660 s = splhigh(); 661 TAILQ_REMOVE(&sc->sc_intrq, ih, entry); 662 if (TAILQ_EMPTY(&sc->sc_intrq)) { 663 sdmmc_chip_card_intr_mask(sc->sct, sc->sch, 0); 664 sdmmc_intr_disable(sc->sc_fn0); 665 } 666 splx(s); 667 668 free(ih->ih_name, M_DEVBUF); 669 free(ih, M_DEVBUF); 670 } 671 672 /* 673 * Call established SDIO card interrupt handlers. The host controller 674 * must call this function from its own interrupt handler to handle an 675 * SDIO interrupt from the card. 676 */ 677 void 678 sdmmc_card_intr(struct device *sdmmc) 679 { 680 struct sdmmc_softc *sc = (struct sdmmc_softc *)sdmmc; 681 682 if (sc->sct->card_intr_mask == NULL) 683 return; 684 685 if (!sdmmc_task_pending(&sc->sc_intr_task)) 686 sdmmc_add_task(sc, &sc->sc_intr_task); 687 } 688 689 void 690 sdmmc_intr_task(void *arg) 691 { 692 struct sdmmc_softc *sc = arg; 693 struct sdmmc_intr_handler *ih; 694 int s; 695 696 s = splhigh(); 697 TAILQ_FOREACH(ih, &sc->sc_intrq, entry) { 698 splx(s); 699 700 /* XXX examine return value and do evcount stuff*/ 701 (void)ih->ih_fun(ih->ih_arg); 702 703 s = splhigh(); 704 } 705 sdmmc_chip_card_intr_ack(sc->sct, sc->sch); 706 splx(s); 707 } 708