100c8b1685fd2f8445c438c9a46a80d672fd5ce5
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.9 / 0036-mmc-Add-MMC_QUIRK_ERASE_BROKEN-for-some-cards.patch
1 From f6be5bc28ee258731e13b5e917d69f601d062014 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Wed, 11 May 2016 12:50:33 +0100
4 Subject: [PATCH] mmc: Add MMC_QUIRK_ERASE_BROKEN for some cards
5
6 Some SD cards have been found that corrupt data when small blocks
7 are erased. Add a quirk to indicate that ERASE should not be used,
8 and set it for cards of that type.
9
10 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
11
12 mmc: Apply QUIRK_BROKEN_ERASE to other capacities
13
14 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
15
16 mmc: Add card_quirks module parameter, log quirks
17
18 Use mmc_block.card_quirks to override the quirks for all SD or MMC
19 cards. The value is a bitfield using the bit positions defined in
20 include/linux/mmc/card.h. If the module parameter is placed in the
21 kernel command line (or bootargs) stored on the card then, assuming the
22 device only has one SD card interface, the override effectively becomes
23 card-specific.
24
25 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
26 ---
27 drivers/mmc/card/block.c | 39 ++++++++++++++++++++++++++++++++++++---
28 drivers/mmc/core/core.c | 3 ++-
29 include/linux/mmc/card.h | 3 +++
30 3 files changed, 41 insertions(+), 4 deletions(-)
31
32 --- a/drivers/mmc/card/block.c
33 +++ b/drivers/mmc/card/block.c
34 @@ -135,6 +135,13 @@ enum {
35 module_param(perdev_minors, int, 0444);
36 MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
37
38 +/*
39 + * Allow quirks to be overridden for the current card
40 + */
41 +static char *card_quirks;
42 +module_param(card_quirks, charp, 0644);
43 +MODULE_PARM_DESC(card_quirks, "Force the use of the indicated quirks (a bitfield)");
44 +
45 static inline int mmc_blk_part_switch(struct mmc_card *card,
46 struct mmc_blk_data *md);
47 static int get_card_status(struct mmc_card *card, u32 *status, int retries);
48 @@ -2573,6 +2580,17 @@ static const struct mmc_fixup blk_fixups
49 MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
50 MMC_QUIRK_TRIM_BROKEN),
51
52 + /*
53 + * On some Kingston SD cards, multiple erases of less than 64
54 + * sectors can cause corruption.
55 + */
56 + MMC_FIXUP("SD16G", 0x41, 0x3432, add_quirk_mmc,
57 + MMC_QUIRK_ERASE_BROKEN),
58 + MMC_FIXUP("SD32G", 0x41, 0x3432, add_quirk_mmc,
59 + MMC_QUIRK_ERASE_BROKEN),
60 + MMC_FIXUP("SD64G", 0x41, 0x3432, add_quirk_mmc,
61 + MMC_QUIRK_ERASE_BROKEN),
62 +
63 END_FIXUP
64 };
65
66 @@ -2580,6 +2598,7 @@ static int mmc_blk_probe(struct mmc_card
67 {
68 struct mmc_blk_data *md, *part_md;
69 char cap_str[10];
70 + char quirk_str[24];
71
72 /*
73 * Check that the card supports the command class(es) we need.
74 @@ -2587,7 +2606,16 @@ static int mmc_blk_probe(struct mmc_card
75 if (!(card->csd.cmdclass & CCC_BLOCK_READ))
76 return -ENODEV;
77
78 - mmc_fixup_device(card, blk_fixups);
79 + if (card_quirks) {
80 + unsigned long quirks;
81 + if (kstrtoul(card_quirks, 0, &quirks) == 0)
82 + card->quirks = (unsigned int)quirks;
83 + else
84 + pr_err("mmc_block: Invalid card_quirks parameter '%s'\n",
85 + card_quirks);
86 + }
87 + else
88 + mmc_fixup_device(card, blk_fixups);
89
90 md = mmc_blk_alloc(card);
91 if (IS_ERR(md))
92 @@ -2595,9 +2623,14 @@ static int mmc_blk_probe(struct mmc_card
93
94 string_get_size((u64)get_capacity(md->disk), 512, STRING_UNITS_2,
95 cap_str, sizeof(cap_str));
96 - pr_info("%s: %s %s %s %s\n",
97 + if (card->quirks)
98 + snprintf(quirk_str, sizeof(quirk_str),
99 + " (quirks 0x%08x)", card->quirks);
100 + else
101 + quirk_str[0] = '\0';
102 + pr_info("%s: %s %s %s%s%s\n",
103 md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
104 - cap_str, md->read_only ? "(ro)" : "");
105 + cap_str, md->read_only ? " (ro)" : "", quirk_str);
106
107 if (mmc_blk_alloc_parts(card, md))
108 goto out;
109 --- a/drivers/mmc/core/core.c
110 +++ b/drivers/mmc/core/core.c
111 @@ -2409,7 +2409,8 @@ EXPORT_SYMBOL(mmc_erase);
112 int mmc_can_erase(struct mmc_card *card)
113 {
114 if ((card->host->caps & MMC_CAP_ERASE) &&
115 - (card->csd.cmdclass & CCC_ERASE) && card->erase_size)
116 + (card->csd.cmdclass & CCC_ERASE) && card->erase_size &&
117 + !(card->quirks & MMC_QUIRK_ERASE_BROKEN))
118 return 1;
119 return 0;
120 }
121 --- a/include/linux/mmc/card.h
122 +++ b/include/linux/mmc/card.h
123 @@ -283,6 +283,9 @@ struct mmc_card {
124 #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */
125
126
127 +#define MMC_QUIRK_ERASE_BROKEN (1<<31) /* Skip erase */
128 +
129 +
130 unsigned int erase_size; /* erase size in sectors */
131 unsigned int erase_shift; /* if erase unit is power 2 */
132 unsigned int pref_erase; /* in sectors */