1 |
From 54309fde1a352ad2674ebba004a79f7d20b9f037 Mon Sep 17 00:00:00 2001 |
2 |
From: =?UTF-8?q?Christian=20L=C3=B6hle?= <CLoehle@hyperstone.com> |
3 |
Date: Fri, 4 Feb 2022 15:11:37 +0000 |
4 |
Subject: mmc: block: fix read single on recovery logic |
5 |
|
6 |
From: Christian Löhle <CLoehle@hyperstone.com> |
7 |
|
8 |
commit 54309fde1a352ad2674ebba004a79f7d20b9f037 upstream. |
9 |
|
10 |
On reads with MMC_READ_MULTIPLE_BLOCK that fail, |
11 |
the recovery handler will use MMC_READ_SINGLE_BLOCK for |
12 |
each of the blocks, up to MMC_READ_SINGLE_RETRIES times each. |
13 |
The logic for this is fixed to never report unsuccessful reads |
14 |
as success to the block layer. |
15 |
|
16 |
On command error with retries remaining, blk_update_request was |
17 |
called with whatever value error was set last to. |
18 |
In case it was last set to BLK_STS_OK (default), the read will be |
19 |
reported as success, even though there was no data read from the device. |
20 |
This could happen on a CRC mismatch for the response, |
21 |
a card rejecting the command (e.g. again due to a CRC mismatch). |
22 |
In case it was last set to BLK_STS_IOERR, the error is reported correctly, |
23 |
but no retries will be attempted. |
24 |
|
25 |
Fixes: 81196976ed946c ("mmc: block: Add blk-mq support") |
26 |
Cc: stable@vger.kernel.org |
27 |
Signed-off-by: Christian Loehle <cloehle@hyperstone.com> |
28 |
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com> |
29 |
Link: https://lore.kernel.org/r/bc706a6ab08c4fe2834ba0c05a804672@hyperstone.com |
30 |
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> |
31 |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
32 |
--- |
33 |
drivers/mmc/core/block.c | 28 ++++++++++++++-------------- |
34 |
1 file changed, 14 insertions(+), 14 deletions(-) |
35 |
|
36 |
--- a/drivers/mmc/core/block.c |
37 |
+++ b/drivers/mmc/core/block.c |
38 |
@@ -1682,31 +1682,31 @@ static void mmc_blk_read_single(struct m |
39 |
struct mmc_card *card = mq->card; |
40 |
struct mmc_host *host = card->host; |
41 |
blk_status_t error = BLK_STS_OK; |
42 |
- int retries = 0; |
43 |
|
44 |
do { |
45 |
u32 status; |
46 |
int err; |
47 |
+ int retries = 0; |
48 |
|
49 |
- mmc_blk_rw_rq_prep(mqrq, card, 1, mq); |
50 |
+ while (retries++ <= MMC_READ_SINGLE_RETRIES) { |
51 |
+ mmc_blk_rw_rq_prep(mqrq, card, 1, mq); |
52 |
|
53 |
- mmc_wait_for_req(host, mrq); |
54 |
+ mmc_wait_for_req(host, mrq); |
55 |
|
56 |
- err = mmc_send_status(card, &status); |
57 |
- if (err) |
58 |
- goto error_exit; |
59 |
- |
60 |
- if (!mmc_host_is_spi(host) && |
61 |
- !mmc_ready_for_data(status)) { |
62 |
- err = mmc_blk_fix_state(card, req); |
63 |
+ err = mmc_send_status(card, &status); |
64 |
if (err) |
65 |
goto error_exit; |
66 |
- } |
67 |
|
68 |
- if (mrq->cmd->error && retries++ < MMC_READ_SINGLE_RETRIES) |
69 |
- continue; |
70 |
+ if (!mmc_host_is_spi(host) && |
71 |
+ !mmc_ready_for_data(status)) { |
72 |
+ err = mmc_blk_fix_state(card, req); |
73 |
+ if (err) |
74 |
+ goto error_exit; |
75 |
+ } |
76 |
|
77 |
- retries = 0; |
78 |
+ if (!mrq->cmd->error) |
79 |
+ break; |
80 |
+ } |
81 |
|
82 |
if (mrq->cmd->error || |
83 |
mrq->data->error || |