Message ID | 20250128084226.15873-1-sooraj20636@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | mmc: sd: Fix incorrect capacity calculation for SDHC/SDXC/SDUC cards | expand |
> The capacity calculation for high-capacity SD cards (SDHC/SDXC/SDUC) used > an incorrect bit shift (10 bits instead of 19 or 22), leading to severely > underestimated storage capacities. > > - For SDHC/SDXC (CSD structure version 1), the capacity is defined as: > `(C_SIZE + 1) * 512 KiB` (SD Physical Layer Spec v3.01, section 5.3.3). > This requires a left shift by 19 bits (2^19 = 512 KiB). > > - For SDUC (CSD structure version 2), the capacity is: > `(C_SIZE + 1) * 4096 KiB` (SD Physical Layer Spec v7.10, section 5.3.3), > requiring a left shift by 22 bits (2^22 = 4096 KiB). > > Update the shifts to 19 and 22 bits for versions 1 and 2 respectively, ensuring > accurate capacity reporting. This resolves issues where cards (e.g., 64GB) > were incorrectly identified as 1-4GB. > > Signed-off-by: sooraj <sooraj20636@gmail.com> Please share the kernel info of your sd insert flow, e.g. something in the form of: [ 5791.041876] mmc0: new ultra high speed SDR104 SDUC card at address d555 [ 5791.041916] mmcblk mmc0:d555: calling add_quirk_sd [ 5791.042108] mmc0: calculated max. discard sectors 1957888 for timeout 60000 ms [ 5791.042127] mmcblk0: mmc0:d555 SR04T 3.72 TiB Also what your /sys/block/mmcblk<x>/size say? where is <x> is your sd card block device. Thanks, Avri > --- > drivers/mmc/core/sd.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index > cc757b850e79..b60de859e978 100644 > --- a/drivers/mmc/core/sd.c > +++ b/drivers/mmc/core/sd.c > @@ -172,7 +172,11 @@ static int mmc_decode_csd(struct mmc_card *card, > bool is_sduc) > else if (csd->c_size >= 0xFFFF) > mmc_card_set_ext_capacity(card); > > - csd->capacity = (1 + (typeof(sector_t))m) << 10; > + /* Correct the capacity calculation based on CSD structure version > */ > + if (csd_struct == 1) > + csd->capacity = (1 + (typeof(sector_t))m) << 19; /* SDHC/SDXC: > (C_SIZE + 1) * 512KB */ > + else > + csd->capacity = (1 + (typeof(sector_t))m) << 22; > + /* SDUC: (C_SIZE + 1) * 4096KB */ > > csd->read_blkbits = 9; > csd->read_partial = 0; > -- > 2.45.2 >
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index cc757b850e79..b60de859e978 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -172,7 +172,11 @@ static int mmc_decode_csd(struct mmc_card *card, bool is_sduc) else if (csd->c_size >= 0xFFFF) mmc_card_set_ext_capacity(card); - csd->capacity = (1 + (typeof(sector_t))m) << 10; + /* Correct the capacity calculation based on CSD structure version */ + if (csd_struct == 1) + csd->capacity = (1 + (typeof(sector_t))m) << 19; /* SDHC/SDXC: (C_SIZE + 1) * 512KB */ + else + csd->capacity = (1 + (typeof(sector_t))m) << 22; /* SDUC: (C_SIZE + 1) * 4096KB */ csd->read_blkbits = 9; csd->read_partial = 0;
The capacity calculation for high-capacity SD cards (SDHC/SDXC/SDUC) used an incorrect bit shift (10 bits instead of 19 or 22), leading to severely underestimated storage capacities. - For SDHC/SDXC (CSD structure version 1), the capacity is defined as: `(C_SIZE + 1) * 512 KiB` (SD Physical Layer Spec v3.01, section 5.3.3). This requires a left shift by 19 bits (2^19 = 512 KiB). - For SDUC (CSD structure version 2), the capacity is: `(C_SIZE + 1) * 4096 KiB` (SD Physical Layer Spec v7.10, section 5.3.3), requiring a left shift by 22 bits (2^22 = 4096 KiB). Update the shifts to 19 and 22 bits for versions 1 and 2 respectively, ensuring accurate capacity reporting. This resolves issues where cards (e.g., 64GB) were incorrectly identified as 1-4GB. Signed-off-by: sooraj <sooraj20636@gmail.com> --- drivers/mmc/core/sd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)