public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes
@ 2011-06-29  8:27 James Hogan
  2011-06-29  8:28 ` [PATCH 1/4] mmc: dw_mmc: fix stop when fallen back to PIO James Hogan
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: James Hogan @ 2011-06-29  8:27 UTC (permalink / raw)
  To: Chris Ball, Will, James Hogan, Jaehoon Chung, Kyungmin Park,
	linux-mmc, linux-kernel

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(-)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/4] mmc: dw_mmc: fix stop when fallen back to PIO
  2011-06-29  8:27 [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes James Hogan
@ 2011-06-29  8:28 ` James Hogan
  2011-06-29  8:29 ` [PATCH 2/4] mmc: dw_mmc: remove unnecessary error messages James Hogan
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: James Hogan @ 2011-06-29  8:28 UTC (permalink / raw)
  To: James Hogan
  Cc: Chris Ball, Will, Jaehoon Chung, Kyungmin Park, linux-mmc,
	linux-kernel

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.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
---
 drivers/mmc/host/dw_mmc.c  |    6 +++++-
 include/linux/mmc/dw_mmc.h |    2 ++
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 10b6979..fcff3c0 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -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
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index f3f68ee..6b46819 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -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;
-- 
1.7.2.3



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/4] mmc: dw_mmc: remove unnecessary error messages
  2011-06-29  8:27 [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes James Hogan
  2011-06-29  8:28 ` [PATCH 1/4] mmc: dw_mmc: fix stop when fallen back to PIO James Hogan
@ 2011-06-29  8:29 ` James Hogan
  2011-06-29  8:29 ` [PATCH 3/4] mmc: dw_mmc: handle "no CRC status" error James Hogan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: James Hogan @ 2011-06-29  8:29 UTC (permalink / raw)
  To: James Hogan
  Cc: Chris Ball, Will, Jaehoon Chung, Kyungmin Park, linux-mmc,
	linux-kernel

Remove error messages for timeout and CRC failure, since the error code
already indicates the problem.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
---
 drivers/mmc/host/dw_mmc.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index fcff3c0..bf2157a 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -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,
-- 
1.7.2.3



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/4] mmc: dw_mmc: handle "no CRC status" error
  2011-06-29  8:27 [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes James Hogan
  2011-06-29  8:28 ` [PATCH 1/4] mmc: dw_mmc: fix stop when fallen back to PIO James Hogan
  2011-06-29  8:29 ` [PATCH 2/4] mmc: dw_mmc: remove unnecessary error messages James Hogan
@ 2011-06-29  8:29 ` James Hogan
  2011-06-29  8:30 ` [PATCH 4/4] mmc: dw_mmc: reset FIFO after an error James Hogan
  2011-06-29  9:16 ` [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes Will Newton
  4 siblings, 0 replies; 8+ messages in thread
From: James Hogan @ 2011-06-29  8:29 UTC (permalink / raw)
  To: James Hogan
  Cc: Chris Ball, Will, Jaehoon Chung, Kyungmin Park, linux-mmc,
	linux-kernel

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>
---
 drivers/mmc/host/dw_mmc.c |   19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index bf2157a..0dac397 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)
 	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 "
-- 
1.7.2.3



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/4] mmc: dw_mmc: reset FIFO after an error
  2011-06-29  8:27 [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes James Hogan
                   ` (2 preceding siblings ...)
  2011-06-29  8:29 ` [PATCH 3/4] mmc: dw_mmc: handle "no CRC status" error James Hogan
@ 2011-06-29  8:30 ` James Hogan
  2011-06-29  9:16 ` [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes Will Newton
  4 siblings, 0 replies; 8+ messages in thread
From: James Hogan @ 2011-06-29  8:30 UTC (permalink / raw)
  To: James Hogan
  Cc: Chris Ball, Will, Jaehoon Chung, Kyungmin Park, linux-mmc,
	linux-kernel

If 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.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
---
 drivers/mmc/host/dw_mmc.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0dac397..0c839d3 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -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;
-- 
1.7.2.3



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes
  2011-06-29  8:27 [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes James Hogan
                   ` (3 preceding siblings ...)
  2011-06-29  8:30 ` [PATCH 4/4] mmc: dw_mmc: reset FIFO after an error James Hogan
@ 2011-06-29  9:16 ` Will Newton
  2011-06-30  5:26   ` Jaehoon Chung
  4 siblings, 1 reply; 8+ messages in thread
From: Will Newton @ 2011-06-29  9:16 UTC (permalink / raw)
  To: James Hogan
  Cc: Chris Ball, Jaehoon Chung, Kyungmin Park, linux-mmc, linux-kernel

On Wed, Jun 29, 2011 at 9:27 AM, James Hogan <james.hogan@imgtec.com> wrote:
> 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(-)

These all look good to me.

Acked-by: Will Newton <will.newton@imgtec.com>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes
  2011-06-29  9:16 ` [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes Will Newton
@ 2011-06-30  5:26   ` Jaehoon Chung
  2011-06-30  8:01     ` James Hogan
  0 siblings, 1 reply; 8+ messages in thread
From: Jaehoon Chung @ 2011-06-30  5:26 UTC (permalink / raw)
  To: Will Newton
  Cc: James Hogan, Chris Ball, Jaehoon Chung, Kyungmin Park, linux-mmc,
	linux-kernel

Tested-by: Jaehoon Chung <jh80.chung@samsung.com>

Will Newton wrote:
> On Wed, Jun 29, 2011 at 9:27 AM, James Hogan <james.hogan@imgtec.com> wrote:
>> 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(-)
> 
> These all look good to me.
> 
> Acked-by: Will Newton <will.newton@imgtec.com>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes
  2011-06-30  5:26   ` Jaehoon Chung
@ 2011-06-30  8:01     ` James Hogan
  0 siblings, 0 replies; 8+ messages in thread
From: James Hogan @ 2011-06-30  8:01 UTC (permalink / raw)
  To: Jaehoon Chung
  Cc: Will Newton, Chris Ball, Kyungmin Park, linux-mmc, linux-kernel

On 06/30/2011 06:26 AM, Jaehoon Chung wrote:
> Tested-by: Jaehoon Chung <jh80.chung@samsung.com>

Thanks for testing

Cheers
James

> 
> Will Newton wrote:
>> On Wed, Jun 29, 2011 at 9:27 AM, James Hogan <james.hogan@imgtec.com> wrote:
>>> 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(-)
>>
>> These all look good to me.
>>
>> Acked-by: Will Newton <will.newton@imgtec.com>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-06-30  8:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-29  8:27 [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes James Hogan
2011-06-29  8:28 ` [PATCH 1/4] mmc: dw_mmc: fix stop when fallen back to PIO James Hogan
2011-06-29  8:29 ` [PATCH 2/4] mmc: dw_mmc: remove unnecessary error messages James Hogan
2011-06-29  8:29 ` [PATCH 3/4] mmc: dw_mmc: handle "no CRC status" error James Hogan
2011-06-29  8:30 ` [PATCH 4/4] mmc: dw_mmc: reset FIFO after an error James Hogan
2011-06-29  9:16 ` [PATCH 0/4] mmc: dw_mmc: mmc_test related fixes Will Newton
2011-06-30  5:26   ` Jaehoon Chung
2011-06-30  8:01     ` James Hogan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox