[PATCH] Fix emmc error state after mmc write timeout
Peng Fan
peng.fan at oss.nxp.com
Thu Jul 24 06:07:01 CEST 2025
On Mon, Jul 21, 2025 at 03:35:00PM +0300, Jimmy Durand Wesolowski wrote:
>From: Iulian Banaga <iulianeugen.banaga at mobileye.com>
>
>This is a fix for the sporadic mmc write failure:
> mmc write failed
> 0 blocks written: ERROR
>
>After this happens the emmc will remain in an error state
>where subsequent read/writes fail with a timeout.
>
>The mmc driver sends CMD25 - WRITE_MULTIPLE_BLOCK which
>can sporadically timeout. When this happens, the mmc driver
>aborts the transfer and returns the above error messages.
>
>But the emmc still remains in data transfer mode, since
>the timeout was decided by uboot, not by the emmc.
>
>Fix this by sending the STOP_TRANSMISSION command (CMD12)
>and waiting for the emmc to be in ready state again (CMD13).
>
>Transferring data blocks after a CMD25 can take anywhere
>between 5 and +15s on Samsung EMMCs and the current timeout
>is not enough. Increase the timeout by 2x to accommodate the
>long transfer times observed.
>
>Signed-off-by: Iulian Banaga <iulianeugen.banaga at mobileye.com>
>Acked-by: Jimmy Durand Wesolowski <jimmy.wesolowski at mobileye.com>
>---
>
> drivers/mmc/mmc_write.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
>index 90fcf2679bb..37a42887cab 100644
>--- a/drivers/mmc/mmc_write.c
>+++ b/drivers/mmc/mmc_write.c
>@@ -155,6 +155,7 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
> struct mmc_cmd cmd;
> struct mmc_data data;
> int timeout_ms = 1000;
>+ int err;
>
> if ((start + blkcnt) > mmc_get_blk_desc(mmc)->lba) {
> printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
>@@ -181,9 +182,11 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
> data.blocksize = mmc->write_bl_len;
> data.flags = MMC_DATA_WRITE;
>
>- if (mmc_send_cmd(mmc, &cmd, &data)) {
>+ err = mmc_send_cmd(mmc, &cmd, &data);
>+ if (err) {
> printf("mmc write failed\n");
>- return 0;
>+ // do not return 0 here since the emmc will still be in data
>+ // transfer mode continue to send the STOP_TRANSMISSION command
> }
>
> /* SPI multiblock writes terminate using a special
>@@ -203,6 +206,9 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
> if (mmc_poll_for_busy(mmc, timeout_ms))
> return 0;
>
>+ if (err)
>+ return 0;
>+
> return blkcnt;
> }
I would keep the comments aligned with others. I will update when apply
the patch.
Reviewed-by: Peng Fan <peng.fan at nxp.com>
Thanks,
Peng
More information about the U-Boot
mailing list