Annotation of qemu/hw/sd.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * SD Memory Card emulation as defined in the "SD Memory Card Physical
        !             3:  * layer specification, Version 1.10."
        !             4:  *
        !             5:  * Copyright (c) 2006 Andrzej Zaborowski  <[email protected]>
        !             6:  * Copyright (c) 2007 CodeSourcery
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  *
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in
        !            16:  *    the documentation and/or other materials provided with the
        !            17:  *    distribution.
        !            18:  *
        !            19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
        !            20:  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
        !            21:  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
        !            22:  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR
        !            23:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
        !            24:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
        !            25:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
        !            26:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
        !            27:  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            28:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        !            29:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            30:  */
        !            31: 
        !            32: #include "hw.h"
        !            33: #include "block.h"
        !            34: #include "sd.h"
        !            35: 
        !            36: //#define DEBUG_SD 1
        !            37: 
        !            38: #ifdef DEBUG_SD
        !            39: #define DPRINTF(fmt, args...) \
        !            40: do { printf("SD: " fmt , ##args); } while (0)
        !            41: #else
        !            42: #define DPRINTF(fmt, args...) do {} while(0)
        !            43: #endif
        !            44: 
        !            45: typedef enum {
        !            46:     sd_r0 = 0,    /* no response */
        !            47:     sd_r1,        /* normal response command */
        !            48:     sd_r2_i,      /* CID register */
        !            49:     sd_r2_s,      /* CSD register */
        !            50:     sd_r3,        /* OCR register */
        !            51:     sd_r6 = 6,    /* Published RCA response */
        !            52:     sd_r7,        /* Operating voltage */
        !            53:     sd_r1b = -1,
        !            54: } sd_rsp_type_t;
        !            55: 
        !            56: struct SDState {
        !            57:     enum {
        !            58:         sd_inactive,
        !            59:         sd_card_identification_mode,
        !            60:         sd_data_transfer_mode,
        !            61:     } mode;
        !            62:     enum {
        !            63:         sd_inactive_state = -1,
        !            64:         sd_idle_state = 0,
        !            65:         sd_ready_state,
        !            66:         sd_identification_state,
        !            67:         sd_standby_state,
        !            68:         sd_transfer_state,
        !            69:         sd_sendingdata_state,
        !            70:         sd_receivingdata_state,
        !            71:         sd_programming_state,
        !            72:         sd_disconnect_state,
        !            73:     } state;
        !            74:     uint32_t ocr;
        !            75:     uint8_t scr[8];
        !            76:     uint8_t cid[16];
        !            77:     uint8_t csd[16];
        !            78:     uint16_t rca;
        !            79:     uint32_t card_status;
        !            80:     uint8_t sd_status[64];
        !            81:     uint32_t vhs;
        !            82:     int wp_switch;
        !            83:     int *wp_groups;
        !            84:     uint32_t size;
        !            85:     int blk_len;
        !            86:     uint32_t erase_start;
        !            87:     uint32_t erase_end;
        !            88:     uint8_t pwd[16];
        !            89:     int pwd_len;
        !            90:     int function_group[6];
        !            91: 
        !            92:     int spi;
        !            93:     int current_cmd;
        !            94:     int blk_written;
        !            95:     uint32_t data_start;
        !            96:     uint32_t data_offset;
        !            97:     uint8_t data[512];
        !            98:     qemu_irq readonly_cb;
        !            99:     qemu_irq inserted_cb;
        !           100:     BlockDriverState *bdrv;
        !           101:     uint8_t *buf;
        !           102: };
        !           103: 
        !           104: static void sd_set_status(SDState *sd)
        !           105: {
        !           106:     switch (sd->state) {
        !           107:     case sd_inactive_state:
        !           108:         sd->mode = sd_inactive;
        !           109:         break;
        !           110: 
        !           111:     case sd_idle_state:
        !           112:     case sd_ready_state:
        !           113:     case sd_identification_state:
        !           114:         sd->mode = sd_card_identification_mode;
        !           115:         break;
        !           116: 
        !           117:     case sd_standby_state:
        !           118:     case sd_transfer_state:
        !           119:     case sd_sendingdata_state:
        !           120:     case sd_receivingdata_state:
        !           121:     case sd_programming_state:
        !           122:     case sd_disconnect_state:
        !           123:         sd->mode = sd_data_transfer_mode;
        !           124:         break;
        !           125:     }
        !           126: 
        !           127:     sd->card_status &= ~CURRENT_STATE;
        !           128:     sd->card_status |= sd->state << 9;
        !           129: }
        !           130: 
        !           131: static const sd_cmd_type_t sd_cmd_type[64] = {
        !           132:     sd_bc,   sd_none, sd_bcr,  sd_bcr,  sd_none, sd_none, sd_none, sd_ac,
        !           133:     sd_bcr,  sd_ac,   sd_ac,   sd_adtc, sd_ac,   sd_ac,   sd_none, sd_ac,
        !           134:     sd_ac,   sd_adtc, sd_adtc, sd_none, sd_none, sd_none, sd_none, sd_none,
        !           135:     sd_adtc, sd_adtc, sd_adtc, sd_adtc, sd_ac,   sd_ac,   sd_adtc, sd_none,
        !           136:     sd_ac,   sd_ac,   sd_none, sd_none, sd_none, sd_none, sd_ac,   sd_none,
        !           137:     sd_none, sd_none, sd_bc,   sd_none, sd_none, sd_none, sd_none, sd_none,
        !           138:     sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_ac,
        !           139:     sd_adtc, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none,
        !           140: };
        !           141: 
        !           142: static const sd_cmd_type_t sd_acmd_type[64] = {
        !           143:     sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_ac,   sd_none,
        !           144:     sd_none, sd_none, sd_none, sd_none, sd_none, sd_adtc, sd_none, sd_none,
        !           145:     sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_adtc, sd_ac,
        !           146:     sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none,
        !           147:     sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none,
        !           148:     sd_none, sd_bcr,  sd_ac,   sd_none, sd_none, sd_none, sd_none, sd_none,
        !           149:     sd_none, sd_none, sd_none, sd_adtc, sd_none, sd_none, sd_none, sd_none,
        !           150:     sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none,
        !           151: };
        !           152: 
        !           153: static const int sd_cmd_class[64] = {
        !           154:     0,  0,  0,  0,  0,  9, 10,  0,  0,  0,  0,  1,  0,  0,  0,  0,
        !           155:     2,  2,  2,  2,  3,  3,  3,  3,  4,  4,  4,  4,  6,  6,  6,  6,
        !           156:     5,  5, 10, 10, 10, 10,  5,  9,  9,  9,  7,  7,  7,  7,  7,  7,
        !           157:     7,  7, 10,  7,  9,  9,  9,  8,  8, 10,  8,  8,  8,  8,  8,  8,
        !           158: };
        !           159: 
        !           160: static uint8_t sd_crc7(void *message, size_t width)
        !           161: {
        !           162:     int i, bit;
        !           163:     uint8_t shift_reg = 0x00;
        !           164:     uint8_t *msg = (uint8_t *) message;
        !           165: 
        !           166:     for (i = 0; i < width; i ++, msg ++)
        !           167:         for (bit = 7; bit >= 0; bit --) {
        !           168:             shift_reg <<= 1;
        !           169:             if ((shift_reg >> 7) ^ ((*msg >> bit) & 1))
        !           170:                 shift_reg ^= 0x89;
        !           171:         }
        !           172: 
        !           173:     return shift_reg;
        !           174: }
        !           175: 
        !           176: static uint16_t sd_crc16(void *message, size_t width)
        !           177: {
        !           178:     int i, bit;
        !           179:     uint16_t shift_reg = 0x0000;
        !           180:     uint16_t *msg = (uint16_t *) message;
        !           181:     width <<= 1;
        !           182: 
        !           183:     for (i = 0; i < width; i ++, msg ++)
        !           184:         for (bit = 15; bit >= 0; bit --) {
        !           185:             shift_reg <<= 1;
        !           186:             if ((shift_reg >> 15) ^ ((*msg >> bit) & 1))
        !           187:                 shift_reg ^= 0x1011;
        !           188:         }
        !           189: 
        !           190:     return shift_reg;
        !           191: }
        !           192: 
        !           193: static void sd_set_ocr(SDState *sd)
        !           194: {
        !           195:     /* All voltages OK, card power-up OK, Standard Capacity SD Memory Card */
        !           196:     sd->ocr = 0x80ffff80;
        !           197: }
        !           198: 
        !           199: static void sd_set_scr(SDState *sd)
        !           200: {
        !           201:     sd->scr[0] = 0x00;         /* SCR Structure */
        !           202:     sd->scr[1] = 0x2f;         /* SD Security Support */
        !           203:     sd->scr[2] = 0x00;
        !           204:     sd->scr[3] = 0x00;
        !           205:     sd->scr[4] = 0x00;
        !           206:     sd->scr[5] = 0x00;
        !           207:     sd->scr[6] = 0x00;
        !           208:     sd->scr[7] = 0x00;
        !           209: }
        !           210: 
        !           211: #define MID    0xaa
        !           212: #define OID    "XY"
        !           213: #define PNM    "QEMU!"
        !           214: #define PRV    0x01
        !           215: #define MDT_YR 2006
        !           216: #define MDT_MON        2
        !           217: 
        !           218: static void sd_set_cid(SDState *sd)
        !           219: {
        !           220:     sd->cid[0] = MID;          /* Fake card manufacturer ID (MID) */
        !           221:     sd->cid[1] = OID[0];       /* OEM/Application ID (OID) */
        !           222:     sd->cid[2] = OID[1];
        !           223:     sd->cid[3] = PNM[0];       /* Fake product name (PNM) */
        !           224:     sd->cid[4] = PNM[1];
        !           225:     sd->cid[5] = PNM[2];
        !           226:     sd->cid[6] = PNM[3];
        !           227:     sd->cid[7] = PNM[4];
        !           228:     sd->cid[8] = PRV;          /* Fake product revision (PRV) */
        !           229:     sd->cid[9] = 0xde;         /* Fake serial number (PSN) */
        !           230:     sd->cid[10] = 0xad;
        !           231:     sd->cid[11] = 0xbe;
        !           232:     sd->cid[12] = 0xef;
        !           233:     sd->cid[13] = 0x00 |       /* Manufacture date (MDT) */
        !           234:         ((MDT_YR - 2000) / 10);
        !           235:     sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
        !           236:     sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
        !           237: }
        !           238: 
        !           239: #define HWBLOCK_SHIFT  9                       /* 512 bytes */
        !           240: #define SECTOR_SHIFT   5                       /* 16 kilobytes */
        !           241: #define WPGROUP_SHIFT  7                       /* 2 megs */
        !           242: #define CMULT_SHIFT    9                       /* 512 times HWBLOCK_SIZE */
        !           243: #define BLOCK_SIZE     (1 << (HWBLOCK_SHIFT))
        !           244: #define SECTOR_SIZE    (1 << (HWBLOCK_SHIFT + SECTOR_SHIFT))
        !           245: #define WPGROUP_SIZE   (1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
        !           246: 
        !           247: static const uint8_t sd_csd_rw_mask[16] = {
        !           248:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           249:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe,
        !           250: };
        !           251: 
        !           252: static void sd_set_csd(SDState *sd, uint32_t size)
        !           253: {
        !           254:     uint32_t csize = (size >> (CMULT_SHIFT + HWBLOCK_SHIFT)) - 1;
        !           255:     uint32_t sectsize = (1 << (SECTOR_SHIFT + 1)) - 1;
        !           256:     uint32_t wpsize = (1 << (WPGROUP_SHIFT + 1)) - 1;
        !           257: 
        !           258:     sd->csd[0] = 0x00;         /* CSD structure */
        !           259:     sd->csd[1] = 0x26;         /* Data read access-time-1 */
        !           260:     sd->csd[2] = 0x00;         /* Data read access-time-2 */
        !           261:     sd->csd[3] = 0x5a;         /* Max. data transfer rate */
        !           262:     sd->csd[4] = 0x5f;         /* Card Command Classes */
        !           263:     sd->csd[5] = 0x50 |                /* Max. read data block length */
        !           264:         HWBLOCK_SHIFT;
        !           265:     sd->csd[6] = 0xe0 |                /* Partial block for read allowed */
        !           266:         ((csize >> 10) & 0x03);
        !           267:     sd->csd[7] = 0x00 |                /* Device size */
        !           268:         ((csize >> 2) & 0xff);
        !           269:     sd->csd[8] = 0x3f |                /* Max. read current */
        !           270:         ((csize << 6) & 0xc0);
        !           271:     sd->csd[9] = 0xfc |                /* Max. write current */
        !           272:         ((CMULT_SHIFT - 2) >> 1);
        !           273:     sd->csd[10] = 0x40 |       /* Erase sector size */
        !           274:         (((CMULT_SHIFT - 2) << 7) & 0x80) | (sectsize >> 1);
        !           275:     sd->csd[11] = 0x00 |       /* Write protect group size */
        !           276:         ((sectsize << 7) & 0x80) | wpsize;
        !           277:     sd->csd[12] = 0x90 |       /* Write speed factor */
        !           278:         (HWBLOCK_SHIFT >> 2);
        !           279:     sd->csd[13] = 0x20 |       /* Max. write data block length */
        !           280:         ((HWBLOCK_SHIFT << 6) & 0xc0);
        !           281:     sd->csd[14] = 0x00;                /* File format group */
        !           282:     sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
        !           283: }
        !           284: 
        !           285: static void sd_set_rca(SDState *sd)
        !           286: {
        !           287:     sd->rca += 0x4567;
        !           288: }
        !           289: 
        !           290: #define CARD_STATUS_A  0x02004100
        !           291: #define CARD_STATUS_B  0x00c01e00
        !           292: #define CARD_STATUS_C  0xfd39a028
        !           293: 
        !           294: static void sd_set_cardstatus(SDState *sd)
        !           295: {
        !           296:     sd->card_status = 0x00000100;
        !           297: }
        !           298: 
        !           299: static void sd_set_sdstatus(SDState *sd)
        !           300: {
        !           301:     memset(sd->sd_status, 0, 64);
        !           302: }
        !           303: 
        !           304: static int sd_req_crc_validate(struct sd_request_s *req)
        !           305: {
        !           306:     uint8_t buffer[5];
        !           307:     buffer[0] = 0x40 | req->cmd;
        !           308:     buffer[1] = (req->arg >> 24) & 0xff;
        !           309:     buffer[2] = (req->arg >> 16) & 0xff;
        !           310:     buffer[3] = (req->arg >> 8) & 0xff;
        !           311:     buffer[4] = (req->arg >> 0) & 0xff;
        !           312:     return 0;
        !           313:     return sd_crc7(buffer, 5) != req->crc;     /* TODO */
        !           314: }
        !           315: 
        !           316: static void sd_response_r1_make(SDState *sd,
        !           317:                                 uint8_t *response, uint32_t last_status)
        !           318: {
        !           319:     uint32_t mask = CARD_STATUS_B ^ ILLEGAL_COMMAND;
        !           320:     uint32_t status;
        !           321: 
        !           322:     status = (sd->card_status & ~mask) | (last_status & mask);
        !           323:     sd->card_status &= ~CARD_STATUS_C | APP_CMD;
        !           324: 
        !           325:     response[0] = (status >> 24) & 0xff;
        !           326:     response[1] = (status >> 16) & 0xff;
        !           327:     response[2] = (status >> 8) & 0xff;
        !           328:     response[3] = (status >> 0) & 0xff;
        !           329: }
        !           330: 
        !           331: static void sd_response_r3_make(SDState *sd, uint8_t *response)
        !           332: {
        !           333:     response[0] = (sd->ocr >> 24) & 0xff;
        !           334:     response[1] = (sd->ocr >> 16) & 0xff;
        !           335:     response[2] = (sd->ocr >> 8) & 0xff;
        !           336:     response[3] = (sd->ocr >> 0) & 0xff;
        !           337: }
        !           338: 
        !           339: static void sd_response_r6_make(SDState *sd, uint8_t *response)
        !           340: {
        !           341:     uint16_t arg;
        !           342:     uint16_t status;
        !           343: 
        !           344:     arg = sd->rca;
        !           345:     status = ((sd->card_status >> 8) & 0xc000) |
        !           346:              ((sd->card_status >> 6) & 0x2000) |
        !           347:               (sd->card_status & 0x1fff);
        !           348: 
        !           349:     response[0] = (arg >> 8) & 0xff;
        !           350:     response[1] = arg & 0xff;
        !           351:     response[2] = (status >> 8) & 0xff;
        !           352:     response[3] = status & 0xff;
        !           353: }
        !           354: 
        !           355: static void sd_response_r7_make(SDState *sd, uint8_t *response)
        !           356: {
        !           357:     response[0] = (sd->vhs >> 24) & 0xff;
        !           358:     response[1] = (sd->vhs >> 16) & 0xff;
        !           359:     response[2] = (sd->vhs >>  8) & 0xff;
        !           360:     response[3] = (sd->vhs >>  0) & 0xff;
        !           361: }
        !           362: 
        !           363: static void sd_reset(SDState *sd, BlockDriverState *bdrv)
        !           364: {
        !           365:     uint32_t size;
        !           366:     uint64_t sect;
        !           367: 
        !           368:     bdrv_get_geometry(bdrv, &sect);
        !           369:     sect <<= 9;
        !           370: 
        !           371:     if (sect > 0x40000000)
        !           372:         size = 0x40000000;     /* 1 gig */
        !           373:     else
        !           374:         size = sect + 1;
        !           375: 
        !           376:     sect = (size >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)) + 1;
        !           377: 
        !           378:     sd->state = sd_idle_state;
        !           379:     sd->rca = 0x0000;
        !           380:     sd_set_ocr(sd);
        !           381:     sd_set_scr(sd);
        !           382:     sd_set_cid(sd);
        !           383:     sd_set_csd(sd, size);
        !           384:     sd_set_cardstatus(sd);
        !           385:     sd_set_sdstatus(sd);
        !           386: 
        !           387:     sd->bdrv = bdrv;
        !           388: 
        !           389:     if (sd->wp_groups)
        !           390:         qemu_free(sd->wp_groups);
        !           391:     sd->wp_switch = bdrv_is_read_only(bdrv);
        !           392:     sd->wp_groups = (int *) qemu_mallocz(sizeof(int) * sect);
        !           393:     memset(sd->function_group, 0, sizeof(int) * 6);
        !           394:     sd->erase_start = 0;
        !           395:     sd->erase_end = 0;
        !           396:     sd->size = size;
        !           397:     sd->blk_len = 0x200;
        !           398:     sd->pwd_len = 0;
        !           399: }
        !           400: 
        !           401: static void sd_cardchange(void *opaque)
        !           402: {
        !           403:     SDState *sd = opaque;
        !           404:     qemu_set_irq(sd->inserted_cb, bdrv_is_inserted(sd->bdrv));
        !           405:     if (bdrv_is_inserted(sd->bdrv)) {
        !           406:         sd_reset(sd, sd->bdrv);
        !           407:         qemu_set_irq(sd->readonly_cb, sd->wp_switch);
        !           408:     }
        !           409: }
        !           410: 
        !           411: /* We do not model the chip select pin, so allow the board to select
        !           412:    whether card should be in SSI or MMC/SD mode.  It is also up to the
        !           413:    board to ensure that ssi transfers only occur when the chip select
        !           414:    is asserted.  */
        !           415: SDState *sd_init(BlockDriverState *bs, int is_spi)
        !           416: {
        !           417:     SDState *sd;
        !           418: 
        !           419:     sd = (SDState *) qemu_mallocz(sizeof(SDState));
        !           420:     sd->buf = qemu_memalign(512, 512);
        !           421:     sd->spi = is_spi;
        !           422:     sd_reset(sd, bs);
        !           423:     bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd);
        !           424:     return sd;
        !           425: }
        !           426: 
        !           427: void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)
        !           428: {
        !           429:     sd->readonly_cb = readonly;
        !           430:     sd->inserted_cb = insert;
        !           431:     qemu_set_irq(readonly, bdrv_is_read_only(sd->bdrv));
        !           432:     qemu_set_irq(insert, bdrv_is_inserted(sd->bdrv));
        !           433: }
        !           434: 
        !           435: static void sd_erase(SDState *sd)
        !           436: {
        !           437:     int i, start, end;
        !           438:     if (!sd->erase_start || !sd->erase_end) {
        !           439:         sd->card_status |= ERASE_SEQ_ERROR;
        !           440:         return;
        !           441:     }
        !           442: 
        !           443:     start = sd->erase_start >>
        !           444:             (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
        !           445:     end = sd->erase_end >>
        !           446:             (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
        !           447:     sd->erase_start = 0;
        !           448:     sd->erase_end = 0;
        !           449:     sd->csd[14] |= 0x40;
        !           450: 
        !           451:     for (i = start; i <= end; i ++)
        !           452:         if (sd->wp_groups[i])
        !           453:             sd->card_status |= WP_ERASE_SKIP;
        !           454: }
        !           455: 
        !           456: static uint32_t sd_wpbits(SDState *sd, uint32_t addr)
        !           457: {
        !           458:     uint32_t i, wpnum;
        !           459:     uint32_t ret = 0;
        !           460: 
        !           461:     wpnum = addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
        !           462: 
        !           463:     for (i = 0; i < 32; i ++, wpnum ++, addr += WPGROUP_SIZE)
        !           464:         if (addr < sd->size && sd->wp_groups[wpnum])
        !           465:             ret |= (1 << i);
        !           466: 
        !           467:     return ret;
        !           468: }
        !           469: 
        !           470: static void sd_function_switch(SDState *sd, uint32_t arg)
        !           471: {
        !           472:     int i, mode, new_func, crc;
        !           473:     mode = !!(arg & 0x80000000);
        !           474: 
        !           475:     sd->data[0] = 0x00;                /* Maximum current consumption */
        !           476:     sd->data[1] = 0x01;
        !           477:     sd->data[2] = 0x80;                /* Supported group 6 functions */
        !           478:     sd->data[3] = 0x01;
        !           479:     sd->data[4] = 0x80;                /* Supported group 5 functions */
        !           480:     sd->data[5] = 0x01;
        !           481:     sd->data[6] = 0x80;                /* Supported group 4 functions */
        !           482:     sd->data[7] = 0x01;
        !           483:     sd->data[8] = 0x80;                /* Supported group 3 functions */
        !           484:     sd->data[9] = 0x01;
        !           485:     sd->data[10] = 0x80;       /* Supported group 2 functions */
        !           486:     sd->data[11] = 0x43;
        !           487:     sd->data[12] = 0x80;       /* Supported group 1 functions */
        !           488:     sd->data[13] = 0x03;
        !           489:     for (i = 0; i < 6; i ++) {
        !           490:         new_func = (arg >> (i * 4)) & 0x0f;
        !           491:         if (mode && new_func != 0x0f)
        !           492:             sd->function_group[i] = new_func;
        !           493:         sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4);
        !           494:     }
        !           495:     memset(&sd->data[17], 0, 47);
        !           496:     crc = sd_crc16(sd->data, 64);
        !           497:     sd->data[65] = crc >> 8;
        !           498:     sd->data[66] = crc & 0xff;
        !           499: }
        !           500: 
        !           501: static inline int sd_wp_addr(SDState *sd, uint32_t addr)
        !           502: {
        !           503:     return sd->wp_groups[addr >>
        !           504:             (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)];
        !           505: }
        !           506: 
        !           507: static void sd_lock_command(SDState *sd)
        !           508: {
        !           509:     int erase, lock, clr_pwd, set_pwd, pwd_len;
        !           510:     erase = !!(sd->data[0] & 0x08);
        !           511:     lock = sd->data[0] & 0x04;
        !           512:     clr_pwd = sd->data[0] & 0x02;
        !           513:     set_pwd = sd->data[0] & 0x01;
        !           514: 
        !           515:     if (sd->blk_len > 1)
        !           516:         pwd_len = sd->data[1];
        !           517:     else
        !           518:         pwd_len = 0;
        !           519: 
        !           520:     if (erase) {
        !           521:         if (!(sd->card_status & CARD_IS_LOCKED) || sd->blk_len > 1 ||
        !           522:                         set_pwd || clr_pwd || lock || sd->wp_switch ||
        !           523:                         (sd->csd[14] & 0x20)) {
        !           524:             sd->card_status |= LOCK_UNLOCK_FAILED;
        !           525:             return;
        !           526:         }
        !           527:         memset(sd->wp_groups, 0, sizeof(int) * (sd->size >>
        !           528:                         (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)));
        !           529:         sd->csd[14] &= ~0x10;
        !           530:         sd->card_status &= ~CARD_IS_LOCKED;
        !           531:         sd->pwd_len = 0;
        !           532:         /* Erasing the entire card here! */
        !           533:         printf("SD: Card force-erased by CMD42\n");
        !           534:         return;
        !           535:     }
        !           536: 
        !           537:     if (sd->blk_len < 2 + pwd_len ||
        !           538:                     pwd_len <= sd->pwd_len ||
        !           539:                     pwd_len > sd->pwd_len + 16) {
        !           540:         sd->card_status |= LOCK_UNLOCK_FAILED;
        !           541:         return;
        !           542:     }
        !           543: 
        !           544:     if (sd->pwd_len && memcmp(sd->pwd, sd->data + 2, sd->pwd_len)) {
        !           545:         sd->card_status |= LOCK_UNLOCK_FAILED;
        !           546:         return;
        !           547:     }
        !           548: 
        !           549:     pwd_len -= sd->pwd_len;
        !           550:     if ((pwd_len && !set_pwd) ||
        !           551:                     (clr_pwd && (set_pwd || lock)) ||
        !           552:                     (lock && !sd->pwd_len && !set_pwd) ||
        !           553:                     (!set_pwd && !clr_pwd &&
        !           554:                      (((sd->card_status & CARD_IS_LOCKED) && lock) ||
        !           555:                       (!(sd->card_status & CARD_IS_LOCKED) && !lock)))) {
        !           556:         sd->card_status |= LOCK_UNLOCK_FAILED;
        !           557:         return;
        !           558:     }
        !           559: 
        !           560:     if (set_pwd) {
        !           561:         memcpy(sd->pwd, sd->data + 2 + sd->pwd_len, pwd_len);
        !           562:         sd->pwd_len = pwd_len;
        !           563:     }
        !           564: 
        !           565:     if (clr_pwd) {
        !           566:         sd->pwd_len = 0;
        !           567:     }
        !           568: 
        !           569:     if (lock)
        !           570:         sd->card_status |= CARD_IS_LOCKED;
        !           571:     else
        !           572:         sd->card_status &= ~CARD_IS_LOCKED;
        !           573: }
        !           574: 
        !           575: static sd_rsp_type_t sd_normal_command(SDState *sd,
        !           576:                                        struct sd_request_s req)
        !           577: {
        !           578:     uint32_t rca = 0x0000;
        !           579: 
        !           580:     if (sd_cmd_type[req.cmd] == sd_ac || sd_cmd_type[req.cmd] == sd_adtc)
        !           581:         rca = req.arg >> 16;
        !           582: 
        !           583:     DPRINTF("CMD%d 0x%08x state %d\n", req.cmd, req.arg, sd->state);
        !           584:     switch (req.cmd) {
        !           585:     /* Basic commands (Class 0 and Class 1) */
        !           586:     case 0:    /* CMD0:   GO_IDLE_STATE */
        !           587:         switch (sd->state) {
        !           588:         case sd_inactive_state:
        !           589:             return sd->spi ? sd_r1 : sd_r0;
        !           590: 
        !           591:         default:
        !           592:             sd->state = sd_idle_state;
        !           593:             sd_reset(sd, sd->bdrv);
        !           594:             return sd->spi ? sd_r1 : sd_r0;
        !           595:         }
        !           596:         break;
        !           597: 
        !           598:     case 1:    /* CMD1:   SEND_OP_CMD */
        !           599:         if (!sd->spi)
        !           600:             goto bad_cmd;
        !           601: 
        !           602:         sd->state = sd_transfer_state;
        !           603:         return sd_r1;
        !           604: 
        !           605:     case 2:    /* CMD2:   ALL_SEND_CID */
        !           606:         if (sd->spi)
        !           607:             goto bad_cmd;
        !           608:         switch (sd->state) {
        !           609:         case sd_ready_state:
        !           610:             sd->state = sd_identification_state;
        !           611:             return sd_r2_i;
        !           612: 
        !           613:         default:
        !           614:             break;
        !           615:         }
        !           616:         break;
        !           617: 
        !           618:     case 3:    /* CMD3:   SEND_RELATIVE_ADDR */
        !           619:         if (sd->spi)
        !           620:             goto bad_cmd;
        !           621:         switch (sd->state) {
        !           622:         case sd_identification_state:
        !           623:         case sd_standby_state:
        !           624:             sd->state = sd_standby_state;
        !           625:             sd_set_rca(sd);
        !           626:             return sd_r6;
        !           627: 
        !           628:         default:
        !           629:             break;
        !           630:         }
        !           631:         break;
        !           632: 
        !           633:     case 4:    /* CMD4:   SEND_DSR */
        !           634:         if (sd->spi)
        !           635:             goto bad_cmd;
        !           636:         switch (sd->state) {
        !           637:         case sd_standby_state:
        !           638:             break;
        !           639: 
        !           640:         default:
        !           641:             break;
        !           642:         }
        !           643:         break;
        !           644: 
        !           645:     case 6:    /* CMD6:   SWITCH_FUNCTION */
        !           646:         if (sd->spi)
        !           647:             goto bad_cmd;
        !           648:         switch (sd->mode) {
        !           649:         case sd_data_transfer_mode:
        !           650:             sd_function_switch(sd, req.arg);
        !           651:             sd->state = sd_sendingdata_state;
        !           652:             sd->data_start = 0;
        !           653:             sd->data_offset = 0;
        !           654:             return sd_r1;
        !           655: 
        !           656:         default:
        !           657:             break;
        !           658:         }
        !           659:         break;
        !           660: 
        !           661:     case 7:    /* CMD7:   SELECT/DESELECT_CARD */
        !           662:         if (sd->spi)
        !           663:             goto bad_cmd;
        !           664:         switch (sd->state) {
        !           665:         case sd_standby_state:
        !           666:             if (sd->rca != rca)
        !           667:                 return sd_r0;
        !           668: 
        !           669:             sd->state = sd_transfer_state;
        !           670:             return sd_r1b;
        !           671: 
        !           672:         case sd_transfer_state:
        !           673:         case sd_sendingdata_state:
        !           674:             if (sd->rca == rca)
        !           675:                 break;
        !           676: 
        !           677:             sd->state = sd_standby_state;
        !           678:             return sd_r1b;
        !           679: 
        !           680:         case sd_disconnect_state:
        !           681:             if (sd->rca != rca)
        !           682:                 return sd_r0;
        !           683: 
        !           684:             sd->state = sd_programming_state;
        !           685:             return sd_r1b;
        !           686: 
        !           687:         case sd_programming_state:
        !           688:             if (sd->rca == rca)
        !           689:                 break;
        !           690: 
        !           691:             sd->state = sd_disconnect_state;
        !           692:             return sd_r1b;
        !           693: 
        !           694:         default:
        !           695:             break;
        !           696:         }
        !           697:         break;
        !           698: 
        !           699:     case 8:    /* CMD8:   SEND_IF_COND */
        !           700:         /* Physical Layer Specification Version 2.00 command */
        !           701:         switch (sd->state) {
        !           702:         case sd_idle_state:
        !           703:             sd->vhs = 0;
        !           704: 
        !           705:             /* No response if not exactly one VHS bit is set.  */
        !           706:             if (!(req.arg >> 8) || (req.arg >> ffs(req.arg & ~0xff)))
        !           707:                 return sd->spi ? sd_r7 : sd_r0;
        !           708: 
        !           709:             /* Accept.  */
        !           710:             sd->vhs = req.arg;
        !           711:             return sd_r7;
        !           712: 
        !           713:         default:
        !           714:             break;
        !           715:         }
        !           716:         break;
        !           717: 
        !           718:     case 9:    /* CMD9:   SEND_CSD */
        !           719:         switch (sd->state) {
        !           720:         case sd_standby_state:
        !           721:             if (sd->rca != rca)
        !           722:                 return sd_r0;
        !           723: 
        !           724:             return sd_r2_s;
        !           725: 
        !           726:         case sd_transfer_state:
        !           727:             if (!sd->spi)
        !           728:                 break;
        !           729:             sd->state = sd_sendingdata_state;
        !           730:             memcpy(sd->data, sd->csd, 16);
        !           731:             sd->data_start = req.arg;
        !           732:             sd->data_offset = 0;
        !           733:             return sd_r1;
        !           734: 
        !           735:         default:
        !           736:             break;
        !           737:         }
        !           738:         break;
        !           739: 
        !           740:     case 10:   /* CMD10:  SEND_CID */
        !           741:         switch (sd->state) {
        !           742:         case sd_standby_state:
        !           743:             if (sd->rca != rca)
        !           744:                 return sd_r0;
        !           745: 
        !           746:             return sd_r2_i;
        !           747: 
        !           748:         case sd_transfer_state:
        !           749:             if (!sd->spi)
        !           750:                 break;
        !           751:             sd->state = sd_sendingdata_state;
        !           752:             memcpy(sd->data, sd->cid, 16);
        !           753:             sd->data_start = req.arg;
        !           754:             sd->data_offset = 0;
        !           755:             return sd_r1;
        !           756: 
        !           757:         default:
        !           758:             break;
        !           759:         }
        !           760:         break;
        !           761: 
        !           762:     case 11:   /* CMD11:  READ_DAT_UNTIL_STOP */
        !           763:         if (sd->spi)
        !           764:             goto bad_cmd;
        !           765:         switch (sd->state) {
        !           766:         case sd_transfer_state:
        !           767:             sd->state = sd_sendingdata_state;
        !           768:             sd->data_start = req.arg;
        !           769:             sd->data_offset = 0;
        !           770: 
        !           771:             if (sd->data_start + sd->blk_len > sd->size)
        !           772:                 sd->card_status |= ADDRESS_ERROR;
        !           773:             return sd_r0;
        !           774: 
        !           775:         default:
        !           776:             break;
        !           777:         }
        !           778:         break;
        !           779: 
        !           780:     case 12:   /* CMD12:  STOP_TRANSMISSION */
        !           781:         switch (sd->state) {
        !           782:         case sd_sendingdata_state:
        !           783:             sd->state = sd_transfer_state;
        !           784:             return sd_r1b;
        !           785: 
        !           786:         case sd_receivingdata_state:
        !           787:             sd->state = sd_programming_state;
        !           788:             /* Bzzzzzzztt .... Operation complete.  */
        !           789:             sd->state = sd_transfer_state;
        !           790:             return sd_r1b;
        !           791: 
        !           792:         default:
        !           793:             break;
        !           794:         }
        !           795:         break;
        !           796: 
        !           797:     case 13:   /* CMD13:  SEND_STATUS */
        !           798:         switch (sd->mode) {
        !           799:         case sd_data_transfer_mode:
        !           800:             if (sd->rca != rca)
        !           801:                 return sd_r0;
        !           802: 
        !           803:             return sd_r1;
        !           804: 
        !           805:         default:
        !           806:             break;
        !           807:         }
        !           808:         break;
        !           809: 
        !           810:     case 15:   /* CMD15:  GO_INACTIVE_STATE */
        !           811:         if (sd->spi)
        !           812:             goto bad_cmd;
        !           813:         switch (sd->mode) {
        !           814:         case sd_data_transfer_mode:
        !           815:             if (sd->rca != rca)
        !           816:                 return sd_r0;
        !           817: 
        !           818:             sd->state = sd_inactive_state;
        !           819:             return sd_r0;
        !           820: 
        !           821:         default:
        !           822:             break;
        !           823:         }
        !           824:         break;
        !           825: 
        !           826:     /* Block read commands (Classs 2) */
        !           827:     case 16:   /* CMD16:  SET_BLOCKLEN */
        !           828:         switch (sd->state) {
        !           829:         case sd_transfer_state:
        !           830:             if (req.arg > (1 << HWBLOCK_SHIFT))
        !           831:                 sd->card_status |= BLOCK_LEN_ERROR;
        !           832:             else
        !           833:                 sd->blk_len = req.arg;
        !           834: 
        !           835:             return sd_r1;
        !           836: 
        !           837:         default:
        !           838:             break;
        !           839:         }
        !           840:         break;
        !           841: 
        !           842:     case 17:   /* CMD17:  READ_SINGLE_BLOCK */
        !           843:         switch (sd->state) {
        !           844:         case sd_transfer_state:
        !           845:             sd->state = sd_sendingdata_state;
        !           846:             sd->data_start = req.arg;
        !           847:             sd->data_offset = 0;
        !           848: 
        !           849:             if (sd->data_start + sd->blk_len > sd->size)
        !           850:                 sd->card_status |= ADDRESS_ERROR;
        !           851:             return sd_r1;
        !           852: 
        !           853:         default:
        !           854:             break;
        !           855:         }
        !           856:         break;
        !           857: 
        !           858:     case 18:   /* CMD18:  READ_MULTIPLE_BLOCK */
        !           859:         switch (sd->state) {
        !           860:         case sd_transfer_state:
        !           861:             sd->state = sd_sendingdata_state;
        !           862:             sd->data_start = req.arg;
        !           863:             sd->data_offset = 0;
        !           864: 
        !           865:             if (sd->data_start + sd->blk_len > sd->size)
        !           866:                 sd->card_status |= ADDRESS_ERROR;
        !           867:             return sd_r1;
        !           868: 
        !           869:         default:
        !           870:             break;
        !           871:         }
        !           872:         break;
        !           873: 
        !           874:     /* Block write commands (Class 4) */
        !           875:     case 24:   /* CMD24:  WRITE_SINGLE_BLOCK */
        !           876:         if (sd->spi)
        !           877:             goto unimplemented_cmd;
        !           878:         switch (sd->state) {
        !           879:         case sd_transfer_state:
        !           880:             /* Writing in SPI mode not implemented.  */
        !           881:             if (sd->spi)
        !           882:                 break;
        !           883:             sd->state = sd_receivingdata_state;
        !           884:             sd->data_start = req.arg;
        !           885:             sd->data_offset = 0;
        !           886:             sd->blk_written = 0;
        !           887: 
        !           888:             if (sd->data_start + sd->blk_len > sd->size)
        !           889:                 sd->card_status |= ADDRESS_ERROR;
        !           890:             if (sd_wp_addr(sd, sd->data_start))
        !           891:                 sd->card_status |= WP_VIOLATION;
        !           892:             if (sd->csd[14] & 0x30)
        !           893:                 sd->card_status |= WP_VIOLATION;
        !           894:             return sd_r1;
        !           895: 
        !           896:         default:
        !           897:             break;
        !           898:         }
        !           899:         break;
        !           900: 
        !           901:     case 25:   /* CMD25:  WRITE_MULTIPLE_BLOCK */
        !           902:         if (sd->spi)
        !           903:             goto unimplemented_cmd;
        !           904:         switch (sd->state) {
        !           905:         case sd_transfer_state:
        !           906:             /* Writing in SPI mode not implemented.  */
        !           907:             if (sd->spi)
        !           908:                 break;
        !           909:             sd->state = sd_receivingdata_state;
        !           910:             sd->data_start = req.arg;
        !           911:             sd->data_offset = 0;
        !           912:             sd->blk_written = 0;
        !           913: 
        !           914:             if (sd->data_start + sd->blk_len > sd->size)
        !           915:                 sd->card_status |= ADDRESS_ERROR;
        !           916:             if (sd_wp_addr(sd, sd->data_start))
        !           917:                 sd->card_status |= WP_VIOLATION;
        !           918:             if (sd->csd[14] & 0x30)
        !           919:                 sd->card_status |= WP_VIOLATION;
        !           920:             return sd_r1;
        !           921: 
        !           922:         default:
        !           923:             break;
        !           924:         }
        !           925:         break;
        !           926: 
        !           927:     case 26:   /* CMD26:  PROGRAM_CID */
        !           928:         if (sd->spi)
        !           929:             goto bad_cmd;
        !           930:         switch (sd->state) {
        !           931:         case sd_transfer_state:
        !           932:             sd->state = sd_receivingdata_state;
        !           933:             sd->data_start = 0;
        !           934:             sd->data_offset = 0;
        !           935:             return sd_r1;
        !           936: 
        !           937:         default:
        !           938:             break;
        !           939:         }
        !           940:         break;
        !           941: 
        !           942:     case 27:   /* CMD27:  PROGRAM_CSD */
        !           943:         if (sd->spi)
        !           944:             goto unimplemented_cmd;
        !           945:         switch (sd->state) {
        !           946:         case sd_transfer_state:
        !           947:             sd->state = sd_receivingdata_state;
        !           948:             sd->data_start = 0;
        !           949:             sd->data_offset = 0;
        !           950:             return sd_r1;
        !           951: 
        !           952:         default:
        !           953:             break;
        !           954:         }
        !           955:         break;
        !           956: 
        !           957:     /* Write protection (Class 6) */
        !           958:     case 28:   /* CMD28:  SET_WRITE_PROT */
        !           959:         switch (sd->state) {
        !           960:         case sd_transfer_state:
        !           961:             if (req.arg >= sd->size) {
        !           962:                 sd->card_status = ADDRESS_ERROR;
        !           963:                 return sd_r1b;
        !           964:             }
        !           965: 
        !           966:             sd->state = sd_programming_state;
        !           967:             sd->wp_groups[req.arg >> (HWBLOCK_SHIFT +
        !           968:                             SECTOR_SHIFT + WPGROUP_SHIFT)] = 1;
        !           969:             /* Bzzzzzzztt .... Operation complete.  */
        !           970:             sd->state = sd_transfer_state;
        !           971:             return sd_r1b;
        !           972: 
        !           973:         default:
        !           974:             break;
        !           975:         }
        !           976:         break;
        !           977: 
        !           978:     case 29:   /* CMD29:  CLR_WRITE_PROT */
        !           979:         switch (sd->state) {
        !           980:         case sd_transfer_state:
        !           981:             if (req.arg >= sd->size) {
        !           982:                 sd->card_status = ADDRESS_ERROR;
        !           983:                 return sd_r1b;
        !           984:             }
        !           985: 
        !           986:             sd->state = sd_programming_state;
        !           987:             sd->wp_groups[req.arg >> (HWBLOCK_SHIFT +
        !           988:                             SECTOR_SHIFT + WPGROUP_SHIFT)] = 0;
        !           989:             /* Bzzzzzzztt .... Operation complete.  */
        !           990:             sd->state = sd_transfer_state;
        !           991:             return sd_r1b;
        !           992: 
        !           993:         default:
        !           994:             break;
        !           995:         }
        !           996:         break;
        !           997: 
        !           998:     case 30:   /* CMD30:  SEND_WRITE_PROT */
        !           999:         switch (sd->state) {
        !          1000:         case sd_transfer_state:
        !          1001:             sd->state = sd_sendingdata_state;
        !          1002:             *(uint32_t *) sd->data = sd_wpbits(sd, req.arg);
        !          1003:             sd->data_start = req.arg;
        !          1004:             sd->data_offset = 0;
        !          1005:             return sd_r1b;
        !          1006: 
        !          1007:         default:
        !          1008:             break;
        !          1009:         }
        !          1010:         break;
        !          1011: 
        !          1012:     /* Erase commands (Class 5) */
        !          1013:     case 32:   /* CMD32:  ERASE_WR_BLK_START */
        !          1014:         switch (sd->state) {
        !          1015:         case sd_transfer_state:
        !          1016:             sd->erase_start = req.arg;
        !          1017:             return sd_r1;
        !          1018: 
        !          1019:         default:
        !          1020:             break;
        !          1021:         }
        !          1022:         break;
        !          1023: 
        !          1024:     case 33:   /* CMD33:  ERASE_WR_BLK_END */
        !          1025:         switch (sd->state) {
        !          1026:         case sd_transfer_state:
        !          1027:             sd->erase_end = req.arg;
        !          1028:             return sd_r1;
        !          1029: 
        !          1030:         default:
        !          1031:             break;
        !          1032:         }
        !          1033:         break;
        !          1034: 
        !          1035:     case 38:   /* CMD38:  ERASE */
        !          1036:         switch (sd->state) {
        !          1037:         case sd_transfer_state:
        !          1038:             if (sd->csd[14] & 0x30) {
        !          1039:                 sd->card_status |= WP_VIOLATION;
        !          1040:                 return sd_r1b;
        !          1041:             }
        !          1042: 
        !          1043:             sd->state = sd_programming_state;
        !          1044:             sd_erase(sd);
        !          1045:             /* Bzzzzzzztt .... Operation complete.  */
        !          1046:             sd->state = sd_transfer_state;
        !          1047:             return sd_r1b;
        !          1048: 
        !          1049:         default:
        !          1050:             break;
        !          1051:         }
        !          1052:         break;
        !          1053: 
        !          1054:     /* Lock card commands (Class 7) */
        !          1055:     case 42:   /* CMD42:  LOCK_UNLOCK */
        !          1056:         if (sd->spi)
        !          1057:             goto unimplemented_cmd;
        !          1058:         switch (sd->state) {
        !          1059:         case sd_transfer_state:
        !          1060:             sd->state = sd_receivingdata_state;
        !          1061:             sd->data_start = 0;
        !          1062:             sd->data_offset = 0;
        !          1063:             return sd_r1;
        !          1064: 
        !          1065:         default:
        !          1066:             break;
        !          1067:         }
        !          1068:         break;
        !          1069: 
        !          1070:     /* Application specific commands (Class 8) */
        !          1071:     case 55:   /* CMD55:  APP_CMD */
        !          1072:         if (sd->rca != rca)
        !          1073:             return sd_r0;
        !          1074: 
        !          1075:         sd->card_status |= APP_CMD;
        !          1076:         return sd_r1;
        !          1077: 
        !          1078:     case 56:   /* CMD56:  GEN_CMD */
        !          1079:         printf("SD: GEN_CMD 0x%08x\n", req.arg);
        !          1080: 
        !          1081:         switch (sd->state) {
        !          1082:         case sd_transfer_state:
        !          1083:             sd->data_offset = 0;
        !          1084:             if (req.arg & 1)
        !          1085:                 sd->state = sd_sendingdata_state;
        !          1086:             else
        !          1087:                 sd->state = sd_receivingdata_state;
        !          1088:             return sd_r1;
        !          1089: 
        !          1090:         default:
        !          1091:             break;
        !          1092:         }
        !          1093:         break;
        !          1094: 
        !          1095:     default:
        !          1096:     bad_cmd:
        !          1097:         sd->card_status |= ILLEGAL_COMMAND;
        !          1098: 
        !          1099:         printf("SD: Unknown CMD%i\n", req.cmd);
        !          1100:         return sd_r0;
        !          1101: 
        !          1102:     unimplemented_cmd:
        !          1103:         /* Commands that are recognised but not yet implemented in SPI mode.  */
        !          1104:         sd->card_status |= ILLEGAL_COMMAND;
        !          1105:         printf ("SD: CMD%i not implemented in SPI mode\n", req.cmd);
        !          1106:         return sd_r0;
        !          1107:     }
        !          1108: 
        !          1109:     sd->card_status |= ILLEGAL_COMMAND;
        !          1110:     printf("SD: CMD%i in a wrong state\n", req.cmd);
        !          1111:     return sd_r0;
        !          1112: }
        !          1113: 
        !          1114: static sd_rsp_type_t sd_app_command(SDState *sd,
        !          1115:                                     struct sd_request_s req) {
        !          1116:     uint32_t rca;
        !          1117: 
        !          1118:     if (sd_cmd_type[req.cmd] == sd_ac || sd_cmd_type[req.cmd] == sd_adtc)
        !          1119:         rca = req.arg >> 16;
        !          1120: 
        !          1121:     DPRINTF("ACMD%d 0x%08x\n", req.cmd, req.arg);
        !          1122:     switch (req.cmd) {
        !          1123:     case 6:    /* ACMD6:  SET_BUS_WIDTH */
        !          1124:         switch (sd->state) {
        !          1125:         case sd_transfer_state:
        !          1126:             sd->sd_status[0] &= 0x3f;
        !          1127:             sd->sd_status[0] |= (req.arg & 0x03) << 6;
        !          1128:             return sd_r1;
        !          1129: 
        !          1130:         default:
        !          1131:             break;
        !          1132:         }
        !          1133:         break;
        !          1134: 
        !          1135:     case 13:   /* ACMD13: SD_STATUS */
        !          1136:         switch (sd->state) {
        !          1137:         case sd_transfer_state:
        !          1138:             sd->data_start = 0;
        !          1139:             sd->data_offset = 0;
        !          1140:             return sd_r1;
        !          1141: 
        !          1142:         default:
        !          1143:             break;
        !          1144:         }
        !          1145:         break;
        !          1146: 
        !          1147:     case 22:   /* ACMD22: SEND_NUM_WR_BLOCKS */
        !          1148:         switch (sd->state) {
        !          1149:         case sd_transfer_state:
        !          1150:             *(uint32_t *) sd->data = sd->blk_written;
        !          1151: 
        !          1152:             sd->data_start = 0;
        !          1153:             sd->data_offset = 0;
        !          1154:             return sd_r1;
        !          1155: 
        !          1156:         default:
        !          1157:             break;
        !          1158:         }
        !          1159:         break;
        !          1160: 
        !          1161:     case 23:   /* ACMD23: SET_WR_BLK_ERASE_COUNT */
        !          1162:         switch (sd->state) {
        !          1163:         case sd_transfer_state:
        !          1164:             return sd_r1;
        !          1165: 
        !          1166:         default:
        !          1167:             break;
        !          1168:         }
        !          1169:         break;
        !          1170: 
        !          1171:     case 41:   /* ACMD41: SD_APP_OP_COND */
        !          1172:         if (sd->spi) {
        !          1173:             /* SEND_OP_CMD */
        !          1174:             sd->state = sd_transfer_state;
        !          1175:             return sd_r1;
        !          1176:         }
        !          1177:         switch (sd->state) {
        !          1178:         case sd_idle_state:
        !          1179:             /* We accept any voltage.  10000 V is nothing.  */
        !          1180:             if (req.arg)
        !          1181:                 sd->state = sd_ready_state;
        !          1182: 
        !          1183:             return sd_r3;
        !          1184: 
        !          1185:         default:
        !          1186:             break;
        !          1187:         }
        !          1188:         break;
        !          1189: 
        !          1190:     case 42:   /* ACMD42: SET_CLR_CARD_DETECT */
        !          1191:         switch (sd->state) {
        !          1192:         case sd_transfer_state:
        !          1193:             /* Bringing in the 50KOhm pull-up resistor... Done.  */
        !          1194:             return sd_r1;
        !          1195: 
        !          1196:         default:
        !          1197:             break;
        !          1198:         }
        !          1199:         break;
        !          1200: 
        !          1201:     case 51:   /* ACMD51: SEND_SCR */
        !          1202:         switch (sd->state) {
        !          1203:         case sd_transfer_state:
        !          1204:             sd->state = sd_sendingdata_state;
        !          1205:             sd->data_start = 0;
        !          1206:             sd->data_offset = 0;
        !          1207:             return sd_r1;
        !          1208: 
        !          1209:         default:
        !          1210:             break;
        !          1211:         }
        !          1212:         break;
        !          1213: 
        !          1214:     default:
        !          1215:         /* Fall back to standard commands.  */
        !          1216:         sd->card_status &= ~APP_CMD;
        !          1217:         return sd_normal_command(sd, req);
        !          1218:     }
        !          1219: 
        !          1220:     printf("SD: ACMD%i in a wrong state\n", req.cmd);
        !          1221:     return sd_r0;
        !          1222: }
        !          1223: 
        !          1224: int sd_do_command(SDState *sd, struct sd_request_s *req,
        !          1225:                   uint8_t *response) {
        !          1226:     uint32_t last_status = sd->card_status;
        !          1227:     sd_rsp_type_t rtype;
        !          1228:     int rsplen;
        !          1229: 
        !          1230:     if (!bdrv_is_inserted(sd->bdrv)) {
        !          1231:         return 0;
        !          1232:     }
        !          1233: 
        !          1234:     if (sd_req_crc_validate(req)) {
        !          1235:         sd->card_status &= ~COM_CRC_ERROR;
        !          1236:         return 0;
        !          1237:     }
        !          1238: 
        !          1239:     sd->card_status &= ~CARD_STATUS_B;
        !          1240:     sd_set_status(sd);
        !          1241: 
        !          1242:     if (last_status & CARD_IS_LOCKED)
        !          1243:         if (((last_status & APP_CMD) &&
        !          1244:                                  req->cmd == 41) ||
        !          1245:                         (!(last_status & APP_CMD) &&
        !          1246:                          (sd_cmd_class[req->cmd] == 0 ||
        !          1247:                           sd_cmd_class[req->cmd] == 7 ||
        !          1248:                           req->cmd == 16 || req->cmd == 55))) {
        !          1249:             sd->card_status |= ILLEGAL_COMMAND;
        !          1250:             printf("SD: Card is locked\n");
        !          1251:             return 0;
        !          1252:         }
        !          1253: 
        !          1254:     if (last_status & APP_CMD) {
        !          1255:         rtype = sd_app_command(sd, *req);
        !          1256:         sd->card_status &= ~APP_CMD;
        !          1257:     } else
        !          1258:         rtype = sd_normal_command(sd, *req);
        !          1259: 
        !          1260:     sd->current_cmd = req->cmd;
        !          1261: 
        !          1262:     switch (rtype) {
        !          1263:     case sd_r1:
        !          1264:     case sd_r1b:
        !          1265:         sd_response_r1_make(sd, response, last_status);
        !          1266:         rsplen = 4;
        !          1267:         break;
        !          1268: 
        !          1269:     case sd_r2_i:
        !          1270:         memcpy(response, sd->cid, sizeof(sd->cid));
        !          1271:         rsplen = 16;
        !          1272:         break;
        !          1273: 
        !          1274:     case sd_r2_s:
        !          1275:         memcpy(response, sd->csd, sizeof(sd->csd));
        !          1276:         rsplen = 16;
        !          1277:         break;
        !          1278: 
        !          1279:     case sd_r3:
        !          1280:         sd_response_r3_make(sd, response);
        !          1281:         rsplen = 4;
        !          1282:         break;
        !          1283: 
        !          1284:     case sd_r6:
        !          1285:         sd_response_r6_make(sd, response);
        !          1286:         rsplen = 4;
        !          1287:         break;
        !          1288: 
        !          1289:     case sd_r7:
        !          1290:         sd_response_r7_make(sd, response);
        !          1291:         rsplen = 4;
        !          1292:         break;
        !          1293: 
        !          1294:     case sd_r0:
        !          1295:     default:
        !          1296:         rsplen = 0;
        !          1297:         break;
        !          1298:     }
        !          1299: 
        !          1300:     if (sd->card_status & ILLEGAL_COMMAND)
        !          1301:         rsplen = 0;
        !          1302: 
        !          1303: #ifdef DEBUG_SD
        !          1304:     if (rsplen) {
        !          1305:         int i;
        !          1306:         DPRINTF("Response:");
        !          1307:         for (i = 0; i < rsplen; i++)
        !          1308:             printf(" %02x", response[i]);
        !          1309:         printf(" state %d\n", sd->state);
        !          1310:     } else {
        !          1311:         DPRINTF("No response %d\n", sd->state);
        !          1312:     }
        !          1313: #endif
        !          1314: 
        !          1315:     return rsplen;
        !          1316: }
        !          1317: 
        !          1318: /* No real need for 64 bit addresses here */
        !          1319: static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len)
        !          1320: {
        !          1321:     uint32_t end = addr + len;
        !          1322: 
        !          1323:     if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
        !          1324:         printf("sd_blk_read: read error on host side\n");
        !          1325:         return;
        !          1326:     }
        !          1327: 
        !          1328:     if (end > (addr & ~511) + 512) {
        !          1329:         memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511));
        !          1330: 
        !          1331:         if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {
        !          1332:             printf("sd_blk_read: read error on host side\n");
        !          1333:             return;
        !          1334:         }
        !          1335:         memcpy(sd->data + 512 - (addr & 511), sd->buf, end & 511);
        !          1336:     } else
        !          1337:         memcpy(sd->data, sd->buf + (addr & 511), len);
        !          1338: }
        !          1339: 
        !          1340: static void sd_blk_write(SDState *sd, uint32_t addr, uint32_t len)
        !          1341: {
        !          1342:     uint32_t end = addr + len;
        !          1343: 
        !          1344:     if ((addr & 511) || len < 512)
        !          1345:         if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
        !          1346:             printf("sd_blk_write: read error on host side\n");
        !          1347:             return;
        !          1348:         }
        !          1349: 
        !          1350:     if (end > (addr & ~511) + 512) {
        !          1351:         memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511));
        !          1352:         if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
        !          1353:             printf("sd_blk_write: write error on host side\n");
        !          1354:             return;
        !          1355:         }
        !          1356: 
        !          1357:         if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {
        !          1358:             printf("sd_blk_write: read error on host side\n");
        !          1359:             return;
        !          1360:         }
        !          1361:         memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511);
        !          1362:         if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) == -1)
        !          1363:             printf("sd_blk_write: write error on host side\n");
        !          1364:     } else {
        !          1365:         memcpy(sd->buf + (addr & 511), sd->data, len);
        !          1366:         if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1)
        !          1367:             printf("sd_blk_write: write error on host side\n");
        !          1368:     }
        !          1369: }
        !          1370: 
        !          1371: #define BLK_READ_BLOCK(a, len) sd_blk_read(sd, a, len)
        !          1372: #define BLK_WRITE_BLOCK(a, len)        sd_blk_write(sd, a, len)
        !          1373: #define APP_READ_BLOCK(a, len) memset(sd->data, 0xec, len)
        !          1374: #define APP_WRITE_BLOCK(a, len)
        !          1375: 
        !          1376: void sd_write_data(SDState *sd, uint8_t value)
        !          1377: {
        !          1378:     int i;
        !          1379: 
        !          1380:     if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))
        !          1381:         return;
        !          1382: 
        !          1383:     if (sd->state != sd_receivingdata_state) {
        !          1384:         printf("sd_write_data: not in Receiving-Data state\n");
        !          1385:         return;
        !          1386:     }
        !          1387: 
        !          1388:     if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
        !          1389:         return;
        !          1390: 
        !          1391:     switch (sd->current_cmd) {
        !          1392:     case 24:   /* CMD24:  WRITE_SINGLE_BLOCK */
        !          1393:         sd->data[sd->data_offset ++] = value;
        !          1394:         if (sd->data_offset >= sd->blk_len) {
        !          1395:             /* TODO: Check CRC before committing */
        !          1396:             sd->state = sd_programming_state;
        !          1397:             BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
        !          1398:             sd->blk_written ++;
        !          1399:             sd->csd[14] |= 0x40;
        !          1400:             /* Bzzzzzzztt .... Operation complete.  */
        !          1401:             sd->state = sd_transfer_state;
        !          1402:         }
        !          1403:         break;
        !          1404: 
        !          1405:     case 25:   /* CMD25:  WRITE_MULTIPLE_BLOCK */
        !          1406:         sd->data[sd->data_offset ++] = value;
        !          1407:         if (sd->data_offset >= sd->blk_len) {
        !          1408:             /* TODO: Check CRC before committing */
        !          1409:             sd->state = sd_programming_state;
        !          1410:             BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
        !          1411:             sd->blk_written ++;
        !          1412:             sd->data_start += sd->blk_len;
        !          1413:             sd->data_offset = 0;
        !          1414:             if (sd->data_start + sd->blk_len > sd->size) {
        !          1415:                 sd->card_status |= ADDRESS_ERROR;
        !          1416:                 break;
        !          1417:             }
        !          1418:             if (sd_wp_addr(sd, sd->data_start)) {
        !          1419:                 sd->card_status |= WP_VIOLATION;
        !          1420:                 break;
        !          1421:             }
        !          1422:             sd->csd[14] |= 0x40;
        !          1423: 
        !          1424:             /* Bzzzzzzztt .... Operation complete.  */
        !          1425:             sd->state = sd_receivingdata_state;
        !          1426:         }
        !          1427:         break;
        !          1428: 
        !          1429:     case 26:   /* CMD26:  PROGRAM_CID */
        !          1430:         sd->data[sd->data_offset ++] = value;
        !          1431:         if (sd->data_offset >= sizeof(sd->cid)) {
        !          1432:             /* TODO: Check CRC before committing */
        !          1433:             sd->state = sd_programming_state;
        !          1434:             for (i = 0; i < sizeof(sd->cid); i ++)
        !          1435:                 if ((sd->cid[i] | 0x00) != sd->data[i])
        !          1436:                     sd->card_status |= CID_CSD_OVERWRITE;
        !          1437: 
        !          1438:             if (!(sd->card_status & CID_CSD_OVERWRITE))
        !          1439:                 for (i = 0; i < sizeof(sd->cid); i ++) {
        !          1440:                     sd->cid[i] |= 0x00;
        !          1441:                     sd->cid[i] &= sd->data[i];
        !          1442:                 }
        !          1443:             /* Bzzzzzzztt .... Operation complete.  */
        !          1444:             sd->state = sd_transfer_state;
        !          1445:         }
        !          1446:         break;
        !          1447: 
        !          1448:     case 27:   /* CMD27:  PROGRAM_CSD */
        !          1449:         sd->data[sd->data_offset ++] = value;
        !          1450:         if (sd->data_offset >= sizeof(sd->csd)) {
        !          1451:             /* TODO: Check CRC before committing */
        !          1452:             sd->state = sd_programming_state;
        !          1453:             for (i = 0; i < sizeof(sd->csd); i ++)
        !          1454:                 if ((sd->csd[i] | sd_csd_rw_mask[i]) !=
        !          1455:                     (sd->data[i] | sd_csd_rw_mask[i]))
        !          1456:                     sd->card_status |= CID_CSD_OVERWRITE;
        !          1457: 
        !          1458:             /* Copy flag (OTP) & Permanent write protect */
        !          1459:             if (sd->csd[14] & ~sd->data[14] & 0x60)
        !          1460:                 sd->card_status |= CID_CSD_OVERWRITE;
        !          1461: 
        !          1462:             if (!(sd->card_status & CID_CSD_OVERWRITE))
        !          1463:                 for (i = 0; i < sizeof(sd->csd); i ++) {
        !          1464:                     sd->csd[i] |= sd_csd_rw_mask[i];
        !          1465:                     sd->csd[i] &= sd->data[i];
        !          1466:                 }
        !          1467:             /* Bzzzzzzztt .... Operation complete.  */
        !          1468:             sd->state = sd_transfer_state;
        !          1469:         }
        !          1470:         break;
        !          1471: 
        !          1472:     case 42:   /* CMD42:  LOCK_UNLOCK */
        !          1473:         sd->data[sd->data_offset ++] = value;
        !          1474:         if (sd->data_offset >= sd->blk_len) {
        !          1475:             /* TODO: Check CRC before committing */
        !          1476:             sd->state = sd_programming_state;
        !          1477:             sd_lock_command(sd);
        !          1478:             /* Bzzzzzzztt .... Operation complete.  */
        !          1479:             sd->state = sd_transfer_state;
        !          1480:         }
        !          1481:         break;
        !          1482: 
        !          1483:     case 56:   /* CMD56:  GEN_CMD */
        !          1484:         sd->data[sd->data_offset ++] = value;
        !          1485:         if (sd->data_offset >= sd->blk_len) {
        !          1486:             APP_WRITE_BLOCK(sd->data_start, sd->data_offset);
        !          1487:             sd->state = sd_transfer_state;
        !          1488:         }
        !          1489:         break;
        !          1490: 
        !          1491:     default:
        !          1492:         printf("sd_write_data: unknown command\n");
        !          1493:         break;
        !          1494:     }
        !          1495: }
        !          1496: 
        !          1497: uint8_t sd_read_data(SDState *sd)
        !          1498: {
        !          1499:     /* TODO: Append CRCs */
        !          1500:     uint8_t ret;
        !          1501: 
        !          1502:     if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))
        !          1503:         return 0x00;
        !          1504: 
        !          1505:     if (sd->state != sd_sendingdata_state) {
        !          1506:         printf("sd_read_data: not in Sending-Data state\n");
        !          1507:         return 0x00;
        !          1508:     }
        !          1509: 
        !          1510:     if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
        !          1511:         return 0x00;
        !          1512: 
        !          1513:     switch (sd->current_cmd) {
        !          1514:     case 6:    /* CMD6:   SWITCH_FUNCTION */
        !          1515:         ret = sd->data[sd->data_offset ++];
        !          1516: 
        !          1517:         if (sd->data_offset >= 64)
        !          1518:             sd->state = sd_transfer_state;
        !          1519:         break;
        !          1520: 
        !          1521:     case 9:    /* CMD9:   SEND_CSD */
        !          1522:     case 10:   /* CMD10:  SEND_CID */
        !          1523:         ret = sd->data[sd->data_offset ++];
        !          1524: 
        !          1525:         if (sd->data_offset >= 16)
        !          1526:             sd->state = sd_transfer_state;
        !          1527:         break;
        !          1528: 
        !          1529:     case 11:   /* CMD11:  READ_DAT_UNTIL_STOP */
        !          1530:         if (sd->data_offset == 0)
        !          1531:             BLK_READ_BLOCK(sd->data_start, sd->blk_len);
        !          1532:         ret = sd->data[sd->data_offset ++];
        !          1533: 
        !          1534:         if (sd->data_offset >= sd->blk_len) {
        !          1535:             sd->data_start += sd->blk_len;
        !          1536:             sd->data_offset = 0;
        !          1537:             if (sd->data_start + sd->blk_len > sd->size) {
        !          1538:                 sd->card_status |= ADDRESS_ERROR;
        !          1539:                 break;
        !          1540:             }
        !          1541:         }
        !          1542:         break;
        !          1543: 
        !          1544:     case 13:   /* ACMD13: SD_STATUS */
        !          1545:         ret = sd->sd_status[sd->data_offset ++];
        !          1546: 
        !          1547:         if (sd->data_offset >= sizeof(sd->sd_status))
        !          1548:             sd->state = sd_transfer_state;
        !          1549:         break;
        !          1550: 
        !          1551:     case 17:   /* CMD17:  READ_SINGLE_BLOCK */
        !          1552:         if (sd->data_offset == 0)
        !          1553:             BLK_READ_BLOCK(sd->data_start, sd->blk_len);
        !          1554:         ret = sd->data[sd->data_offset ++];
        !          1555: 
        !          1556:         if (sd->data_offset >= sd->blk_len)
        !          1557:             sd->state = sd_transfer_state;
        !          1558:         break;
        !          1559: 
        !          1560:     case 18:   /* CMD18:  READ_MULTIPLE_BLOCK */
        !          1561:         if (sd->data_offset == 0)
        !          1562:             BLK_READ_BLOCK(sd->data_start, sd->blk_len);
        !          1563:         ret = sd->data[sd->data_offset ++];
        !          1564: 
        !          1565:         if (sd->data_offset >= sd->blk_len) {
        !          1566:             sd->data_start += sd->blk_len;
        !          1567:             sd->data_offset = 0;
        !          1568:             if (sd->data_start + sd->blk_len > sd->size) {
        !          1569:                 sd->card_status |= ADDRESS_ERROR;
        !          1570:                 break;
        !          1571:             }
        !          1572:         }
        !          1573:         break;
        !          1574: 
        !          1575:     case 22:   /* ACMD22: SEND_NUM_WR_BLOCKS */
        !          1576:         ret = sd->data[sd->data_offset ++];
        !          1577: 
        !          1578:         if (sd->data_offset >= 4)
        !          1579:             sd->state = sd_transfer_state;
        !          1580:         break;
        !          1581: 
        !          1582:     case 30:   /* CMD30:  SEND_WRITE_PROT */
        !          1583:         ret = sd->data[sd->data_offset ++];
        !          1584: 
        !          1585:         if (sd->data_offset >= 4)
        !          1586:             sd->state = sd_transfer_state;
        !          1587:         break;
        !          1588: 
        !          1589:     case 51:   /* ACMD51: SEND_SCR */
        !          1590:         ret = sd->scr[sd->data_offset ++];
        !          1591: 
        !          1592:         if (sd->data_offset >= sizeof(sd->scr))
        !          1593:             sd->state = sd_transfer_state;
        !          1594:         break;
        !          1595: 
        !          1596:     case 56:   /* CMD56:  GEN_CMD */
        !          1597:         if (sd->data_offset == 0)
        !          1598:             APP_READ_BLOCK(sd->data_start, sd->blk_len);
        !          1599:         ret = sd->data[sd->data_offset ++];
        !          1600: 
        !          1601:         if (sd->data_offset >= sd->blk_len)
        !          1602:             sd->state = sd_transfer_state;
        !          1603:         break;
        !          1604: 
        !          1605:     default:
        !          1606:         printf("sd_read_data: unknown command\n");
        !          1607:         return 0x00;
        !          1608:     }
        !          1609: 
        !          1610:     return ret;
        !          1611: }
        !          1612: 
        !          1613: int sd_data_ready(SDState *sd)
        !          1614: {
        !          1615:     return sd->state == sd_sendingdata_state;
        !          1616: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.