brcm2708: update linux 4.4 patches to latest version
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0349-mmc-Add-MMC_QUIRK_ERASE_BROKEN-for-some-cards.patch
1 From efba060602bfb54eb1106972360df001bb88ae3b 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 349/423] 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 drivers/mmc/card/block.c | 7 +++++++
13 drivers/mmc/core/core.c | 3 ++-
14 include/linux/mmc/card.h | 3 +++
15 3 files changed, 12 insertions(+), 1 deletion(-)
16
17 --- a/drivers/mmc/card/block.c
18 +++ b/drivers/mmc/card/block.c
19 @@ -2552,6 +2552,13 @@ static const struct mmc_fixup blk_fixups
20 MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
21 MMC_QUIRK_TRIM_BROKEN),
22
23 + /*
24 + * On some Kingston SD cards, multiple erases of less than 64
25 + * sectors can cause corruption.
26 + */
27 + MMC_FIXUP("SD16G", 0x41, 0x3432, add_quirk_mmc,
28 + MMC_QUIRK_ERASE_BROKEN),
29 +
30 END_FIXUP
31 };
32
33 --- a/drivers/mmc/core/core.c
34 +++ b/drivers/mmc/core/core.c
35 @@ -2253,7 +2253,8 @@ EXPORT_SYMBOL(mmc_erase);
36 int mmc_can_erase(struct mmc_card *card)
37 {
38 if ((card->host->caps & MMC_CAP_ERASE) &&
39 - (card->csd.cmdclass & CCC_ERASE) && card->erase_size)
40 + (card->csd.cmdclass & CCC_ERASE) && card->erase_size &&
41 + !(card->quirks & MMC_QUIRK_ERASE_BROKEN))
42 return 1;
43 return 0;
44 }
45 --- a/include/linux/mmc/card.h
46 +++ b/include/linux/mmc/card.h
47 @@ -281,6 +281,9 @@ struct mmc_card {
48 #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */
49
50
51 +#define MMC_QUIRK_ERASE_BROKEN (1<<31) /* Skip erase */
52 +
53 +
54 unsigned int erase_size; /* erase size in sectors */
55 unsigned int erase_shift; /* if erase unit is power 2 */
56 unsigned int pref_erase; /* in sectors */