{
struct mmc_spi_host *host = mmc_priv(mmc);
int status = -EINVAL;
+ int crc_retry = 5;
+ struct mmc_command stop;
#ifdef DEBUG
/* MMC core and layered drivers *MUST* issue SPI-aware commands */
/* request exclusive bus access */
spi_bus_lock(host->spi->master);
+crc_recover:
/* issue command; then optionally data and stop */
status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL);
if (status == 0 && mrq->data) {
mmc_spi_data_do(host, mrq->cmd, mrq->data, mrq->data->blksz);
+
+ /*
+ * The SPI bus is not always reliable for large data transfers.
+ * If an occasional crc error is reported by the SD device with
+ * data read/write over SPI, it may be recovered by repeating
+ * the last SD command again. The retry count is set to 5 to
+ * ensure the driver passes stress tests.
+ */
+ if (mrq->data->error == -EILSEQ && crc_retry) {
+ stop.opcode = MMC_STOP_TRANSMISSION;
+ stop.arg = 0;
+ stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+ status = mmc_spi_command_send(host, mrq, &stop, 0);
+ crc_retry--;
+ mrq->data->error = 0;
+ goto crc_recover;
+ }
+
if (mrq->stop)
status = mmc_spi_command_send(host, mrq, mrq->stop, 0);
else