diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f86f30058c1..59c890e7b4c 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -736,6 +736,23 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); } +static void shdci_check_dma_overrun(struct sdhci_host *host, struct mmc_data *data) +{ + u32 dma_pos = readl(host->ioaddr + SDHCI_DMA_ADDRESS); + u32 dma_start = sg_dma_address(data->sg); + u32 dma_end = dma_start + data->sg->length; + + /* Test whether we ended up moving more data than + * was originally requested. */ + + if (dma_pos <= dma_end) + return; + + printk(KERN_ERR "%s: dma overrun, dma %08x, req %08x..%08x\n", + mmc_hostname(host->mmc), dma_pos, + dma_start, dma_end); +} + static void sdhci_finish_data(struct sdhci_host *host) { struct mmc_data *data; @@ -749,6 +766,8 @@ static void sdhci_finish_data(struct sdhci_host *host) if (host->flags & SDHCI_USE_ADMA) sdhci_adma_table_post(host, data); else { + shdci_check_dma_overrun(host, data); + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, (data->flags & MMC_DATA_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |