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