aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card
diff options
context:
space:
mode:
authorTrey Ramsay <tramsay@linux.vnet.ibm.com>2012-11-16 10:31:41 -0500
committerChris Ball <cjb@laptop.org>2012-12-06 13:54:42 -0500
commit8fee476b219d1869762d9ef5c189a0c85e919a4d (patch)
tree460bb7932c106fae3b84646117b82e79c2618110 /drivers/mmc/card
parente95baf132f9709b86721a562210403473ef72249 (diff)
mmc: core: Fix some driver hangs when dealing with broken devices
There are infinite loops in the mmc code that can be caused by bad hardware. The code will loop forever if the device never comes back from program mode, R1_STATE_PRG, and it is not ready for data, R1_READY_FOR_DATA. A long timeout is added to prevent the code from looping forever. The timeout will occur if the device never comes back from program state or the device never becomes ready for data. It's not clear whether the timeout will do more than log a pr_err() and then start a fresh hang all over again. We may need to extend this patch later to perform some kind of reset of the device (is that possible?) or rejection of new I/O to the device. Signed-off-by: Trey Ramsay <tramsay@linux.vnet.ibm.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r--drivers/mmc/card/block.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 172a768036d8..8e6050869382 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -57,6 +57,7 @@ MODULE_ALIAS("mmc:block");
57#define INAND_CMD38_ARG_SECERASE 0x80 57#define INAND_CMD38_ARG_SECERASE 0x80
58#define INAND_CMD38_ARG_SECTRIM1 0x81 58#define INAND_CMD38_ARG_SECTRIM1 0x81
59#define INAND_CMD38_ARG_SECTRIM2 0x88 59#define INAND_CMD38_ARG_SECTRIM2 0x88
60#define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
60 61
61static DEFINE_MUTEX(block_mutex); 62static DEFINE_MUTEX(block_mutex);
62 63
@@ -1034,6 +1035,9 @@ static int mmc_blk_err_check(struct mmc_card *card,
1034 */ 1035 */
1035 if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { 1036 if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
1036 u32 status; 1037 u32 status;
1038 unsigned long timeout;
1039
1040 timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS);
1037 do { 1041 do {
1038 int err = get_card_status(card, &status, 5); 1042 int err = get_card_status(card, &status, 5);
1039 if (err) { 1043 if (err) {
@@ -1041,6 +1045,17 @@ static int mmc_blk_err_check(struct mmc_card *card,
1041 req->rq_disk->disk_name, err); 1045 req->rq_disk->disk_name, err);
1042 return MMC_BLK_CMD_ERR; 1046 return MMC_BLK_CMD_ERR;
1043 } 1047 }
1048
1049 /* Timeout if the device never becomes ready for data
1050 * and never leaves the program state.
1051 */
1052 if (time_after(jiffies, timeout)) {
1053 pr_err("%s: Card stuck in programming state!"\
1054 " %s %s\n", mmc_hostname(card->host),
1055 req->rq_disk->disk_name, __func__);
1056
1057 return MMC_BLK_CMD_ERR;
1058 }
1044 /* 1059 /*
1045 * Some cards mishandle the status bits, 1060 * Some cards mishandle the status bits,
1046 * so make sure to check both the busy 1061 * so make sure to check both the busy