Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
mmc: sd: add quirk for buggy CMD49 handling
Several card OEMs, mainly using Silicon Motion SM270x flash controllers,
have a deficient CMD49 handler that throws away length/offset and
applies the whole block to the addressed extension register page.

Add a quirk to do a read-modify-write cycle for any extension register
write.

Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
  • Loading branch information
P33M committed Mar 5, 2026
commit 397d0e65941df16ad0deee589e2f0f3e7ad6437f
19 changes: 16 additions & 3 deletions drivers/mmc/core/sd_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,10 +421,23 @@ int mmc_sd_write_ext_reg(struct mmc_card *card, u8 fno, u8 page, u16 offset,
* [17:9] offset address.
* [8:0] length (0 = 1 byte).
*/
cmd.arg = fno << 27 | page << 18 | offset << 9;
if (card->quirks & MMC_QUIRK_NONSTD_SD_CMD49) {
int err;
/*
* Card ignores length/offset and always applies
* all 512B of the write data block. RmW cycle required.
*/
err = mmc_sd_read_ext_reg(card, fno, page, 0, 512, reg_buf);
if (err)
return err;

/* The first byte in the buffer is the data to be written. */
reg_buf[0] = reg_data;
cmd.arg = fno << 27 | page << 18;
reg_buf[offset] = reg_data;
} else {
cmd.arg = fno << 27 | page << 18 | offset << 9;
/* The first byte in the buffer is the data to be written. */
reg_buf[0] = reg_data;
}

data.flags = MMC_DATA_WRITE;
data.blksz = 512;
Expand Down
1 change: 1 addition & 0 deletions include/linux/mmc/card.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ struct mmc_card {
#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 */
#define MMC_QUIRK_NO_UHS_DDR50_TUNING (1<<18) /* Disable DDR50 tuning */
#define MMC_QUIRK_NONSTD_SD_CMD49 (1<<29) /* SD card ignores length/offset argument */
#define MMC_QUIRK_WORKING_SD_CQ (1<<30) /* SD card has known-good CQ implementation */
#define MMC_QUIRK_ERASE_BROKEN (1<<31) /* Skip erase */

Expand Down