From 3332acd9089ba21a16570a149c207d37bb910dec Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 12 Jul 2010 15:50:56 +0800 Subject: [PATCH] --- yaml --- r: 219031 b: refs/heads/master c: 061c6c847eeb11743e489a16e907b41c6f9042b6 h: refs/heads/master i: 219029: 5580ee39bf6a35ba314b7e610e05c5f8192bfe25 219027: cfdc7a4a05d9e7de383383e8c2d7ba39bef223ea 219023: c3589dbce897641a24c5895dead20412acfa4024 v: v3 --- [refs] | 2 +- trunk/drivers/mmc/host/mmc_spi.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 370a236fb1ac..8829f075e5d8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 95f25efe0ce22e28d61722d655d2ef582f5f7520 +refs/heads/master: 061c6c847eeb11743e489a16e907b41c6f9042b6 diff --git a/trunk/drivers/mmc/host/mmc_spi.c b/trunk/drivers/mmc/host/mmc_spi.c index 5b0b50636ec4..fd877f633dd2 100644 --- a/trunk/drivers/mmc/host/mmc_spi.c +++ b/trunk/drivers/mmc/host/mmc_spi.c @@ -1055,6 +1055,8 @@ static void mmc_spi_request(struct mmc_host *mmc, struct mmc_request *mrq) { 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 */ @@ -1087,10 +1089,29 @@ static void mmc_spi_request(struct mmc_host *mmc, struct mmc_request *mrq) /* 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