Skip to contentSkip to conversation

Patch "mmc: sd: SDUC Support Recognition" has been added to the 6.12-stable tree

DISCUSSION Avri Altman 1 participant 1 message Dec 15, 2024 1 message not in the archive Stable branch

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

This patch is part of the series - https://patchwork.kernel.org/project/linux-mmc/list/?series=895924
This is patch 1/10, looks like the other 9 patches are missing.

Thanks,
Avri

Quoted 221 lines

This is a note to let you know that I've just added the patch titled

mmc: sd: SDUC Support Recognition

to the 6.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-
queue.git;a=summary

The filename of the patch is:
mmc-sd-sduc-support-recognition.patch
and it can be found in the queue-6.12 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

commit 67bc965d660760bd68981c067932c4bd807ebf95

Author: Avri Altman <[email protected]>
Date:   Sun Oct 6 08:11:39 2024 +0300

mmc: sd: SDUC Support Recognition

[ Upstream commit fce2ce78af1e14dc1316aaddb5b3308be05cf452 ]

Ultra Capacity SD cards (SDUC) was already introduced in SD7.0. Those cards support capacity larger than 2TB and up to including 128TB.

ACMD41 was extended to support the host-card handshake during initialization. The card expects that the HCS & HO2T bits to be set in the command argument, and sets the applicable bits in the R3 returned response. On the contrary, if a SDUC card is inserted to a non-supporting host, it will never respond to this ACMD41 until eventually, the host will timed out and give up.

Also, add SD CSD version 3.0 - designated for SDUC, and properly parse the csd register as the c_size field got expanded to 28 bits.

Do not enable SDUC for now - leave it to the last patch in the series.

[email protected]

Stable-dep-of: 869d37475788 ("mmc: core: Use GFP_NOIO in ACMD22")

drivers/mmc/core/bus.c index renamed from drivers/mmc/core/bus.c +0 -0

0ddaee0eae54f..30763b342bd36 100644

drivers/mmc/core/bus.c +3 -1
@@ -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 b7754a1b8d978..64dcb463a4f49 100644

drivers/mmc/core/card.h +3 -0
@@ -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 12fe282bea77e..1d09f0f2e7697 100644

drivers/mmc/core/sd.c +17 -11
@@ -100,7 +100,7 @@ void mmc_decode_cid(struct mmc_card *card)
 /*
  * Given a 128-bit response, decode to our card CSD structure.
  */
-static int mmc_decode_csd(struct mmc_card *card)
+static int mmc_decode_csd(struct mmc_card *card, bool is_sduc)
 {
        struct mmc_csd *csd = &card->csd;
        unsigned int e, m, csd_struct;
@@ -144,9 +144,10 @@ 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
+                * This is a block-addressed SDHC, SDXC or SDUC card.
+                * Most interesting fields are unused and have fixed
                 * values. To avoid getting tripped by buggy cards,
                 * we assume those fixed values ourselves.
                 */
@@ -159,14 +160,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 && is_sduc)
+                       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;
@@ -876,7 +882,7 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr,
 u32 *cid, u32 *rocr)
        return err;
 }
 
-int mmc_sd_get_csd(struct mmc_card *card)
+int mmc_sd_get_csd(struct mmc_card *card, bool is_sduc)
 {
        int err;
@@ -887,7 +893,7 @@ int mmc_sd_get_csd(struct mmc_card *card)
        if (err)
                return err;
 
-       err = mmc_decode_csd(card);
+       err = mmc_decode_csd(card, is_sduc);
        if (err)
                return err;
 
@@ -1442,7 +1448,7 @@ static int mmc_sd_init_card(struct mmc_host
 *host, u32 ocr,
        }
 
        if (!oldcard) {
-               err = mmc_sd_get_csd(card);
+               err = mmc_sd_get_csd(card, false);
                if (err)
                        goto free_card;
drivers/mmc/core/sd.h index renamed from drivers/mmc/core/sd.h +0 -0

fe6dd46927a42..7e8beface2ca6 100644

drivers/mmc/core/sd.h +1 -0
@@ -10,7 +10,7 @@ struct mmc_host;
 struct mmc_card;
 
 int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr); -
 int mmc_sd_get_csd(struct mmc_card *card);
+int mmc_sd_get_csd(struct mmc_card *card, bool is_sduc);
 void mmc_decode_cid(struct mmc_card *card);  int
 mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
        bool reinit);
drivers/mmc/core/sdio.c index renamed from drivers/mmc/core/sdio.c +0 -0

4fb247fde5c08..9566837c9848e 100644

drivers/mmc/core/sdio.c +1 -1
@@ -769,7 +769,7 @@ static int mmc_sdio_init_card(struct mmc_host *host,
 u32 ocr,
         * Read CSD, before selecting the card
         */
        if (!oldcard && mmc_card_sd_combo(card)) {
-               err = mmc_sd_get_csd(card);
+               err = mmc_sd_get_csd(card, false);
                if (err)
                        goto remove;
include/linux/mmc/card.h index renamed from include/linux/mmc/card.h +0 -0

f34407cc27888..f39bce3223654 100644

include/linux/mmc/card.h +1 -1
@@ -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, diff --git a/include/linux/mmc/sd.h

b/include/linux/mmc/sd.h index 6727576a87555..865cc0ca8543d 100644

include/linux/mmc/sd.h +0 -0
@@ -36,6 +36,7 @@
 /* OCR bit definitions */
 #define SD_OCR_S18R            (1 << 24)    /* 1.8V switching request */
 #define SD_ROCR_S18A           SD_OCR_S18R  /* 1.8V switching accepted by

card */

+#define SD_OCR_2T              (1 << 27)    /* HO2T/CO2T - SDUC support */
 #define SD_OCR_XPC             (1 << 28)    /* SDXC power control */
 #define SD_OCR_CCS             (1 << 30)    /* Card Capacity Status */