Commit a8ad82cc authored by Sujit Reddy Thumma's avatar Sujit Reddy Thumma Committed by Chris Ball

mmc: card: Kill block requests if card is removed

Kill block requests when the host realizes that the card is
removed from the slot and is sure that subsequent requests
are bound to fail. Do this silently so that the block
layer doesn't output unnecessary error messages.
Signed-off-by: default avatarSujit Reddy Thumma <sthumma@codeaurora.org>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 4137e504
...@@ -121,6 +121,7 @@ enum mmc_blk_status { ...@@ -121,6 +121,7 @@ enum mmc_blk_status {
MMC_BLK_ABORT, MMC_BLK_ABORT,
MMC_BLK_DATA_ERR, MMC_BLK_DATA_ERR,
MMC_BLK_ECC_ERR, MMC_BLK_ECC_ERR,
MMC_BLK_NOMEDIUM,
}; };
module_param(perdev_minors, int, 0444); module_param(perdev_minors, int, 0444);
...@@ -639,6 +640,7 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries) ...@@ -639,6 +640,7 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries)
return err; return err;
} }
#define ERR_NOMEDIUM 3
#define ERR_RETRY 2 #define ERR_RETRY 2
#define ERR_ABORT 1 #define ERR_ABORT 1
#define ERR_CONTINUE 0 #define ERR_CONTINUE 0
...@@ -706,6 +708,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, ...@@ -706,6 +708,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
u32 status, stop_status = 0; u32 status, stop_status = 0;
int err, retry; int err, retry;
if (mmc_card_removed(card))
return ERR_NOMEDIUM;
/* /*
* Try to get card status which indicates both the card state * Try to get card status which indicates both the card state
* and why there was no response. If the first attempt fails, * and why there was no response. If the first attempt fails,
...@@ -722,8 +727,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, ...@@ -722,8 +727,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
} }
/* We couldn't get a response from the card. Give up. */ /* We couldn't get a response from the card. Give up. */
if (err) if (err) {
/* Check if the card is removed */
if (mmc_detect_card_removed(card->host))
return ERR_NOMEDIUM;
return ERR_ABORT; return ERR_ABORT;
}
/* Flag ECC errors */ /* Flag ECC errors */
if ((status & R1_CARD_ECC_FAILED) || if ((status & R1_CARD_ECC_FAILED) ||
...@@ -996,6 +1005,8 @@ static int mmc_blk_err_check(struct mmc_card *card, ...@@ -996,6 +1005,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
return MMC_BLK_RETRY; return MMC_BLK_RETRY;
case ERR_ABORT: case ERR_ABORT:
return MMC_BLK_ABORT; return MMC_BLK_ABORT;
case ERR_NOMEDIUM:
return MMC_BLK_NOMEDIUM;
case ERR_CONTINUE: case ERR_CONTINUE:
break; break;
} }
...@@ -1329,6 +1340,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) ...@@ -1329,6 +1340,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
if (!ret) if (!ret)
goto start_new_req; goto start_new_req;
break; break;
case MMC_BLK_NOMEDIUM:
goto cmd_abort;
} }
if (ret) { if (ret) {
...@@ -1345,6 +1358,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) ...@@ -1345,6 +1358,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
cmd_abort: cmd_abort:
spin_lock_irq(&md->lock); spin_lock_irq(&md->lock);
if (mmc_card_removed(card))
req->cmd_flags |= REQ_QUIET;
while (ret) while (ret)
ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
spin_unlock_irq(&md->lock); spin_unlock_irq(&md->lock);
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
*/ */
static int mmc_prep_request(struct request_queue *q, struct request *req) static int mmc_prep_request(struct request_queue *q, struct request *req)
{ {
struct mmc_queue *mq = q->queuedata;
/* /*
* We only like normal block requests and discards. * We only like normal block requests and discards.
*/ */
...@@ -37,6 +39,9 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) ...@@ -37,6 +39,9 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
return BLKPREP_KILL; return BLKPREP_KILL;
} }
if (mq && mmc_card_removed(mq->card))
return BLKPREP_KILL;
req->cmd_flags |= REQ_DONTPREP; req->cmd_flags |= REQ_DONTPREP;
return BLKPREP_OK; return BLKPREP_OK;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment