Message ID | 20240814072934.2559911-3-avri.altman@wdc.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Add SDUC Support | expand |
On Wed, 14 Aug 2024 at 09:31, Avri Altman <avri.altman@wdc.com> wrote: > > Ultra Capacity SD cards (SDUC) was already introduced in SD7.0. Those > cards support capacity larger than 2TB and up to including 128TB. > Properly parse the csd register as the c_size field got expanded to 28 > bits. > > Tested-by: Ricky WU <ricky_wu@realtek.com> > Signed-off-by: Avri Altman <avri.altman@wdc.com> This is more what I expected from patch1. Perhaps we should simply squash patch1 and patch2? Kind regards Uffe > --- > drivers/mmc/core/bus.c | 4 +++- > drivers/mmc/core/card.h | 3 +++ > drivers/mmc/core/sd.c | 16 +++++++++++----- > include/linux/mmc/card.h | 2 +- > 4 files changed, 18 insertions(+), 7 deletions(-) > > diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c > index 0ddaee0eae54..30763b342bd3 100644 > --- a/drivers/mmc/core/bus.c > +++ b/drivers/mmc/core/bus.c > @@ -321,7 +321,9 @@ int mmc_add_card(struct mmc_card *card) > case MMC_TYPE_SD: > type = "SD"; > if (mmc_card_blockaddr(card)) { > - if (mmc_card_ext_capacity(card)) > + if (mmc_card_ult_capacity(card)) > + type = "SDUC"; > + else if (mmc_card_ext_capacity(card)) > type = "SDXC"; > else > type = "SDHC"; > diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h > index b7754a1b8d97..64dcb463a4f4 100644 > --- a/drivers/mmc/core/card.h > +++ b/drivers/mmc/core/card.h > @@ -23,6 +23,7 @@ > #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ > #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ > #define MMC_STATE_SUSPENDED (1<<5) /* card is suspended */ > +#define MMC_CARD_SDUC (1<<6) /* card is SDUC */ > > #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) > #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) > @@ -30,11 +31,13 @@ > #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) > #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) > #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) > +#define mmc_card_ult_capacity(c) ((c)->state & MMC_CARD_SDUC) > > #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) > #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) > #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) > #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) > +#define mmc_card_set_ult_capacity(c) ((c)->state |= MMC_CARD_SDUC) > #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) > #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) > #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c > index 1c8148cdda50..28193a9b31c9 100644 > --- a/drivers/mmc/core/sd.c > +++ b/drivers/mmc/core/sd.c > @@ -157,6 +157,7 @@ static int mmc_decode_csd(struct mmc_card *card) > mmc_card_set_readonly(card); > break; > case 1: > + case 2: > /* > * This is a block-addressed SDHC or SDXC card. Most > * interesting fields are unused and have fixed > @@ -172,14 +173,19 @@ static int mmc_decode_csd(struct mmc_card *card) > e = UNSTUFF_BITS(resp, 96, 3); > csd->max_dtr = tran_exp[e] * tran_mant[m]; > csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); > - csd->c_size = UNSTUFF_BITS(resp, 48, 22); > > - /* SDXC cards have a minimum C_SIZE of 0x00FFFF */ > - if (csd->c_size >= 0xFFFF) > + if (csd_struct == 1) > + m = UNSTUFF_BITS(resp, 48, 22); > + else > + m = UNSTUFF_BITS(resp, 48, 28); > + csd->c_size = m; > + > + if (csd->c_size >= 0x400000 && mmc_card_is_sduc(card->host)) > + mmc_card_set_ult_capacity(card); > + else if (csd->c_size >= 0xFFFF) > mmc_card_set_ext_capacity(card); > > - m = UNSTUFF_BITS(resp, 48, 22); > - csd->capacity = (1 + m) << 10; > + csd->capacity = (1 + (typeof(sector_t))m) << 10; > > csd->read_blkbits = 9; > csd->read_partial = 0; > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h > index f34407cc2788..f39bce322365 100644 > --- a/include/linux/mmc/card.h > +++ b/include/linux/mmc/card.h > @@ -35,7 +35,7 @@ struct mmc_csd { > unsigned int wp_grp_size; > unsigned int read_blkbits; > unsigned int write_blkbits; > - unsigned int capacity; > + sector_t capacity; > unsigned int read_partial:1, > read_misalign:1, > write_partial:1, > -- > 2.25.1 >
> On Wed, 14 Aug 2024 at 09:31, Avri Altman <avri.altman@wdc.com> wrote: > > > > Ultra Capacity SD cards (SDUC) was already introduced in SD7.0. Those > > cards support capacity larger than 2TB and up to including 128TB. > > Properly parse the csd register as the c_size field got expanded to 28 > > bits. > > > > Tested-by: Ricky WU <ricky_wu@realtek.com> > > Signed-off-by: Avri Altman <avri.altman@wdc.com> > > This is more what I expected from patch1. Perhaps we should simply squash > patch1 and patch2? Done. Thanks, Avri > > Kind regards > Uffe > > > --- > > drivers/mmc/core/bus.c | 4 +++- > > drivers/mmc/core/card.h | 3 +++ > > drivers/mmc/core/sd.c | 16 +++++++++++----- > > include/linux/mmc/card.h | 2 +- > > 4 files changed, 18 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index > > 0ddaee0eae54..30763b342bd3 100644 > > --- a/drivers/mmc/core/bus.c > > +++ b/drivers/mmc/core/bus.c > > @@ -321,7 +321,9 @@ int mmc_add_card(struct mmc_card *card) > > case MMC_TYPE_SD: > > type = "SD"; > > if (mmc_card_blockaddr(card)) { > > - if (mmc_card_ext_capacity(card)) > > + if (mmc_card_ult_capacity(card)) > > + type = "SDUC"; > > + else if (mmc_card_ext_capacity(card)) > > type = "SDXC"; > > else > > type = "SDHC"; diff --git > > a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index > > b7754a1b8d97..64dcb463a4f4 100644 > > --- a/drivers/mmc/core/card.h > > +++ b/drivers/mmc/core/card.h > > @@ -23,6 +23,7 @@ > > #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ > > #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ > > #define MMC_STATE_SUSPENDED (1<<5) /* card is suspended */ > > +#define MMC_CARD_SDUC (1<<6) /* card is SDUC */ > > > > #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) > > #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) > > @@ -30,11 +31,13 @@ > > #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) > > #define mmc_card_removed(c) ((c) && ((c)->state & > MMC_CARD_REMOVED)) > > #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) > > +#define mmc_card_ult_capacity(c) ((c)->state & MMC_CARD_SDUC) > > > > #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) > > #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) > > #define mmc_card_set_blockaddr(c) ((c)->state |= > MMC_STATE_BLOCKADDR) > > #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) > > +#define mmc_card_set_ult_capacity(c) ((c)->state |= MMC_CARD_SDUC) > > #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) > > #define mmc_card_set_suspended(c) ((c)->state |= > MMC_STATE_SUSPENDED) > > #define mmc_card_clr_suspended(c) ((c)->state &= > ~MMC_STATE_SUSPENDED) > > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index > > 1c8148cdda50..28193a9b31c9 100644 > > --- a/drivers/mmc/core/sd.c > > +++ b/drivers/mmc/core/sd.c > > @@ -157,6 +157,7 @@ static int mmc_decode_csd(struct mmc_card *card) > > mmc_card_set_readonly(card); > > break; > > case 1: > > + case 2: > > /* > > * This is a block-addressed SDHC or SDXC card. Most > > * interesting fields are unused and have fixed @@ > > -172,14 +173,19 @@ static int mmc_decode_csd(struct mmc_card *card) > > e = UNSTUFF_BITS(resp, 96, 3); > > csd->max_dtr = tran_exp[e] * tran_mant[m]; > > csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); > > - csd->c_size = UNSTUFF_BITS(resp, 48, 22); > > > > - /* SDXC cards have a minimum C_SIZE of 0x00FFFF */ > > - if (csd->c_size >= 0xFFFF) > > + if (csd_struct == 1) > > + m = UNSTUFF_BITS(resp, 48, 22); > > + else > > + m = UNSTUFF_BITS(resp, 48, 28); > > + csd->c_size = m; > > + > > + if (csd->c_size >= 0x400000 && mmc_card_is_sduc(card->host)) > > + mmc_card_set_ult_capacity(card); > > + else if (csd->c_size >= 0xFFFF) > > mmc_card_set_ext_capacity(card); > > > > - m = UNSTUFF_BITS(resp, 48, 22); > > - csd->capacity = (1 + m) << 10; > > + csd->capacity = (1 + (typeof(sector_t))m) << 10; > > > > csd->read_blkbits = 9; > > csd->read_partial = 0; diff --git > > a/include/linux/mmc/card.h b/include/linux/mmc/card.h index > > f34407cc2788..f39bce322365 100644 > > --- a/include/linux/mmc/card.h > > +++ b/include/linux/mmc/card.h > > @@ -35,7 +35,7 @@ struct mmc_csd { > > unsigned int wp_grp_size; > > unsigned int read_blkbits; > > unsigned int write_blkbits; > > - unsigned int capacity; > > + sector_t capacity; > > unsigned int read_partial:1, > > read_misalign:1, > > write_partial:1, > > -- > > 2.25.1 > >
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 0ddaee0eae54..30763b342bd3 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -321,7 +321,9 @@ int mmc_add_card(struct mmc_card *card) case MMC_TYPE_SD: type = "SD"; if (mmc_card_blockaddr(card)) { - if (mmc_card_ext_capacity(card)) + if (mmc_card_ult_capacity(card)) + type = "SDUC"; + else if (mmc_card_ext_capacity(card)) type = "SDXC"; else type = "SDHC"; diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index b7754a1b8d97..64dcb463a4f4 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h @@ -23,6 +23,7 @@ #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ #define MMC_STATE_SUSPENDED (1<<5) /* card is suspended */ +#define MMC_CARD_SDUC (1<<6) /* card is SDUC */ #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) @@ -30,11 +31,13 @@ #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) +#define mmc_card_ult_capacity(c) ((c)->state & MMC_CARD_SDUC) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) +#define mmc_card_set_ult_capacity(c) ((c)->state |= MMC_CARD_SDUC) #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 1c8148cdda50..28193a9b31c9 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -157,6 +157,7 @@ static int mmc_decode_csd(struct mmc_card *card) mmc_card_set_readonly(card); break; case 1: + case 2: /* * This is a block-addressed SDHC or SDXC card. Most * interesting fields are unused and have fixed @@ -172,14 +173,19 @@ static int mmc_decode_csd(struct mmc_card *card) e = UNSTUFF_BITS(resp, 96, 3); csd->max_dtr = tran_exp[e] * tran_mant[m]; csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); - csd->c_size = UNSTUFF_BITS(resp, 48, 22); - /* SDXC cards have a minimum C_SIZE of 0x00FFFF */ - if (csd->c_size >= 0xFFFF) + if (csd_struct == 1) + m = UNSTUFF_BITS(resp, 48, 22); + else + m = UNSTUFF_BITS(resp, 48, 28); + csd->c_size = m; + + if (csd->c_size >= 0x400000 && mmc_card_is_sduc(card->host)) + mmc_card_set_ult_capacity(card); + else if (csd->c_size >= 0xFFFF) mmc_card_set_ext_capacity(card); - m = UNSTUFF_BITS(resp, 48, 22); - csd->capacity = (1 + m) << 10; + csd->capacity = (1 + (typeof(sector_t))m) << 10; csd->read_blkbits = 9; csd->read_partial = 0; diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index f34407cc2788..f39bce322365 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -35,7 +35,7 @@ struct mmc_csd { unsigned int wp_grp_size; unsigned int read_blkbits; unsigned int write_blkbits; - unsigned int capacity; + sector_t capacity; unsigned int read_partial:1, read_misalign:1, write_partial:1,