Annotation of sys/dev/sdmmc/sdmmc.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: sdmmc.c,v 1.12 2007/05/31 10:09:01 uwe 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: /*
20: * Host controller independent SD/MMC bus driver based on information
21: * from SanDisk SD Card Product Manual Revision 2.2 (SanDisk), SDIO
22: * Simple Specification Version 1.0 (SDIO) and the Linux "mmc" driver.
23: */
24:
25: #include <sys/param.h>
26: #include <sys/device.h>
27: #include <sys/kernel.h>
28: #include <sys/kthread.h>
29: #include <sys/malloc.h>
30: #include <sys/proc.h>
31: #include <sys/systm.h>
32:
33: #include <scsi/scsi_all.h>
34: #include <scsi/scsiconf.h>
35:
36: #include <dev/sdmmc/sdmmc_ioreg.h>
37: #include <dev/sdmmc/sdmmc_scsi.h>
38: #include <dev/sdmmc/sdmmcchip.h>
39: #include <dev/sdmmc/sdmmcreg.h>
40: #include <dev/sdmmc/sdmmcvar.h>
41:
42: #ifdef SDMMC_IOCTL
43: #include "bio.h"
44: #if NBIO < 1
45: #undef SDMMC_IOCTL
46: #endif
47: #include <dev/biovar.h>
48: #endif
49:
50: int sdmmc_match(struct device *, void *, void *);
51: void sdmmc_attach(struct device *, struct device *, void *);
52: int sdmmc_detach(struct device *, int);
53: void sdmmc_create_thread(void *);
54: void sdmmc_task_thread(void *);
55: void sdmmc_discover_task(void *);
56: void sdmmc_card_attach(struct sdmmc_softc *);
57: void sdmmc_card_detach(struct sdmmc_softc *, int);
58: int sdmmc_enable(struct sdmmc_softc *);
59: void sdmmc_disable(struct sdmmc_softc *);
60: int sdmmc_scan(struct sdmmc_softc *);
61: int sdmmc_init(struct sdmmc_softc *);
62: int sdmmc_set_bus_width(struct sdmmc_function *);
63: #ifdef SDMMC_IOCTL
64: int sdmmc_ioctl(struct device *, u_long, caddr_t);
65: #endif
66:
67: #define DEVNAME(sc) SDMMCDEVNAME(sc)
68:
69: #ifdef SDMMC_DEBUG
70: int sdmmcdebug = 0;
71: extern int sdhcdebug; /* XXX should have a sdmmc_chip_debug() function */
72: void sdmmc_dump_command(struct sdmmc_softc *, struct sdmmc_command *);
73: #define DPRINTF(n,s) do { if ((n) <= sdmmcdebug) printf s; } while (0)
74: #else
75: #define DPRINTF(n,s) do {} while (0)
76: #endif
77:
78: struct cfattach sdmmc_ca = {
79: sizeof(struct sdmmc_softc), sdmmc_match, sdmmc_attach, sdmmc_detach
80: };
81:
82: struct cfdriver sdmmc_cd = {
83: NULL, "sdmmc", DV_DULL
84: };
85:
86: int
87: sdmmc_match(struct device *parent, void *match, void *aux)
88: {
89: struct cfdata *cf = match;
90: struct sdmmcbus_attach_args *saa = aux;
91:
92: return strcmp(saa->saa_busname, cf->cf_driver->cd_name) == 0;
93: }
94:
95: void
96: sdmmc_attach(struct device *parent, struct device *self, void *aux)
97: {
98: struct sdmmc_softc *sc = (struct sdmmc_softc *)self;
99: struct sdmmcbus_attach_args *saa = aux;
100:
101: printf("\n");
102:
103: sc->sct = saa->sct;
104: sc->sch = saa->sch;
105:
106: SIMPLEQ_INIT(&sc->sf_head);
107: TAILQ_INIT(&sc->sc_tskq);
108: TAILQ_INIT(&sc->sc_intrq);
109: sdmmc_init_task(&sc->sc_discover_task, sdmmc_discover_task, sc);
110: sdmmc_init_task(&sc->sc_intr_task, sdmmc_intr_task, sc);
111: lockinit(&sc->sc_lock, PRIBIO, DEVNAME(sc), 0, LK_CANRECURSE);
112:
113: #ifdef SDMMC_IOCTL
114: if (bio_register(self, sdmmc_ioctl) != 0)
115: printf("%s: unable to register ioctl\n", DEVNAME(sc));
116: #endif
117:
118: /*
119: * Create the event thread that will attach and detach cards
120: * and perform other lengthy operations.
121: */
122: #ifdef DO_CONFIG_PENDING
123: config_pending_incr();
124: #endif
125: kthread_create_deferred(sdmmc_create_thread, sc);
126: }
127:
128: int
129: sdmmc_detach(struct device *self, int flags)
130: {
131: struct sdmmc_softc *sc = (struct sdmmc_softc *)self;
132:
133: sc->sc_dying = 1;
134: while (sc->sc_task_thread != NULL) {
135: wakeup(&sc->sc_tskq);
136: tsleep(sc, PWAIT, "mmcdie", 0);
137: }
138: return 0;
139: }
140:
141: void
142: sdmmc_create_thread(void *arg)
143: {
144: struct sdmmc_softc *sc = arg;
145:
146: if (kthread_create(sdmmc_task_thread, sc, &sc->sc_task_thread,
147: "%s", DEVNAME(sc)) != 0)
148: printf("%s: can't create task thread\n", DEVNAME(sc));
149:
150: #ifdef DO_CONFIG_PENDING
151: config_pending_decr();
152: #endif
153: }
154:
155: void
156: sdmmc_task_thread(void *arg)
157: {
158: struct sdmmc_softc *sc = arg;
159: struct sdmmc_task *task;
160: int s;
161:
162: sdmmc_needs_discover(&sc->sc_dev);
163:
164: s = splsdmmc();
165: while (!sc->sc_dying) {
166: for (task = TAILQ_FIRST(&sc->sc_tskq); task != NULL;
167: task = TAILQ_FIRST(&sc->sc_tskq)) {
168: splx(s);
169: sdmmc_del_task(task);
170: task->func(task->arg);
171: s = splsdmmc();
172: }
173: tsleep(&sc->sc_tskq, PWAIT, "mmctsk", 0);
174: }
175: splx(s);
176:
177: if (ISSET(sc->sc_flags, SMF_CARD_PRESENT))
178: sdmmc_card_detach(sc, DETACH_FORCE);
179:
180: sc->sc_task_thread = NULL;
181: wakeup(sc);
182: kthread_exit(0);
183: }
184:
185: void
186: sdmmc_add_task(struct sdmmc_softc *sc, struct sdmmc_task *task)
187: {
188: int s;
189:
190: s = splsdmmc();
191: TAILQ_INSERT_TAIL(&sc->sc_tskq, task, next);
192: task->onqueue = 1;
193: task->sc = sc;
194: wakeup(&sc->sc_tskq);
195: splx(s);
196: }
197:
198: void
199: sdmmc_del_task(struct sdmmc_task *task)
200: {
201: struct sdmmc_softc *sc = task->sc;
202: int s;
203:
204: if (sc == NULL)
205: return;
206:
207: s = splsdmmc();
208: task->sc = NULL;
209: task->onqueue = 0;
210: TAILQ_REMOVE(&sc->sc_tskq, task, next);
211: splx(s);
212: }
213:
214: void
215: sdmmc_needs_discover(struct device *self)
216: {
217: struct sdmmc_softc *sc = (struct sdmmc_softc *)self;
218:
219: if (!sdmmc_task_pending(&sc->sc_discover_task))
220: sdmmc_add_task(sc, &sc->sc_discover_task);
221: }
222:
223: void
224: sdmmc_discover_task(void *arg)
225: {
226: struct sdmmc_softc *sc = arg;
227:
228: if (sdmmc_chip_card_detect(sc->sct, sc->sch)) {
229: if (!ISSET(sc->sc_flags, SMF_CARD_PRESENT)) {
230: SET(sc->sc_flags, SMF_CARD_PRESENT);
231: sdmmc_card_attach(sc);
232: }
233: } else {
234: if (ISSET(sc->sc_flags, SMF_CARD_PRESENT)) {
235: CLR(sc->sc_flags, SMF_CARD_PRESENT);
236: sdmmc_card_detach(sc, DETACH_FORCE);
237: }
238: }
239: }
240:
241: /*
242: * Called from process context when a card is present.
243: */
244: void
245: sdmmc_card_attach(struct sdmmc_softc *sc)
246: {
247: DPRINTF(1,("%s: attach card\n", DEVNAME(sc)));
248:
249: SDMMC_LOCK(sc);
250: CLR(sc->sc_flags, SMF_CARD_ATTACHED);
251:
252: /*
253: * Power up the card (or card stack).
254: */
255: if (sdmmc_enable(sc) != 0) {
256: printf("%s: can't enable card\n", DEVNAME(sc));
257: goto err;
258: }
259:
260: /*
261: * Scan for I/O functions and memory cards on the bus,
262: * allocating a sdmmc_function structure for each.
263: */
264: if (sdmmc_scan(sc) != 0) {
265: printf("%s: no functions\n", DEVNAME(sc));
266: goto err;
267: }
268:
269: /*
270: * Initialize the I/O functions and memory cards.
271: */
272: if (sdmmc_init(sc) != 0) {
273: printf("%s: init failed\n", DEVNAME(sc));
274: goto err;
275: }
276:
277: /* Attach SCSI emulation for memory cards. */
278: if (ISSET(sc->sc_flags, SMF_MEM_MODE))
279: sdmmc_scsi_attach(sc);
280:
281: /* Attach I/O function drivers. */
282: if (ISSET(sc->sc_flags, SMF_IO_MODE))
283: sdmmc_io_attach(sc);
284:
285: SET(sc->sc_flags, SMF_CARD_ATTACHED);
286: SDMMC_UNLOCK(sc);
287: return;
288: err:
289: sdmmc_card_detach(sc, DETACH_FORCE);
290: SDMMC_UNLOCK(sc);
291: }
292:
293: /*
294: * Called from process context with DETACH_* flags from <sys/device.h>
295: * when cards are gone.
296: */
297: void
298: sdmmc_card_detach(struct sdmmc_softc *sc, int flags)
299: {
300: struct sdmmc_function *sf, *sfnext;
301:
302: DPRINTF(1,("%s: detach card\n", DEVNAME(sc)));
303:
304: if (ISSET(sc->sc_flags, SMF_CARD_ATTACHED)) {
305: /* Detach I/O function drivers. */
306: if (ISSET(sc->sc_flags, SMF_IO_MODE))
307: sdmmc_io_detach(sc);
308:
309: /* Detach the SCSI emulation for memory cards. */
310: if (ISSET(sc->sc_flags, SMF_MEM_MODE))
311: sdmmc_scsi_detach(sc);
312:
313: CLR(sc->sc_flags, SMF_CARD_ATTACHED);
314: }
315:
316: /* Power down. */
317: sdmmc_disable(sc);
318:
319: /* Free all sdmmc_function structures. */
320: for (sf = SIMPLEQ_FIRST(&sc->sf_head); sf != NULL; sf = sfnext) {
321: sfnext = SIMPLEQ_NEXT(sf, sf_list);
322: sdmmc_function_free(sf);
323: }
324: SIMPLEQ_INIT(&sc->sf_head);
325: sc->sc_function_count = 0;
326: sc->sc_fn0 = NULL;
327: }
328:
329: int
330: sdmmc_enable(struct sdmmc_softc *sc)
331: {
332: u_int32_t host_ocr;
333: int error;
334:
335: /*
336: * Calculate the equivalent of the card OCR from the host
337: * capabilities and select the maximum supported bus voltage.
338: */
339: host_ocr = sdmmc_chip_host_ocr(sc->sct, sc->sch);
340: error = sdmmc_chip_bus_power(sc->sct, sc->sch, host_ocr);
341: if (error != 0) {
342: printf("%s: can't supply bus power\n", DEVNAME(sc));
343: goto err;
344: }
345:
346: /*
347: * Select the minimum clock frequency.
348: */
349: error = sdmmc_chip_bus_clock(sc->sct, sc->sch, SDMMC_SDCLK_400KHZ);
350: if (error != 0) {
351: printf("%s: can't supply clock\n", DEVNAME(sc));
352: goto err;
353: }
354:
355: /* XXX wait for card to power up */
356: sdmmc_delay(100000);
357:
358: /* Initialize SD I/O card function(s). */
359: if ((error = sdmmc_io_enable(sc)) != 0)
360: goto err;
361:
362: /* Initialize SD/MMC memory card(s). */
363: if (ISSET(sc->sc_flags, SMF_MEM_MODE) &&
364: (error = sdmmc_mem_enable(sc)) != 0)
365: goto err;
366:
367: /* XXX respect host and card capabilities */
368: if (ISSET(sc->sc_flags, SMF_SD_MODE))
369: (void)sdmmc_chip_bus_clock(sc->sct, sc->sch,
370: SDMMC_SDCLK_25MHZ);
371:
372: err:
373: if (error != 0)
374: sdmmc_disable(sc);
375: return error;
376: }
377:
378: void
379: sdmmc_disable(struct sdmmc_softc *sc)
380: {
381: /* XXX complete commands if card is still present. */
382:
383: /* Make sure no card is still selected. */
384: (void)sdmmc_select_card(sc, NULL);
385:
386: /* Turn off bus power and clock. */
387: (void)sdmmc_chip_bus_clock(sc->sct, sc->sch, SDMMC_SDCLK_OFF);
388: (void)sdmmc_chip_bus_power(sc->sct, sc->sch, 0);
389: }
390:
391: /*
392: * Set the lowest bus voltage supported by the card and the host.
393: */
394: int
395: sdmmc_set_bus_power(struct sdmmc_softc *sc, u_int32_t host_ocr,
396: u_int32_t card_ocr)
397: {
398: u_int32_t bit;
399:
400: /* Mask off unsupported voltage levels and select the lowest. */
401: DPRINTF(1,("%s: host_ocr=%x ", DEVNAME(sc), host_ocr));
402: host_ocr &= card_ocr;
403: for (bit = 4; bit < 23; bit++) {
404: if (ISSET(host_ocr, 1<<bit)) {
405: host_ocr &= 3<<bit;
406: break;
407: }
408: }
409: DPRINTF(1,("card_ocr=%x new_ocr=%x\n", card_ocr, host_ocr));
410:
411: if (host_ocr == 0 ||
412: sdmmc_chip_bus_power(sc->sct, sc->sch, host_ocr) != 0)
413: return 1;
414: return 0;
415: }
416:
417: struct sdmmc_function *
418: sdmmc_function_alloc(struct sdmmc_softc *sc)
419: {
420: struct sdmmc_function *sf;
421:
422: MALLOC(sf, struct sdmmc_function *, sizeof *sf, M_DEVBUF,
423: M_WAITOK);
424: bzero(sf, sizeof *sf);
425: sf->sc = sc;
426: sf->number = -1;
427: sf->cis.manufacturer = SDMMC_VENDOR_INVALID;
428: sf->cis.product = SDMMC_PRODUCT_INVALID;
429: sf->cis.function = SDMMC_FUNCTION_INVALID;
430: return sf;
431: }
432:
433: void
434: sdmmc_function_free(struct sdmmc_function *sf)
435: {
436: FREE(sf, M_DEVBUF);
437: }
438:
439: /*
440: * Scan for I/O functions and memory cards on the bus, allocating a
441: * sdmmc_function structure for each.
442: */
443: int
444: sdmmc_scan(struct sdmmc_softc *sc)
445: {
446: /* Scan for I/O functions. */
447: if (ISSET(sc->sc_flags, SMF_IO_MODE))
448: sdmmc_io_scan(sc);
449:
450: /* Scan for memory cards on the bus. */
451: if (ISSET(sc->sc_flags, SMF_MEM_MODE))
452: sdmmc_mem_scan(sc);
453:
454: /* There should be at least one function now. */
455: if (SIMPLEQ_EMPTY(&sc->sf_head)) {
456: printf("%s: can't identify card\n", DEVNAME(sc));
457: return 1;
458: }
459: return 0;
460: }
461:
462: /*
463: * Initialize all the distinguished functions of the card, be it I/O
464: * or memory functions.
465: */
466: int
467: sdmmc_init(struct sdmmc_softc *sc)
468: {
469: struct sdmmc_function *sf;
470:
471: /* Initialize all identified card functions. */
472: SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
473: if (ISSET(sc->sc_flags, SMF_IO_MODE) &&
474: sdmmc_io_init(sc, sf) != 0)
475: printf("%s: i/o init failed\n", DEVNAME(sc));
476:
477: if (ISSET(sc->sc_flags, SMF_MEM_MODE) &&
478: sdmmc_mem_init(sc, sf) != 0)
479: printf("%s: mem init failed\n", DEVNAME(sc));
480: }
481:
482: /* Any good functions left after initialization? */
483: SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
484: if (!ISSET(sf->flags, SFF_ERROR))
485: return 0;
486: }
487: /* No, we should probably power down the card. */
488: return 1;
489: }
490:
491: void
492: sdmmc_delay(u_int usecs)
493: {
494: int ticks = usecs / (1000000 / hz);
495:
496: if (ticks > 0)
497: tsleep(&sdmmc_delay, PWAIT, "mmcdly", ticks);
498: else
499: delay(usecs);
500: }
501:
502: int
503: sdmmc_app_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd)
504: {
505: struct sdmmc_command acmd;
506: int error;
507:
508: SDMMC_LOCK(sc);
509:
510: bzero(&acmd, sizeof acmd);
511: acmd.c_opcode = MMC_APP_CMD;
512: acmd.c_arg = 0;
513: acmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
514:
515: error = sdmmc_mmc_command(sc, &acmd);
516: if (error != 0) {
517: SDMMC_UNLOCK(sc);
518: return error;
519: }
520:
521: if (!ISSET(MMC_R1(acmd.c_resp), MMC_R1_APP_CMD)) {
522: /* Card does not support application commands. */
523: SDMMC_UNLOCK(sc);
524: return ENODEV;
525: }
526:
527: error = sdmmc_mmc_command(sc, cmd);
528: SDMMC_UNLOCK(sc);
529: return error;
530: }
531:
532: /*
533: * Execute MMC command and data transfers. All interactions with the
534: * host controller to complete the command happen in the context of
535: * the current process.
536: */
537: int
538: sdmmc_mmc_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd)
539: {
540: int error;
541:
542: SDMMC_LOCK(sc);
543:
544: sdmmc_chip_exec_command(sc->sct, sc->sch, cmd);
545:
546: #ifdef SDMMC_DEBUG
547: sdmmc_dump_command(sc, cmd);
548: #endif
549:
550: error = cmd->c_error;
551: wakeup(cmd);
552:
553: SDMMC_UNLOCK(sc);
554: return error;
555: }
556:
557: /*
558: * Send the "GO IDLE STATE" command.
559: */
560: void
561: sdmmc_go_idle_state(struct sdmmc_softc *sc)
562: {
563: struct sdmmc_command cmd;
564:
565: bzero(&cmd, sizeof cmd);
566: cmd.c_opcode = MMC_GO_IDLE_STATE;
567: cmd.c_flags = SCF_CMD_BC | SCF_RSP_R0;
568:
569: (void)sdmmc_mmc_command(sc, &cmd);
570: }
571:
572: /*
573: * Retrieve (SD) or set (MMC) the relative card address (RCA).
574: */
575: int
576: sdmmc_set_relative_addr(struct sdmmc_softc *sc,
577: struct sdmmc_function *sf)
578: {
579: struct sdmmc_command cmd;
580:
581: bzero(&cmd, sizeof cmd);
582:
583: if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
584: cmd.c_opcode = SD_SEND_RELATIVE_ADDR;
585: cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R6;
586: } else {
587: cmd.c_opcode = MMC_SET_RELATIVE_ADDR;
588: cmd.c_arg = MMC_ARG_RCA(sf->rca);
589: cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
590: }
591:
592: if (sdmmc_mmc_command(sc, &cmd) != 0)
593: return 1;
594:
595: if (ISSET(sc->sc_flags, SMF_SD_MODE))
596: sf->rca = SD_R6_RCA(cmd.c_resp);
597: return 0;
598: }
599:
600: /*
601: * Switch card and host to the maximum supported bus width.
602: */
603: int
604: sdmmc_set_bus_width(struct sdmmc_function *sf)
605: {
606: struct sdmmc_softc *sc = sf->sc;
607: struct sdmmc_command cmd;
608: int error;
609:
610: SDMMC_LOCK(sc);
611:
612: if (!ISSET(sc->sc_flags, SMF_SD_MODE)) {
613: SDMMC_UNLOCK(sc);
614: return EOPNOTSUPP;
615: }
616:
617: if ((error = sdmmc_select_card(sc, sf)) != 0) {
618: SDMMC_UNLOCK(sc);
619: return error;
620: }
621:
622: bzero(&cmd, sizeof cmd);
623: cmd.c_opcode = SD_APP_SET_BUS_WIDTH;
624: cmd.c_arg = SD_ARG_BUS_WIDTH_4;
625: cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
626: error = sdmmc_app_command(sc, &cmd);
627: SDMMC_UNLOCK(sc);
628: return error;
629: }
630:
631: int
632: sdmmc_select_card(struct sdmmc_softc *sc, struct sdmmc_function *sf)
633: {
634: struct sdmmc_command cmd;
635: int error;
636:
637: if (sc->sc_card == sf || (sf && sc->sc_card &&
638: sc->sc_card->rca == sf->rca)) {
639: sc->sc_card = sf;
640: return 0;
641: }
642:
643: bzero(&cmd, sizeof cmd);
644: cmd.c_opcode = MMC_SELECT_CARD;
645: cmd.c_arg = sf == NULL ? 0 : MMC_ARG_RCA(sf->rca);
646: cmd.c_flags = SCF_CMD_AC | (sf == NULL ? SCF_RSP_R0 : SCF_RSP_R1);
647: error = sdmmc_mmc_command(sc, &cmd);
648: if (error == 0 || sf == NULL)
649: sc->sc_card = sf;
650: return error;
651: }
652:
653: #ifdef SDMMC_IOCTL
654: int
655: sdmmc_ioctl(struct device *self, u_long request, caddr_t addr)
656: {
657: struct sdmmc_softc *sc = (struct sdmmc_softc *)self;
658: struct sdmmc_command *ucmd;
659: struct sdmmc_command cmd;
660: void *data;
661: int error;
662:
663: switch (request) {
664: #ifdef SDMMC_DEBUG
665: case SDIOCSETDEBUG:
666: sdmmcdebug = (((struct bio_sdmmc_debug *)addr)->debug) & 0xff;
667: sdhcdebug = (((struct bio_sdmmc_debug *)addr)->debug >> 8) & 0xff;
668: break;
669: #endif
670:
671: case SDIOCEXECMMC:
672: case SDIOCEXECAPP:
673: ucmd = &((struct bio_sdmmc_command *)addr)->cmd;
674:
675: /* Refuse to transfer more than 512K per command. */
676: if (ucmd->c_datalen > 524288)
677: return ENOMEM;
678:
679: /* Verify that the data buffer is safe to copy. */
680: if ((ucmd->c_datalen > 0 && ucmd->c_data == NULL) ||
681: (ucmd->c_datalen < 1 && ucmd->c_data != NULL) ||
682: ucmd->c_datalen < 0)
683: return EINVAL;
684:
685: bzero(&cmd, sizeof cmd);
686: cmd.c_opcode = ucmd->c_opcode;
687: cmd.c_arg = ucmd->c_arg;
688: cmd.c_flags = ucmd->c_flags;
689: cmd.c_blklen = ucmd->c_blklen;
690:
691: if (ucmd->c_data) {
692: data = malloc(ucmd->c_datalen, M_TEMP,
693: M_WAITOK | M_CANFAIL);
694: if (data == NULL)
695: return ENOMEM;
696: if (copyin(ucmd->c_data, data, ucmd->c_datalen))
697: return EFAULT;
698:
699: cmd.c_data = data;
700: cmd.c_datalen = ucmd->c_datalen;
701: }
702:
703: if (request == SDIOCEXECMMC)
704: error = sdmmc_mmc_command(sc, &cmd);
705: else
706: error = sdmmc_app_command(sc, &cmd);
707: if (error && !cmd.c_error)
708: cmd.c_error = error;
709:
710: bcopy(&cmd.c_resp, ucmd->c_resp, sizeof cmd.c_resp);
711: ucmd->c_flags = cmd.c_flags;
712: ucmd->c_error = cmd.c_error;
713:
714: if (ucmd->c_data && copyout(data, ucmd->c_data,
715: ucmd->c_datalen))
716: return EFAULT;
717:
718: if (ucmd->c_data)
719: free(data, M_TEMP);
720: break;
721:
722: default:
723: return ENOTTY;
724: }
725: return 0;
726: }
727: #endif
728:
729: #ifdef SDMMC_DEBUG
730: void
731: sdmmc_dump_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd)
732: {
733: int i;
734:
735: DPRINTF(1,("%s: cmd %u arg=%#x data=%#x dlen=%d flags=%#x "
736: "proc=\"%s\" (error %d)\n", DEVNAME(sc), cmd->c_opcode,
737: cmd->c_arg, cmd->c_data, cmd->c_datalen, cmd->c_flags,
738: curproc ? curproc->p_comm : "", cmd->c_error));
739:
740: if (cmd->c_error || sdmmcdebug < 1)
741: return;
742:
743: printf("%s: resp=", DEVNAME(sc));
744: if (ISSET(cmd->c_flags, SCF_RSP_136))
745: for (i = 0; i < sizeof cmd->c_resp; i++)
746: printf("%02x ", ((u_char *)cmd->c_resp)[i]);
747: else if (ISSET(cmd->c_flags, SCF_RSP_PRESENT))
748: for (i = 0; i < 4; i++)
749: printf("%02x ", ((u_char *)cmd->c_resp)[i]);
750: printf("\n");
751: }
752: #endif
CVSweb