diff options
-rw-r--r-- | drivers/mmc/card/block.c | 17 | ||||
-rw-r--r-- | drivers/mmc/card/queue.c | 5 |
2 files changed, 21 insertions, 1 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 0c959c96005e..0cad48a284a8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -121,6 +121,7 @@ enum mmc_blk_status { | |||
121 | MMC_BLK_ABORT, | 121 | MMC_BLK_ABORT, |
122 | MMC_BLK_DATA_ERR, | 122 | MMC_BLK_DATA_ERR, |
123 | MMC_BLK_ECC_ERR, | 123 | MMC_BLK_ECC_ERR, |
124 | MMC_BLK_NOMEDIUM, | ||
124 | }; | 125 | }; |
125 | 126 | ||
126 | module_param(perdev_minors, int, 0444); | 127 | module_param(perdev_minors, int, 0444); |
@@ -639,6 +640,7 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries) | |||
639 | return err; | 640 | return err; |
640 | } | 641 | } |
641 | 642 | ||
643 | #define ERR_NOMEDIUM 3 | ||
642 | #define ERR_RETRY 2 | 644 | #define ERR_RETRY 2 |
643 | #define ERR_ABORT 1 | 645 | #define ERR_ABORT 1 |
644 | #define ERR_CONTINUE 0 | 646 | #define ERR_CONTINUE 0 |
@@ -706,6 +708,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, | |||
706 | u32 status, stop_status = 0; | 708 | u32 status, stop_status = 0; |
707 | int err, retry; | 709 | int err, retry; |
708 | 710 | ||
711 | if (mmc_card_removed(card)) | ||
712 | return ERR_NOMEDIUM; | ||
713 | |||
709 | /* | 714 | /* |
710 | * Try to get card status which indicates both the card state | 715 | * Try to get card status which indicates both the card state |
711 | * and why there was no response. If the first attempt fails, | 716 | * 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 | } | 727 | } |
723 | 728 | ||
724 | /* We couldn't get a response from the card. Give up. */ | 729 | /* We couldn't get a response from the card. Give up. */ |
725 | if (err) | 730 | if (err) { |
731 | /* Check if the card is removed */ | ||
732 | if (mmc_detect_card_removed(card->host)) | ||
733 | return ERR_NOMEDIUM; | ||
726 | return ERR_ABORT; | 734 | return ERR_ABORT; |
735 | } | ||
727 | 736 | ||
728 | /* Flag ECC errors */ | 737 | /* Flag ECC errors */ |
729 | if ((status & R1_CARD_ECC_FAILED) || | 738 | if ((status & R1_CARD_ECC_FAILED) || |
@@ -996,6 +1005,8 @@ static int mmc_blk_err_check(struct mmc_card *card, | |||
996 | return MMC_BLK_RETRY; | 1005 | return MMC_BLK_RETRY; |
997 | case ERR_ABORT: | 1006 | case ERR_ABORT: |
998 | return MMC_BLK_ABORT; | 1007 | return MMC_BLK_ABORT; |
1008 | case ERR_NOMEDIUM: | ||
1009 | return MMC_BLK_NOMEDIUM; | ||
999 | case ERR_CONTINUE: | 1010 | case ERR_CONTINUE: |
1000 | break; | 1011 | break; |
1001 | } | 1012 | } |
@@ -1329,6 +1340,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1329 | if (!ret) | 1340 | if (!ret) |
1330 | goto start_new_req; | 1341 | goto start_new_req; |
1331 | break; | 1342 | break; |
1343 | case MMC_BLK_NOMEDIUM: | ||
1344 | goto cmd_abort; | ||
1332 | } | 1345 | } |
1333 | 1346 | ||
1334 | if (ret) { | 1347 | if (ret) { |
@@ -1345,6 +1358,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1345 | 1358 | ||
1346 | cmd_abort: | 1359 | cmd_abort: |
1347 | spin_lock_irq(&md->lock); | 1360 | spin_lock_irq(&md->lock); |
1361 | if (mmc_card_removed(card)) | ||
1362 | req->cmd_flags |= REQ_QUIET; | ||
1348 | while (ret) | 1363 | while (ret) |
1349 | ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); | 1364 | ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); |
1350 | spin_unlock_irq(&md->lock); | 1365 | spin_unlock_irq(&md->lock); |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index dcad59cbfef1..2517547b4366 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -29,6 +29,8 @@ | |||
29 | */ | 29 | */ |
30 | static int mmc_prep_request(struct request_queue *q, struct request *req) | 30 | static int mmc_prep_request(struct request_queue *q, struct request *req) |
31 | { | 31 | { |
32 | struct mmc_queue *mq = q->queuedata; | ||
33 | |||
32 | /* | 34 | /* |
33 | * We only like normal block requests and discards. | 35 | * We only like normal block requests and discards. |
34 | */ | 36 | */ |
@@ -37,6 +39,9 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) | |||
37 | return BLKPREP_KILL; | 39 | return BLKPREP_KILL; |
38 | } | 40 | } |
39 | 41 | ||
42 | if (mq && mmc_card_removed(mq->card)) | ||
43 | return BLKPREP_KILL; | ||
44 | |||
40 | req->cmd_flags |= REQ_DONTPREP; | 45 | req->cmd_flags |= REQ_DONTPREP; |
41 | 46 | ||
42 | return BLKPREP_OK; | 47 | return BLKPREP_OK; |