Home | History | Annotate | Line # | Download | only in sdmmc
sdmmc_io.c revision 1.2
      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 (at) 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