diff options
author | Christophe Kerello <christophe.kerello@foss.st.com> | 2025-08-12 15:55:26 +0200 |
---|---|---|
committer | Patrice Chotard <patrice.chotard@foss.st.com> | 2025-08-25 16:47:39 +0200 |
commit | 1067d2060ff017fb58758c0c21ae35504d144ea7 (patch) | |
tree | 5ed67e70b3c234c0646098584fed7d41e08758c1 | |
parent | 4c28c4d9a3a814cebb93e20842ed2c1c90f703d3 (diff) |
mmc: stm32_sdmmc2: avoid infinite while loop
Avoid unlimited while loop by adding a timeout. The timeout is
calculated based on a minimal throughput of 256 KB/s.
The timeout is set at least to 2 seconds.
Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
-rw-r--r-- | drivers/mmc/stm32_sdmmc2.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index 9483fb57daf..122690aef3e 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -385,15 +385,29 @@ static int stm32_sdmmc2_end_data(struct udevice *dev, u32 mask = SDMMC_STA_DCRCFAIL | SDMMC_STA_DTIMEOUT | SDMMC_STA_IDMATE | SDMMC_STA_DATAEND; u32 status; + unsigned long timeout_msecs = ctx->data_length >> 8; + unsigned long start_timeout; + + /* At least, a timeout of 2 seconds is set */ + if (timeout_msecs < 2000) + timeout_msecs = 2000; if (data->flags & MMC_DATA_READ) mask |= SDMMC_STA_RXOVERR; else mask |= SDMMC_STA_TXUNDERR; + start_timeout = get_timer(0); status = readl(plat->base + SDMMC_STA); - while (!(status & mask)) + while (!(status & mask)) { + if (get_timer(start_timeout) > timeout_msecs) { + ctx->dpsm_abort = true; + return -ETIMEDOUT; + } + + schedule(); status = readl(plat->base + SDMMC_STA); + } /* * Need invalidate the dcache again to avoid any |