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

Annotation of sys/dev/sdmmc/sdmmc_mem.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: sdmmc_mem.c,v 1.7 2007/03/18 22:07:16 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: /* Routines for SD/MMC memory cards. */
                     20:
                     21: #include <sys/param.h>
                     22: #include <sys/kernel.h>
                     23: #include <sys/malloc.h>
                     24: #include <sys/systm.h>
                     25:
                     26: #include <dev/sdmmc/sdmmcchip.h>
                     27: #include <dev/sdmmc/sdmmcreg.h>
                     28: #include <dev/sdmmc/sdmmcvar.h>
                     29:
                     30: int    sdmmc_decode_csd(struct sdmmc_softc *, sdmmc_response,
                     31:            struct sdmmc_function *);
                     32: int    sdmmc_decode_cid(struct sdmmc_softc *, sdmmc_response,
                     33:            struct sdmmc_function *);
                     34: void   sdmmc_print_cid(struct sdmmc_cid *);
                     35:
                     36: int    sdmmc_mem_send_op_cond(struct sdmmc_softc *, u_int32_t, u_int32_t *);
                     37: int    sdmmc_mem_set_blocklen(struct sdmmc_softc *, struct sdmmc_function *);
                     38:
                     39: #ifdef SDMMC_DEBUG
                     40: #define DPRINTF(s)     printf s
                     41: #else
                     42: #define DPRINTF(s)     /**/
                     43: #endif
                     44:
                     45: /*
                     46:  * Initialize SD/MMC memory cards and memory in SDIO "combo" cards.
                     47:  */
                     48: int
                     49: sdmmc_mem_enable(struct sdmmc_softc *sc)
                     50: {
                     51:        u_int32_t host_ocr;
                     52:        u_int32_t card_ocr;
                     53:
                     54:        /* Set host mode to SD "combo" card or SD memory-only. */
                     55:        SET(sc->sc_flags, SMF_SD_MODE|SMF_MEM_MODE);
                     56:
                     57:        /* Reset memory (*must* do that before CMD55 or CMD1). */
                     58:        sdmmc_go_idle_state(sc);
                     59:
                     60:        /*
                     61:         * Read the SD/MMC memory OCR value by issuing CMD55 followed
                     62:         * by ACMD41 to read the OCR value from memory-only SD cards.
                     63:         * MMC cards will not respond to CMD55 or ACMD41 and this is
                     64:         * how we distinguish them from SD cards.
                     65:         */
                     66:  mmc_mode:
                     67:        if (sdmmc_mem_send_op_cond(sc, 0, &card_ocr) != 0) {
                     68:                if (ISSET(sc->sc_flags, SMF_SD_MODE) &&
                     69:                    !ISSET(sc->sc_flags, SMF_IO_MODE)) {
                     70:                        /* Not a SD card, switch to MMC mode. */
                     71:                        CLR(sc->sc_flags, SMF_SD_MODE);
                     72:                        goto mmc_mode;
                     73:                }
                     74:                if (!ISSET(sc->sc_flags, SMF_SD_MODE)) {
                     75:                        DPRINTF(("%s: can't read memory OCR\n",
                     76:                            SDMMCDEVNAME(sc)));
                     77:                        return 1;
                     78:                } else {
                     79:                        /* Not a "combo" card. */
                     80:                        CLR(sc->sc_flags, SMF_MEM_MODE);
                     81:                        return 0;
                     82:                }
                     83:        }
                     84:
                     85:        /* Set the lowest voltage supported by the card and host. */
                     86:        host_ocr = sdmmc_chip_host_ocr(sc->sct, sc->sch);
                     87:        if (sdmmc_set_bus_power(sc, host_ocr, card_ocr) != 0) {
                     88:                DPRINTF(("%s: can't supply voltage requested by card\n",
                     89:                    SDMMCDEVNAME(sc)));
                     90:                return 1;
                     91:        }
                     92:
                     93:        /* Tell the card(s) to enter the idle state (again). */
                     94:        sdmmc_go_idle_state(sc);
                     95:
                     96:        /* Send the new OCR value until all cards are ready. */
                     97:        if (sdmmc_mem_send_op_cond(sc, host_ocr, NULL) != 0) {
                     98:                DPRINTF(("%s: can't send memory OCR\n", SDMMCDEVNAME(sc)));
                     99:                return 1;
                    100:        }
                    101:        return 0;
                    102: }
                    103:
                    104: /*
                    105:  * Read the CSD and CID from all cards and assign each card a unique
                    106:  * relative card address (RCA).  CMD2 is ignored by SDIO-only cards.
                    107:  */
                    108: void
                    109: sdmmc_mem_scan(struct sdmmc_softc *sc)
                    110: {
                    111:        struct sdmmc_command cmd;
                    112:        struct sdmmc_function *sf;
                    113:        u_int16_t next_rca;
                    114:        int error;
                    115:        int i;
                    116:
                    117:        /*
                    118:         * CMD2 is a broadcast command understood by SD cards and MMC
                    119:         * cards.  All cards begin to respond to the command, but back
                    120:         * off if another card drives the CMD line to a different level.
                    121:         * Only one card will get its entire response through.  That
                    122:         * card remains silent once it has been assigned a RCA.
                    123:         */
                    124:        for (i = 0; i < 100; i++) {
                    125:                bzero(&cmd, sizeof cmd);
                    126:                cmd.c_opcode = MMC_ALL_SEND_CID;
                    127:                cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R2;
                    128:
                    129:                error = sdmmc_mmc_command(sc, &cmd);
                    130:                if (error == ETIMEDOUT) {
                    131:                        /* No more cards there. */
                    132:                        break;
                    133:                } else if (error != 0) {
                    134:                        DPRINTF(("%s: can't read CID\n", SDMMCDEVNAME(sc)));
                    135:                        break;
                    136:                }
                    137:
                    138:                /* In MMC mode, find the next available RCA. */
                    139:                next_rca = 1;
                    140:                if (!ISSET(sc->sc_flags, SMF_SD_MODE))
                    141:                        SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list)
                    142:                                next_rca++;
                    143:
                    144:                /* Allocate a sdmmc_function structure. */
                    145:                sf = sdmmc_function_alloc(sc);
                    146:                sf->rca = next_rca;
                    147:
                    148:                /*
                    149:                 * Remember the CID returned in the CMD2 response for
                    150:                 * later decoding.
                    151:                 */
                    152:                bcopy(cmd.c_resp, sf->raw_cid, sizeof sf->raw_cid);
                    153:
                    154:                /*
                    155:                 * Silence the card by assigning it a unique RCA, or
                    156:                 * querying it for its RCA in the case of SD.
                    157:                 */
                    158:                if (sdmmc_set_relative_addr(sc, sf) != 0) {
                    159:                        printf("%s: can't set mem RCA\n", SDMMCDEVNAME(sc));
                    160:                        sdmmc_function_free(sf);
                    161:                        break;
                    162:                }
                    163:
                    164: #if 0
                    165:                /* Verify that the RCA has been set by selecting the card. */
                    166:                if (sdmmc_select_card(sc, sf) != 0) {
                    167:                        printf("%s: can't select mem RCA %d\n",
                    168:                            SDMMCDEVNAME(sc), sf->rca);
                    169:                        sdmmc_function_free(sf);
                    170:                        break;
                    171:                }
                    172:
                    173:                /* Deselect. */
                    174:                (void)sdmmc_select_card(sc, NULL);
                    175: #endif
                    176:
                    177:                /*
                    178:                 * If this is a memory-only card, the card responding
                    179:                 * first becomes an alias for SDIO function 0.
                    180:                 */
                    181:                if (sc->sc_fn0 == NULL)
                    182:                        sc->sc_fn0 = sf;
                    183:
                    184:                SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list);
                    185:        }
                    186:
                    187:        /*
                    188:         * All cards are either inactive or awaiting further commands.
                    189:         * Read the CSDs and decode the raw CID for each card.
                    190:         */
                    191:        SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
                    192:                bzero(&cmd, sizeof cmd);
                    193:                cmd.c_opcode = MMC_SEND_CSD;
                    194:                cmd.c_arg = MMC_ARG_RCA(sf->rca);
                    195:                cmd.c_flags = SCF_CMD_AC | SCF_RSP_R2;
                    196:
                    197:                if (sdmmc_mmc_command(sc, &cmd) != 0) {
                    198:                        SET(sf->flags, SFF_ERROR);
                    199:                        continue;
                    200:                }
                    201:
                    202:                if (sdmmc_decode_csd(sc, cmd.c_resp, sf) != 0 ||
                    203:                    sdmmc_decode_cid(sc, sf->raw_cid, sf) != 0) {
                    204:                        SET(sf->flags, SFF_ERROR);
                    205:                        continue;
                    206:                }
                    207:
                    208: #ifdef SDMMC_DEBUG
                    209:                printf("%s: CID: ", SDMMCDEVNAME(sc));
                    210:                sdmmc_print_cid(&sf->cid);
                    211: #endif
                    212:        }
                    213: }
                    214:
                    215: int
                    216: sdmmc_decode_csd(struct sdmmc_softc *sc, sdmmc_response resp,
                    217:     struct sdmmc_function *sf)
                    218: {
                    219:        struct sdmmc_csd *csd = &sf->csd;
                    220:
                    221:        if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
                    222:                /*
                    223:                 * CSD version 1.0 corresponds to SD system
                    224:                 * specification version 1.0 - 1.10. (SanDisk, 3.5.3)
                    225:                 */
                    226:                csd->csdver = SD_CSD_CSDVER(resp);
                    227:                if (csd->csdver != SD_CSD_CSDVER_1_0) {
                    228:                        printf("%s: unknown SD CSD structure version 0x%x\n",
                    229:                            SDMMCDEVNAME(sc), csd->csdver);
                    230:                        return 1;
                    231:                }
                    232:
                    233:                csd->capacity = SD_CSD_CAPACITY(resp);
                    234:                csd->read_bl_len = SD_CSD_READ_BL_LEN(resp);
                    235:        } else {
                    236:                csd->csdver = MMC_CSD_CSDVER(resp);
                    237:                if (csd->csdver != MMC_CSD_CSDVER_1_0 &&
                    238:                    csd->csdver != MMC_CSD_CSDVER_2_0) {
                    239:                        printf("%s: unknown MMC CSD structure version 0x%x\n",
                    240:                            SDMMCDEVNAME(sc), csd->csdver);
                    241:                        return 1;
                    242:                }
                    243:
                    244:                csd->mmcver = MMC_CSD_MMCVER(resp);
                    245:                csd->capacity = MMC_CSD_CAPACITY(resp);
                    246:                csd->read_bl_len = MMC_CSD_READ_BL_LEN(resp);
                    247:        }
                    248:        csd->sector_size = MIN(1 << csd->read_bl_len,
                    249:            sdmmc_chip_host_maxblklen(sc->sct, sc->sch));
                    250:        if (csd->sector_size < (1<<csd->read_bl_len))
                    251:                csd->capacity *= (1<<csd->read_bl_len) /
                    252:                    csd->sector_size;
                    253:
                    254:        return 0;
                    255: }
                    256:
                    257: int
                    258: sdmmc_decode_cid(struct sdmmc_softc *sc, sdmmc_response resp,
                    259:     struct sdmmc_function *sf)
                    260: {
                    261:        struct sdmmc_cid *cid = &sf->cid;
                    262:
                    263:        if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
                    264:                cid->mid = SD_CID_MID(resp);
                    265:                cid->oid = SD_CID_OID(resp);
                    266:                SD_CID_PNM_CPY(resp, cid->pnm);
                    267:                cid->rev = SD_CID_REV(resp);
                    268:                cid->psn = SD_CID_PSN(resp);
                    269:                cid->mdt = SD_CID_MDT(resp);
                    270:        } else {
                    271:                switch(sf->csd.mmcver) {
                    272:                case MMC_CSD_MMCVER_1_0:
                    273:                case MMC_CSD_MMCVER_1_4:
                    274:                        cid->mid = MMC_CID_MID_V1(resp);
                    275:                        MMC_CID_PNM_V1_CPY(resp, cid->pnm);
                    276:                        cid->rev = MMC_CID_REV_V1(resp);
                    277:                        cid->psn = MMC_CID_PSN_V1(resp);
                    278:                        cid->mdt = MMC_CID_MDT_V1(resp);
                    279:                        break;
                    280:                case MMC_CSD_MMCVER_2_0:
                    281:                case MMC_CSD_MMCVER_3_1:
                    282:                case MMC_CSD_MMCVER_4_0:
                    283:                        cid->mid = MMC_CID_MID_V2(resp);
                    284:                        cid->oid = MMC_CID_OID_V2(resp);
                    285:                        MMC_CID_PNM_V2_CPY(resp, cid->pnm);
                    286:                        cid->psn = MMC_CID_PSN_V2(resp);
                    287:                        break;
                    288:                default:
                    289:                        printf("%s: unknown MMC version %d\n",
                    290:                            SDMMCDEVNAME(sc), sf->csd.mmcver);
                    291:                        return 1;
                    292:                }
                    293:        }
                    294:        return 0;
                    295: }
                    296:
                    297: #ifdef SDMMC_DEBUG
                    298: void
                    299: sdmmc_print_cid(struct sdmmc_cid *cid)
                    300: {
                    301:        printf("mid=0x%02x oid=0x%04x pnm=\"%s\" rev=0x%02x psn=0x%08x"
                    302:            " mdt=%03x\n", cid->mid, cid->oid, cid->pnm, cid->rev, cid->psn,
                    303:            cid->mdt);
                    304: }
                    305: #endif
                    306:
                    307: /*
                    308:  * Initialize a SD/MMC memory card.
                    309:  */
                    310: int
                    311: sdmmc_mem_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
                    312: {
                    313:        int error = 0;
                    314:
                    315:        SDMMC_LOCK(sc);
                    316:        if (sdmmc_select_card(sc, sf) != 0 ||
                    317:            sdmmc_mem_set_blocklen(sc, sf) != 0)
                    318:                error = 1;
                    319:        SDMMC_UNLOCK(sc);
                    320:        return error;
                    321: }
                    322:
                    323: /*
                    324:  * Get or set the card's memory OCR value (SD or MMC).
                    325:  */
                    326: int
                    327: sdmmc_mem_send_op_cond(struct sdmmc_softc *sc, u_int32_t ocr,
                    328:     u_int32_t *ocrp)
                    329: {
                    330:        struct sdmmc_command cmd;
                    331:        int error;
                    332:        int i;
                    333:
                    334:        SDMMC_LOCK(sc);
                    335:
                    336:        /*
                    337:         * If we change the OCR value, retry the command until the OCR
                    338:         * we receive in response has the "CARD BUSY" bit set, meaning
                    339:         * that all cards are ready for identification.
                    340:         */
                    341:        for (i = 0; i < 100; i++) {
                    342:                bzero(&cmd, sizeof cmd);
                    343:                cmd.c_arg = ocr;
                    344:                cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R3;
                    345:
                    346:                if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
                    347:                        cmd.c_opcode = SD_APP_OP_COND;
                    348:                        error = sdmmc_app_command(sc, &cmd);
                    349:                } else {
                    350:                        cmd.c_opcode = MMC_SEND_OP_COND;
                    351:                        error = sdmmc_mmc_command(sc, &cmd);
                    352:                }
                    353:                if (error != 0)
                    354:                        break;
                    355:                if (ISSET(MMC_R3(cmd.c_resp), MMC_OCR_MEM_READY) ||
                    356:                    ocr == 0)
                    357:                        break;
                    358:                error = ETIMEDOUT;
                    359:                sdmmc_delay(10000);
                    360:        }
                    361:        if (error == 0 && ocrp != NULL)
                    362:                *ocrp = MMC_R3(cmd.c_resp);
                    363:
                    364:        SDMMC_UNLOCK(sc);
                    365:        return error;
                    366: }
                    367:
                    368: /*
                    369:  * Set the read block length appropriately for this card, according to
                    370:  * the card CSD register value.
                    371:  */
                    372: int
                    373: sdmmc_mem_set_blocklen(struct sdmmc_softc *sc, struct sdmmc_function *sf)
                    374: {
                    375:        struct sdmmc_command cmd;
                    376:
                    377:        bzero(&cmd, sizeof cmd);
                    378:        cmd.c_opcode = MMC_SET_BLOCKLEN;
                    379:        cmd.c_arg = sf->csd.sector_size;
                    380:        cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
                    381:        DPRINTF(("%s: read_bl_len=%d sector_size=%d\n", SDMMCDEVNAME(sc),
                    382:            1 << sf->csd.read_bl_len, sf->csd.sector_size));
                    383:
                    384:        return sdmmc_mmc_command(sc, &cmd);
                    385: }
                    386:
                    387: int
                    388: sdmmc_mem_read_block(struct sdmmc_function *sf, int blkno, u_char *data,
                    389:     size_t datalen)
                    390: {
                    391:        struct sdmmc_softc *sc = sf->sc;
                    392:        struct sdmmc_command cmd;
                    393:        int error;
                    394:
                    395:        SDMMC_LOCK(sc);
                    396:
                    397:        if ((error = sdmmc_select_card(sc, sf)) != 0)
                    398:                goto err;
                    399:
                    400:        bzero(&cmd, sizeof cmd);
                    401:        cmd.c_data = data;
                    402:        cmd.c_datalen = datalen;
                    403:        cmd.c_blklen = sf->csd.sector_size;
                    404:        cmd.c_opcode = (datalen / cmd.c_blklen) > 1 ?
                    405:            MMC_READ_BLOCK_MULTIPLE : MMC_READ_BLOCK_SINGLE;
                    406:        cmd.c_arg = blkno << 9;
                    407:        cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1;
                    408:
                    409:        error = sdmmc_mmc_command(sc, &cmd);
                    410:        if (error != 0)
                    411:                goto err;
                    412:
                    413:        /* XXX sdhc(4) does not need this */
                    414: #ifdef __zaurus__
                    415:        if (cmd.c_opcode == MMC_READ_BLOCK_MULTIPLE) {
                    416:                bzero(&cmd, sizeof cmd);
                    417:                cmd.c_opcode = MMC_STOP_TRANSMISSION;
                    418:                cmd.c_arg = MMC_ARG_RCA(sf->rca);
                    419:                cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B;
                    420:                error = sdmmc_mmc_command(sc, &cmd);
                    421:                if (error != 0)
                    422:                        goto err;
                    423:        }
                    424: #endif
                    425:
                    426:        do {
                    427:                bzero(&cmd, sizeof cmd);
                    428:                cmd.c_opcode = MMC_SEND_STATUS;
                    429:                cmd.c_arg = MMC_ARG_RCA(sf->rca);
                    430:                cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
                    431:                error = sdmmc_mmc_command(sc, &cmd);
                    432:                if (error != 0)
                    433:                        break;
                    434:                /* XXX time out */
                    435:        } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA));
                    436:
                    437: err:
                    438:        SDMMC_UNLOCK(sc);
                    439:        return error;
                    440: }
                    441:
                    442: int
                    443: sdmmc_mem_write_block(struct sdmmc_function *sf, int blkno, u_char *data,
                    444:     size_t datalen)
                    445: {
                    446:        struct sdmmc_softc *sc = sf->sc;
                    447:        struct sdmmc_command cmd;
                    448:        int error;
                    449:
                    450:        SDMMC_LOCK(sc);
                    451:
                    452:        if ((error = sdmmc_select_card(sc, sf)) != 0)
                    453:                goto err;
                    454:
                    455:        bzero(&cmd, sizeof cmd);
                    456:        cmd.c_data = data;
                    457:        cmd.c_datalen = datalen;
                    458:        cmd.c_blklen = sf->csd.sector_size;
                    459:        cmd.c_opcode = (datalen / cmd.c_blklen) > 1 ?
                    460:            MMC_WRITE_BLOCK_MULTIPLE : MMC_WRITE_BLOCK_SINGLE;
                    461:        cmd.c_arg = blkno << 9;
                    462:        cmd.c_flags = SCF_CMD_ADTC | SCF_RSP_R1;
                    463:
                    464:        error = sdmmc_mmc_command(sc, &cmd);
                    465:        if (error != 0)
                    466:                goto err;
                    467:
                    468:        /* XXX sdhc(4) does not need this */
                    469: #ifdef __zaurus__
                    470:        if (cmd.c_opcode == MMC_WRITE_BLOCK_MULTIPLE) {
                    471:                bzero(&cmd, sizeof cmd);
                    472:                cmd.c_opcode = MMC_STOP_TRANSMISSION;
                    473:                cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B;
                    474:                error = sdmmc_mmc_command(sc, &cmd);
                    475:                if (error != 0)
                    476:                        goto err;
                    477:        }
                    478: #endif
                    479:
                    480:        do {
                    481:                bzero(&cmd, sizeof cmd);
                    482:                cmd.c_opcode = MMC_SEND_STATUS;
                    483:                cmd.c_arg = MMC_ARG_RCA(sf->rca);
                    484:                cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
                    485:                error = sdmmc_mmc_command(sc, &cmd);
                    486:                if (error != 0)
                    487:                        break;
                    488:                /* XXX time out */
                    489:        } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA));
                    490:
                    491: err:
                    492:        SDMMC_UNLOCK(sc);
                    493:        return error;
                    494: }

CVSweb