summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-11-27 16:05:55 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-11-27 16:05:55 -0800
commitb246b38b901b4211cfdfd0a26603f48767291e14 (patch)
tree1c30508571ea1ce56d9e1febfd67b05d2113e495 /drivers
parentfd7545d7d2f7a2aea18482537712f0aa46f99073 (diff)
parente8dce7e56dfc825a43fd775fe81d54cae21d2232 (diff)
Merge "mmc: card: Requeue the request if it fails during issuing"
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/card/block.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 063e00517660..7d2ceda7f80e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -3170,6 +3170,16 @@ static struct mmc_cmdq_req *mmc_blk_cmdq_rw_prep(
return &mqrq->cmdq_req;
}
+static void mmc_blk_cmdq_requeue_rw_rq(struct mmc_queue *mq,
+ struct request *req)
+{
+ struct mmc_card *card = mq->card;
+ struct mmc_host *host = card->host;
+
+ blk_requeue_request(req->q, req);
+ mmc_put_card(host->card);
+}
+
static int mmc_blk_cmdq_issue_rw_rq(struct mmc_queue *mq, struct request *req)
{
struct mmc_queue_req *active_mqrq;
@@ -3217,6 +3227,15 @@ static int mmc_blk_cmdq_issue_rw_rq(struct mmc_queue *mq, struct request *req)
wait_event_interruptible(ctx->queue_empty_wq,
(!ctx->active_reqs));
+ if (ret) {
+ /* clear pending request */
+ WARN_ON(!test_and_clear_bit(req->tag,
+ &host->cmdq_ctx.data_active_reqs));
+ WARN_ON(!test_and_clear_bit(req->tag,
+ &host->cmdq_ctx.active_reqs));
+ mmc_cmdq_clk_scaling_stop_busy(host, true, false);
+ }
+
return ret;
}
@@ -4042,6 +4061,13 @@ static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req)
ret = mmc_blk_cmdq_issue_flush_rq(mq, req);
} else {
ret = mmc_blk_cmdq_issue_rw_rq(mq, req);
+ /*
+ * If issuing of the request fails with eitehr EBUSY or
+ * EAGAIN error, re-queue the request.
+ * This case would occur with ICE calls.
+ */
+ if (ret == -EBUSY || ret == -EAGAIN)
+ mmc_blk_cmdq_requeue_rw_rq(mq, req);
}
}