Revision 10a412da hw/sd.c

b/hw/sd.c
104 104
    int enable;
105 105
};
106 106

  
107
static void sd_set_status(SDState *sd)
107
static void sd_set_mode(SDState *sd)
108 108
{
109 109
    switch (sd->state) {
110 110
    case sd_inactive_state:
......
126 126
        sd->mode = sd_data_transfer_mode;
127 127
        break;
128 128
    }
129

  
130
    sd->card_status &= ~CURRENT_STATE;
131
    sd->card_status |= sd->state << 9;
132 129
}
133 130

  
134 131
static const sd_cmd_type_t sd_cmd_type[64] = {
......
341 338
    return sd_crc7(buffer, 5) != req->crc;	/* TODO */
342 339
}
343 340

  
344
static void sd_response_r1_make(SDState *sd,
345
                                uint8_t *response, uint32_t last_status)
341
static void sd_response_r1_make(SDState *sd, uint8_t *response)
346 342
{
347
    uint32_t mask = CARD_STATUS_B ^ ILLEGAL_COMMAND;
348
    uint32_t status;
349

  
350
    status = (sd->card_status & ~mask) | (last_status & mask);
343
    uint32_t status = sd->card_status;
344
    /* Clear the "clear on read" status bits (except APP_CMD) */
351 345
    sd->card_status &= ~CARD_STATUS_C | APP_CMD;
352 346

  
353 347
    response[0] = (status >> 24) & 0xff;
......
1286 1280

  
1287 1281
int sd_do_command(SDState *sd, SDRequest *req,
1288 1282
                  uint8_t *response) {
1289
    uint32_t last_status = sd->card_status;
1283
    int last_state;
1290 1284
    sd_rsp_type_t rtype;
1291 1285
    int rsplen;
1292 1286

  
......
1300 1294
        goto send_response;
1301 1295
    }
1302 1296

  
1303
    sd->card_status &= ~CARD_STATUS_B;
1304
    sd_set_status(sd);
1305

  
1306
    if (last_status & CARD_IS_LOCKED) {
1297
    if (sd->card_status & CARD_IS_LOCKED) {
1307 1298
        if (!cmd_valid_while_locked(sd, req)) {
1308 1299
            sd->card_status |= ILLEGAL_COMMAND;
1309 1300
            fprintf(stderr, "SD: Card is locked\n");
......
1312 1303
        }
1313 1304
    }
1314 1305

  
1315
    if (last_status & APP_CMD) {
1306
    last_state = sd->state;
1307
    sd_set_mode(sd);
1308

  
1309
    if (sd->card_status & APP_CMD) {
1316 1310
        rtype = sd_app_command(sd, *req);
1317 1311
        sd->card_status &= ~APP_CMD;
1318 1312
    } else
......
1320 1314

  
1321 1315
    if (rtype == sd_illegal) {
1322 1316
        sd->card_status |= ILLEGAL_COMMAND;
1317
    } else {
1318
        /* Valid command, we can update the 'state before command' bits.
1319
         * (Do this now so they appear in r1 responses.)
1320
         */
1321
        sd->current_cmd = req->cmd;
1322
        sd->card_status &= ~CURRENT_STATE;
1323
        sd->card_status |= (last_state << 9);
1323 1324
    }
1324 1325

  
1325
    sd->current_cmd = req->cmd;
1326

  
1327 1326
send_response:
1328 1327
    switch (rtype) {
1329 1328
    case sd_r1:
1330 1329
    case sd_r1b:
1331
        sd_response_r1_make(sd, response, last_status);
1330
        sd_response_r1_make(sd, response);
1332 1331
        rsplen = 4;
1333 1332
        break;
1334 1333

  
......
1364 1363
        break;
1365 1364
    }
1366 1365

  
1366
    if (rtype != sd_illegal) {
1367
        /* Clear the "clear on valid command" status bits now we've
1368
         * sent any response
1369
         */
1370
        sd->card_status &= ~CARD_STATUS_B;
1371
    }
1372

  
1367 1373
#ifdef DEBUG_SD
1368 1374
    if (rsplen) {
1369 1375
        int i;

Also available in: Unified diff