]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/mmc/host/mmc_spi.c
Merge branch 'master' into csb1725
[mv-sheeva.git] / drivers / mmc / host / mmc_spi.c
index 62a35822003ef5b0383c1c97ddaaaf05c1c7a479..fd877f633dd220eb4b3bd3e9e7d104af0aef603f 100644 (file)
@@ -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
@@ -1345,8 +1366,7 @@ static int mmc_spi_probe(struct spi_device *spi)
 
        mmc->ops = &mmc_spi_ops;
        mmc->max_blk_size = MMC_SPI_BLOCKSIZE;
-       mmc->max_hw_segs = MMC_SPI_BLOCKSATONCE;
-       mmc->max_phys_segs = MMC_SPI_BLOCKSATONCE;
+       mmc->max_segs = MMC_SPI_BLOCKSATONCE;
        mmc->max_req_size = MMC_SPI_BLOCKSATONCE * MMC_SPI_BLOCKSIZE;
        mmc->max_blk_count = MMC_SPI_BLOCKSATONCE;