1 /* $OpenBSD: sdmmc_io.c,v 1.17 2009/11/11 21:59:16 jasper 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/proc.h> 26 #include <sys/systm.h> 27 28 #include <dev/sdmmc/sdmmc_ioreg.h> 29 #include <dev/sdmmc/sdmmcchip.h> 30 #include <dev/sdmmc/sdmmcreg.h> 31 #include <dev/sdmmc/sdmmcvar.h> 32 33 struct sdmmc_intr_handler { 34 struct sdmmc_softc *ih_softc; 35 const char *ih_name; 36 int (*ih_fun)(void *); 37 void *ih_arg; 38 TAILQ_ENTRY(sdmmc_intr_handler) entry; 39 }; 40 41 int sdmmc_submatch(struct device *, void *, void *); 42 int sdmmc_print(void *, const char *); 43 int sdmmc_io_rw_direct(struct sdmmc_softc *, struct sdmmc_function *, 44 int, u_char *, int); 45 int sdmmc_io_rw_extended(struct sdmmc_softc *, struct sdmmc_function *, 46 int, u_char *, int, int); 47 int sdmmc_io_xchg(struct sdmmc_softc *, struct sdmmc_function *, 48 int, u_char *); 49 void sdmmc_io_reset(struct sdmmc_softc *); 50 int sdmmc_io_send_op_cond(struct sdmmc_softc *, u_int32_t, u_int32_t *); 51 52 #ifdef SDMMC_DEBUG 53 #define DPRINTF(s) printf s 54 #else 55 #define DPRINTF(s) /**/ 56 #endif 57 58 #ifdef SDMMC_DEBUG 59 int sdmmc_verbose = 1; 60 #else 61 int sdmmc_verbose = 0; 62 #endif 63 64 /* 65 * Initialize SD I/O card functions (before memory cards). The host 66 * system and controller must support card interrupts in order to use 67 * I/O functions. 68 */ 69 int 70 sdmmc_io_enable(struct sdmmc_softc *sc) 71 { 72 u_int32_t host_ocr; 73 u_int32_t card_ocr; 74 75 SDMMC_ASSERT_LOCKED(sc); 76 77 /* Set host mode to SD "combo" card. */ 78 SET(sc->sc_flags, SMF_SD_MODE|SMF_IO_MODE|SMF_MEM_MODE); 79 80 /* Reset I/O functions. */ 81 sdmmc_io_reset(sc); 82 83 /* 84 * Read the I/O OCR value, determine the number of I/O 85 * functions and whether memory is also present (a "combo 86 * card") by issuing CMD5. SD memory-only and MMC cards 87 * do not respond to CMD5. 88 */ 89 if (sdmmc_io_send_op_cond(sc, 0, &card_ocr) != 0) { 90 /* No SDIO card; switch to SD memory-only mode. */ 91 CLR(sc->sc_flags, SMF_IO_MODE); 92 return 0; 93 } 94 95 /* Parse the additional bits in the I/O OCR value. */ 96 if (!ISSET(card_ocr, SD_IO_OCR_MEM_PRESENT)) { 97 /* SDIO card without memory (not a "combo card"). */ 98 DPRINTF(("%s: no memory present\n", SDMMCDEVNAME(sc))); 99 CLR(sc->sc_flags, SMF_MEM_MODE); 100 } 101 sc->sc_function_count = SD_IO_OCR_NUM_FUNCTIONS(card_ocr); 102 if (sc->sc_function_count == 0) { 103 /* Useless SDIO card without any I/O functions. */ 104 DPRINTF(("%s: no I/O functions\n", SDMMCDEVNAME(sc))); 105 CLR(sc->sc_flags, SMF_IO_MODE); 106 return 0; 107 } 108 card_ocr &= SD_IO_OCR_MASK; 109 110 /* Set the lowest voltage supported by the card and host. */ 111 host_ocr = sdmmc_chip_host_ocr(sc->sct, sc->sch); 112 if (sdmmc_set_bus_power(sc, host_ocr, card_ocr) != 0) { 113 printf("%s: can't supply voltage requested by card\n", 114 SDMMCDEVNAME(sc)); 115 return 1; 116 } 117 118 /* Reset I/O functions (again). */ 119 sdmmc_io_reset(sc); 120 121 /* Send the new OCR value until all cards are ready. */ 122 if (sdmmc_io_send_op_cond(sc, host_ocr, NULL) != 0) { 123 printf("%s: can't send I/O OCR\n", SDMMCDEVNAME(sc)); 124 return 1; 125 } 126 return 0; 127 } 128 129 /* 130 * Allocate sdmmc_function structures for SD card I/O function 131 * (including function 0). 132 */ 133 void 134 sdmmc_io_scan(struct sdmmc_softc *sc) 135 { 136 struct sdmmc_function *sf0, *sf; 137 int i; 138 139 SDMMC_ASSERT_LOCKED(sc); 140 141 sf0 = sdmmc_function_alloc(sc); 142 sf0->number = 0; 143 if (sdmmc_set_relative_addr(sc, sf0) != 0) { 144 printf("%s: can't set I/O RCA\n", SDMMCDEVNAME(sc)); 145 SET(sf0->flags, SFF_ERROR); 146 return; 147 } 148 sc->sc_fn0 = sf0; 149 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf0, sf_list); 150 151 /* Verify that the RCA has been set by selecting the card. */ 152 if (sdmmc_select_card(sc, sf0) != 0) { 153 printf("%s: can't select I/O RCA %d\n", SDMMCDEVNAME(sc), 154 sf0->rca); 155 SET(sf0->flags, SFF_ERROR); 156 return; 157 } 158 159 for (i = 1; i <= sc->sc_function_count; i++) { 160 sf = sdmmc_function_alloc(sc); 161 sf->number = i; 162 sf->rca = sf0->rca; 163 164 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list); 165 } 166 } 167 168 /* 169 * Initialize SDIO card functions. 170 */ 171 int 172 sdmmc_io_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) 173 { 174 SDMMC_ASSERT_LOCKED(sc); 175 176 if (sf->number == 0) { 177 sdmmc_io_write_1(sf, SD_IO_CCCR_BUS_WIDTH, 178 CCCR_BUS_WIDTH_1); 179 180 if (sdmmc_read_cis(sf, &sf->cis) != 0) { 181 printf("%s: can't read CIS\n", SDMMCDEVNAME(sc)); 182 SET(sf->flags, SFF_ERROR); 183 return 1; 184 } 185 186 sdmmc_check_cis_quirks(sf); 187 188 if (sdmmc_verbose) 189 sdmmc_print_cis(sf); 190 } 191 return 0; 192 } 193 194 /* 195 * Indicate whether the function is ready to operate. 196 */ 197 int 198 sdmmc_io_function_ready(struct sdmmc_function *sf) 199 { 200 struct sdmmc_softc *sc = sf->sc; 201 struct sdmmc_function *sf0 = sc->sc_fn0; 202 u_int8_t rv; 203 204 SDMMC_ASSERT_LOCKED(sc); 205 206 if (sf->number == 0) 207 return 1; /* FN0 is always ready */ 208 209 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_READY); 210 211 return (rv & (1 << sf->number)) != 0; 212 } 213 214 /* 215 * Enable the I/O function. Return zero if the function was 216 * enabled successfully. 217 */ 218 int 219 sdmmc_io_function_enable(struct sdmmc_function *sf) 220 { 221 struct sdmmc_softc *sc = sf->sc; 222 struct sdmmc_function *sf0 = sc->sc_fn0; 223 u_int8_t rv; 224 int retry = 5; 225 226 if (sf->number == 0) 227 return 0; /* FN0 is always enabled */ 228 229 SDMMC_LOCK(sc); 230 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE); 231 rv |= (1<<sf->number); 232 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, rv); 233 SDMMC_UNLOCK(sc); 234 235 while (!sdmmc_io_function_ready(sf) && retry-- > 0) 236 tsleep(&lbolt, PPAUSE, "pause", 0); 237 return (retry >= 0) ? 0 : ETIMEDOUT; 238 } 239 240 /* 241 * Disable the I/O function. Return zero if the function was 242 * disabled successfully. 243 */ 244 void 245 sdmmc_io_function_disable(struct sdmmc_function *sf) 246 { 247 struct sdmmc_softc *sc = sf->sc; 248 struct sdmmc_function *sf0 = sc->sc_fn0; 249 u_int8_t rv; 250 251 SDMMC_ASSERT_LOCKED(sc); 252 253 if (sf->number == 0) 254 return; /* FN0 is always enabled */ 255 256 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE); 257 rv &= ~(1<<sf->number); 258 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, rv); 259 } 260 261 void 262 sdmmc_io_attach(struct sdmmc_softc *sc) 263 { 264 struct sdmmc_function *sf; 265 struct sdmmc_attach_args saa; 266 267 SDMMC_ASSERT_LOCKED(sc); 268 269 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) { 270 if (sf->number < 1) 271 continue; 272 273 bzero(&saa, sizeof saa); 274 saa.sf = sf; 275 276 sf->child = config_found_sm(&sc->sc_dev, &saa, sdmmc_print, 277 sdmmc_submatch); 278 } 279 } 280 281 int 282 sdmmc_submatch(struct device *parent, void *match, void *aux) 283 { 284 struct cfdata *cf = match; 285 286 /* Skip the scsibus, it is configured directly. */ 287 if (strcmp(cf->cf_driver->cd_name, "scsibus") == 0) 288 return 0; 289 290 return cf->cf_attach->ca_match(parent, cf, aux); 291 } 292 293 int 294 sdmmc_print(void *aux, const char *pnp) 295 { 296 struct sdmmc_attach_args *sa = aux; 297 struct sdmmc_function *sf = sa->sf; 298 struct sdmmc_cis *cis = &sf->sc->sc_fn0->cis; 299 int i; 300 301 if (pnp) { 302 if (sf->number == 0) 303 return QUIET; 304 305 for (i = 0; i < 4 && cis->cis1_info[i]; i++) 306 printf("%s%s", i ? ", " : "\"", cis->cis1_info[i]); 307 if (i != 0) 308 printf("\""); 309 310 if (cis->manufacturer != SDMMC_VENDOR_INVALID && 311 cis->product != SDMMC_PRODUCT_INVALID) { 312 printf("%s(", i ? " " : ""); 313 if (cis->manufacturer != SDMMC_VENDOR_INVALID) 314 printf("manufacturer 0x%x%s", 315 cis->manufacturer, 316 cis->product == SDMMC_PRODUCT_INVALID ? 317 "" : ", "); 318 if (cis->product != SDMMC_PRODUCT_INVALID) 319 printf("product 0x%x", cis->product); 320 printf(")"); 321 } 322 printf("%sat %s", i ? " " : "", pnp); 323 } 324 printf(" function %d", sf->number); 325 326 if (!pnp) { 327 for (i = 0; i < 3 && cis->cis1_info[i]; i++) 328 printf("%s%s", i ? ", " : " \"", cis->cis1_info[i]); 329 if (i != 0) 330 printf("\""); 331 } 332 return UNCONF; 333 } 334 335 void 336 sdmmc_io_detach(struct sdmmc_softc *sc) 337 { 338 struct sdmmc_function *sf; 339 340 SDMMC_ASSERT_LOCKED(sc); 341 342 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) { 343 if (sf->child != NULL) { 344 config_detach(sf->child, DETACH_FORCE); 345 sf->child = NULL; 346 } 347 } 348 349 KASSERT(TAILQ_EMPTY(&sc->sc_intrq)); 350 } 351 352 int 353 sdmmc_io_rw_direct(struct sdmmc_softc *sc, struct sdmmc_function *sf, 354 int reg, u_char *datap, int arg) 355 { 356 struct sdmmc_command cmd; 357 int error; 358 359 SDMMC_ASSERT_LOCKED(sc); 360 361 /* Make sure the card is selected. */ 362 if ((error = sdmmc_select_card(sc, sf)) != 0) { 363 SDMMC_UNLOCK(sc); 364 return error; 365 } 366 367 arg |= ((sf == NULL ? 0 : sf->number) & SD_ARG_CMD52_FUNC_MASK) << 368 SD_ARG_CMD52_FUNC_SHIFT; 369 arg |= (reg & SD_ARG_CMD52_REG_MASK) << 370 SD_ARG_CMD52_REG_SHIFT; 371 arg |= (*datap & SD_ARG_CMD52_DATA_MASK) << 372 SD_ARG_CMD52_DATA_SHIFT; 373 374 bzero(&cmd, sizeof cmd); 375 cmd.c_opcode = SD_IO_RW_DIRECT; 376 cmd.c_arg = arg; 377 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5; 378 379 error = sdmmc_mmc_command(sc, &cmd); 380 *datap = SD_R5_DATA(cmd.c_resp); 381 382 return error; 383 } 384 385 /* 386 * Useful values of `arg' to pass in are either SD_ARG_CMD53_READ or 387 * SD_ARG_CMD53_WRITE. SD_ARG_CMD53_INCREMENT may be ORed into `arg' 388 * to access successive register locations instead of accessing the 389 * same register many times. 390 */ 391 int 392 sdmmc_io_rw_extended(struct sdmmc_softc *sc, struct sdmmc_function *sf, 393 int reg, u_char *datap, int datalen, int arg) 394 { 395 struct sdmmc_command cmd; 396 int error; 397 398 SDMMC_ASSERT_LOCKED(sc); 399 400 #if 0 401 /* Make sure the card is selected. */ 402 if ((error = sdmmc_select_card(sc, sf)) != 0) { 403 SDMMC_UNLOCK(sc); 404 return error; 405 } 406 #endif 407 408 arg |= ((sf == NULL ? 0 : sf->number) & SD_ARG_CMD53_FUNC_MASK) << 409 SD_ARG_CMD53_FUNC_SHIFT; 410 arg |= (reg & SD_ARG_CMD53_REG_MASK) << 411 SD_ARG_CMD53_REG_SHIFT; 412 arg |= (datalen & SD_ARG_CMD53_LENGTH_MASK) << 413 SD_ARG_CMD53_LENGTH_SHIFT; 414 415 bzero(&cmd, sizeof cmd); 416 cmd.c_opcode = SD_IO_RW_EXTENDED; 417 cmd.c_arg = arg; 418 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5; 419 cmd.c_data = datap; 420 cmd.c_datalen = datalen; 421 cmd.c_blklen = MIN(datalen, sdmmc_chip_host_maxblklen(sc->sct, sc->sch)); 422 423 if (!ISSET(arg, SD_ARG_CMD53_WRITE)) 424 cmd.c_flags |= SCF_CMD_READ; 425 426 error = sdmmc_mmc_command(sc, &cmd); 427 SDMMC_UNLOCK(sc); 428 return error; 429 } 430 431 u_int8_t 432 sdmmc_io_read_1(struct sdmmc_function *sf, int reg) 433 { 434 u_int8_t data = 0; 435 436 SDMMC_ASSERT_LOCKED(sf->sc); 437 438 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, 439 SD_ARG_CMD52_READ); 440 return data; 441 } 442 443 void 444 sdmmc_io_write_1(struct sdmmc_function *sf, int reg, u_int8_t data) 445 { 446 SDMMC_ASSERT_LOCKED(sf->sc); 447 448 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data, 449 SD_ARG_CMD52_WRITE); 450 } 451 452 u_int16_t 453 sdmmc_io_read_2(struct sdmmc_function *sf, int reg) 454 { 455 u_int16_t data = 0; 456 457 SDMMC_ASSERT_LOCKED(sf->sc); 458 459 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2, 460 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT); 461 return data; 462 } 463 464 void 465 sdmmc_io_write_2(struct sdmmc_function *sf, int reg, u_int16_t data) 466 { 467 SDMMC_ASSERT_LOCKED(sf->sc); 468 469 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2, 470 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT); 471 } 472 473 u_int32_t 474 sdmmc_io_read_4(struct sdmmc_function *sf, int reg) 475 { 476 u_int32_t data = 0; 477 478 SDMMC_ASSERT_LOCKED(sf->sc); 479 480 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4, 481 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT); 482 return data; 483 } 484 485 void 486 sdmmc_io_write_4(struct sdmmc_function *sf, int reg, u_int32_t data) 487 { 488 SDMMC_ASSERT_LOCKED(sf->sc); 489 490 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4, 491 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT); 492 } 493 494 int 495 sdmmc_io_read_multi_1(struct sdmmc_function *sf, int reg, u_char *data, 496 int datalen) 497 { 498 int error; 499 500 SDMMC_ASSERT_LOCKED(sf->sc); 501 502 while (datalen > SD_ARG_CMD53_LENGTH_MAX) { 503 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, 504 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_READ); 505 if (error) 506 return error; 507 data += SD_ARG_CMD53_LENGTH_MAX; 508 datalen -= SD_ARG_CMD53_LENGTH_MAX; 509 } 510 511 return sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen, 512 SD_ARG_CMD53_READ); 513 } 514 515 int 516 sdmmc_io_write_multi_1(struct sdmmc_function *sf, int reg, u_char *data, 517 int datalen) 518 { 519 int error; 520 521 SDMMC_ASSERT_LOCKED(sf->sc); 522 523 while (datalen > SD_ARG_CMD53_LENGTH_MAX) { 524 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data, 525 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_WRITE); 526 if (error) 527 return error; 528 data += SD_ARG_CMD53_LENGTH_MAX; 529 datalen -= SD_ARG_CMD53_LENGTH_MAX; 530 } 531 532 return sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen, 533 SD_ARG_CMD53_WRITE); 534 } 535 536 int 537 sdmmc_io_xchg(struct sdmmc_softc *sc, struct sdmmc_function *sf, 538 int reg, u_char *datap) 539 { 540 541 SDMMC_ASSERT_LOCKED(sc); 542 543 return sdmmc_io_rw_direct(sc, sf, reg, datap, 544 SD_ARG_CMD52_WRITE|SD_ARG_CMD52_EXCHANGE); 545 } 546 547 /* 548 * Reset the I/O functions of the card. 549 */ 550 void 551 sdmmc_io_reset(struct sdmmc_softc *sc) 552 { 553 #if 0 /* XXX command fails */ 554 (void)sdmmc_io_write(sc, NULL, SD_IO_REG_CCCR_CTL, CCCR_CTL_RES); 555 sdmmc_delay(100000); 556 #endif 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 SDMMC_ASSERT_LOCKED(sc); 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 SDMMC_LOCK(sc); 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 SDMMC_UNLOCK(sc); 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 SDMMC_LOCK(sc); 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 SDMMC_UNLOCK(sc); 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); 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