xref: /openbsd-src/sys/dev/sdmmc/sdmmc_io.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
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