All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] Add SDUC Support
@ 2024-08-07  6:02 Avri Altman
  2024-08-07  6:03 ` [PATCH v2 01/10] mmc: sd: SDUC Support Recognition Avri Altman
                   ` (10 more replies)
  0 siblings, 11 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:02 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

Ultra Capacity SD cards (SDUC) was already introduced in SD7.0.  Those
cards support capacity larger than 2TB and up to including 128TB. Thus,
the address range of the card expands beyond the 32-bit command
argument. To that end, a new command - CMD22 is defined, to carry the
extra 6-bit upper part of the 38-bit block address that enable access to
128TB memory space.

SDUC capacity is agnostic to the interface mode: UHS-I and UHS-II – Same
as SDXC.

The spec defines several extensions/modifications to the current SDXC
cards, which we address in patches 1 - 10.  Otherwise requirements are
out-of-scope of this change.  Specifically, CMDQ (CMD44+CMD45), and
Extension for Video Speed Class (CMD20).

First publication of SDUC was in [1].  This series was developed and
tested separately from [1] and does not borrow from it.

[1] https://lwn.net/Articles/982566/

---
Changes in v2:
 - Attend kernel test robot warnings

---

Avri Altman (10):
  mmc: sd: SDUC Support Recognition
  mmc: sd: Add SD CSD version 3.0
  mmc: sd: Add Extension memory addressing
  mmc: core: Add open-ended Ext memory addressing
  mmc: host: Always use manual-cmd23 in SDUC
  mmc: core: Add close-ended Ext memory addressing
  mmc: host: Add close-ended Ext memory addressing
  mmc: core: Allow mmc erase to carry large addresses
  mmc: core: Add Ext memory addressing for erase
  mmc: core: Adjust ACMD22 to SDUC

 drivers/mmc/core/block.c  | 45 +++++++++++++++++++++++++++++-------
 drivers/mmc/core/bus.c    |  4 +++-
 drivers/mmc/core/card.h   |  3 +++
 drivers/mmc/core/core.c   | 48 +++++++++++++++++++++++++++++++--------
 drivers/mmc/core/core.h   |  2 +-
 drivers/mmc/core/queue.h  |  1 +
 drivers/mmc/core/sd.c     | 16 +++++++++----
 drivers/mmc/core/sd_ops.c | 34 +++++++++++++++++++++++----
 drivers/mmc/core/sd_ops.h |  1 +
 drivers/mmc/host/sdhci.c  | 38 ++++++++++++++++++++++++++-----
 include/linux/mmc/card.h  |  2 +-
 include/linux/mmc/core.h  |  1 +
 include/linux/mmc/host.h  |  6 +++++
 include/linux/mmc/sd.h    |  4 ++++
 14 files changed, 169 insertions(+), 36 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2 01/10] mmc: sd: SDUC Support Recognition
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-09  9:53   ` Ricky WU
  2024-08-07  6:03 ` [PATCH v2 02/10] mmc: sd: Add SD CSD version 3.0 Avri Altman
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

ACMD21 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 ACMD21 until
eventually, the host will timed out and give up.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/sd_ops.c | 19 +++++++++++++++----
 include/linux/mmc/host.h  |  6 ++++++
 include/linux/mmc/sd.h    |  1 +
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 8b9b34286ef3..7f6963dac873 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -168,12 +168,16 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 		.cmd = &cmd
 	};
 	int err;
+	u32 sduc_arg = SD_OCR_CCS | SD_OCR_2T;
 
 	cmd.opcode = SD_APP_OP_COND;
+	cmd.arg = ocr;
+
 	if (mmc_host_is_spi(host))
-		cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
+		cmd.arg &= (1 << 30); /* SPI only defines one bit */
 	else
-		cmd.arg = ocr;
+		cmd.arg |= sduc_arg;
+
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
 
 	err = __mmc_poll_for_busy(host, SD_APP_OP_COND_PERIOD_US,
@@ -182,8 +186,15 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 	if (err)
 		return err;
 
-	if (rocr && !mmc_host_is_spi(host))
-		*rocr = cmd.resp[0];
+	if (!mmc_host_is_spi(host)) {
+		if (rocr)
+			*rocr = cmd.resp[0];
+
+		if ((cmd.resp[0] & sduc_arg) == sduc_arg)
+			host->caps2 |= MMC_CAP2_SD_SDUC;
+		else
+			host->caps2 &= ~MMC_CAP2_SD_SDUC;
+	}
 
 	return 0;
 }
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 88c6a76042ee..a9c36a3e1a10 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -427,6 +427,7 @@ struct mmc_host {
 #define MMC_CAP2_CRYPTO		0
 #endif
 #define MMC_CAP2_ALT_GPT_TEGRA	(1 << 28)	/* Host with eMMC that has GPT entry at a non-standard location */
+#define MMC_CAP2_SD_SDUC	(1 << 29)	/* SD over 2TB */
 
 	int			fixed_drv_type;	/* fixed driver type for non-removable media */
 
@@ -638,6 +639,11 @@ static inline int mmc_card_uhs(struct mmc_card *card)
 		card->host->ios.timing <= MMC_TIMING_UHS_DDR50;
 }
 
+static inline int mmc_card_is_sduc(struct mmc_host *host)
+{
+	return host->caps2 & MMC_CAP2_SD_SDUC;
+}
+
 void mmc_retune_timer_stop(struct mmc_host *host);
 
 static inline void mmc_retune_needed(struct mmc_host *host)
diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h
index 6727576a8755..865cc0ca8543 100644
--- a/include/linux/mmc/sd.h
+++ b/include/linux/mmc/sd.h
@@ -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 */
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 02/10] mmc: sd: Add SD CSD version 3.0
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
  2024-08-07  6:03 ` [PATCH v2 01/10] mmc: sd: SDUC Support Recognition Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-07  6:03 ` [PATCH v2 03/10] mmc: sd: Add Extension memory addressing Avri Altman
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

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(-)

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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 03/10] mmc: sd: Add Extension memory addressing
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
  2024-08-07  6:03 ` [PATCH v2 01/10] mmc: sd: SDUC Support Recognition Avri Altman
  2024-08-07  6:03 ` [PATCH v2 02/10] mmc: sd: Add SD CSD version 3.0 Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-09  9:54   ` Ricky WU
  2024-08-07  6:03 ` [PATCH v2 04/10] mmc: core: Add open-ended Ext " Avri Altman
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

SDUC memory addressing spans beyond 2TB and up to 128TB.  Therefore, 38
bits are required to access the entire memory space of all sectors.
Those extra 6 bits are to be carried by CMD22 prior of sending
read/write/erase commands: CMD17, CMD18, CMD24, CMD25, CMD32, and CMD33.

CMD22 will carry the higher order 6 bits, and must precedes any of the
above commands even if it targets sector < 2TB.

No error related to address or length is indicated in CMD22 but rather
in the read/write command itself.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/sd_ops.c | 15 +++++++++++++++
 drivers/mmc/core/sd_ops.h |  1 +
 include/linux/mmc/sd.h    |  3 +++
 3 files changed, 19 insertions(+)

diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 7f6963dac873..8b69129d7b61 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -199,6 +199,21 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 	return 0;
 }
 
+int mmc_send_ext_addr(struct mmc_host *host, sector_t addr)
+{
+	struct mmc_command cmd = {
+		.opcode = SD_ADDR_EXT,
+		.arg = (u32)((addr >> 32) & 0x3F),
+		.flags = MMC_RSP_R1 | MMC_CMD_AC,
+	};
+
+	if (!mmc_card_is_sduc(host))
+		return 0;
+
+	return mmc_wait_for_cmd(host, &cmd, 0);
+}
+EXPORT_SYMBOL_GPL(mmc_send_ext_addr);
+
 static int __mmc_send_if_cond(struct mmc_host *host, u32 ocr, u8 pcie_bits,
 			      u32 *resp)
 {
diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h
index 7667fc223b74..462efd43acfa 100644
--- a/drivers/mmc/core/sd_ops.h
+++ b/drivers/mmc/core/sd_ops.h
@@ -21,6 +21,7 @@ int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca);
 int mmc_app_send_scr(struct mmc_card *card);
 int mmc_app_sd_status(struct mmc_card *card, void *ssr);
 int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card);
+int mmc_send_ext_addr(struct mmc_host *host, sector_t addr);
 
 #endif
 
diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h
index 865cc0ca8543..af5fc70e09a2 100644
--- a/include/linux/mmc/sd.h
+++ b/include/linux/mmc/sd.h
@@ -15,6 +15,9 @@
 #define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7  */
 #define SD_SWITCH_VOLTAGE         11  /* ac                      R1  */
 
+/* Class 2 */
+#define SD_ADDR_EXT		 22   /* ac   [5:0]              R1  */
+
   /* class 10 */
 #define SD_SWITCH                 6   /* adtc [31:0] See below   R1  */
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 04/10] mmc: core: Add open-ended Ext memory addressing
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
                   ` (2 preceding siblings ...)
  2024-08-07  6:03 ` [PATCH v2 03/10] mmc: sd: Add Extension memory addressing Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-07  6:03 ` [PATCH v2 05/10] mmc: host: Always use manual-cmd23 in SDUC Avri Altman
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

For open-ended read/write - just send CMD22 before issuing the command.
While at it, make sure that the rw command arg is properly casting the
lower 32 bits, as it can be larger now.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/block.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 367509b5b646..392621232ad8 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -180,6 +180,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
 static int mmc_spi_err_check(struct mmc_card *card);
 static int mmc_blk_busy_cb(void *cb_data, bool *busy);
+static int mmc_blk_wait_for_idle(struct mmc_queue *mq, struct mmc_host *host);
 
 static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
 {
@@ -1664,7 +1665,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 
 	brq->mrq.cmd = &brq->cmd;
 
-	brq->cmd.arg = blk_rq_pos(req);
+	brq->cmd.arg = blk_rq_pos(req) & 0xFFFFFFFF;
 	if (!mmc_card_blockaddr(card))
 		brq->cmd.arg <<= 9;
 	brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
@@ -1712,6 +1713,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 			(do_data_tag ? (1 << 29) : 0);
 		brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
 		brq->mrq.sbc = &brq->sbc;
+	} else if (mmc_card_is_sduc(card->host)) {
+		mmc_blk_wait_for_idle(mq, card->host);
+		mmc_send_ext_addr(card->host, blk_rq_pos(req));
 	}
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 05/10] mmc: host: Always use manual-cmd23 in SDUC
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
                   ` (3 preceding siblings ...)
  2024-08-07  6:03 ` [PATCH v2 04/10] mmc: core: Add open-ended Ext " Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-07  6:03 ` [PATCH v2 06/10] mmc: core: Add close-ended Ext memory addressing Avri Altman
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

In Multi-Block read/write, CMD23 must precede CMD22.  Therefore always
use manual cmd23 so that we'll be able to control the sequence of
commands.  Also, add an applicable mmc_command member for both
mmc_blk_request and mmc_request to accommodate the address extension
command.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/queue.h | 1 +
 drivers/mmc/host/sdhci.c | 4 ++--
 include/linux/mmc/core.h | 1 +
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h
index 9ade3bcbb714..d903fd8a45b5 100644
--- a/drivers/mmc/core/queue.h
+++ b/drivers/mmc/core/queue.h
@@ -40,6 +40,7 @@ struct mmc_blk_ioc_data;
 struct mmc_blk_request {
 	struct mmc_request	mrq;
 	struct mmc_command	sbc;
+	struct mmc_command	ext;
 	struct mmc_command	cmd;
 	struct mmc_command	stop;
 	struct mmc_data		data;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 4b91c9e96635..f62b489c9e9c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1399,13 +1399,13 @@ static inline bool sdhci_auto_cmd12(struct sdhci_host *host,
 static inline bool sdhci_auto_cmd23(struct sdhci_host *host,
 				    struct mmc_request *mrq)
 {
-	return mrq->sbc && (host->flags & SDHCI_AUTO_CMD23);
+	return mrq->sbc && (host->flags & SDHCI_AUTO_CMD23) && !mrq->ext;
 }
 
 static inline bool sdhci_manual_cmd23(struct sdhci_host *host,
 				      struct mmc_request *mrq)
 {
-	return mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23);
+	return mrq->sbc && (mrq->ext || !(host->flags & SDHCI_AUTO_CMD23));
 }
 
 static inline void sdhci_auto_cmd_select(struct sdhci_host *host,
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 2c7928a50907..5560e70cb8d4 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -142,6 +142,7 @@ struct mmc_data {
 struct mmc_host;
 struct mmc_request {
 	struct mmc_command	*sbc;		/* SET_BLOCK_COUNT for multiblock */
+	struct mmc_command	*ext;		/* SD_ADDR_EXT for SDUC */
 	struct mmc_command	*cmd;
 	struct mmc_data		*data;
 	struct mmc_command	*stop;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 06/10] mmc: core: Add close-ended Ext memory addressing
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
                   ` (4 preceding siblings ...)
  2024-08-07  6:03 ` [PATCH v2 05/10] mmc: host: Always use manual-cmd23 in SDUC Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-07  6:03 ` [PATCH v2 07/10] mmc: host: " Avri Altman
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

In a multi-block data transfer, CMD23 shall precede CMD22. Prepare CMD22
in advance as an additional extension of the mrq, to be handle by the
host once CMD23 is done.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/block.c |  7 +++++++
 drivers/mmc/core/core.c  | 18 ++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 392621232ad8..abf1e8a124a5 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -1713,6 +1713,13 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 			(do_data_tag ? (1 << 29) : 0);
 		brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
 		brq->mrq.sbc = &brq->sbc;
+
+		if (mmc_card_is_sduc(card->host)) {
+			brq->ext.opcode = SD_ADDR_EXT;
+			brq->ext.arg = (u32)((blk_rq_pos(req) >> 32) & 0x3F);
+			brq->ext.flags = MMC_RSP_R1 | MMC_CMD_AC;
+			brq->mrq.ext = &brq->ext;
+		}
 	} else if (mmc_card_is_sduc(card->host)) {
 		mmc_blk_wait_for_idle(mq, card->host);
 		mmc_send_ext_addr(card->host, blk_rq_pos(req));
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d6c819dd68ed..754e628b061b 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -184,6 +184,14 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
 				mrq->sbc->resp[2], mrq->sbc->resp[3]);
 		}
 
+		if (mrq->ext) {
+			pr_debug("%s: req done <CMD%u>: %d: %08x %08x %08x %08x\n",
+				mmc_hostname(host), mrq->ext->opcode,
+				mrq->ext->error,
+				mrq->ext->resp[0], mrq->ext->resp[1],
+				mrq->ext->resp[2], mrq->ext->resp[3]);
+		}
+
 		pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",
 			mmc_hostname(host), cmd->opcode, err,
 			cmd->resp[0], cmd->resp[1],
@@ -270,6 +278,12 @@ static void mmc_mrq_pr_debug(struct mmc_host *host, struct mmc_request *mrq,
 			 mrq->sbc->arg, mrq->sbc->flags);
 	}
 
+	if (mrq->ext) {
+		pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n",
+			 mmc_hostname(host), mrq->ext->opcode,
+			 mrq->ext->arg, mrq->ext->flags);
+	}
+
 	if (mrq->cmd) {
 		pr_debug("%s: starting %sCMD%u arg %08x flags %08x\n",
 			 mmc_hostname(host), cqe ? "CQE direct " : "",
@@ -309,6 +323,10 @@ static int mmc_mrq_prep(struct mmc_host *host, struct mmc_request *mrq)
 		mrq->sbc->error = 0;
 		mrq->sbc->mrq = mrq;
 	}
+	if (mrq->ext) {
+		mrq->ext->error = 0;
+		mrq->ext->mrq = mrq;
+	}
 	if (mrq->data) {
 		if (mrq->data->blksz > host->max_blk_size ||
 		    mrq->data->blocks > host->max_blk_count ||
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 07/10] mmc: host: Add close-ended Ext memory addressing
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
                   ` (5 preceding siblings ...)
  2024-08-07  6:03 ` [PATCH v2 06/10] mmc: core: Add close-ended Ext memory addressing Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-07  6:03 ` [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses Avri Altman
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

In a close-ended multi-block data transfer, CMD23 shall precede CMD22.
Handle that logic once the sbc is done.

Host drivers that handle their own sbc logic, e.g. bcm2835 etc. are out
of scope of this change.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/host/sdhci.c | 34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index f62b489c9e9c..75a91d0ed16a 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1791,9 +1791,36 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
 	}
 }
 
+static struct mmc_command *sdhci_get_sbc_ext(struct sdhci_host *host,
+					     struct mmc_command *cmd)
+{
+	if (mmc_card_is_sduc(host->mmc)) {
+		/*  Finished CMD22, now send actual command */
+		if (cmd == cmd->mrq->ext)
+			return cmd->mrq->cmd;
+	}
+
+	/* Finished CMD23 */
+	if (cmd == cmd->mrq->sbc) {
+		if (mmc_card_is_sduc(host->mmc)) {
+			/* send CMD22 after CMD23 */
+			if (WARN_ON(!cmd->mrq->ext))
+				return NULL;
+			else
+				return cmd->mrq->ext;
+		} else {
+			/* Finished CMD23, now send actual command */
+			return cmd->mrq->cmd;
+		}
+	}
+
+	return NULL;
+}
+
 static void sdhci_finish_command(struct sdhci_host *host)
 {
 	struct mmc_command *cmd = host->cmd;
+	struct mmc_command *sbc_ext = NULL;
 
 	host->cmd = NULL;
 
@@ -1828,14 +1855,13 @@ static void sdhci_finish_command(struct sdhci_host *host)
 		}
 	}
 
-	/* Finished CMD23, now send actual command. */
-	if (cmd == cmd->mrq->sbc) {
-		if (!sdhci_send_command(host, cmd->mrq->cmd)) {
+	sbc_ext = sdhci_get_sbc_ext(host, cmd);
+	if (sbc_ext) {
+		if (!sdhci_send_command(host, sbc_ext)) {
 			WARN_ON(host->deferred_cmd);
 			host->deferred_cmd = cmd->mrq->cmd;
 		}
 	} else {
-
 		/* Processed actual command. */
 		if (host->data && host->data_early)
 			sdhci_finish_data(host);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
                   ` (6 preceding siblings ...)
  2024-08-07  6:03 ` [PATCH v2 07/10] mmc: host: " Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-07 20:15   ` kernel test robot
  2024-08-07 21:07   ` kernel test robot
  2024-08-07  6:03 ` [PATCH v2 09/10] mmc: core: Add Ext memory addressing for erase Avri Altman
                   ` (2 subsequent siblings)
  10 siblings, 2 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

Preparing for SDUC, Allow the erase address to be larger beyond a 32 bit
address.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/block.c |  6 ++++--
 drivers/mmc/core/core.c  | 18 ++++++++++--------
 drivers/mmc/core/core.h  |  2 +-
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index abf1e8a124a5..55b9fc34fdd4 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -1154,7 +1154,8 @@ static void mmc_blk_issue_erase_rq(struct mmc_queue *mq, struct request *req,
 {
 	struct mmc_blk_data *md = mq->blkdata;
 	struct mmc_card *card = md->queue.card;
-	unsigned int from, nr;
+	unsigned int nr;
+	sector_t from;
 	int err = 0;
 	blk_status_t status = BLK_STS_OK;
 
@@ -1209,7 +1210,8 @@ static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
 {
 	struct mmc_blk_data *md = mq->blkdata;
 	struct mmc_card *card = md->queue.card;
-	unsigned int from, nr, arg;
+	unsigned int nr, arg;
+	sector_t from;
 	int err = 0, type = MMC_BLK_SECDISCARD;
 	blk_status_t status = BLK_STS_OK;
 
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 754e628b061b..8ea28a04e438 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1616,8 +1616,8 @@ static unsigned int mmc_erase_timeout(struct mmc_card *card,
 		return mmc_mmc_erase_timeout(card, arg, qty);
 }
 
-static int mmc_do_erase(struct mmc_card *card, unsigned int from,
-			unsigned int to, unsigned int arg)
+static int mmc_do_erase(struct mmc_card *card, sector_t from,
+			sector_t to, unsigned int arg)
 {
 	struct mmc_command cmd = {};
 	unsigned int qty = 0, busy_timeout = 0;
@@ -1718,18 +1718,19 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
 }
 
 static unsigned int mmc_align_erase_size(struct mmc_card *card,
-					 unsigned int *from,
-					 unsigned int *to,
+					 sector_t *from,
+					 sector_t *to,
 					 unsigned int nr)
 {
-	unsigned int from_new = *from, nr_new = nr, rem;
+	sector_t from_new = *from;
+	unsigned int nr_new = nr, rem;
 
 	/*
 	 * When the 'card->erase_size' is power of 2, we can use round_up/down()
 	 * to align the erase size efficiently.
 	 */
 	if (is_power_of_2(card->erase_size)) {
-		unsigned int temp = from_new;
+		sector_t temp = from_new;
 
 		from_new = round_up(temp, card->erase_size);
 		rem = from_new - temp;
@@ -1774,10 +1775,11 @@ static unsigned int mmc_align_erase_size(struct mmc_card *card,
  *
  * Caller must claim host before calling this function.
  */
-int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
+int mmc_erase(struct mmc_card *card, sector_t from, unsigned int nr,
 	      unsigned int arg)
 {
-	unsigned int rem, to = from + nr;
+	unsigned int rem;
+	sector_t to = from + nr;
 	int err;
 
 	if (!(card->csd.cmdclass & CCC_ERASE))
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 37091a6589ed..faae4b6404ad 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -116,7 +116,7 @@ bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq);
 
 int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq);
 
-int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
+int mmc_erase(struct mmc_card *card, sector_t from, unsigned int nr,
 		unsigned int arg);
 int mmc_can_erase(struct mmc_card *card);
 int mmc_can_trim(struct mmc_card *card);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 09/10] mmc: core: Add Ext memory addressing for erase
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
                   ` (7 preceding siblings ...)
  2024-08-07  6:03 ` [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-07  6:03 ` [PATCH v2 10/10] mmc: core: Adjust ACMD22 to SDUC Avri Altman
  2024-08-09  6:54 ` [PATCH v2 00/10] Add SDUC Support Ricky WU
  10 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

CMD22 shall precede CMD32 and CMD33 to configure 38-bit erase start
address and 38 bit erase stop address.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/core.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 8ea28a04e438..7f724f6a1332 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1660,8 +1660,12 @@ static int mmc_do_erase(struct mmc_card *card, sector_t from,
 		cmd.opcode = SD_ERASE_WR_BLK_START;
 	else
 		cmd.opcode = MMC_ERASE_GROUP_START;
-	cmd.arg = from;
+	cmd.arg = from & 0xFFFFFFFF;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
+
+	if (mmc_card_is_sduc(card->host))
+		mmc_send_ext_addr(card->host, from);
+
 	err = mmc_wait_for_cmd(card->host, &cmd, 0);
 	if (err) {
 		pr_err("mmc_erase: group start error %d, "
@@ -1675,8 +1679,12 @@ static int mmc_do_erase(struct mmc_card *card, sector_t from,
 		cmd.opcode = SD_ERASE_WR_BLK_END;
 	else
 		cmd.opcode = MMC_ERASE_GROUP_END;
-	cmd.arg = to;
+	cmd.arg = to & 0xFFFFFFFF;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
+
+	if (mmc_card_is_sduc(card->host))
+		mmc_send_ext_addr(card->host, to);
+
 	err = mmc_wait_for_cmd(card->host, &cmd, 0);
 	if (err) {
 		pr_err("mmc_erase: group end error %d, status %#x\n",
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 10/10] mmc: core: Adjust ACMD22 to SDUC
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
                   ` (8 preceding siblings ...)
  2024-08-07  6:03 ` [PATCH v2 09/10] mmc: core: Add Ext memory addressing for erase Avri Altman
@ 2024-08-07  6:03 ` Avri Altman
  2024-08-09  6:54 ` [PATCH v2 00/10] Add SDUC Support Ricky WU
  10 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-07  6:03 UTC (permalink / raw)
  To: Ulf Hansson, linux-mmc; +Cc: Ricky WU, Avri Altman

ACMD22 is used to verify the previously write operation.  Normally, it
returns the number of written sectors as u32.  SDUC, however, returns it
as u64.  This is a superfluous requirement, as the previously write
operation could not be more than the block layer limits, just make room
for a u64 and ignore the 2nd dword.

Moreover, SD cards expect to be allowed the full 500msec busy period
post write operations.  This is true for standard capacity SD, and even
more so for high volume SD cards, specifically SDUC.  If CMD13 return an
error bit, the recovery flow is entered regardless of the busy period.
Thus, better enforce the busy period for SDUC, otherwise it might return
a bogus bytes written.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/block.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 55b9fc34fdd4..cb268af26982 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -948,13 +948,20 @@ static int mmc_sd_num_wr_blocks(struct mmc_card *card, u32 *written_blocks)
 	int err;
 	u32 result;
 	__be32 *blocks;
-
+	u8 resp_sz;
 	struct mmc_request mrq = {};
 	struct mmc_command cmd = {};
 	struct mmc_data data = {};
-
 	struct scatterlist sg;
 
+	/*
+	 * SD cards, specifically high volume cards, expect to be allowed with the
+	 * full 500msec busy period post write. Otherwise, they may not indicate
+	 * correctly the number of bytes written.
+	 */
+	if (mmc_card_is_sduc(card->host))
+		mmc_delay(500);
+
 	err = mmc_app_cmd(card->host, card);
 	if (err)
 		return err;
@@ -963,7 +970,16 @@ static int mmc_sd_num_wr_blocks(struct mmc_card *card, u32 *written_blocks)
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
-	data.blksz = 4;
+	/*
+	 * Normally, ACMD22 returns the number of written sectors as u32.
+	 * SDUC, however, returns it as u64.  This is a superfluous
+	 * requirement, as the previously write operation could not be more
+	 * than the block layer limits, just make room for a u64 and ignore
+	 * the 2nd dword.
+	 */
+	resp_sz = mmc_card_is_sduc(card->host) ? 8 : 4;
+
+	data.blksz = resp_sz;
 	data.blocks = 1;
 	data.flags = MMC_DATA_READ;
 	data.sg = &sg;
@@ -973,11 +989,11 @@ static int mmc_sd_num_wr_blocks(struct mmc_card *card, u32 *written_blocks)
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 
-	blocks = kmalloc(4, GFP_KERNEL);
+	blocks = kmalloc(resp_sz, GFP_KERNEL);
 	if (!blocks)
 		return -ENOMEM;
 
-	sg_init_one(&sg, blocks, 4);
+	sg_init_one(&sg, blocks, resp_sz);
 
 	mmc_wait_for_req(card->host, &mrq);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses
  2024-08-07  6:03 ` [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses Avri Altman
@ 2024-08-07 20:15   ` kernel test robot
  2024-08-07 21:07   ` kernel test robot
  1 sibling, 0 replies; 20+ messages in thread
From: kernel test robot @ 2024-08-07 20:15 UTC (permalink / raw)
  To: Avri Altman, Ulf Hansson, linux-mmc; +Cc: oe-kbuild-all, Ricky WU, Avri Altman

Hi Avri,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.11-rc2 next-20240807]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Avri-Altman/mmc-sd-SDUC-Support-Recognition/20240807-140950
base:   linus/master
patch link:    https://lore.kernel.org/r/20240807060309.2403023-9-avri.altman%40wdc.com
patch subject: [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses
config: i386-randconfig-004-20240807 (https://download.01.org/0day-ci/archive/20240808/202408080458.9guIB91o-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240808/202408080458.9guIB91o-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408080458.9guIB91o-lkp@intel.com/

All errors (new ones prefixed by >>):

   ld: drivers/mmc/core/core.o: in function `mmc_do_erase':
>> drivers/mmc/core/core.c:1651: undefined reference to `__udivdi3'
>> ld: drivers/mmc/core/core.c:1652: undefined reference to `__udivdi3'
   ld: drivers/mmc/core/core.o: in function `mmc_erase':
>> drivers/mmc/core/core.c:1827: undefined reference to `__umoddi3'
   ld: drivers/mmc/core/core.o: in function `mmc_align_erase_size':
   drivers/mmc/core/core.c:1745: undefined reference to `__umoddi3'
   ld: drivers/mmc/core/core.o: in function `mmc_erase':
   drivers/mmc/core/core.c:1803: undefined reference to `__umoddi3'


vim +1651 drivers/mmc/core/core.c

dfe86cba7676d5 Adrian Hunter   2010-08-11  1618  
d3d1cbaa99327c Avri Altman     2024-08-07  1619  static int mmc_do_erase(struct mmc_card *card, sector_t from,
d3d1cbaa99327c Avri Altman     2024-08-07  1620  			sector_t to, unsigned int arg)
dfe86cba7676d5 Adrian Hunter   2010-08-11  1621  {
c7836d1593b87c Masahiro Yamada 2016-12-19  1622  	struct mmc_command cmd = {};
bb4eecf23be259 Baolin Wang     2016-07-25  1623  	unsigned int qty = 0, busy_timeout = 0;
e62f1e0b2384e2 Ulf Hansson     2021-05-04  1624  	bool use_r1b_resp;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1625  	int err;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1626  
8f11d1064e01e1 Adrian Hunter   2015-05-07  1627  	mmc_retune_hold(card->host);
8f11d1064e01e1 Adrian Hunter   2015-05-07  1628  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1629  	/*
dfe86cba7676d5 Adrian Hunter   2010-08-11  1630  	 * qty is used to calculate the erase timeout which depends on how many
dfe86cba7676d5 Adrian Hunter   2010-08-11  1631  	 * erase groups (or allocation units in SD terminology) are affected.
dfe86cba7676d5 Adrian Hunter   2010-08-11  1632  	 * We count erasing part of an erase group as one erase group.
dfe86cba7676d5 Adrian Hunter   2010-08-11  1633  	 * For SD, the allocation units are always a power of 2.  For MMC, the
dfe86cba7676d5 Adrian Hunter   2010-08-11  1634  	 * erase group size is almost certainly also power of 2, but it does not
dfe86cba7676d5 Adrian Hunter   2010-08-11  1635  	 * seem to insist on that in the JEDEC standard, so we fall back to
dfe86cba7676d5 Adrian Hunter   2010-08-11  1636  	 * division in that case.  SD may not specify an allocation unit size,
dfe86cba7676d5 Adrian Hunter   2010-08-11  1637  	 * in which case the timeout is based on the number of write blocks.
dfe86cba7676d5 Adrian Hunter   2010-08-11  1638  	 *
dfe86cba7676d5 Adrian Hunter   2010-08-11  1639  	 * Note that the timeout for secure trim 2 will only be correct if the
dfe86cba7676d5 Adrian Hunter   2010-08-11  1640  	 * number of erase groups specified is the same as the total of all
dfe86cba7676d5 Adrian Hunter   2010-08-11  1641  	 * preceding secure trim 1 commands.  Since the power may have been
dfe86cba7676d5 Adrian Hunter   2010-08-11  1642  	 * lost since the secure trim 1 commands occurred, it is generally
dfe86cba7676d5 Adrian Hunter   2010-08-11  1643  	 * impossible to calculate the secure trim 2 timeout correctly.
dfe86cba7676d5 Adrian Hunter   2010-08-11  1644  	 */
dfe86cba7676d5 Adrian Hunter   2010-08-11  1645  	if (card->erase_shift)
dfe86cba7676d5 Adrian Hunter   2010-08-11  1646  		qty += ((to >> card->erase_shift) -
dfe86cba7676d5 Adrian Hunter   2010-08-11  1647  			(from >> card->erase_shift)) + 1;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1648  	else if (mmc_card_sd(card))
dfe86cba7676d5 Adrian Hunter   2010-08-11  1649  		qty += to - from + 1;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1650  	else
dfe86cba7676d5 Adrian Hunter   2010-08-11 @1651  		qty += ((to / card->erase_size) -
dfe86cba7676d5 Adrian Hunter   2010-08-11 @1652  			(from / card->erase_size)) + 1;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1653  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1654  	if (!mmc_card_blockaddr(card)) {
dfe86cba7676d5 Adrian Hunter   2010-08-11  1655  		from <<= 9;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1656  		to <<= 9;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1657  	}
dfe86cba7676d5 Adrian Hunter   2010-08-11  1658  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1659  	if (mmc_card_sd(card))
dfe86cba7676d5 Adrian Hunter   2010-08-11  1660  		cmd.opcode = SD_ERASE_WR_BLK_START;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1661  	else
dfe86cba7676d5 Adrian Hunter   2010-08-11  1662  		cmd.opcode = MMC_ERASE_GROUP_START;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1663  	cmd.arg = from;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1664  	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1665  	err = mmc_wait_for_cmd(card->host, &cmd, 0);
dfe86cba7676d5 Adrian Hunter   2010-08-11  1666  	if (err) {
a3c76eb9d4a1e6 Girish K S      2011-10-11  1667  		pr_err("mmc_erase: group start error %d, "
dfe86cba7676d5 Adrian Hunter   2010-08-11  1668  		       "status %#x\n", err, cmd.resp[0]);
67716327eec7e9 Adrian Hunter   2011-08-29  1669  		err = -EIO;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1670  		goto out;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1671  	}
dfe86cba7676d5 Adrian Hunter   2010-08-11  1672  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1673  	memset(&cmd, 0, sizeof(struct mmc_command));
dfe86cba7676d5 Adrian Hunter   2010-08-11  1674  	if (mmc_card_sd(card))
dfe86cba7676d5 Adrian Hunter   2010-08-11  1675  		cmd.opcode = SD_ERASE_WR_BLK_END;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1676  	else
dfe86cba7676d5 Adrian Hunter   2010-08-11  1677  		cmd.opcode = MMC_ERASE_GROUP_END;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1678  	cmd.arg = to;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1679  	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1680  	err = mmc_wait_for_cmd(card->host, &cmd, 0);
dfe86cba7676d5 Adrian Hunter   2010-08-11  1681  	if (err) {
a3c76eb9d4a1e6 Girish K S      2011-10-11  1682  		pr_err("mmc_erase: group end error %d, status %#x\n",
dfe86cba7676d5 Adrian Hunter   2010-08-11  1683  		       err, cmd.resp[0]);
67716327eec7e9 Adrian Hunter   2011-08-29  1684  		err = -EIO;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1685  		goto out;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1686  	}
dfe86cba7676d5 Adrian Hunter   2010-08-11  1687  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1688  	memset(&cmd, 0, sizeof(struct mmc_command));
dfe86cba7676d5 Adrian Hunter   2010-08-11  1689  	cmd.opcode = MMC_ERASE;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1690  	cmd.arg = arg;
bb4eecf23be259 Baolin Wang     2016-07-25  1691  	busy_timeout = mmc_erase_timeout(card, arg, qty);
e62f1e0b2384e2 Ulf Hansson     2021-05-04  1692  	use_r1b_resp = mmc_prepare_busy_cmd(card->host, &cmd, busy_timeout);
bb4eecf23be259 Baolin Wang     2016-07-25  1693  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1694  	err = mmc_wait_for_cmd(card->host, &cmd, 0);
dfe86cba7676d5 Adrian Hunter   2010-08-11  1695  	if (err) {
a3c76eb9d4a1e6 Girish K S      2011-10-11  1696  		pr_err("mmc_erase: erase error %d, status %#x\n",
dfe86cba7676d5 Adrian Hunter   2010-08-11  1697  		       err, cmd.resp[0]);
dfe86cba7676d5 Adrian Hunter   2010-08-11  1698  		err = -EIO;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1699  		goto out;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1700  	}
dfe86cba7676d5 Adrian Hunter   2010-08-11  1701  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1702  	if (mmc_host_is_spi(card->host))
dfe86cba7676d5 Adrian Hunter   2010-08-11  1703  		goto out;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1704  
bb4eecf23be259 Baolin Wang     2016-07-25  1705  	/*
bb4eecf23be259 Baolin Wang     2016-07-25  1706  	 * In case of when R1B + MMC_CAP_WAIT_WHILE_BUSY is used, the polling
bb4eecf23be259 Baolin Wang     2016-07-25  1707  	 * shall be avoided.
bb4eecf23be259 Baolin Wang     2016-07-25  1708  	 */
bb4eecf23be259 Baolin Wang     2016-07-25  1709  	if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp)
bb4eecf23be259 Baolin Wang     2016-07-25  1710  		goto out;
bb4eecf23be259 Baolin Wang     2016-07-25  1711  
0d84c3e6a5b2cd Ulf Hansson     2020-02-04  1712  	/* Let's poll to find out when the erase operation completes. */
04f967ad28c836 Ulf Hansson     2021-05-04  1713  	err = mmc_poll_for_busy(card, busy_timeout, false, MMC_BUSY_ERASE);
8fee476b219d18 Trey Ramsay     2012-11-16  1714  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1715  out:
8f11d1064e01e1 Adrian Hunter   2015-05-07  1716  	mmc_retune_release(card->host);
dfe86cba7676d5 Adrian Hunter   2010-08-11  1717  	return err;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1718  }
dfe86cba7676d5 Adrian Hunter   2010-08-11  1719  
71085123d27dc5 Baolin Wang     2016-09-07  1720  static unsigned int mmc_align_erase_size(struct mmc_card *card,
d3d1cbaa99327c Avri Altman     2024-08-07  1721  					 sector_t *from,
d3d1cbaa99327c Avri Altman     2024-08-07  1722  					 sector_t *to,
71085123d27dc5 Baolin Wang     2016-09-07  1723  					 unsigned int nr)
71085123d27dc5 Baolin Wang     2016-09-07  1724  {
d3d1cbaa99327c Avri Altman     2024-08-07  1725  	sector_t from_new = *from;
d3d1cbaa99327c Avri Altman     2024-08-07  1726  	unsigned int nr_new = nr, rem;
71085123d27dc5 Baolin Wang     2016-09-07  1727  
6c689886fbe41b Baolin Wang     2016-09-07  1728  	/*
6c689886fbe41b Baolin Wang     2016-09-07  1729  	 * When the 'card->erase_size' is power of 2, we can use round_up/down()
6c689886fbe41b Baolin Wang     2016-09-07  1730  	 * to align the erase size efficiently.
6c689886fbe41b Baolin Wang     2016-09-07  1731  	 */
6c689886fbe41b Baolin Wang     2016-09-07  1732  	if (is_power_of_2(card->erase_size)) {
d3d1cbaa99327c Avri Altman     2024-08-07  1733  		sector_t temp = from_new;
6c689886fbe41b Baolin Wang     2016-09-07  1734  
6c689886fbe41b Baolin Wang     2016-09-07  1735  		from_new = round_up(temp, card->erase_size);
6c689886fbe41b Baolin Wang     2016-09-07  1736  		rem = from_new - temp;
6c689886fbe41b Baolin Wang     2016-09-07  1737  
6c689886fbe41b Baolin Wang     2016-09-07  1738  		if (nr_new > rem)
6c689886fbe41b Baolin Wang     2016-09-07  1739  			nr_new -= rem;
6c689886fbe41b Baolin Wang     2016-09-07  1740  		else
6c689886fbe41b Baolin Wang     2016-09-07  1741  			return 0;
6c689886fbe41b Baolin Wang     2016-09-07  1742  
6c689886fbe41b Baolin Wang     2016-09-07  1743  		nr_new = round_down(nr_new, card->erase_size);
6c689886fbe41b Baolin Wang     2016-09-07  1744  	} else {
71085123d27dc5 Baolin Wang     2016-09-07  1745  		rem = from_new % card->erase_size;
71085123d27dc5 Baolin Wang     2016-09-07  1746  		if (rem) {
71085123d27dc5 Baolin Wang     2016-09-07  1747  			rem = card->erase_size - rem;
71085123d27dc5 Baolin Wang     2016-09-07  1748  			from_new += rem;
71085123d27dc5 Baolin Wang     2016-09-07  1749  			if (nr_new > rem)
71085123d27dc5 Baolin Wang     2016-09-07  1750  				nr_new -= rem;
71085123d27dc5 Baolin Wang     2016-09-07  1751  			else
71085123d27dc5 Baolin Wang     2016-09-07  1752  				return 0;
71085123d27dc5 Baolin Wang     2016-09-07  1753  		}
71085123d27dc5 Baolin Wang     2016-09-07  1754  
71085123d27dc5 Baolin Wang     2016-09-07  1755  		rem = nr_new % card->erase_size;
71085123d27dc5 Baolin Wang     2016-09-07  1756  		if (rem)
71085123d27dc5 Baolin Wang     2016-09-07  1757  			nr_new -= rem;
6c689886fbe41b Baolin Wang     2016-09-07  1758  	}
71085123d27dc5 Baolin Wang     2016-09-07  1759  
71085123d27dc5 Baolin Wang     2016-09-07  1760  	if (nr_new == 0)
71085123d27dc5 Baolin Wang     2016-09-07  1761  		return 0;
71085123d27dc5 Baolin Wang     2016-09-07  1762  
71085123d27dc5 Baolin Wang     2016-09-07  1763  	*to = from_new + nr_new;
71085123d27dc5 Baolin Wang     2016-09-07  1764  	*from = from_new;
71085123d27dc5 Baolin Wang     2016-09-07  1765  
71085123d27dc5 Baolin Wang     2016-09-07  1766  	return nr_new;
71085123d27dc5 Baolin Wang     2016-09-07  1767  }
71085123d27dc5 Baolin Wang     2016-09-07  1768  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1769  /**
dfe86cba7676d5 Adrian Hunter   2010-08-11  1770   * mmc_erase - erase sectors.
dfe86cba7676d5 Adrian Hunter   2010-08-11  1771   * @card: card to erase
dfe86cba7676d5 Adrian Hunter   2010-08-11  1772   * @from: first sector to erase
dfe86cba7676d5 Adrian Hunter   2010-08-11  1773   * @nr: number of sectors to erase
bc47e2f6f9e261 Avri Altman     2019-02-26  1774   * @arg: erase command argument
dfe86cba7676d5 Adrian Hunter   2010-08-11  1775   *
dfe86cba7676d5 Adrian Hunter   2010-08-11  1776   * Caller must claim host before calling this function.
dfe86cba7676d5 Adrian Hunter   2010-08-11  1777   */
d3d1cbaa99327c Avri Altman     2024-08-07  1778  int mmc_erase(struct mmc_card *card, sector_t from, unsigned int nr,
dfe86cba7676d5 Adrian Hunter   2010-08-11  1779  	      unsigned int arg)
dfe86cba7676d5 Adrian Hunter   2010-08-11  1780  {
d3d1cbaa99327c Avri Altman     2024-08-07  1781  	unsigned int rem;
d3d1cbaa99327c Avri Altman     2024-08-07  1782  	sector_t to = from + nr;
642c28ab86f766 David Jander    2015-06-23  1783  	int err;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1784  
94fe2580a2f3bb Ulf Hansson     2020-05-08  1785  	if (!(card->csd.cmdclass & CCC_ERASE))
dfe86cba7676d5 Adrian Hunter   2010-08-11  1786  		return -EOPNOTSUPP;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1787  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1788  	if (!card->erase_size)
dfe86cba7676d5 Adrian Hunter   2010-08-11  1789  		return -EOPNOTSUPP;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1790  
bc47e2f6f9e261 Avri Altman     2019-02-26  1791  	if (mmc_card_sd(card) && arg != SD_ERASE_ARG && arg != SD_DISCARD_ARG)
dfe86cba7676d5 Adrian Hunter   2010-08-11  1792  		return -EOPNOTSUPP;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1793  
bc47e2f6f9e261 Avri Altman     2019-02-26  1794  	if (mmc_card_mmc(card) && (arg & MMC_SECURE_ARGS) &&
dfe86cba7676d5 Adrian Hunter   2010-08-11  1795  	    !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN))
dfe86cba7676d5 Adrian Hunter   2010-08-11  1796  		return -EOPNOTSUPP;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1797  
489d144563f239 Christian Löhle 2022-11-17  1798  	if (mmc_card_mmc(card) && is_trim_arg(arg) &&
dfe86cba7676d5 Adrian Hunter   2010-08-11  1799  	    !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN))
dfe86cba7676d5 Adrian Hunter   2010-08-11  1800  		return -EOPNOTSUPP;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1801  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1802  	if (arg == MMC_SECURE_ERASE_ARG) {
dfe86cba7676d5 Adrian Hunter   2010-08-11  1803  		if (from % card->erase_size || nr % card->erase_size)
dfe86cba7676d5 Adrian Hunter   2010-08-11  1804  			return -EINVAL;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1805  	}
dfe86cba7676d5 Adrian Hunter   2010-08-11  1806  
71085123d27dc5 Baolin Wang     2016-09-07  1807  	if (arg == MMC_ERASE_ARG)
71085123d27dc5 Baolin Wang     2016-09-07  1808  		nr = mmc_align_erase_size(card, &from, &to, nr);
dfe86cba7676d5 Adrian Hunter   2010-08-11  1809  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1810  	if (nr == 0)
dfe86cba7676d5 Adrian Hunter   2010-08-11  1811  		return 0;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1812  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1813  	if (to <= from)
dfe86cba7676d5 Adrian Hunter   2010-08-11  1814  		return -EINVAL;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1815  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1816  	/* 'from' and 'to' are inclusive */
dfe86cba7676d5 Adrian Hunter   2010-08-11  1817  	to -= 1;
dfe86cba7676d5 Adrian Hunter   2010-08-11  1818  
642c28ab86f766 David Jander    2015-06-23  1819  	/*
642c28ab86f766 David Jander    2015-06-23  1820  	 * Special case where only one erase-group fits in the timeout budget:
642c28ab86f766 David Jander    2015-06-23  1821  	 * If the region crosses an erase-group boundary on this particular
642c28ab86f766 David Jander    2015-06-23  1822  	 * case, we will be trimming more than one erase-group which, does not
642c28ab86f766 David Jander    2015-06-23  1823  	 * fit in the timeout budget of the controller, so we need to split it
642c28ab86f766 David Jander    2015-06-23  1824  	 * and call mmc_do_erase() twice if necessary. This special case is
642c28ab86f766 David Jander    2015-06-23  1825  	 * identified by the card->eg_boundary flag.
642c28ab86f766 David Jander    2015-06-23  1826  	 */
642c28ab86f766 David Jander    2015-06-23 @1827  	rem = card->erase_size - (from % card->erase_size);
489d144563f239 Christian Löhle 2022-11-17  1828  	if ((arg & MMC_TRIM_OR_DISCARD_ARGS) && card->eg_boundary && nr > rem) {
642c28ab86f766 David Jander    2015-06-23  1829  		err = mmc_do_erase(card, from, from + rem - 1, arg);
642c28ab86f766 David Jander    2015-06-23  1830  		from += rem;
642c28ab86f766 David Jander    2015-06-23  1831  		if ((err) || (to <= from))
642c28ab86f766 David Jander    2015-06-23  1832  			return err;
642c28ab86f766 David Jander    2015-06-23  1833  	}
642c28ab86f766 David Jander    2015-06-23  1834  
dfe86cba7676d5 Adrian Hunter   2010-08-11  1835  	return mmc_do_erase(card, from, to, arg);
dfe86cba7676d5 Adrian Hunter   2010-08-11  1836  }
dfe86cba7676d5 Adrian Hunter   2010-08-11  1837  EXPORT_SYMBOL(mmc_erase);
dfe86cba7676d5 Adrian Hunter   2010-08-11  1838  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses
  2024-08-07  6:03 ` [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses Avri Altman
  2024-08-07 20:15   ` kernel test robot
@ 2024-08-07 21:07   ` kernel test robot
  1 sibling, 0 replies; 20+ messages in thread
From: kernel test robot @ 2024-08-07 21:07 UTC (permalink / raw)
  To: Avri Altman, Ulf Hansson, linux-mmc; +Cc: oe-kbuild-all, Ricky WU, Avri Altman

Hi Avri,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.11-rc2 next-20240807]
[cannot apply to ulf-hansson-mmc-mirror/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Avri-Altman/mmc-sd-SDUC-Support-Recognition/20240807-140950
base:   linus/master
patch link:    https://lore.kernel.org/r/20240807060309.2403023-9-avri.altman%40wdc.com
patch subject: [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses
config: i386-randconfig-012-20240807 (https://download.01.org/0day-ci/archive/20240808/202408080428.IWxLHNou-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240808/202408080428.IWxLHNou-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408080428.IWxLHNou-lkp@intel.com/

All errors (new ones prefixed by >>):

   ld: drivers/mmc/core/core.o: in function `mmc_do_erase':
   drivers/mmc/core/core.c:1651: undefined reference to `__udivdi3'
   ld: drivers/mmc/core/core.c:1652: undefined reference to `__udivdi3'
   ld: drivers/mmc/core/core.o: in function `mmc_erase':
   drivers/mmc/core/core.c:1803: undefined reference to `__umoddi3'
>> ld: drivers/mmc/core/core.c:1827: undefined reference to `__umoddi3'
   ld: drivers/mmc/core/core.o: in function `mmc_align_erase_size':
   drivers/mmc/core/core.c:1745: undefined reference to `__umoddi3'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH v2 00/10] Add SDUC Support
  2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
                   ` (9 preceding siblings ...)
  2024-08-07  6:03 ` [PATCH v2 10/10] mmc: core: Adjust ACMD22 to SDUC Avri Altman
@ 2024-08-09  6:54 ` Ricky WU
  2024-08-09  7:37   ` Avri Altman
  10 siblings, 1 reply; 20+ messages in thread
From: Ricky WU @ 2024-08-09  6:54 UTC (permalink / raw)
  To: Avri Altman, Ulf Hansson, linux-mmc@vger.kernel.org

Hi Avri,

I tested this SDUC patch for Realtek card readers and it works  


> Ultra Capacity SD cards (SDUC) was already introduced in SD7.0.  Those cards
> support capacity larger than 2TB and up to including 128TB. Thus, the address
> range of the card expands beyond the 32-bit command argument. To that end,
> a new command - CMD22 is defined, to carry the extra 6-bit upper part of the
> 38-bit block address that enable access to 128TB memory space.
> 
> SDUC capacity is agnostic to the interface mode: UHS-I and UHS-II – Same as
> SDXC.
> 
> The spec defines several extensions/modifications to the current SDXC cards,
> which we address in patches 1 - 10.  Otherwise requirements are out-of-scope
> of this change.  Specifically, CMDQ (CMD44+CMD45), and Extension for
> Video Speed Class (CMD20).
> 
> First publication of SDUC was in [1].  This series was developed and tested
> separately from [1] and does not borrow from it.
> 
> [1] https://lwn.net/Articles/982566/
> 
> ---
> Changes in v2:
>  - Attend kernel test robot warnings
> 
> ---
> 
> Avri Altman (10):
>   mmc: sd: SDUC Support Recognition
>   mmc: sd: Add SD CSD version 3.0
>   mmc: sd: Add Extension memory addressing
>   mmc: core: Add open-ended Ext memory addressing
>   mmc: host: Always use manual-cmd23 in SDUC
>   mmc: core: Add close-ended Ext memory addressing
>   mmc: host: Add close-ended Ext memory addressing
>   mmc: core: Allow mmc erase to carry large addresses
>   mmc: core: Add Ext memory addressing for erase
>   mmc: core: Adjust ACMD22 to SDUC
> 
>  drivers/mmc/core/block.c  | 45 +++++++++++++++++++++++++++++-------
>  drivers/mmc/core/bus.c    |  4 +++-
>  drivers/mmc/core/card.h   |  3 +++
>  drivers/mmc/core/core.c   | 48 +++++++++++++++++++++++++++++++--------
>  drivers/mmc/core/core.h   |  2 +-
>  drivers/mmc/core/queue.h  |  1 +
>  drivers/mmc/core/sd.c     | 16 +++++++++----
>  drivers/mmc/core/sd_ops.c | 34 +++++++++++++++++++++++----
> drivers/mmc/core/sd_ops.h |  1 +  drivers/mmc/host/sdhci.c  | 38
> ++++++++++++++++++++++++++-----  include/linux/mmc/card.h  |  2 +-
> include/linux/mmc/core.h  |  1 +  include/linux/mmc/host.h  |  6 +++++
>  include/linux/mmc/sd.h    |  4 ++++
>  14 files changed, 169 insertions(+), 36 deletions(-)
> 
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH v2 00/10] Add SDUC Support
  2024-08-09  6:54 ` [PATCH v2 00/10] Add SDUC Support Ricky WU
@ 2024-08-09  7:37   ` Avri Altman
  0 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-09  7:37 UTC (permalink / raw)
  To: Ricky WU, Ulf Hansson, linux-mmc@vger.kernel.org

> 
> Hi Avri,
> 
> I tested this SDUC patch for Realtek card readers and it works
Ricky thanks.  Will add your "Tested-by" tag to my next spin.

Would appreciate any further constructive reviews - helping to move this series forward.
Thanks a lot,
Avri

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH v2 01/10] mmc: sd: SDUC Support Recognition
  2024-08-07  6:03 ` [PATCH v2 01/10] mmc: sd: SDUC Support Recognition Avri Altman
@ 2024-08-09  9:53   ` Ricky WU
  2024-08-10  7:58     ` Avri Altman
  0 siblings, 1 reply; 20+ messages in thread
From: Ricky WU @ 2024-08-09  9:53 UTC (permalink / raw)
  To: Avri Altman, Ulf Hansson, linux-mmc@vger.kernel.org

> 
> ACMD21 was extended to support the host-card handshake during initialization.

Is ACMD41?

> 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 ACMD21 until eventually, the host will timed out and give up.
> 
> Signed-off-by: Avri Altman <avri.altman@wdc.com>
> ---
>  drivers/mmc/core/sd_ops.c | 19 +++++++++++++++----
> include/linux/mmc/host.h  |  6 ++++++
>  include/linux/mmc/sd.h    |  1 +
>  3 files changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index
> 8b9b34286ef3..7f6963dac873 100644
> --- a/drivers/mmc/core/sd_ops.c
> +++ b/drivers/mmc/core/sd_ops.c
> @@ -168,12 +168,16 @@ int mmc_send_app_op_cond(struct mmc_host *host,
> u32 ocr, u32 *rocr)
>                 .cmd = &cmd
>         };
>         int err;
> +       u32 sduc_arg = SD_OCR_CCS | SD_OCR_2T;
> 
>         cmd.opcode = SD_APP_OP_COND;
> +       cmd.arg = ocr;
> +
>         if (mmc_host_is_spi(host))
> -               cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
> +               cmd.arg &= (1 << 30); /* SPI only defines one bit */
>         else
> -               cmd.arg = ocr;
> +               cmd.arg |= sduc_arg;
> +
>         cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
> 
>         err = __mmc_poll_for_busy(host, SD_APP_OP_COND_PERIOD_US,
> @@ -182,8 +186,15 @@ int mmc_send_app_op_cond(struct mmc_host *host,
> u32 ocr, u32 *rocr)
>         if (err)
>                 return err;
> 
> -       if (rocr && !mmc_host_is_spi(host))
> -               *rocr = cmd.resp[0];
> +       if (!mmc_host_is_spi(host)) {
> +               if (rocr)
> +                       *rocr = cmd.resp[0];
> +
> +               if ((cmd.resp[0] & sduc_arg) == sduc_arg)
> +                       host->caps2 |= MMC_CAP2_SD_SDUC;
> +               else
> +                       host->caps2 &= ~MMC_CAP2_SD_SDUC;

I think host->caps2 is for host to claim caps, here can just call mmc_card_set_ult_capacity? 
Don't need to wait csd, because SDXC and SDHC need to identify by capacity, but SDUC can be identified here
And all your mmc_card_is_sduc() I think change to mmc_card_ult_capacity() to know the card type

> +       }
> 
>         return 0;
>  }
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index
> 88c6a76042ee..a9c36a3e1a10 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -427,6 +427,7 @@ struct mmc_host {
>  #define MMC_CAP2_CRYPTO                0
>  #endif
>  #define MMC_CAP2_ALT_GPT_TEGRA (1 << 28)       /* Host with eMMC
> that has GPT entry at a non-standard location */
> +#define MMC_CAP2_SD_SDUC       (1 << 29)       /* SD over 2TB */
> 
>         int                     fixed_drv_type; /* fixed driver type for
> non-removable media */
> 
> @@ -638,6 +639,11 @@ static inline int mmc_card_uhs(struct mmc_card
> *card)
>                 card->host->ios.timing <= MMC_TIMING_UHS_DDR50;  }
> 
> +static inline int mmc_card_is_sduc(struct mmc_host *host) {
> +       return host->caps2 & MMC_CAP2_SD_SDUC; }
> +
>  void mmc_retune_timer_stop(struct mmc_host *host);
> 
>  static inline void mmc_retune_needed(struct mmc_host *host) diff --git
> a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index
> 6727576a8755..865cc0ca8543 100644
> --- a/include/linux/mmc/sd.h
> +++ b/include/linux/mmc/sd.h
> @@ -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 */
> 
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH v2 03/10] mmc: sd: Add Extension memory addressing
  2024-08-07  6:03 ` [PATCH v2 03/10] mmc: sd: Add Extension memory addressing Avri Altman
@ 2024-08-09  9:54   ` Ricky WU
  2024-08-10  8:11     ` Avri Altman
  0 siblings, 1 reply; 20+ messages in thread
From: Ricky WU @ 2024-08-09  9:54 UTC (permalink / raw)
  To: Avri Altman, Ulf Hansson, linux-mmc@vger.kernel.org

> SDUC memory addressing spans beyond 2TB and up to 128TB.  Therefore, 38
> bits are required to access the entire memory space of all sectors.
> Those extra 6 bits are to be carried by CMD22 prior of sending
> read/write/erase commands: CMD17, CMD18, CMD24, CMD25, CMD32, and
> CMD33.
> 
> CMD22 will carry the higher order 6 bits, and must precedes any of the above
> commands even if it targets sector < 2TB.
> 
> No error related to address or length is indicated in CMD22 but rather in the
> read/write command itself.
> 
> Signed-off-by: Avri Altman <avri.altman@wdc.com>
> ---
>  drivers/mmc/core/sd_ops.c | 15 +++++++++++++++
> drivers/mmc/core/sd_ops.h |  1 +
>  include/linux/mmc/sd.h    |  3 +++
>  3 files changed, 19 insertions(+)
> 
> diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index
> 7f6963dac873..8b69129d7b61 100644
> --- a/drivers/mmc/core/sd_ops.c
> +++ b/drivers/mmc/core/sd_ops.c
> @@ -199,6 +199,21 @@ int mmc_send_app_op_cond(struct mmc_host *host,
> u32 ocr, u32 *rocr)
>         return 0;
>  }
> 
> +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr) {
> +       struct mmc_command cmd = {
> +               .opcode = SD_ADDR_EXT,
> +               .arg = (u32)((addr >> 32) & 0x3F),
> +               .flags = MMC_RSP_R1 | MMC_CMD_AC,
> +       };
> +
> +       if (!mmc_card_is_sduc(host))
> +               return 0;
> +
I think here can be removed, all mmc_send_ext_addr caller are have if-statement to check the card is SDUC

> +       return mmc_wait_for_cmd(host, &cmd, 0); }
> +EXPORT_SYMBOL_GPL(mmc_send_ext_addr);
> +
>  static int __mmc_send_if_cond(struct mmc_host *host, u32 ocr, u8 pcie_bits,
>                               u32 *resp)  { diff --git
> a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index
> 7667fc223b74..462efd43acfa 100644
> --- a/drivers/mmc/core/sd_ops.h
> +++ b/drivers/mmc/core/sd_ops.h
> @@ -21,6 +21,7 @@ int mmc_send_relative_addr(struct mmc_host *host,
> unsigned int *rca);  int mmc_app_send_scr(struct mmc_card *card);  int
> mmc_app_sd_status(struct mmc_card *card, void *ssr);  int
> mmc_app_cmd(struct mmc_host *host, struct mmc_card *card);
> +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr);
> 
>  #endif
> 
> diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index
> 865cc0ca8543..af5fc70e09a2 100644
> --- a/include/linux/mmc/sd.h
> +++ b/include/linux/mmc/sd.h
> @@ -15,6 +15,9 @@
>  #define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7
> */
>  #define SD_SWITCH_VOLTAGE         11  /* ac
> R1  */
> 
> +/* Class 2 */
> +#define SD_ADDR_EXT             22   /* ac   [5:0]
> R1  */
> +
>    /* class 10 */
>  #define SD_SWITCH                 6   /* adtc [31:0] See below   R1
> */
> 
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH v2 01/10] mmc: sd: SDUC Support Recognition
  2024-08-09  9:53   ` Ricky WU
@ 2024-08-10  7:58     ` Avri Altman
  2024-08-13  5:42       ` Avri Altman
  0 siblings, 1 reply; 20+ messages in thread
From: Avri Altman @ 2024-08-10  7:58 UTC (permalink / raw)
  To: Ricky WU, Ulf Hansson, linux-mmc@vger.kernel.org

> > ACMD21 was extended to support the host-card handshake during initialization.
> 
> Is ACMD41?
Yes.  Thank you.

> 
> > 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 ACMD21 until eventually, the host will timed out
> and give up.
> >
> > Signed-off-by: Avri Altman <avri.altman@wdc.com>
> > ---
> >  drivers/mmc/core/sd_ops.c | 19 +++++++++++++++----
> > include/linux/mmc/host.h  |  6 ++++++
> >  include/linux/mmc/sd.h    |  1 +
> >  3 files changed, 22 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
> > index
> > 8b9b34286ef3..7f6963dac873 100644
> > --- a/drivers/mmc/core/sd_ops.c
> > +++ b/drivers/mmc/core/sd_ops.c
> > @@ -168,12 +168,16 @@ int mmc_send_app_op_cond(struct mmc_host
> *host,
> > u32 ocr, u32 *rocr)
> >                 .cmd = &cmd
> >         };
> >         int err;
> > +       u32 sduc_arg = SD_OCR_CCS | SD_OCR_2T;
> >
> >         cmd.opcode = SD_APP_OP_COND;
> > +       cmd.arg = ocr;
> > +
> >         if (mmc_host_is_spi(host))
> > -               cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
> > +               cmd.arg &= (1 << 30); /* SPI only defines one bit */
> >         else
> > -               cmd.arg = ocr;
> > +               cmd.arg |= sduc_arg;
> > +
> >         cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
> >
> >         err = __mmc_poll_for_busy(host, SD_APP_OP_COND_PERIOD_US, @@
> > -182,8 +186,15 @@ int mmc_send_app_op_cond(struct mmc_host *host,
> > u32 ocr, u32 *rocr)
> >         if (err)
> >                 return err;
> >
> > -       if (rocr && !mmc_host_is_spi(host))
> > -               *rocr = cmd.resp[0];
> > +       if (!mmc_host_is_spi(host)) {
> > +               if (rocr)
> > +                       *rocr = cmd.resp[0];
> > +
> > +               if ((cmd.resp[0] & sduc_arg) == sduc_arg)
> > +                       host->caps2 |= MMC_CAP2_SD_SDUC;
> > +               else
> > +                       host->caps2 &= ~MMC_CAP2_SD_SDUC;
> 
> I think host->caps2 is for host to claim caps, here can just call
> mmc_card_set_ult_capacity?
> Don't need to wait csd, because SDXC and SDHC need to identify by capacity, but
> SDUC can be identified here And all your mmc_card_is_sduc() I think change to
> mmc_card_ult_capacity() to know the card type
This is an interesting idea - and yes, we can do that.
Also the line of reasoning that you provide makes a lot of sense.
However, SDUC is not a card state, so I am not sure I should use it.
I added it to comply with SDXC, but using the card state to imply of a card type doesn't seems right.

Thanks,
Avri

> 
> > +       }
> >
> >         return 0;
> >  }
> > diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index
> > 88c6a76042ee..a9c36a3e1a10 100644
> > --- a/include/linux/mmc/host.h
> > +++ b/include/linux/mmc/host.h
> > @@ -427,6 +427,7 @@ struct mmc_host {
> >  #define MMC_CAP2_CRYPTO                0
> >  #endif
> >  #define MMC_CAP2_ALT_GPT_TEGRA (1 << 28)       /* Host with eMMC
> > that has GPT entry at a non-standard location */
> > +#define MMC_CAP2_SD_SDUC       (1 << 29)       /* SD over 2TB */
> >
> >         int                     fixed_drv_type; /* fixed driver type for
> > non-removable media */
> >
> > @@ -638,6 +639,11 @@ static inline int mmc_card_uhs(struct mmc_card
> > *card)
> >                 card->host->ios.timing <= MMC_TIMING_UHS_DDR50;  }
> >
> > +static inline int mmc_card_is_sduc(struct mmc_host *host) {
> > +       return host->caps2 & MMC_CAP2_SD_SDUC; }
> > +
> >  void mmc_retune_timer_stop(struct mmc_host *host);
> >
> >  static inline void mmc_retune_needed(struct mmc_host *host) diff
> > --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index
> > 6727576a8755..865cc0ca8543 100644
> > --- a/include/linux/mmc/sd.h
> > +++ b/include/linux/mmc/sd.h
> > @@ -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 */
> >
> > --
> > 2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH v2 03/10] mmc: sd: Add Extension memory addressing
  2024-08-09  9:54   ` Ricky WU
@ 2024-08-10  8:11     ` Avri Altman
  0 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-10  8:11 UTC (permalink / raw)
  To: Ricky WU, Ulf Hansson, linux-mmc@vger.kernel.org

> > SDUC memory addressing spans beyond 2TB and up to 128TB.  Therefore,
> > 38 bits are required to access the entire memory space of all sectors.
> > Those extra 6 bits are to be carried by CMD22 prior of sending
> > read/write/erase commands: CMD17, CMD18, CMD24, CMD25, CMD32, and
> > CMD33.
> >
> > CMD22 will carry the higher order 6 bits, and must precedes any of the
> > above commands even if it targets sector < 2TB.
> >
> > No error related to address or length is indicated in CMD22 but rather
> > in the read/write command itself.
> >
> > Signed-off-by: Avri Altman <avri.altman@wdc.com>
> > ---
> >  drivers/mmc/core/sd_ops.c | 15 +++++++++++++++
> > drivers/mmc/core/sd_ops.h |  1 +
> >  include/linux/mmc/sd.h    |  3 +++
> >  3 files changed, 19 insertions(+)
> >
> > diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
> > index
> > 7f6963dac873..8b69129d7b61 100644
> > --- a/drivers/mmc/core/sd_ops.c
> > +++ b/drivers/mmc/core/sd_ops.c
> > @@ -199,6 +199,21 @@ int mmc_send_app_op_cond(struct mmc_host *host,
> > u32 ocr, u32 *rocr)
> >         return 0;
> >  }
> >
> > +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr) {
> > +       struct mmc_command cmd = {
> > +               .opcode = SD_ADDR_EXT,
> > +               .arg = (u32)((addr >> 32) & 0x3F),
> > +               .flags = MMC_RSP_R1 | MMC_CMD_AC,
> > +       };
> > +
> > +       if (!mmc_card_is_sduc(host))
> > +               return 0;
> > +
> I think here can be removed, all mmc_send_ext_addr caller are have if-statement
> to check the card is SDUC
Theoretically yes.
But since it is exported (kernel test robot warning), we should protect from loadable modules callers.
Also, IMO it serves as some sort of documentation and improves readability.

Thanks,
Avri
> 
> > +       return mmc_wait_for_cmd(host, &cmd, 0); }
> > +EXPORT_SYMBOL_GPL(mmc_send_ext_addr);
> > +
> >  static int __mmc_send_if_cond(struct mmc_host *host, u32 ocr, u8 pcie_bits,
> >                               u32 *resp)  { diff --git
> > a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index
> > 7667fc223b74..462efd43acfa 100644
> > --- a/drivers/mmc/core/sd_ops.h
> > +++ b/drivers/mmc/core/sd_ops.h
> > @@ -21,6 +21,7 @@ int mmc_send_relative_addr(struct mmc_host *host,
> > unsigned int *rca);  int mmc_app_send_scr(struct mmc_card *card);  int
> > mmc_app_sd_status(struct mmc_card *card, void *ssr);  int
> > mmc_app_cmd(struct mmc_host *host, struct mmc_card *card);
> > +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr);
> >
> >  #endif
> >
> > diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index
> > 865cc0ca8543..af5fc70e09a2 100644
> > --- a/include/linux/mmc/sd.h
> > +++ b/include/linux/mmc/sd.h
> > @@ -15,6 +15,9 @@
> >  #define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7
> > */
> >  #define SD_SWITCH_VOLTAGE         11  /* ac
> > R1  */
> >
> > +/* Class 2 */
> > +#define SD_ADDR_EXT             22   /* ac   [5:0]
> > R1  */
> > +
> >    /* class 10 */
> >  #define SD_SWITCH                 6   /* adtc [31:0] See below   R1
> > */
> >
> > --
> > 2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH v2 01/10] mmc: sd: SDUC Support Recognition
  2024-08-10  7:58     ` Avri Altman
@ 2024-08-13  5:42       ` Avri Altman
  0 siblings, 0 replies; 20+ messages in thread
From: Avri Altman @ 2024-08-13  5:42 UTC (permalink / raw)
  To: Ricky WU, Ulf Hansson, linux-mmc@vger.kernel.org

> > > -182,8 +186,15 @@ int mmc_send_app_op_cond(struct mmc_host *host,
> > > u32 ocr, u32 *rocr)
> > >         if (err)
> > >                 return err;
> > >
> > > -       if (rocr && !mmc_host_is_spi(host))
> > > -               *rocr = cmd.resp[0];
> > > +       if (!mmc_host_is_spi(host)) {
> > > +               if (rocr)
> > > +                       *rocr = cmd.resp[0];
> > > +
> > > +               if ((cmd.resp[0] & sduc_arg) == sduc_arg)
> > > +                       host->caps2 |= MMC_CAP2_SD_SDUC;
> > > +               else
> > > +                       host->caps2 &= ~MMC_CAP2_SD_SDUC;
> >
> > I think host->caps2 is for host to claim caps, here can just call
> > mmc_card_set_ult_capacity?
> > Don't need to wait csd, because SDXC and SDHC need to identify by
> > capacity, but SDUC can be identified here And all your
> > mmc_card_is_sduc() I think change to
> > mmc_card_ult_capacity() to know the card type
> This is an interesting idea - and yes, we can do that.
> Also the line of reasoning that you provide makes a lot of sense.
> However, SDUC is not a card state, so I am not sure I should use it.
> I added it to comply with SDXC, but using the card state to imply of a card type
> doesn't seems right.
How about extending the use of card->type for that?
e.g., adding the various SD sub-types etc.
But this needs to be done in a separate patch, probably after this series get accepted.

Thanks,
Avri

> 
> Thanks,
> Avri
> 
> >
> > > +       }
> > >
> > >         return 0;
> > >  }
> > > diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> > > index
> > > 88c6a76042ee..a9c36a3e1a10 100644
> > > --- a/include/linux/mmc/host.h
> > > +++ b/include/linux/mmc/host.h
> > > @@ -427,6 +427,7 @@ struct mmc_host {
> > >  #define MMC_CAP2_CRYPTO                0
> > >  #endif
> > >  #define MMC_CAP2_ALT_GPT_TEGRA (1 << 28)       /* Host with eMMC
> > > that has GPT entry at a non-standard location */
> > > +#define MMC_CAP2_SD_SDUC       (1 << 29)       /* SD over 2TB */
> > >
> > >         int                     fixed_drv_type; /* fixed driver type for
> > > non-removable media */
> > >
> > > @@ -638,6 +639,11 @@ static inline int mmc_card_uhs(struct mmc_card
> > > *card)
> > >                 card->host->ios.timing <= MMC_TIMING_UHS_DDR50;  }
> > >
> > > +static inline int mmc_card_is_sduc(struct mmc_host *host) {
> > > +       return host->caps2 & MMC_CAP2_SD_SDUC; }
> > > +
> > >  void mmc_retune_timer_stop(struct mmc_host *host);
> > >
> > >  static inline void mmc_retune_needed(struct mmc_host *host) diff
> > > --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index
> > > 6727576a8755..865cc0ca8543 100644
> > > --- a/include/linux/mmc/sd.h
> > > +++ b/include/linux/mmc/sd.h
> > > @@ -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 */
> > >
> > > --
> > > 2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2024-08-13  5:42 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-07  6:02 [PATCH v2 00/10] Add SDUC Support Avri Altman
2024-08-07  6:03 ` [PATCH v2 01/10] mmc: sd: SDUC Support Recognition Avri Altman
2024-08-09  9:53   ` Ricky WU
2024-08-10  7:58     ` Avri Altman
2024-08-13  5:42       ` Avri Altman
2024-08-07  6:03 ` [PATCH v2 02/10] mmc: sd: Add SD CSD version 3.0 Avri Altman
2024-08-07  6:03 ` [PATCH v2 03/10] mmc: sd: Add Extension memory addressing Avri Altman
2024-08-09  9:54   ` Ricky WU
2024-08-10  8:11     ` Avri Altman
2024-08-07  6:03 ` [PATCH v2 04/10] mmc: core: Add open-ended Ext " Avri Altman
2024-08-07  6:03 ` [PATCH v2 05/10] mmc: host: Always use manual-cmd23 in SDUC Avri Altman
2024-08-07  6:03 ` [PATCH v2 06/10] mmc: core: Add close-ended Ext memory addressing Avri Altman
2024-08-07  6:03 ` [PATCH v2 07/10] mmc: host: " Avri Altman
2024-08-07  6:03 ` [PATCH v2 08/10] mmc: core: Allow mmc erase to carry large addresses Avri Altman
2024-08-07 20:15   ` kernel test robot
2024-08-07 21:07   ` kernel test robot
2024-08-07  6:03 ` [PATCH v2 09/10] mmc: core: Add Ext memory addressing for erase Avri Altman
2024-08-07  6:03 ` [PATCH v2 10/10] mmc: core: Adjust ACMD22 to SDUC Avri Altman
2024-08-09  6:54 ` [PATCH v2 00/10] Add SDUC Support Ricky WU
2024-08-09  7:37   ` Avri Altman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.