Message ID | 1390402824-9850-10-git-send-email-ulf.hansson@linaro.org |
---|---|
State | Superseded |
Headers | show |
On 22 January 2014 16:19, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote: > On Wed, Jan 22, 2014 at 04:00:23PM +0100, Ulf Hansson wrote: >> In case of a read operation both MCI_CMDRESPEND and MCI_DATAEND can be >> set in the status register when entering the interrupt handler. This is >> due to that the card start sending data before the host has >> acknowledged the command response. >> >> To resolve the issue for this scenario, we must start by handling the >> CMD irq instead of the DATA irq. The reason is beacuse the completion >> of the DATA irq will not respect the current command and then causing >> it to be garbled. > > And that's because the driver isn't written to be able to handle a > command being issued concurrently with a data transfer, because it > only has one place to store the current command. For a READ request, we are starting the data state machine by invoking mmci_start_data before we send the READ command. That is not like we handle concurrent requests, it is still only one request we are operating on. Now, suppose you have a high interface speed and a well performing card, that will mean you can actually get the DATAEND irq at the same time you get the CMD response. It is only because of this scenario we need to reverse the order of handling the IRQs. Sorry if the commit message was to vague. > > Consider what happens in this case: > > - Command issued to start a transfer. > - Command completes, data transfer starts. > - New command comes along to be issued, and is in progress > - Data transfer finishes, we now issue the stop command to halt the > transfer > - We overwrite the new command with the stop command > > All hell breaks loose. No, this isn't a fix I want to see until the > driver can properly handle concurrent commands. This is not the scenario I want or need to solve. The host must only handle one request at time. When we are done, we do call mmc_request_done, which tells the mmc core it's fine to start a new one. So the above sequence is not even possible. Kind regards Ulf Hansson > > -- > FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation > in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad. > Estimate before purchase was "up to 13.2Mbit". -- 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
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f320579..1a4b153 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1144,16 +1144,17 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); + cmd = host->cmd; + if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT| + MCI_CMDRESPEND) && cmd) + mmci_cmd_irq(host, cmd, status); + data = host->data; if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| MCI_DATABLOCKEND) && data) mmci_data_irq(host, data, status); - cmd = host->cmd; - if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND) && cmd) - mmci_cmd_irq(host, cmd, status); - ret = 1; } while (status);
In case of a read operation both MCI_CMDRESPEND and MCI_DATAEND can be set in the status register when entering the interrupt handler. This is due to that the card start sending data before the host has acknowledged the command response. To resolve the issue for this scenario, we must start by handling the CMD irq instead of the DATA irq. The reason is beacuse the completion of the DATA irq will not respect the current command and then causing it to be garbled. Cc: Russell King <linux@arm.linux.org.uk> Cc: Johan Rudholm <jrudholm@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> --- drivers/mmc/host/mmci.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)