mmc: block: cmdq discard should use softirq completion path
Currently cmdq discard requests are not using same
softirq completion path as other cmdq request. So there
is no way to detect any error and handle it in case
of error of DCMD requests.
Make cmdq discard requests use blk_complete_requests
which complete via softirq completion path.
Change-Id: I1e03c81bc6fee8266cf1c86bada015e548770d7a
Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
[xiaonian@codeaurora.org: fixed trivial merge conflicts &
one compilation error, changed REQ_FLUSH to REQ_PREFLUSH
as new defined in msm-4.9]
Signed-off-by: Xiaonian Wang <xiaonian@codeaurora.org>
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 5a91f9c..2b4d193 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1873,13 +1873,12 @@
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
struct mmc_cmdq_req *cmdq_req = NULL;
- struct mmc_host *host = card->host;
- struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx;
unsigned int from, nr, arg;
int err = 0;
if (!mmc_can_erase(card)) {
err = -EOPNOTSUPP;
+ blk_end_request(req, err, blk_rq_bytes(req));
goto out;
}
@@ -1908,16 +1907,9 @@
}
err = mmc_cmdq_erase(cmdq_req, card, from, nr, arg);
clear_dcmd:
- /* clear pending request */
- if (cmdq_req) {
- BUG_ON(!test_and_clear_bit(cmdq_req->tag,
- &ctx_info->active_reqs));
- clear_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state);
- }
+ mmc_host_clk_hold(card->host);
+ blk_complete_request(req);
out:
- blk_end_request(req, err, blk_rq_bytes(req));
- wake_up(&ctx_info->wait);
- mmc_put_card(card);
return err ? 1 : 0;
}
@@ -1971,12 +1963,11 @@
struct mmc_card *card = md->queue.card;
struct mmc_cmdq_req *cmdq_req = NULL;
unsigned int from, nr, arg;
- struct mmc_host *host = card->host;
- struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx;
int err = 0;
if (!(mmc_can_secure_erase_trim(card))) {
err = -EOPNOTSUPP;
+ blk_end_request(req, err, blk_rq_bytes(req));
goto out;
}
@@ -2022,16 +2013,9 @@
MMC_SECURE_TRIM2_ARG);
}
clear_dcmd:
- /* clear pending request */
- if (cmdq_req) {
- BUG_ON(!test_and_clear_bit(cmdq_req->tag,
- &ctx_info->active_reqs));
- clear_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state);
- }
+ mmc_host_clk_hold(card->host);
+ blk_complete_request(req);
out:
- blk_end_request(req, err, blk_rq_bytes(req));
- wake_up(&ctx_info->wait);
- mmc_put_card(card);
return err ? 1 : 0;
}
@@ -3459,6 +3443,19 @@
else
mrq->data->error = -ETIMEDOUT;
+ if (mrq->cmd && mrq->cmd->error) {
+ if (!(mrq->req->cmd_flags & REQ_PREFLUSH)) {
+ /*
+ * Notify completion for non flush commands like
+ * discard that wait for DCMD finish.
+ */
+ set_bit(CMDQ_STATE_REQ_TIMED_OUT,
+ &ctx_info->curr_state);
+ complete(&mrq->completion);
+ return BLK_EH_NOT_HANDLED;
+ }
+ }
+
if (test_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state) ||
test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state))
return BLK_EH_NOT_HANDLED;
@@ -3519,14 +3516,6 @@
} else if (mrq->cmd && mrq->cmd->error) {
/* DCMD commands */
err = mrq->cmd->error;
-
- /*
- * Notify completion for non flush commands like discard
- * that wait for DCMD finish.
- */
- if (!(mrq->req->cmd_flags & REQ_PREFLUSH)) {
- complete(&mrq->completion);
- }
}
reset: