aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/mmc/card/block.c15
-rw-r--r--drivers/mmc/core/core.c18
-rw-r--r--drivers/mmc/core/mmc_ops.c11
3 files changed, 43 insertions, 1 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
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 06c42cfb7c34..bccfd1858b08 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -42,6 +42,9 @@
42#include "sd_ops.h" 42#include "sd_ops.h"
43#include "sdio_ops.h" 43#include "sdio_ops.h"
44 44
45/* If the device is not responding */
46#define MMC_CORE_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
47
45/* 48/*
46 * Background operations can take a long time, depending on the housekeeping 49 * Background operations can take a long time, depending on the housekeeping
47 * operations the card has to perform. 50 * operations the card has to perform.
@@ -1631,6 +1634,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
1631{ 1634{
1632 struct mmc_command cmd = {0}; 1635 struct mmc_command cmd = {0};
1633 unsigned int qty = 0; 1636 unsigned int qty = 0;
1637 unsigned long timeout;
1634 int err; 1638 int err;
1635 1639
1636 /* 1640 /*
@@ -1708,6 +1712,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
1708 if (mmc_host_is_spi(card->host)) 1712 if (mmc_host_is_spi(card->host))
1709 goto out; 1713 goto out;
1710 1714
1715 timeout = jiffies + msecs_to_jiffies(MMC_CORE_TIMEOUT_MS);
1711 do { 1716 do {
1712 memset(&cmd, 0, sizeof(struct mmc_command)); 1717 memset(&cmd, 0, sizeof(struct mmc_command));
1713 cmd.opcode = MMC_SEND_STATUS; 1718 cmd.opcode = MMC_SEND_STATUS;
@@ -1721,8 +1726,19 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
1721 err = -EIO; 1726 err = -EIO;
1722 goto out; 1727 goto out;
1723 } 1728 }
1729
1730 /* Timeout if the device never becomes ready for data and
1731 * never leaves the program state.
1732 */
1733 if (time_after(jiffies, timeout)) {
1734 pr_err("%s: Card stuck in programming state! %s\n",
1735 mmc_hostname(card->host), __func__);
1736 err = -EIO;
1737 goto out;
1738 }
1739
1724 } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || 1740 } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
1725 R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG); 1741 (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));
1726out: 1742out:
1727 return err; 1743 return err;
1728} 1744}
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index a0e172042e65..6d8f7012d73a 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -21,6 +21,8 @@
21#include "core.h" 21#include "core.h"
22#include "mmc_ops.h" 22#include "mmc_ops.h"
23 23
24#define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
25
24static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) 26static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
25{ 27{
26 int err; 28 int err;
@@ -409,6 +411,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
409{ 411{
410 int err; 412 int err;
411 struct mmc_command cmd = {0}; 413 struct mmc_command cmd = {0};
414 unsigned long timeout;
412 u32 status; 415 u32 status;
413 416
414 BUG_ON(!card); 417 BUG_ON(!card);
@@ -437,6 +440,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
437 return 0; 440 return 0;
438 441
439 /* Must check status to be sure of no errors */ 442 /* Must check status to be sure of no errors */
443 timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS);
440 do { 444 do {
441 err = mmc_send_status(card, &status); 445 err = mmc_send_status(card, &status);
442 if (err) 446 if (err)
@@ -445,6 +449,13 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
445 break; 449 break;
446 if (mmc_host_is_spi(card->host)) 450 if (mmc_host_is_spi(card->host))
447 break; 451 break;
452
453 /* Timeout if the device never leaves the program state. */
454 if (time_after(jiffies, timeout)) {
455 pr_err("%s: Card stuck in programming state! %s\n",
456 mmc_hostname(card->host), __func__);
457 return -ETIMEDOUT;
458 }
448 } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); 459 } while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
449 460
450 if (mmc_host_is_spi(card->host)) { 461 if (mmc_host_is_spi(card->host)) {