Skip to content

Commit 6771632

Browse files
ahunter6cjb
authored andcommitted
mmc: block: add eMMC hardware reset support
For cards that support hardware reset (just eMMC), try a reset and retry before returning an I/O error. However this is not done for ECC errors and is never done twice for the same operation type (READ, WRITE, DISCARD, SECURE DISCARD) until that type of operation again succeeds. Signed-off-by: Adrian Hunter <[email protected]> Signed-off-by: Chris Ball <[email protected]>
1 parent 2311344 commit 6771632

File tree

2 files changed

+144
-61
lines changed

2 files changed

+144
-61
lines changed

drivers/mmc/card/block.c

Lines changed: 142 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ struct mmc_blk_data {
9494
unsigned int read_only;
9595
unsigned int part_type;
9696
unsigned int name_idx;
97+
unsigned int reset_done;
98+
#define MMC_BLK_READ BIT(0)
99+
#define MMC_BLK_WRITE BIT(1)
100+
#define MMC_BLK_DISCARD BIT(2)
101+
#define MMC_BLK_SECDISCARD BIT(3)
97102

98103
/*
99104
* Only set in main mmc_blk_data associated
@@ -109,11 +114,11 @@ static DEFINE_MUTEX(open_lock);
109114
enum mmc_blk_status {
110115
MMC_BLK_SUCCESS = 0,
111116
MMC_BLK_PARTIAL,
112-
MMC_BLK_RETRY,
113-
MMC_BLK_RETRY_SINGLE,
114-
MMC_BLK_DATA_ERR,
115117
MMC_BLK_CMD_ERR,
118+
MMC_BLK_RETRY,
116119
MMC_BLK_ABORT,
120+
MMC_BLK_DATA_ERR,
121+
MMC_BLK_ECC_ERR,
117122
};
118123

119124
module_param(perdev_minors, int, 0444);
@@ -454,7 +459,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card,
454459
card->ext_csd.part_time);
455460
if (ret)
456461
return ret;
457-
}
462+
}
458463

459464
main_md->part_curr = md->part_type;
460465
return 0;
@@ -616,7 +621,7 @@ static int mmc_blk_cmd_error(struct request *req, const char *name, int error,
616621
* Otherwise we don't understand what happened, so abort.
617622
*/
618623
static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
619-
struct mmc_blk_request *brq)
624+
struct mmc_blk_request *brq, int *ecc_err)
620625
{
621626
bool prev_cmd_status_valid = true;
622627
u32 status, stop_status = 0;
@@ -641,6 +646,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
641646
if (err)
642647
return ERR_ABORT;
643648

649+
/* Flag ECC errors */
650+
if ((status & R1_CARD_ECC_FAILED) ||
651+
(brq->stop.resp[0] & R1_CARD_ECC_FAILED) ||
652+
(brq->cmd.resp[0] & R1_CARD_ECC_FAILED))
653+
*ecc_err = 1;
654+
644655
/*
645656
* Check the current card state. If it is in some data transfer
646657
* mode, tell it to stop (and hopefully transition back to TRAN.)
@@ -658,6 +669,8 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
658669
*/
659670
if (err)
660671
return ERR_ABORT;
672+
if (stop_status & R1_CARD_ECC_FAILED)
673+
*ecc_err = 1;
661674
}
662675

663676
/* Check for set block count errors */
@@ -670,6 +683,10 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
670683
return mmc_blk_cmd_error(req, "r/w cmd", brq->cmd.error,
671684
prev_cmd_status_valid, status);
672685

686+
/* Data errors */
687+
if (!brq->stop.error)
688+
return ERR_CONTINUE;
689+
673690
/* Now for stop errors. These aren't fatal to the transfer. */
674691
pr_err("%s: error %d sending stop command, original cmd response %#x, card status %#x\n",
675692
req->rq_disk->disk_name, brq->stop.error,
@@ -686,12 +703,45 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
686703
return ERR_CONTINUE;
687704
}
688705

706+
static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
707+
int type)
708+
{
709+
int err;
710+
711+
if (md->reset_done & type)
712+
return -EEXIST;
713+
714+
md->reset_done |= type;
715+
err = mmc_hw_reset(host);
716+
/* Ensure we switch back to the correct partition */
717+
if (err != -EOPNOTSUPP) {
718+
struct mmc_blk_data *main_md = mmc_get_drvdata(host->card);
719+
int part_err;
720+
721+
main_md->part_curr = main_md->part_type;
722+
part_err = mmc_blk_part_switch(host->card, md);
723+
if (part_err) {
724+
/*
725+
* We have failed to get back into the correct
726+
* partition, so we need to abort the whole request.
727+
*/
728+
return -ENODEV;
729+
}
730+
}
731+
return err;
732+
}
733+
734+
static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type)
735+
{
736+
md->reset_done &= ~type;
737+
}
738+
689739
static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
690740
{
691741
struct mmc_blk_data *md = mq->data;
692742
struct mmc_card *card = md->queue.card;
693743
unsigned int from, nr, arg;
694-
int err = 0;
744+
int err = 0, type = MMC_BLK_DISCARD;
695745

696746
if (!mmc_can_erase(card)) {
697747
err = -EOPNOTSUPP;
@@ -705,7 +755,7 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
705755
arg = MMC_TRIM_ARG;
706756
else
707757
arg = MMC_ERASE_ARG;
708-
758+
retry:
709759
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
710760
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
711761
INAND_CMD38_ARG_EXT_CSD,
@@ -718,6 +768,10 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
718768
}
719769
err = mmc_erase(card, from, nr, arg);
720770
out:
771+
if (err == -EIO && !mmc_blk_reset(md, card->host, type))
772+
goto retry;
773+
if (!err)
774+
mmc_blk_reset_success(md, type);
721775
spin_lock_irq(&md->lock);
722776
__blk_end_request(req, err, blk_rq_bytes(req));
723777
spin_unlock_irq(&md->lock);
@@ -731,7 +785,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
731785
struct mmc_blk_data *md = mq->data;
732786
struct mmc_card *card = md->queue.card;
733787
unsigned int from, nr, arg;
734-
int err = 0;
788+
int err = 0, type = MMC_BLK_SECDISCARD;
735789

736790
if (!mmc_can_secure_erase_trim(card)) {
737791
err = -EOPNOTSUPP;
@@ -745,7 +799,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
745799
arg = MMC_SECURE_TRIM1_ARG;
746800
else
747801
arg = MMC_SECURE_ERASE_ARG;
748-
802+
retry:
749803
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
750804
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
751805
INAND_CMD38_ARG_EXT_CSD,
@@ -769,6 +823,10 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
769823
err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
770824
}
771825
out:
826+
if (err == -EIO && !mmc_blk_reset(md, card->host, type))
827+
goto retry;
828+
if (!err)
829+
mmc_blk_reset_success(md, type);
772830
spin_lock_irq(&md->lock);
773831
__blk_end_request(req, err, blk_rq_bytes(req));
774832
spin_unlock_irq(&md->lock);
@@ -825,11 +883,11 @@ static inline void mmc_apply_rel_rw(struct mmc_blk_request *brq,
825883
static int mmc_blk_err_check(struct mmc_card *card,
826884
struct mmc_async_req *areq)
827885
{
828-
enum mmc_blk_status ret = MMC_BLK_SUCCESS;
829886
struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req,
830887
mmc_active);
831888
struct mmc_blk_request *brq = &mq_mrq->brq;
832889
struct request *req = mq_mrq->req;
890+
int ecc_err = 0;
833891

834892
/*
835893
* sbc.error indicates a problem with the set block count
@@ -841,8 +899,9 @@ static int mmc_blk_err_check(struct mmc_card *card,
841899
* stop.error indicates a problem with the stop command. Data
842900
* may have been transferred, or may still be transferring.
843901
*/
844-
if (brq->sbc.error || brq->cmd.error || brq->stop.error) {
845-
switch (mmc_blk_cmd_recovery(card, req, brq)) {
902+
if (brq->sbc.error || brq->cmd.error || brq->stop.error ||
903+
brq->data.error) {
904+
switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err)) {
846905
case ERR_RETRY:
847906
return MMC_BLK_RETRY;
848907
case ERR_ABORT:
@@ -894,23 +953,21 @@ static int mmc_blk_err_check(struct mmc_card *card,
894953
brq->cmd.resp[0], brq->stop.resp[0]);
895954

896955
if (rq_data_dir(req) == READ) {
897-
if (brq->data.blocks > 1) {
898-
/* Redo read one sector at a time */
899-
pr_warning("%s: retrying using single block read\n",
900-
req->rq_disk->disk_name);
901-
return MMC_BLK_RETRY_SINGLE;
902-
}
956+
if (ecc_err)
957+
return MMC_BLK_ECC_ERR;
903958
return MMC_BLK_DATA_ERR;
904959
} else {
905960
return MMC_BLK_CMD_ERR;
906961
}
907962
}
908963

909-
if (ret == MMC_BLK_SUCCESS &&
910-
blk_rq_bytes(req) != brq->data.bytes_xfered)
911-
ret = MMC_BLK_PARTIAL;
964+
if (!brq->data.bytes_xfered)
965+
return MMC_BLK_RETRY;
912966

913-
return ret;
967+
if (blk_rq_bytes(req) != brq->data.bytes_xfered)
968+
return MMC_BLK_PARTIAL;
969+
970+
return MMC_BLK_SUCCESS;
914971
}
915972

916973
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
@@ -1049,12 +1106,41 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
10491106
mmc_queue_bounce_pre(mqrq);
10501107
}
10511108

1109+
static int mmc_blk_cmd_err(struct mmc_blk_data *md, struct mmc_card *card,
1110+
struct mmc_blk_request *brq, struct request *req,
1111+
int ret)
1112+
{
1113+
/*
1114+
* If this is an SD card and we're writing, we can first
1115+
* mark the known good sectors as ok.
1116+
*
1117+
* If the card is not SD, we can still ok written sectors
1118+
* as reported by the controller (which might be less than
1119+
* the real number of written sectors, but never more).
1120+
*/
1121+
if (mmc_card_sd(card)) {
1122+
u32 blocks;
1123+
1124+
blocks = mmc_sd_num_wr_blocks(card);
1125+
if (blocks != (u32)-1) {
1126+
spin_lock_irq(&md->lock);
1127+
ret = __blk_end_request(req, 0, blocks << 9);
1128+
spin_unlock_irq(&md->lock);
1129+
}
1130+
} else {
1131+
spin_lock_irq(&md->lock);
1132+
ret = __blk_end_request(req, 0, brq->data.bytes_xfered);
1133+
spin_unlock_irq(&md->lock);
1134+
}
1135+
return ret;
1136+
}
1137+
10521138
static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
10531139
{
10541140
struct mmc_blk_data *md = mq->data;
10551141
struct mmc_card *card = md->queue.card;
10561142
struct mmc_blk_request *brq = &mq->mqrq_cur->brq;
1057-
int ret = 1, disable_multi = 0, retry = 0;
1143+
int ret = 1, disable_multi = 0, retry = 0, type;
10581144
enum mmc_blk_status status;
10591145
struct mmc_queue_req *mq_rq;
10601146
struct request *req;
@@ -1076,6 +1162,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
10761162
mq_rq = container_of(areq, struct mmc_queue_req, mmc_active);
10771163
brq = &mq_rq->brq;
10781164
req = mq_rq->req;
1165+
type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE;
10791166
mmc_queue_bounce_post(mq_rq);
10801167

10811168
switch (status) {
@@ -1084,17 +1171,17 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
10841171
/*
10851172
* A block was successfully transferred.
10861173
*/
1174+
mmc_blk_reset_success(md, type);
10871175
spin_lock_irq(&md->lock);
10881176
ret = __blk_end_request(req, 0,
10891177
brq->data.bytes_xfered);
10901178
spin_unlock_irq(&md->lock);
1179+
/*
1180+
* If the blk_end_request function returns non-zero even
1181+
* though all data has been transferred and no errors
1182+
* were returned by the host controller, it's a bug.
1183+
*/
10911184
if (status == MMC_BLK_SUCCESS && ret) {
1092-
/*
1093-
* The blk_end_request has returned non zero
1094-
* even though all data is transfered and no
1095-
* erros returned by host.
1096-
* If this happen it's a bug.
1097-
*/
10981185
printk(KERN_ERR "%s BUG rq_tot %d d_xfer %d\n",
10991186
__func__, blk_rq_bytes(req),
11001187
brq->data.bytes_xfered);
@@ -1103,16 +1190,36 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
11031190
}
11041191
break;
11051192
case MMC_BLK_CMD_ERR:
1106-
goto cmd_err;
1107-
case MMC_BLK_RETRY_SINGLE:
1108-
disable_multi = 1;
1109-
break;
1193+
ret = mmc_blk_cmd_err(md, card, brq, req, ret);
1194+
if (!mmc_blk_reset(md, card->host, type))
1195+
break;
1196+
goto cmd_abort;
11101197
case MMC_BLK_RETRY:
11111198
if (retry++ < 5)
11121199
break;
1200+
/* Fall through */
11131201
case MMC_BLK_ABORT:
1202+
if (!mmc_blk_reset(md, card->host, type))
1203+
break;
11141204
goto cmd_abort;
1115-
case MMC_BLK_DATA_ERR:
1205+
case MMC_BLK_DATA_ERR: {
1206+
int err;
1207+
1208+
err = mmc_blk_reset(md, card->host, type);
1209+
if (!err)
1210+
break;
1211+
if (err == -ENODEV)
1212+
goto cmd_abort;
1213+
/* Fall through */
1214+
}
1215+
case MMC_BLK_ECC_ERR:
1216+
if (brq->data.blocks > 1) {
1217+
/* Redo read one sector at a time */
1218+
pr_warning("%s: retrying using single block read\n",
1219+
req->rq_disk->disk_name);
1220+
disable_multi = 1;
1221+
break;
1222+
}
11161223
/*
11171224
* After an error, we redo I/O one sector at a
11181225
* time, so we only reach here after trying to
@@ -1129,7 +1236,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
11291236

11301237
if (ret) {
11311238
/*
1132-
* In case of a none complete request
1239+
* In case of a incomplete request
11331240
* prepare it again and resend.
11341241
*/
11351242
mmc_blk_rw_rq_prep(mq_rq, card, disable_multi, mq);
@@ -1139,30 +1246,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
11391246

11401247
return 1;
11411248

1142-
cmd_err:
1143-
/*
1144-
* If this is an SD card and we're writing, we can first
1145-
* mark the known good sectors as ok.
1146-
*
1147-
* If the card is not SD, we can still ok written sectors
1148-
* as reported by the controller (which might be less than
1149-
* the real number of written sectors, but never more).
1150-
*/
1151-
if (mmc_card_sd(card)) {
1152-
u32 blocks;
1153-
1154-
blocks = mmc_sd_num_wr_blocks(card);
1155-
if (blocks != (u32)-1) {
1156-
spin_lock_irq(&md->lock);
1157-
ret = __blk_end_request(req, 0, blocks << 9);
1158-
spin_unlock_irq(&md->lock);
1159-
}
1160-
} else {
1161-
spin_lock_irq(&md->lock);
1162-
ret = __blk_end_request(req, 0, brq->data.bytes_xfered);
1163-
spin_unlock_irq(&md->lock);
1164-
}
1165-
11661249
cmd_abort:
11671250
spin_lock_irq(&md->lock);
11681251
while (ret)

0 commit comments

Comments
 (0)