0352-mmc-Add-MMC_QUIRK_ERASE_BROKEN-for-some-cards.patch 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. From 8479891a91161b13f8d63b7d8aa6614cb03e3442 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 352/381] mmc: Add MMC_QUIRK_ERASE_BROKEN for some cards
  5. Some SD cards have been found that corrupt data when small blocks
  6. are erased. Add a quirk to indicate that ERASE should not be used,
  7. and set it for cards of that type.
  8. Signed-off-by: Phil Elwell <phil@raspberrypi.org>
  9. ---
  10. drivers/mmc/card/block.c | 7 +++++++
  11. drivers/mmc/core/core.c | 3 ++-
  12. include/linux/mmc/card.h | 3 +++
  13. 3 files changed, 12 insertions(+), 1 deletion(-)
  14. --- a/drivers/mmc/card/block.c
  15. +++ b/drivers/mmc/card/block.c
  16. @@ -2552,6 +2552,13 @@ static const struct mmc_fixup blk_fixups
  17. MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
  18. MMC_QUIRK_TRIM_BROKEN),
  19. + /*
  20. + * On some Kingston SD cards, multiple erases of less than 64
  21. + * sectors can cause corruption.
  22. + */
  23. + MMC_FIXUP("SD16G", 0x41, 0x3432, add_quirk_mmc,
  24. + MMC_QUIRK_ERASE_BROKEN),
  25. +
  26. END_FIXUP
  27. };
  28. --- a/drivers/mmc/core/core.c
  29. +++ b/drivers/mmc/core/core.c
  30. @@ -2253,7 +2253,8 @@ EXPORT_SYMBOL(mmc_erase);
  31. int mmc_can_erase(struct mmc_card *card)
  32. {
  33. if ((card->host->caps & MMC_CAP_ERASE) &&
  34. - (card->csd.cmdclass & CCC_ERASE) && card->erase_size)
  35. + (card->csd.cmdclass & CCC_ERASE) && card->erase_size &&
  36. + !(card->quirks & MMC_QUIRK_ERASE_BROKEN))
  37. return 1;
  38. return 0;
  39. }
  40. --- a/include/linux/mmc/card.h
  41. +++ b/include/linux/mmc/card.h
  42. @@ -281,6 +281,9 @@ struct mmc_card {
  43. #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */
  44. +#define MMC_QUIRK_ERASE_BROKEN (1<<31) /* Skip erase */
  45. +
  46. +
  47. unsigned int erase_size; /* erase size in sectors */
  48. unsigned int erase_shift; /* if erase unit is power 2 */
  49. unsigned int pref_erase; /* in sectors */