aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2011-06-29 04:29:58 -0400
committerChris Ball <cjb@laptop.org>2011-07-20 17:21:06 -0400
commit55c5efbc0dbcb20b7f0d264d172ab376494d79a1 (patch)
treead31ddb71b4482c57b5affc9543a4d64c751ac6c
parentae837fe6ddb1e4e9238191629baa08c35ed4a6bb (diff)
mmc: dw_mmc: handle "no CRC status" error
When a data write isn't acknowledged by the card (so no CRC status token is detected after the data), the error -EIO is returned instead of the -ETIMEDOUT expected by mmc_test 15 - "Correct xfer_size at write (start failure)" and 17 "Correct xfer_size at write (midway failure)". In PIO mode the reported number of bytes transferred is also exaggerated since the last block actually failed. Handle the "Write no CRC" error specially, setting the error to -ETIMEDOUT and setting the bytes_xferred to 0. Signed-off-by: James Hogan <james.hogan@imgtec.com> Acked-by: Will Newton <will.newton@imgtec.com> Tested-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/dw_mmc.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index bf2157a0e511..0dac397f37fd 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -496,15 +496,16 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
496 host->sg = NULL; 496 host->sg = NULL;
497 host->data = data; 497 host->data = data;
498 498
499 if (data->flags & MMC_DATA_READ)
500 host->dir_status = DW_MCI_RECV_STATUS;
501 else
502 host->dir_status = DW_MCI_SEND_STATUS;
503
499 if (dw_mci_submit_data_dma(host, data)) { 504 if (dw_mci_submit_data_dma(host, data)) {
500 host->sg = data->sg; 505 host->sg = data->sg;
501 host->pio_offset = 0; 506 host->pio_offset = 0;
502 host->part_buf_start = 0; 507 host->part_buf_start = 0;
503 host->part_buf_count = 0; 508 host->part_buf_count = 0;
504 if (data->flags & MMC_DATA_READ)
505 host->dir_status = DW_MCI_RECV_STATUS;
506 else
507 host->dir_status = DW_MCI_SEND_STATUS;
508 509
509 mci_writel(host, RINTSTS, SDMMC_INT_TXDR | SDMMC_INT_RXDR); 510 mci_writel(host, RINTSTS, SDMMC_INT_TXDR | SDMMC_INT_RXDR);
510 temp = mci_readl(host, INTMASK); 511 temp = mci_readl(host, INTMASK);
@@ -911,6 +912,16 @@ static void dw_mci_tasklet_func(unsigned long priv)
911 data->error = -ETIMEDOUT; 912 data->error = -ETIMEDOUT;
912 } else if (status & SDMMC_INT_DCRC) { 913 } else if (status & SDMMC_INT_DCRC) {
913 data->error = -EILSEQ; 914 data->error = -EILSEQ;
915 } else if (status & SDMMC_INT_EBE &&
916 host->dir_status ==
917 DW_MCI_SEND_STATUS) {
918 /*
919 * No data CRC status was returned.
920 * The number of bytes transferred will
921 * be exaggerated in PIO mode.
922 */
923 data->bytes_xfered = 0;
924 data->error = -ETIMEDOUT;
914 } else { 925 } else {
915 dev_err(&host->pdev->dev, 926 dev_err(&host->pdev->dev,
916 "data FIFO error " 927 "data FIFO error "