drivers/mmc/core/block.c | 82 ++++---------------------------------------- drivers/mmc/core/core.c | 3 +- drivers/mmc/core/mmc_test.c | 83 ++++++++++++++++++++------------------------- 3 files changed, 45 insertions(+), 123 deletions(-)
Background and patchset description:
Currently, the MMC driver handles multi-block read/write failures through
two separate mechanisms:
1. For read failures, the native retry mechanism is triggered internally
within the MMC core.
2. For write failures, the corresponding request is re-queued with the
MQRQ_XFER_SINGLE_BLOCK flag for single-block recovery. This separation
creates inconsistency in error handling.
To improve code uniformity and reliability, this patch series consolidates
both read and write failure paths into a unified recovery model by enabling
the use of MQRQ_XFER_SINGLE_BLOCK for handling multi-block read failures as
well. Patch 1-3 are small improvement while reading the code. Patch 4
implements the conversion of multi-block read failures to MQRQ_XFER_SINGLE_BLOCK
mode.
Testing Details:
1. Platforms: Tested on RK3576 with both CQE and non-CQE modes.
2. Methodology:
- Background dd test continuously reading from eMMC.
- Physically interrupting the eMMC data line during tests to simulate CRC errors.
Testing Result:
On CEQ mode, CRC error triggered on slot 4 (blkaddr 734208). It successfully
transitioned to single-block retries using tags 25, 27, 24, 25, 26, etc.
(see logs below):
mmc0: starting CQE transfer for tag 4 blkaddr 734208
mmc0: CQE transfer done tag 9
mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000
mmc0: 524288 bytes transferred: 0
mmc0: starting CQE transfer for tag 5 blkaddr 735232
mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000
mmc0: running CQE recovery
mmc0: starting CMD12 arg 00000000 flags 00000019
mmc0: req failed (CMD12): -110, retrying...
mmc0: req failed (CMD12): -110, retrying...
mmc0: req failed (CMD12): -110, retrying...
mmc0: req done (CMD12): -110: 00000000 00000000 00000000 00000000
mmc0: starting CMD13 arg 00010000 flags 00000195
mmc0: req done (CMD13): 0: 00400900 00000000 00000000 00000000
mmc0: starting CMD48 arg 00000001 flags 00000019
mmc0: req done (CMD48): 0: 00000900 00000000 00000000 00000000
mmc0: CQE transfer done tag 4
mmc0: 0 bytes transferred: -84
mmc0: CQE transfer done tag 5
mmc0: 0 bytes transferred: 0
mmc0: starting CQE transfer for tag 25 blkaddr 734208
mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000
mmc0: starting CQE transfer for tag 26 blkaddr 735232
mmc0: CQE transfer done tag 25
mmc0: 512 bytes transferred: 0
mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000
mmc0: starting CQE transfer for tag 27 blkaddr 734209
mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000
mmc0: CQE transfer done tag 26
mmc0: 524288 bytes transferred: 0
mmc0: CQE transfer done tag 27
mmc0: 512 bytes transferred: 0
mmc0: starting CQE transfer for tag 24 blkaddr 734210
mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000
mmc0: CQE transfer done tag 24
mmc0: 512 bytes transferred: 0
mmc0: starting CQE transfer for tag 25 blkaddr 734211
mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000
mmc0: CQE transfer done tag 25
mmc0: 512 bytes transferred: 0
mmc0: starting CQE transfer for tag 26 blkaddr 734212
mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000
mmc0: CQE transfer done tag 26
mmc0: 512 bytes transferred: 0
On non-CQE mode, a CRC error occurs during a multi-block read
operation (CMD18) targeting sector 0x0002d000. Subsequently,
mmc core initiates a single-block retry using CMD17, starting
from the same sector 0x0002d000(see logs below):
mmc0: starting CMD18 arg 0002d000 flags 000000b5
mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000
mmc0: CMD12 arg 00000000 flags 00000095
mmc0: req done : 0: 00000000 00000000 00000000 00000000
mmc0: req done (CMD18): 0: 00000900 00000000 00000000 00000000
mmc0: 0 bytes transferred: -84
mmc0: (CMD12): 0: 00000b00 00000000 00000000 00000000
mmc0: starting CMD13 arg 00010000 flags 00000195
mmc0: req done (CMD13): 0: 00000900 00000000 00000000 00000000
mmc0: <starting CMD23 arg 00000400 flags 00000015>
mmc0: starting CMD18 arg 0002d400 flags 000000b5
mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000
mmc0: CMD12 arg 00000000 flags 00000095
mmc0: req done : 0: 00000000 00000000 00000000 00000000
mmc0: req done (CMD18): 0: 00000900 00000000 00000000 00000000
mmc0: 524288 bytes transferred: 0
mmc0: (CMD12): 0: 00000000 00000000 00000000 00000000
mmc0: starting CMD17 arg 0002d000 flags 000000b5
mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000
mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000
mmc0: 512 bytes transferred: 0
mmc0: starting CMD17 arg 0002d001 flags 000000b5
mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000
mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000
mmc0: 512 bytes transferred: 0
mmc0: starting CMD17 arg 0002d002 flags 000000b5
mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000
mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000
mmc0: 512 bytes transferred: 0
mmc0: starting CMD17 arg 0002d003 flags 000000b5
mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000
mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000
mmc0: 512 bytes transferred: 0
Shawn Lin (4):
mmc: core: Replace the hard-coded shift value 9 with SECTOR_SHIFT
mmc: block: Convert to use DEFINE_SIMPLE_DEV_PM_OPS()
mmc: mmc_test: Replace hard-coded values with macros and consolidate
test parameters
mmc: block: Use MQRQ_XFER_SINGLE_BLOCK for both read and write
recovery
drivers/mmc/core/block.c | 82 ++++----------------------------------------
drivers/mmc/core/core.c | 3 +-
drivers/mmc/core/mmc_test.c | 83 ++++++++++++++++++++-------------------------
3 files changed, 45 insertions(+), 123 deletions(-)
--
2.7.4
On Mon, 30 Mar 2026 at 05:28, Shawn Lin <shawn.lin@rock-chips.com> wrote: > > > Background and patchset description: > Currently, the MMC driver handles multi-block read/write failures through > two separate mechanisms: > 1. For read failures, the native retry mechanism is triggered internally > within the MMC core. > 2. For write failures, the corresponding request is re-queued with the > MQRQ_XFER_SINGLE_BLOCK flag for single-block recovery. This separation > creates inconsistency in error handling. > > To improve code uniformity and reliability, this patch series consolidates > both read and write failure paths into a unified recovery model by enabling > the use of MQRQ_XFER_SINGLE_BLOCK for handling multi-block read failures as > well. Patch 1-3 are small improvement while reading the code. Patch 4 > implements the conversion of multi-block read failures to MQRQ_XFER_SINGLE_BLOCK > mode. > > Testing Details: > 1. Platforms: Tested on RK3576 with both CQE and non-CQE modes. > 2. Methodology: > - Background dd test continuously reading from eMMC. > - Physically interrupting the eMMC data line during tests to simulate CRC errors. > > Testing Result: > On CEQ mode, CRC error triggered on slot 4 (blkaddr 734208). It successfully > transitioned to single-block retries using tags 25, 27, 24, 25, 26, etc. > (see logs below): > mmc0: starting CQE transfer for tag 4 blkaddr 734208 > mmc0: CQE transfer done tag 9 > mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000 > mmc0: 524288 bytes transferred: 0 > mmc0: starting CQE transfer for tag 5 blkaddr 735232 > mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000 > mmc0: running CQE recovery > mmc0: starting CMD12 arg 00000000 flags 00000019 > mmc0: req failed (CMD12): -110, retrying... > mmc0: req failed (CMD12): -110, retrying... > mmc0: req failed (CMD12): -110, retrying... > mmc0: req done (CMD12): -110: 00000000 00000000 00000000 00000000 > mmc0: starting CMD13 arg 00010000 flags 00000195 > mmc0: req done (CMD13): 0: 00400900 00000000 00000000 00000000 > mmc0: starting CMD48 arg 00000001 flags 00000019 > mmc0: req done (CMD48): 0: 00000900 00000000 00000000 00000000 > mmc0: CQE transfer done tag 4 > mmc0: 0 bytes transferred: -84 > mmc0: CQE transfer done tag 5 > mmc0: 0 bytes transferred: 0 > mmc0: starting CQE transfer for tag 25 blkaddr 734208 > mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000 > mmc0: starting CQE transfer for tag 26 blkaddr 735232 > mmc0: CQE transfer done tag 25 > mmc0: 512 bytes transferred: 0 > mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000 > mmc0: starting CQE transfer for tag 27 blkaddr 734209 > mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000 > mmc0: CQE transfer done tag 26 > mmc0: 524288 bytes transferred: 0 > mmc0: CQE transfer done tag 27 > mmc0: 512 bytes transferred: 0 > mmc0: starting CQE transfer for tag 24 blkaddr 734210 > mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000 > mmc0: CQE transfer done tag 24 > mmc0: 512 bytes transferred: 0 > mmc0: starting CQE transfer for tag 25 blkaddr 734211 > mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000 > mmc0: CQE transfer done tag 25 > mmc0: 512 bytes transferred: 0 > mmc0: starting CQE transfer for tag 26 blkaddr 734212 > mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000 > mmc0: CQE transfer done tag 26 > mmc0: 512 bytes transferred: 0 > > On non-CQE mode, a CRC error occurs during a multi-block read > operation (CMD18) targeting sector 0x0002d000. Subsequently, > mmc core initiates a single-block retry using CMD17, starting > from the same sector 0x0002d000(see logs below): > mmc0: starting CMD18 arg 0002d000 flags 000000b5 > mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000 > mmc0: CMD12 arg 00000000 flags 00000095 > mmc0: req done : 0: 00000000 00000000 00000000 00000000 > mmc0: req done (CMD18): 0: 00000900 00000000 00000000 00000000 > mmc0: 0 bytes transferred: -84 > mmc0: (CMD12): 0: 00000b00 00000000 00000000 00000000 > mmc0: starting CMD13 arg 00010000 flags 00000195 > mmc0: req done (CMD13): 0: 00000900 00000000 00000000 00000000 > mmc0: <starting CMD23 arg 00000400 flags 00000015> > mmc0: starting CMD18 arg 0002d400 flags 000000b5 > mmc0: blksz 512 blocks 1024 flags 00000200 tsac 150 ms nsac 1000 > mmc0: CMD12 arg 00000000 flags 00000095 > mmc0: req done : 0: 00000000 00000000 00000000 00000000 > mmc0: req done (CMD18): 0: 00000900 00000000 00000000 00000000 > mmc0: 524288 bytes transferred: 0 > mmc0: (CMD12): 0: 00000000 00000000 00000000 00000000 > mmc0: starting CMD17 arg 0002d000 flags 000000b5 > mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000 > mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000 > mmc0: 512 bytes transferred: 0 > mmc0: starting CMD17 arg 0002d001 flags 000000b5 > mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000 > mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000 > mmc0: 512 bytes transferred: 0 > mmc0: starting CMD17 arg 0002d002 flags 000000b5 > mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000 > mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000 > mmc0: 512 bytes transferred: 0 > mmc0: starting CMD17 arg 0002d003 flags 000000b5 > mmc0: blksz 512 blocks 1 flags 00000200 tsac 150 ms nsac 1000 > mmc0: req done (CMD17): 0: 00000900 00000000 00000000 00000000 > mmc0: 512 bytes transferred: 0 > > > > Shawn Lin (4): > mmc: core: Replace the hard-coded shift value 9 with SECTOR_SHIFT > mmc: block: Convert to use DEFINE_SIMPLE_DEV_PM_OPS() > mmc: mmc_test: Replace hard-coded values with macros and consolidate > test parameters > mmc: block: Use MQRQ_XFER_SINGLE_BLOCK for both read and write > recovery > > drivers/mmc/core/block.c | 82 ++++---------------------------------------- > drivers/mmc/core/core.c | 3 +- > drivers/mmc/core/mmc_test.c | 83 ++++++++++++++++++++------------------------- > 3 files changed, 45 insertions(+), 123 deletions(-) Nice! > > -- > 2.7.4 > It looks like you could have split this series into separate standalone changes, but let's proceed this time. The series applied for next, thanks! Kind regards Uffe
© 2016 - 2026 Red Hat, Inc.