|
@@ -121,6 +121,7 @@ enum mmc_blk_status {
|
|
|
MMC_BLK_ABORT,
|
|
|
MMC_BLK_DATA_ERR,
|
|
|
MMC_BLK_ECC_ERR,
|
|
|
+ MMC_BLK_NOMEDIUM,
|
|
|
};
|
|
|
|
|
|
module_param(perdev_minors, int, 0444);
|
|
@@ -639,6 +640,7 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+#define ERR_NOMEDIUM 3
|
|
|
#define ERR_RETRY 2
|
|
|
#define ERR_ABORT 1
|
|
|
#define ERR_CONTINUE 0
|
|
@@ -706,6 +708,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
|
|
|
u32 status, stop_status = 0;
|
|
|
int err, retry;
|
|
|
|
|
|
+ if (mmc_card_removed(card))
|
|
|
+ return ERR_NOMEDIUM;
|
|
|
+
|
|
|
/*
|
|
|
* Try to get card status which indicates both the card state
|
|
|
* 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,
|
|
|
}
|
|
|
|
|
|
/* 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;
|
|
|
+ }
|
|
|
|
|
|
/* Flag ECC errors */
|
|
|
if ((status & R1_CARD_ECC_FAILED) ||
|
|
@@ -996,6 +1005,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
|
|
|
return MMC_BLK_RETRY;
|
|
|
case ERR_ABORT:
|
|
|
return MMC_BLK_ABORT;
|
|
|
+ case ERR_NOMEDIUM:
|
|
|
+ return MMC_BLK_NOMEDIUM;
|
|
|
case ERR_CONTINUE:
|
|
|
break;
|
|
|
}
|
|
@@ -1329,6 +1340,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
|
|
|
if (!ret)
|
|
|
goto start_new_req;
|
|
|
break;
|
|
|
+ case MMC_BLK_NOMEDIUM:
|
|
|
+ goto cmd_abort;
|
|
|
}
|
|
|
|
|
|
if (ret) {
|
|
@@ -1345,6 +1358,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
|
|
|
|
|
|
cmd_abort:
|
|
|
spin_lock_irq(&md->lock);
|
|
|
+ if (mmc_card_removed(card))
|
|
|
+ req->cmd_flags |= REQ_QUIET;
|
|
|
while (ret)
|
|
|
ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
|
|
|
spin_unlock_irq(&md->lock);
|