diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2015-05-07 13:10:24 +0300 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2015-06-01 09:06:59 +0200 |
commit | b8360a4945c49c07568892b5958c08e01bf7d6d2 (patch) | |
tree | f372f144ac3eb8a0638e3a977098fcb393dcee76 | |
parent | 6f398ad2075d9af4158d37442e9ca22e528f06c1 (diff) |
mmc: block: Retry errored data requests when re-tuning is needed
Retry errored data requests when re-tuning is needed and
add a flag to struct mmc_blk_request so that the retry
is only done once.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r-- | drivers/mmc/card/block.c | 11 | ||||
-rw-r--r-- | drivers/mmc/card/queue.h | 1 |
2 files changed, 11 insertions, 1 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 5af52fd9e37a..eefdf2510542 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1207,6 +1207,7 @@ static int mmc_blk_err_check(struct mmc_card *card, mmc_active); struct mmc_blk_request *brq = &mq_mrq->brq; struct request *req = mq_mrq->req; + int need_retune = card->host->need_retune; int ecc_err = 0, gen_err = 0; /* @@ -1274,6 +1275,12 @@ static int mmc_blk_err_check(struct mmc_card *card, } if (brq->data.error) { + if (need_retune && !brq->retune_retry_done) { + pr_info("%s: retrying because a re-tune was needed\n", + req->rq_disk->disk_name); + brq->retune_retry_done = 1; + return MMC_BLK_RETRY; + } pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n", req->rq_disk->disk_name, brq->data.error, (unsigned)blk_rq_pos(req), @@ -1833,7 +1840,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_blk_request *brq = &mq->mqrq_cur->brq; - int ret = 1, disable_multi = 0, retry = 0, type; + int ret = 1, disable_multi = 0, retry = 0, type, retune_retry_done = 0; enum mmc_blk_status status; struct mmc_queue_req *mq_rq; struct request *req = rqc; @@ -1917,6 +1924,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) break; goto cmd_abort; case MMC_BLK_RETRY: + retune_retry_done = brq->retune_retry_done; if (retry++ < 5) break; /* Fall through */ @@ -1979,6 +1987,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) mmc_start_req(card->host, &mq_rq->mmc_active, NULL); } + mq_rq->brq.retune_retry_done = retune_retry_done; } } while (ret); diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index 99e6521e6169..36cddab57d77 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h @@ -12,6 +12,7 @@ struct mmc_blk_request { struct mmc_command cmd; struct mmc_command stop; struct mmc_data data; + int retune_retry_done; }; enum mmc_packed_type { |