mmc: block: fix DCMD timeout err handling
DCMD requests don't have data, check for the data pointer before
accessing it to prevent null pointer dereference in case of DCMD
timeout err. Also signal a completion event for non flush requests
like discard that wait for the completion of DCMD request.
Change-Id: Ia71a5f1e278a039ba22f6ac42614d9ae79dba7e9
Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
[xiaonian@codeaurora.org: fixed trivial merge conflicts,
changed REQ_FLUSH to REQ_PREFLUSH as 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 faa8148..88621e5 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -3345,7 +3345,7 @@
goto reset;
}
- if (mrq->data->error) {
+ if (mrq->data && mrq->data->error) {
blk_end_request_all(mrq->req, mrq->data->error);
for (; retry < MAX_RETRIES; retry++) {
err = get_card_status(card, &status, 0);
@@ -3378,8 +3378,18 @@
}
/* DCMD commands */
- if (mrq->cmd->error)
+ if (mrq->cmd && 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);
+ goto reset;
+ }
+ clear_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state);
blk_end_request_all(mrq->req, mrq->cmd->error);
+ }
reset:
spin_lock_irq(mq->queue->queue_lock);