diff options
author | Ian Chen <ian.cy.chen@samsung.com> | 2012-08-29 02:05:36 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-09-04 13:58:10 -0400 |
commit | 3550ccdb9d8d350e526b809bf3dd92b550a74fe1 (patch) | |
tree | 8e656ed3f53adca5c0bc7a598e44d62476f51e78 | |
parent | 9623b5b9192b349bcadb31cce159072a78ac6972 (diff) |
mmc: card: Skip secure erase on MoviNAND; causes unrecoverable corruption.
For several MoviNAND eMMC parts, there are known issues with secure
erase and secure trim. For these specific MoviNAND devices, we skip
these operations.
Specifically, there is a bug in the eMMC firmware that causes
unrecoverable corruption when the MMC is erased with MMC_CAP_ERASE
enabled.
References:
http://forum.xda-developers.com/showthread.php?t=1644364
https://plus.google.com/111398485184813224730/posts/21pTYfTsCkB#111398485184813224730/posts/21pTYfTsCkB
Signed-off-by: Ian Chen <ian.cy.chen@samsung.com>
Reviewed-by: Namjae Jeon <linkinjeon@gmail.com>
Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Cc: stable <stable@vger.kernel.org> [3.0+]
Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r-- | drivers/mmc/card/block.c | 26 | ||||
-rw-r--r-- | include/linux/mmc/card.h | 1 |
2 files changed, 26 insertions, 1 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index f1c84decb192..172a768036d8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -1411,7 +1411,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
1411 | /* complete ongoing async transfer before issuing discard */ | 1411 | /* complete ongoing async transfer before issuing discard */ |
1412 | if (card->host->areq) | 1412 | if (card->host->areq) |
1413 | mmc_blk_issue_rw_rq(mq, NULL); | 1413 | mmc_blk_issue_rw_rq(mq, NULL); |
1414 | if (req->cmd_flags & REQ_SECURE) | 1414 | if (req->cmd_flags & REQ_SECURE && |
1415 | !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN)) | ||
1415 | ret = mmc_blk_issue_secdiscard_rq(mq, req); | 1416 | ret = mmc_blk_issue_secdiscard_rq(mq, req); |
1416 | else | 1417 | else |
1417 | ret = mmc_blk_issue_discard_rq(mq, req); | 1418 | ret = mmc_blk_issue_discard_rq(mq, req); |
@@ -1716,6 +1717,7 @@ force_ro_fail: | |||
1716 | #define CID_MANFID_SANDISK 0x2 | 1717 | #define CID_MANFID_SANDISK 0x2 |
1717 | #define CID_MANFID_TOSHIBA 0x11 | 1718 | #define CID_MANFID_TOSHIBA 0x11 |
1718 | #define CID_MANFID_MICRON 0x13 | 1719 | #define CID_MANFID_MICRON 0x13 |
1720 | #define CID_MANFID_SAMSUNG 0x15 | ||
1719 | 1721 | ||
1720 | static const struct mmc_fixup blk_fixups[] = | 1722 | static const struct mmc_fixup blk_fixups[] = |
1721 | { | 1723 | { |
@@ -1752,6 +1754,28 @@ static const struct mmc_fixup blk_fixups[] = | |||
1752 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, | 1754 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, |
1753 | MMC_QUIRK_LONG_READ_TIME), | 1755 | MMC_QUIRK_LONG_READ_TIME), |
1754 | 1756 | ||
1757 | /* | ||
1758 | * On these Samsung MoviNAND parts, performing secure erase or | ||
1759 | * secure trim can result in unrecoverable corruption due to a | ||
1760 | * firmware bug. | ||
1761 | */ | ||
1762 | MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1763 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1764 | MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1765 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1766 | MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1767 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1768 | MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1769 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1770 | MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1771 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1772 | MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1773 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1774 | MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1775 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1776 | MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1777 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1778 | |||
1755 | END_FIXUP | 1779 | END_FIXUP |
1756 | }; | 1780 | }; |
1757 | 1781 | ||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 111aca5e97f3..4b27f9f503e4 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -239,6 +239,7 @@ struct mmc_card { | |||
239 | #define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ | 239 | #define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ |
240 | #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */ | 240 | #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */ |
241 | #define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */ | 241 | #define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */ |
242 | #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */ | ||
242 | /* byte mode */ | 243 | /* byte mode */ |
243 | unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */ | 244 | unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */ |
244 | #define MMC_NO_POWER_NOTIFICATION 0 | 245 | #define MMC_NO_POWER_NOTIFICATION 0 |