mmc: core: Add SD card quirk for broken poweroff notification
RFC PATCH 1/1 mmc: core: Add SD card quirk for broken poweroff notification
GIGASTONE Gaming Plus microSD cards manufactured on 02/2022 report that they support poweroff notification and cache, but they are not working correctly.
Flush Cache bit never gets cleared in sd_flush_cache() and Poweroff Notification Ready bit also never gets set to 1 within 1 second from the end of busy of CMD49 in sd_poweroff_notify().
This leads to I/O error and runtime PM error state.
I observed that the same card manufactured on 01/2024 works as expected.
This problem seems similar to the Kingston cards fixed with commit c467c8f08185 ("mmc: Add MMC_QUIRK_BROKEN_SD_CACHE for Kingston Canvas Go Plus from 11/2019") and should be handled using quirks.
CID for the problematic card is here.
12345641535443002000000145016200
Manufacturer ID is 0x12 and defined as CID_MANFID_GIGASTONE as of now, but would like comments on what naming is appropriate because MID list is not public and not sure it's right.
--- drivers/mmc/core/card.h | 7 +++++++ drivers/mmc/core/quirks.h | 9 +++++++++ drivers/mmc/core/sd.c | 2 +- include/linux/mmc/card.h | 1 + 4 files changed, 18 insertions(+), 1 deletion(-)
drivers/mmc/core/card.h +7 -0
@@ -82,6 +82,7 @@ struct mmc_fixup {#define CID_MANFID_SANDISK_SD 0x3#define CID_MANFID_ATP 0x9#define CID_MANFID_TOSHIBA 0x11 +#define CID_MANFID_GIGASTONE 0x12#define CID_MANFID_MICRON 0x13#define CID_MANFID_SAMSUNG 0x15#define CID_MANFID_APACER 0x27
@@ -284,4 +285,10 @@ static inline int mmc_card_broken_cache_flush(const struct mmc_card *c) {return c->quirks &MMC_QUIRK_BROKEN_CACHE_FLUSH ; } + +static inline int mmc_card_broken_sd_poweroff_notify (const struct mmc_card *c) +{ +return c->quirks &MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY ; +} +#endif
drivers/mmc/core/quirks.h +9 -0
@@ -25,6 +25,15 @@ static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = { 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY), +/* +* GIGASTONE Gaming Plus microSD cards manufactured on 02/2022 never +* clear Flush Cache bit and set Poweroff Notification Ready bit. +*/ +_FIXUP_EXT ("ASTC" ,CID_MANFID_GIGASTONE ,0x3456 ,2022 ,2 , +0 ,-1ull ,SDIO_ANY_ID ,SDIO_ANY_ID , add_quirk_sd, +MMC_QUIRK_BROKEN_SD_CACHE |MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY , +EXT_CSD_REV_ANY ), + END_FIXUP };
drivers/mmc/core/sd.c +1 -1
@@ -1118,7 +1118,7 @@ static int sd_parse_ext_reg_power(struct mmc_card *card, u8 fno, u8 page, card->ext_power.rev = reg_buf[0 ] &0xf ;/* Power Off Notification support at bit 4. */ -if (reg_buf[1 ] &BIT (4 )) +if ((reg_buf[1 ] &BIT (4 )) && !mmc_card_broken_sd_poweroff_notify (card)) card->ext_power.feature_support |=SD_EXT_POWER_OFF_NOTIFY ;/* Power Sustenance support at bit 5. */
include/linux/mmc/card.h +1 -0
@@ -294,6 +294,7 @@ struct mmc_card {#define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14)/* Disable broken SD discard support */ #define MMC_QUIRK_BROKEN_SD_CACHE (1<<15)/* Disable broken SD cache support */ #define MMC_QUIRK_BROKEN_CACHE_FLUSH (1<<16)/* Don't flush cache until the write has occurred */ +#define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY (1<<17)/* Disable broken SD poweroff notify support */ bool written_flag;/* Indicates eMMC has been written since power on */ bool reenable_cmdq;/* Re-enable Command Queue */
Signature · 1 line
2.46.0
Quoted 17 lines · Keita Aihara
GIGASTONE Gaming Plus microSD cards manufactured on 02/2022 report that they support poweroff notification and cache, but they are not working correctly.
Flush Cache bit never gets cleared in
sd_flush_cache()and Poweroff Notification Ready bit also never gets set to 1 within 1 second from the end of busy of CMD49 insd_poweroff_notify().This leads to I/O error and runtime PM error state.
I observed that the same card manufactured on 01/2024 works as expected.
This problem seems similar to the Kingston cards fixed with commit
c467c8f08185("mmc: AddMMC_QUIRK_BROKEN_SD_CACHEfor Kingston Canvas Go Plus from 11/2019") and should be handled using quirks.
Quoted 8 lines
CID for the problematic card is here.
12345641535443002000000145016200Manufacturer ID is
0x12and defined asCID_MANFID_GIGASTONEas of now, but would like comments on what naming is appropriate because MID list is not public and not sure it's right.Signed-off-by Keita Aihara <[email protected]>
Since the MI list isn't public and there is nobody using 0x12 for now, we might as well use it. At least I don't have a better suggestion.
That said, I have applied this for next, thanks!
Kind regards
Uffe
Quoted 78 lines
--- drivers/mmc/core/card.h | 7 +++++++ drivers/mmc/core/quirks.h | 9 +++++++++ drivers/mmc/core/sd.c | 2 +- include/linux/mmc/card.h | 1 + 4 files changed, 18 insertions(+), 1 deletion(-)drivers/mmc/core/card.h +7
-0@@ -82,6 +82,7 @@ struct mmc_fixup {#define CID_MANFID_SANDISK_SD 0x3#define CID_MANFID_ATP 0x9#define CID_MANFID_TOSHIBA 0x11 +#define CID_MANFID_GIGASTONE 0x12#define CID_MANFID_MICRON 0x13#define CID_MANFID_SAMSUNG 0x15#define CID_MANFID_APACER 0x27@@ -284,4 +285,10 @@ static inline int mmc_card_broken_cache_flush(const struct mmc_card *c) {return c->quirks &MMC_QUIRK_BROKEN_CACHE_FLUSH ; } + +static inline int mmc_card_broken_sd_poweroff_notify (const struct mmc_card *c) +{ +return c->quirks &MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY ; +} +#endif drivers/mmc/core/quirks.h +9
-0@@ -25,6 +25,15 @@ static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = { 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY), +/* +* GIGASTONE Gaming Plus microSD cards manufactured on 02/2022 never +* clear Flush Cache bit and set Poweroff Notification Ready bit. +*/ +_FIXUP_EXT ("ASTC" ,CID_MANFID_GIGASTONE ,0x3456 ,2022 ,2 , +0 ,-1ull ,SDIO_ANY_ID ,SDIO_ANY_ID , add_quirk_sd, +MMC_QUIRK_BROKEN_SD_CACHE |MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY , +EXT_CSD_REV_ANY ), + END_FIXUP };drivers/mmc/core/sd.c +1
-1@@ -1118,7 +1118,7 @@ static int sd_parse_ext_reg_power(struct mmc_card *card, u8 fno, u8 page, card->ext_power.rev = reg_buf[0 ] &0xf ;/* Power Off Notification support at bit 4. */ -if (reg_buf[1 ] &BIT (4 )) +if ((reg_buf[1 ] &BIT (4 )) && !mmc_card_broken_sd_poweroff_notify (card)) card->ext_power.feature_support |=SD_EXT_POWER_OFF_NOTIFY ;/* Power Sustenance support at bit 5. */ include/linux/mmc/card.h +1
-1@@ -294,6 +294,7 @@ struct mmc_card {#define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14)/* Disable broken SD discard support */ #define MMC_QUIRK_BROKEN_SD_CACHE (1<<15)/* Disable broken SD cache support */ #define MMC_QUIRK_BROKEN_CACHE_FLUSH (1<<16)/* Don't flush cache until the write has occurred */ +#define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY (1<<17)/* Disable broken SD poweroff notify support */ bool written_flag;/* Indicates eMMC has been written since power on */ bool reenable_cmdq;/* Re-enable Command Queue */ --2.46.0