Index: sd-as3525.c =================================================================== --- sd-as3525.c (revision 27164) +++ sd-as3525.c (working copy) @@ -257,6 +257,28 @@ return false; } +static void sd_set_widebus_mode(IF_MD2(int drive,) int on) { +#ifndef HAVE_MULTIDRIVE + const int drive = 0; +#endif + long response; + if(sd_wait_for_tran_state(drive) < 0) + panicf("sd_set_widebus: tran"); + /* CMD55 */ /* Response is requested due to timing issue */ + if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_RESP, &response)) + panicf("sd_set_widebus: app_cmd"); + /* ACMD6 */ + if(!send_cmd(drive, SD_SET_BUS_WIDTH, on ? 2 : 0, MCI_RESP, &response)) + panicf("sd_set_widebus: set_bus_width"); + /* Now that card is widebus make controller aware */ + if (on) { + MCI_CLOCK(drive) |= MCI_CLOCK_WIDEBUS; + } else { + MCI_CLOCK(drive) &= ~MCI_CLOCK_WIDEBUS; + } +} + + #define MCI_FULLSPEED (MCI_CLOCK_ENABLE | MCI_CLOCK_BYPASS) /* MCLK */ #define MCI_HALFSPEED (MCI_CLOCK_ENABLE) /* MCLK/2 */ #define MCI_QUARTERSPEED (MCI_CLOCK_ENABLE | 1) /* MCLK/4 */ @@ -362,24 +384,17 @@ if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_RESP, &response)) return -10; - /* Switch to to 4 bit widebus mode */ - if(sd_wait_for_tran_state(drive) < 0) - return -11; + /* Disable card detect pullup, we don't need it */ /* CMD55 */ /* Response is requested due to timing issue */ if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_RESP, &response)) return -14; /* ACMD42 */ if(!send_cmd(drive, SD_SET_CLR_CARD_DETECT, 0, MCI_RESP, &response)) return -15; - /* CMD55 */ /* Response is requested due to timing issue */ - if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_RESP, &response)) - return -12; - /* ACMD6 */ - if(!send_cmd(drive, SD_SET_BUS_WIDTH, 2, MCI_RESP, &response)) - return -13; - /* Now that card is widebus make controller aware */ - MCI_CLOCK(drive) |= MCI_CLOCK_WIDEBUS; + /* Switch to to 4 bit widebus mode */ + sd_set_widebus_mode(IF_MD2(drive,) 1); + /* * enable bank switching * without issuing this command, we only have access to 1/4 of the blocks @@ -874,10 +889,38 @@ return ret; } +#define VERIFY_READ 1 + int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void* buf) { - return sd_transfer_sectors(IF_MD2(drive,) start, count, buf, false); + int ret; + + ret = sd_transfer_sectors(IF_MD2(drive,) start, count, buf, false); + +#ifdef VERIFY_READ + if (ret) /* read failed, no point in verifying? */ + return ret; + + sd_set_widebus_mode(IF_MD2(drive,) 0); /* verify in 1bit mode */ + + while (count) { + int transfer = count; + if(transfer > UNALIGNED_NUM_SECTORS) + transfer = UNALIGNED_NUM_SECTORS; + + sd_transfer_sectors(IF_MD2(drive,) start, transfer, aligned_buffer, false); + if (memcmp(buf, aligned_buffer, transfer * 512) != 0) + panicf("sd: read verify failed: sec=%ld n=%d!", start, transfer); + + buf += transfer * 512; + count -= transfer; + start += transfer; + } + + sd_set_widebus_mode(IF_MD2(drive,) 1); /* switch back to 4bit mode */ +#endif + return ret; } int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count, @@ -908,7 +951,7 @@ if (memcmp(buf, aligned_buffer, transfer * 512) != 0) { /* try the write again in the hope to repair the damage */ sd_transfer_sectors(IF_MD2(drive,) saved_start, saved_count, saved_buf, true); - panicf("sd: verify failed: sec=%ld n=%d!", start, transfer); + panicf("sd: write verify failed: sec=%ld n=%d!", start, transfer); } buf += transfer * 512;