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