[BACK]Return to sdmmc.c CVS log [TXT][DIR] Up to [local] / sys / dev / sdmmc

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