From: Jonas Karlman Date: Thu, 23 Jan 2025 21:48:48 +0000 (+0000) Subject: mmc: sdhci: Fix possible Synchronous Abort using PIO mode X-Git-Tag: v2025.07-rc1~81^2~2 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2057bb4b5160a3668d4785adb6ce0f0d08325c48;p=pandora-u-boot.git mmc: sdhci: Fix possible Synchronous Abort using PIO mode When MMC_SDHCI_SDMA=y or MMC_SDHCI_ADMA=y and PIO mode is used dma_unmap_single() is called on an unmapped address, 0x0. This may result in a Synchronous Abort: ## Checking hash(es) for Image atf-1 ... sha256+ OK CMD_SEND:16 ARG 0x00000200 MMC_RSP_R1,5,6,7 0x00000900 CMD_SEND:18 ARG 0x00004005 "Synchronous Abort" handler, esr 0x96000147 elr: 00000000400015bc lr : 0000000040012b4c x 0: 0000000000008000 x 1: 0000000000092600 x 2: 0000000000000040 x 3: 000000000000003f x 4: 0000000000000030 x 5: 0000000000000001 x 6: 0000000000000001 x 7: 0000000000000000 x 8: 000000000000000a x 9: 0000000000000090 x10: 0000000043dffc68 x11: 0000000043c00440 x12: 0000000043c00440 x13: ffffffffbfe00000 x14: 000000000000031c x15: 0000000240000000 x16: 000000004001145c x17: 0000000000000032 x18: 0000000043dffef0 x19: 0000000043c00000 x20: 0000000043dffbc8 x21: 0000000000000000 x22: 00000000000f3d95 x23: 0000000000000002 x24: 0000000000000493 x25: 0000000000092600 x26: 0000000000000001 x27: 0000000000000001 x28: 0000000000000008 x29: 0000000043dffab0 Code: d2800082 9ac32042 d1000443 8a230000 (d5087620) Resetting CPU ... resetting ... Fix this by only dma_unmap_single() when DMA mode is used and sdhci_prepare_dma() has been called to map host->start_addr. Signed-off-by: Jonas Karlman Signed-off-by: Peng Fan --- diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 4833b5158c7..dc7f0724a7b 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -177,8 +177,10 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data) } while (!(stat & SDHCI_INT_DATA_END)); #if (CONFIG_IS_ENABLED(MMC_SDHCI_SDMA) || CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)) - dma_unmap_single(host->start_addr, data->blocks * data->blocksize, - mmc_get_dma_dir(data)); + if (host->flags & USE_DMA) { + dma_unmap_single(host->start_addr, data->blocks * data->blocksize, + mmc_get_dma_dir(data)); + } #endif return 0;