Re: [PATCH] mmc: spi: reset bytes_xfered before retrying CRC failures

From: Ulf Hansson

Date: Tue Sep 08 2026 - 12:23:26 EST


On Tue, Aug 18, 2026 at 1:32 PM raoxu <raoxu@xxxxxxxxxxxxx> wrote:
>
> From: Xu Rao <raoxu@xxxxxxxxxxxxx>
>
> mmc_spi_data_do() updates data->bytes_xfered after each block has been
> transferred successfully. If a later block in the same data request
> fails with a CRC error, data->bytes_xfered may therefore contain the
> number of bytes completed before the failing block.
>
> mmc_spi_request() has a private recovery path for such CRC failures. It
> sends STOP_TRANSMISSION, clears data->error and jumps back to
> crc_recover to issue the same command and data request again. However,
> it does not clear data->bytes_xfered before the retry.
>
> If the retry succeeds, the request is completed with the bytes from the
> failed attempt still included in data->bytes_xfered. For a multi-block
> request this can make the completed request report more bytes than were
> transferred by the successful retry, and can even exceed the request size
> when most blocks completed before the CRC error.
>
> This is most likely to be observed on MMC-over-SPI systems where long
> multi-block transfers occasionally hit a data CRC error but the
> mmc_spi-internal retry succeeds. The data itself is retried, but the
> completion accounting is not.
>
> Clear data->bytes_xfered together with data->error before repeating the
> request so the final completion reports only the bytes transferred by the
> successful attempt.
>
> Fixes: 061c6c847eeb ("mmc_spi: Recover from CRC errors for r/w operation over SPI.")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Xu Rao <raoxu@xxxxxxxxxxxxx>

Applied for fixes, thanks!

Kind regards
Uffe


> ---
> drivers/mmc/host/mmc_spi.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
> index b471a7795b4d..5217d713c826 100644
> --- a/drivers/mmc/host/mmc_spi.c
> +++ b/drivers/mmc/host/mmc_spi.c
> @@ -952,6 +952,7 @@ static void mmc_spi_request(struct mmc_host *mmc, struct mmc_request *mrq)
> status = mmc_spi_command_send(host, mrq, &stop, 0);
> crc_retry--;
> mrq->data->error = 0;
> + mrq->data->bytes_xfered = 0;
> goto crc_recover;
> }
>
> --
> 2.50.1
>