mmc: dw_mmc: mmc_test related fixes
Subsystems (2)
cover mmc: dw_mmc: mmc_test related fixes
More improvements and fixes for the Synopsys DesignWare MCI driver so that it passes the mmc_test suite:
[PATCH 1/4] mmc: dw_mmc: fix stop when fallen back to PIO
Fixes a hang after an error/timeout in PIO mode.
[PATCH 2/4] mmc: dw_mmc: remove unnecessary error messages
Removes some dev_err's since an errno is sufficient.
[PATCH 3/4] mmc: dw_mmc: handle "no CRC status" error
Fixes "Correct xfer_size at write" tests.
[PATCH 4/4] mmc: dw_mmc: reset FIFO after an error
Fixes modified "Correct xfer_size at write" tests (3 blocks instead of 2).
drivers/mmc/host/dw_mmc.c | 41 +++++++++++++++++++++++++++++++---------- include/linux/mmc/dw_mmc.h | 2 ++ 2 files changed, 33 insertions(+), 10 deletions(-)
PATCH 1/4 mmc: dw_mmc: fix stop when fallen back to PIO
There are several situations when dw_mci_submit_data_dma() decides to fall back to PIO mode instead of using DMA, due to a short (to avoid overhead) or "complex" (e.g. with unaligned buffers) transaction, even though host->use_dma is set. However dw_mci_stop_dma() decides whether to stop DMA or set the EVENT_XFER_COMPLETE event based on host->use_dma. When falling back to PIO mode this results in data timeout errors getting missed and the driver locking up.
Therefore add host->using_dma to indicate whether the current transaction is using dma or not, and adjust dw_mci_stop_dma() to use that instead.
--- drivers/mmc/host/dw_mmc.c | 6 +++++- include/linux/mmc/dw_mmc.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletions(-)
drivers/mmc/host/dw_mmc.c +5 -1
@@ -287,7 +287,7 @@ static void send_stop_cmd(struct dw_mci *host, struct mmc_data *data)/* DMA interface functions */ static void dw_mci_stop_dma (struct dw_mci *host) { -if (host->use_dma) { +if (host->using_dma) { host->dma_ops->stop (host); host->dma_ops->cleanup (host); }else {
@@ -435,6 +435,8 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)unsigned int i, direction, sg_len;u32 temp; + host->using_dma =0 ; +/* If we don't have a channel, we can't do DMA */ if (!host->use_dma)return -ENODEV ;
@@ -454,6 +456,8 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)return -EINVAL ; } + host->using_dma =1 ; +if (data->flags &MMC_DATA_READ ) direction =DMA_FROM_DEVICE ;else
include/linux/mmc/dw_mmc.h +2 -0
@@ -48,6 +48,7 @@ struct mmc_data;* @data: The data currently being transferred, or NULL if no data * transfer is in progress. * @use_dma: Whether DMA channel is initialized or not. +* @using_dma: Whether DMA is in use for the current transfer. * @sg_dma: Bus address of DMA buffer. * @sg_cpu: Virtual address of DMA buffer. * @dma_ops: Pointer to platform-specific DMA callbacks.
@@ -121,6 +122,7 @@ struct dw_mci {/* DMA interface members*/ int use_dma; +int using_dma;dma_addr_t sg_dma;void *sg_cpu;
Signature · 1 line
1.7.2.3
PATCH 2/4 mmc: dw_mmc: remove unnecessary error messages
In reply to James HoganRemove error messages for timeout and CRC failure, since the error code already indicates the problem.
--- drivers/mmc/host/dw_mmc.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-)
drivers/mmc/host/dw_mmc.c +0 -4
@@ -908,12 +908,8 @@ static void dw_mci_tasklet_func(unsigned long priv)if (status &DW_MCI_DATA_ERROR_FLAGS ) {if (status &SDMMC_INT_DTO ) { -dev_err (&host->pdev->dev, -"data timeout error\n" ); data->error = -ETIMEDOUT ; }else if (status &SDMMC_INT_DCRC ) { -dev_err (&host->pdev->dev, -"data CRC error\n" ); data->error = -EILSEQ ; }else { dev_err(&host->pdev->dev,
Signature · 1 line
1.7.2.3
PATCH 3/4 mmc: dw_mmc: handle "no CRC status" error
In reply to James HoganWhen 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.
--- drivers/mmc/host/dw_mmc.c | 19 +++++++++++++++---- 1 files changed, 15 insertions(+), 4 deletions(-)
drivers/mmc/host/dw_mmc.c +15 -4
@@ -496,15 +496,16 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) host->sg =NULL ; host->data = data; +if (data->flags &MMC_DATA_READ ) + host->dir_status =DW_MCI_RECV_STATUS ; +else + host->dir_status =DW_MCI_SEND_STATUS ; +if (dw_mci_submit_data_dma (host, data)) { host->sg = data->sg; host->pio_offset =0 ; host->part_buf_start =0 ; host->part_buf_count =0 ; -if (data->flags &MMC_DATA_READ ) - host->dir_status =DW_MCI_RECV_STATUS ; -else - host->dir_status =DW_MCI_SEND_STATUS ;mci_writel (host,RINTSTS ,SDMMC_INT_TXDR |SDMMC_INT_RXDR ); temp =mci_readl (host,INTMASK );
@@ -911,6 +912,16 @@ static void dw_mci_tasklet_func(unsigned long priv) data->error = -ETIMEDOUT ; }else if (status &SDMMC_INT_DCRC ) { data->error = -EILSEQ ; + }else if (status &SDMMC_INT_EBE && + host->dir_status == +DW_MCI_SEND_STATUS ) { +/* +* No data CRC status was returned. +* The number of bytes transferred will +* be exaggerated in PIO mode. +*/ + data->bytes_xfered =0 ; + data->error = -ETIMEDOUT ; }else {dev_err (&host->pdev->dev, "data FIFO error "
Signature · 1 line
1.7.2.3
PATCH 4/4 mmc: dw_mmc: reset FIFO after an error
In reply to James HoganIf an error occurs mid way through a transaction (such as a missing CRC status response after the 2nd block written out of 3), then the FIFO may still contain data which will interfere with the next transaction. Therefore after an error has been detected, reset the fifo using the CTRL register.
--- drivers/mmc/host/dw_mmc.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-)
drivers/mmc/host/dw_mmc.c +11 -1
@@ -849,7 +849,7 @@ static void dw_mci_tasklet_func(unsigned long priv)struct mmc_command *cmd;enum dw_mci_state state;enum dw_mci_state prev_state; -u32 status; +u32 status, ctrl;spin_lock (&host->lock);
@@ -929,6 +929,16 @@ static void dw_mci_tasklet_func(unsigned long priv) status); data->error = -EIO ; } +/* +* After an error, there may be data lingering +* in the FIFO, so reset it - doing so +* generates a block interrupt, hence setting +* the scatter-gather pointer to NULL. +*/ + host->sg =NULL ; + ctrl =mci_readl (host,CTRL ); + ctrl |=SDMMC_CTRL_FIFO_RESET ; +mci_writel (host,CTRL , ctrl); }else { data->bytes_xfered = data->blocks * data->blksz; data->error =0 ;
Signature · 1 line
1.7.2.3
Quoted 13 lines · James Hogan
More improvements and fixes for the Synopsys DesignWare MCI driver so that it passes the
mmc_testsuite:[PATCH 1/4] mmc:
dw_mmc: fix stop when fallen back to PIO Fixes a hang after an error/timeout in PIO mode. [PATCH 2/4] mmc:dw_mmc: remove unnecessary error messages Removes some dev_err's since an errno is sufficient. [PATCH 3/4] mmc:dw_mmc: handle "no CRC status" error Fixes "Correctxfer_sizeat write" tests.
[PATCH 4/4] mmc:dw_mmc: reset FIFO after an error Fixes modified "Correctxfer_sizeat write" tests (3 blocks instead of 2).
Quoted 3 lines
drivers/mmc/host/dw_mmc.c | 41 +++++++++++++++++++++++++++++++----------
include/linux/mmc/dw_mmc.h| 2 ++2 files changed, 33 insertions(+), 10 deletions(-)
These all look good to me.
Quoted 26 lines · Will Newton
Quoted 13 lines · James Hogan
More improvements and fixes for the Synopsys DesignWare MCI driver so that it passes the
mmc_testsuite:[PATCH 1/4] mmc:
dw_mmc: fix stop when fallen back to PIO
Fixes a hang after an error/timeout in PIO mode.
[PATCH 2/4] mmc:dw_mmc: remove unnecessary error messages
Removes some dev_err's since an errno is sufficient.
[PATCH 3/4] mmc:dw_mmc: handle "no CRC status" error
Fixes "Correctxfer_sizeat write" tests.
[PATCH 4/4] mmc:dw_mmc: reset FIFO after an error
Fixes modified "Correctxfer_sizeat write" tests (3 blocks instead of 2).Quoted 3 lines
drivers/mmc/host/dw_mmc.c | 41 +++++++++++++++++++++++++++++++---------- include/linux/mmc/dw_mmc.h | 2 ++ 2 files changed, 33 insertions(+), 10 deletions(-)These all look good to me.
Acked-by Will Newton <[email protected]>--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 1 line · Jaehoon Chung
Tested-by Jaehoon Chung <[email protected]>
Thanks for testing
Cheers
James
Quoted 29 lines
Quoted 26 lines · Will Newton
Quoted 13 lines · James Hogan
More improvements and fixes for the Synopsys DesignWare MCI driver so that it passes the
mmc_testsuite:[PATCH 1/4] mmc:
dw_mmc: fix stop when fallen back to PIO
Fixes a hang after an error/timeout in PIO mode.
[PATCH 2/4] mmc:dw_mmc: remove unnecessary error messages
Removes some dev_err's since an errno is sufficient.
[PATCH 3/4] mmc:dw_mmc: handle "no CRC status" error
Fixes "Correctxfer_sizeat write" tests.
[PATCH 4/4] mmc:dw_mmc: reset FIFO after an error
Fixes modified "Correctxfer_sizeat write" tests (3 blocks instead of 2).Quoted 3 lines
drivers/mmc/host/dw_mmc.c | 41 +++++++++++++++++++++++++++++++---------- include/linux/mmc/dw_mmc.h | 2 ++ 2 files changed, 33 insertions(+), 10 deletions(-)These all look good to me.
Acked-by Will Newton <[email protected]>--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi James,
Quoted 12 lines · James Hogan
More improvements and fixes for the Synopsys DesignWare MCI driver so that it passes the
mmc_testsuite:[PATCH 1/4] mmc:
dw_mmc: fix stop when fallen back to PIO
Fixes a hang after an error/timeout in PIO mode.
[PATCH 2/4] mmc:dw_mmc: remove unnecessary error messages
Removes some dev_err's since an errno is sufficient.
[PATCH 3/4] mmc:dw_mmc: handle "no CRC status" error
Fixes "Correctxfer_sizeat write" tests.
[PATCH 4/4] mmc:dw_mmc: reset FIFO after an error
Fixes modified "Correctxfer_sizeat write" tests (3 blocks instead of 2).
All pushed to mmc-next for 3.1 with Will's ACK and Jaehoon's Tested-by, thanks.
- Chris.
Signature · 2 lines
Chris Ball <[email protected]> <http://printf.net/> One Laptop Per Child