diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index b261613224f6741d382847c6ec49a9e9bcc91092..5c90941f31d90444db2e9e4f9ab5d1cff42f5086 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2330,6 +2330,23 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *mask) else host->cmd->error = -EILSEQ; + /* + * If this command initiates a data phase and a response + * CRC error is signalled, the card can start transferring + * data - the card may have received the command without + * error. We must not terminate the mmc_request early. + * + * If the card did not receive the command or returned an + * error which prevented it sending data, the data phase + * will time out. + */ + if (host->cmd->data && + (intmask & (SDHCI_INT_CRC | SDHCI_INT_TIMEOUT)) == + SDHCI_INT_CRC) { + host->cmd = NULL; + return; + } + tasklet_schedule(&host->finish_tasklet); return; }