diff options
author | Dr. David Alan Gilbert <david.gilbert@linaro.org> | 2011-07-25 13:21:30 +0100 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2011-07-29 09:33:48 -0500 |
commit | 33fa8234c3d642317583c992b7fdc67ce7fdd1b5 (patch) | |
tree | 92ffb14b9d902239e2ed4432469722ac9a7490d4 | |
parent | cbbab9226da9572346837466a8770c117e7e65a2 (diff) |
Fix last sector write on sd card
When writing the last sector of an SD card using WRITE_MULTIPLE_BLOCK
QEmu throws an error saying that we've run off the end, and leaves
itself in the wrong state.
Tested on ARM Vexpress model.
Signed-off-by: Dr. David Alan Gilbert <david.gilbert@linaro.org>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r-- | hw/sd.c | 19 |
1 files changed, 11 insertions, 8 deletions
@@ -1450,14 +1450,8 @@ void sd_write_data(SDState *sd, uint8_t value) break; case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */ - sd->data[sd->data_offset ++] = value; - if (sd->data_offset >= sd->blk_len) { - /* TODO: Check CRC before committing */ - sd->state = sd_programming_state; - BLK_WRITE_BLOCK(sd->data_start, sd->data_offset); - sd->blk_written ++; - sd->data_start += sd->blk_len; - sd->data_offset = 0; + if (sd->data_offset == 0) { + /* Start of the block - lets check the address is valid */ if (sd->data_start + sd->blk_len > sd->size) { sd->card_status |= ADDRESS_ERROR; break; @@ -1466,6 +1460,15 @@ void sd_write_data(SDState *sd, uint8_t value) sd->card_status |= WP_VIOLATION; break; } + } + sd->data[sd->data_offset++] = value; + if (sd->data_offset >= sd->blk_len) { + /* TODO: Check CRC before committing */ + sd->state = sd_programming_state; + BLK_WRITE_BLOCK(sd->data_start, sd->data_offset); + sd->blk_written++; + sd->data_start += sd->blk_len; + sd->data_offset = 0; sd->csd[14] |= 0x40; /* Bzzzzzzztt .... Operation complete. */ |