On Tue, 20 Jun 2023 at 12:27, Marek Vasut <marex@xxxxxxx> wrote: > > This microSD card never clears Flush Cache bit after cache flush has > been started in sd_flush_cache(). This leads e.g. to failure to mount > file system. Add a quirk which disables the SD cache for this specific > card from specific manufacturing date of 11/2019, since on newer dated > cards from 05/2023 the cache flush works correctly. > > Fixes: 08ebf903af57 ("mmc: core: Fixup support for writeback-cache for eMMC and SD") > Signed-off-by: Marek Vasut <marex@xxxxxxx> Applied for next and by adding a stable tag, thanks! Kind regards Uffe > --- > Cc: Adrian Hunter <adrian.hunter@xxxxxxxxx> > Cc: Avri Altman <avri.altman@xxxxxxx> > Cc: Brian Norris <briannorris@xxxxxxxxxxxx> > Cc: ChanWoo Lee <cw9316.lee@xxxxxxxxxxx> > Cc: Liang He <windhl@xxxxxxx> > Cc: Seunghui Lee <sh043.lee@xxxxxxxxxxx> > Cc: Ulf Hansson <ulf.hansson@xxxxxxxxxx> > Cc: Xander Li <xander_li@xxxxxxxxxxxxxxx> > Cc: Zhen Lei <thunder.leizhen@xxxxxxxxxx> > Cc: linux-mmc@xxxxxxxxxxxxxxx > --- > V2: Drop the unnecessary bail out points > --- > drivers/mmc/core/card.h | 30 +++++++++++++++++++++++------- > drivers/mmc/core/quirks.h | 13 +++++++++++++ > drivers/mmc/core/sd.c | 2 +- > include/linux/mmc/card.h | 1 + > 4 files changed, 38 insertions(+), 8 deletions(-) > > diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h > index cfdd1ff40b865..4edf9057fa79d 100644 > --- a/drivers/mmc/core/card.h > +++ b/drivers/mmc/core/card.h > @@ -53,6 +53,10 @@ struct mmc_fixup { > unsigned int manfid; > unsigned short oemid; > > + /* Manufacturing date */ > + unsigned short year; > + unsigned char month; > + > /* SDIO-specific fields. You can use SDIO_ANY_ID here of course */ > u16 cis_vendor, cis_device; > > @@ -68,6 +72,8 @@ struct mmc_fixup { > > #define CID_MANFID_ANY (-1u) > #define CID_OEMID_ANY ((unsigned short) -1) > +#define CID_YEAR_ANY ((unsigned short) -1) > +#define CID_MONTH_ANY ((unsigned char) -1) > #define CID_NAME_ANY (NULL) > > #define EXT_CSD_REV_ANY (-1u) > @@ -81,17 +87,21 @@ struct mmc_fixup { > #define CID_MANFID_APACER 0x27 > #define CID_MANFID_KINGSTON 0x70 > #define CID_MANFID_HYNIX 0x90 > +#define CID_MANFID_KINGSTON_SD 0x9F > #define CID_MANFID_NUMONYX 0xFE > > #define END_FIXUP { NULL } > > -#define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \ > - _cis_vendor, _cis_device, \ > - _fixup, _data, _ext_csd_rev) \ > +#define _FIXUP_EXT(_name, _manfid, _oemid, _year, _month, \ > + _rev_start, _rev_end, \ > + _cis_vendor, _cis_device, \ > + _fixup, _data, _ext_csd_rev) \ > { \ > .name = (_name), \ > .manfid = (_manfid), \ > .oemid = (_oemid), \ > + .year = (_year), \ > + .month = (_month), \ > .rev_start = (_rev_start), \ > .rev_end = (_rev_end), \ > .cis_vendor = (_cis_vendor), \ > @@ -103,8 +113,8 @@ struct mmc_fixup { > > #define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \ > _fixup, _data, _ext_csd_rev) \ > - _FIXUP_EXT(_name, _manfid, \ > - _oemid, _rev_start, _rev_end, \ > + _FIXUP_EXT(_name, _manfid, _oemid, CID_YEAR_ANY, CID_MONTH_ANY, \ > + _rev_start, _rev_end, \ > SDIO_ANY_ID, SDIO_ANY_ID, \ > _fixup, _data, _ext_csd_rev) \ > > @@ -118,8 +128,9 @@ struct mmc_fixup { > _ext_csd_rev) > > #define SDIO_FIXUP(_vendor, _device, _fixup, _data) \ > - _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \ > - CID_OEMID_ANY, 0, -1ull, \ > + _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, CID_OEMID_ANY, \ > + CID_YEAR_ANY, CID_MONTH_ANY, \ > + 0, -1ull, \ > _vendor, _device, \ > _fixup, _data, EXT_CSD_REV_ANY) \ > > @@ -264,4 +275,9 @@ static inline int mmc_card_broken_sd_discard(const struct mmc_card *c) > return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD; > } > > +static inline int mmc_card_broken_sd_cache(const struct mmc_card *c) > +{ > + return c->quirks & MMC_QUIRK_BROKEN_SD_CACHE; > +} > + > #endif > diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h > index 29b9497936df9..bf7fb72ab8b57 100644 > --- a/drivers/mmc/core/quirks.h > +++ b/drivers/mmc/core/quirks.h > @@ -100,6 +100,15 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = { > MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, > MMC_QUIRK_TRIM_BROKEN), > > + /* > + * Kingston Canvas Go! Plus microSD cards never finish SD cache flush. > + * This has so far only been observed on cards from 11/2019, while new > + * cards from 2023/05 do not exhibit this behavior. > + */ > + _FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11, > + 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, > + MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY), > + > /* > * Some SD cards reports discard support while they don't > */ > @@ -209,6 +218,10 @@ static inline void mmc_fixup_device(struct mmc_card *card, > if (f->of_compatible && > !mmc_fixup_of_compatible_match(card, f->of_compatible)) > continue; > + if (f->year != CID_YEAR_ANY && f->year != card->cid.year) > + continue; > + if (f->month != CID_MONTH_ANY && f->month != card->cid.month) > + continue; > > dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup); > f->vendor_fixup(card, f->data); > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c > index 72b664ed90cf6..246ce027ae0aa 100644 > --- a/drivers/mmc/core/sd.c > +++ b/drivers/mmc/core/sd.c > @@ -1170,7 +1170,7 @@ static int sd_parse_ext_reg_perf(struct mmc_card *card, u8 fno, u8 page, > card->ext_perf.feature_support |= SD_EXT_PERF_HOST_MAINT; > > /* Cache support at bit 0. */ > - if (reg_buf[4] & BIT(0)) > + if ((reg_buf[4] & BIT(0)) && !mmc_card_broken_sd_cache(card)) > card->ext_perf.feature_support |= SD_EXT_PERF_CACHE; > > /* Command queue support indicated via queue depth bits (0 to 4). */ > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h > index c726ea7812552..daa2f40d9ce65 100644 > --- a/include/linux/mmc/card.h > +++ b/include/linux/mmc/card.h > @@ -294,6 +294,7 @@ struct mmc_card { > #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ > #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ > #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 */ > > bool reenable_cmdq; /* Re-enable Command Queue */ > > -- > 2.39.2 >