Commit 3bd4ac22 authored by Avri Altman's avatar Avri Altman Committed by Lipeng Sang
Browse files

mmc: core: Add SD card quirk for broken discard

stable inclusion
from stable-v5.10.152
commit e2f9b62ead9a69f5f605bb8777be5c97f292972d
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I73HJ0

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e2f9b62ead9a69f5f605bb8777be5c97f292972d



--------------------------------

commit 07d2872b upstream.

Some SD-cards from Sandisk that are SDA-6.0 compliant reports they supports
discard, while they actually don't. This might cause mk2fs to fail while
trying to format the card and revert it to a read-only mode.

To fix this problem, let's add a card quirk (MMC_QUIRK_BROKEN_SD_DISCARD)
to indicate that we shall fall-back to use the legacy erase command
instead.

Signed-off-by: default avatarAvri Altman <avri.altman@wdc.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20220928095744.16455-1-avri.altman@wdc.com


[Ulf: Updated the commit message]
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarLipeng Sang <sanglipeng1@jd.com>
parent e6d45f46
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1069,6 +1069,11 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
	nr = blk_rq_sectors(req);

	do {
		unsigned int erase_arg = card->erase_arg;

		if (mmc_card_broken_sd_discard(card))
			erase_arg = SD_ERASE_ARG;

		err = 0;
		if (card->quirks & MMC_QUIRK_INAND_CMD38) {
			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -1079,7 +1084,7 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
					 card->ext_csd.generic_cmd6_time);
		}
		if (!err)
			err = mmc_erase(card, from, nr, card->erase_arg);
			err = mmc_erase(card, from, nr, erase_arg);
	} while (err == -EIO && !mmc_blk_reset(md, card->host, type));
	if (err)
		status = BLK_STS_IOERR;
+6 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ struct mmc_fixup {
#define EXT_CSD_REV_ANY (-1u)

#define CID_MANFID_SANDISK      0x2
#define CID_MANFID_SANDISK_SD   0x3
#define CID_MANFID_ATP          0x9
#define CID_MANFID_TOSHIBA      0x11
#define CID_MANFID_MICRON       0x13
@@ -222,4 +223,9 @@ static inline int mmc_card_broken_hpi(const struct mmc_card *c)
	return c->quirks & MMC_QUIRK_BROKEN_HPI;
}

static inline int mmc_card_broken_sd_discard(const struct mmc_card *c)
{
	return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD;
}

#endif
+6 −0
Original line number Diff line number Diff line
@@ -99,6 +99,12 @@ 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),

	/*
	 * Some SD cards reports discard support while they don't
	 */
	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd,
		  MMC_QUIRK_BROKEN_SD_DISCARD),

	END_FIXUP
};

+1 −0
Original line number Diff line number Diff line
@@ -270,6 +270,7 @@ struct mmc_card {
#define MMC_QUIRK_BROKEN_IRQ_POLLING	(1<<11)	/* Polling SDIO_CCCR_INTx could create a fake interrupt */
#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 */

	bool			reenable_cmdq;	/* Re-enable Command Queue */