diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2016-01-26 13:40:53 (GMT) |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2016-02-29 10:03:16 (GMT) |
commit | 771a3dc225815b7cc691c1ce703a3af8488e48df (patch) | |
tree | ab44647495acf99821bce824add4ea2ad963765f /drivers/mmc/host | |
parent | 0ca33b4ad9cfc133bb3d93eec1ad0eea83d6f252 (diff) | |
download | linux-771a3dc225815b7cc691c1ce703a3af8488e48df.tar.xz |
mmc: sdhci: further fix for DMA unmapping in sdhci_post_req()
sdhci_post_req() exists to unmap a previously mapped but already
finished request, while the next request is in progress. However, the
state of the SDHCI_REQ_USE_DMA flag depends on the last submitted
request.
This means we can end up clearing the flag due to a quirk, which then
means that sdhci_post_req() fails to unmap the DMA buffer, potentially
leading to data corruption.
We can safely ignore the SDHCI_REQ_USE_DMA here, as testing
data->host_cookie is entirely sufficient.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
[ Re-based to apply as a separate fix ]
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org # v4.5+
Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 97e5f40..6fe0e78 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2084,14 +2084,13 @@ static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq, struct sdhci_host *host = mmc_priv(mmc); struct mmc_data *data = mrq->data; - if (host->flags & SDHCI_REQ_USE_DMA) { - if (data->host_cookie == COOKIE_GIVEN || - data->host_cookie == COOKIE_MAPPED) - dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, - data->flags & MMC_DATA_WRITE ? - DMA_TO_DEVICE : DMA_FROM_DEVICE); - data->host_cookie = COOKIE_UNMAPPED; - } + if (data->host_cookie == COOKIE_GIVEN || + data->host_cookie == COOKIE_MAPPED) + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + data->flags & MMC_DATA_WRITE ? + DMA_TO_DEVICE : DMA_FROM_DEVICE); + + data->host_cookie = COOKIE_UNMAPPED; } static int sdhci_pre_dma_transfer(struct sdhci_host *host, |