@@ -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";
@@ -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)
@@ -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;
@@ -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,
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. Signed-off-by: Avri Altman <avri.altman@wdc.com> --- 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(-)