[PATCH v3 2/3] mmc: Introduce mmc_send_stop_transmission()

Marek Vasut marek.vasut+renesas at mailbox.org
Tue Jun 20 00:38:24 CEST 2023


From: Hai Pham <hai.pham.ud at renesas.com>

If a tuning command times out, the card could still be processing it,
which will cause problems for recovery. The eMMC specification section
6.6 Data transfer mode (cont’d) claims that CMD12 can be used to stop
CMD21:
"
The relationship between the various data transfer modes is summarized (see Figure 27):
- All data read commands can be aborted any time by the stop command (CMD12).
  The data transfer will terminate and the Device will return to the Transfer State.
  The read commands are: ... send tuning block (CMD21) ....
"
Add a function that does that.

Based on Linux commit [1] and [2].

[1] e711f0309109 ("mmc: mmc: Introduce mmc_abort_tuning()")
[2] 21adc2e45f4e ("mmc: Improve function name when aborting a tuning
cmd")

Reviewed-by: Takeshi Kihara <takeshi.kihara.df at renesas.com>
Reviewed-by: Marek Vasut <marek.vasut+renesas at mailbox.org>
Signed-off-by: Hai Pham <hai.pham.ud at renesas.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas at mailbox.org>
[Marek: Update commit message, quote relevant part of the specification.
        Rename to mmc_send_stop_transmission().
	Remove tuning opcode check, this is controller driver specific.
	Deduplicate part of mmc_read_blocks() using this function.]
---
V2: Support both read and write transmission stop
V3: Update on previous patch changes
---
Cc: "Ying-Chun Liu (PaulLiu)" <paul.liu at linaro.org>
Cc: Hai Pham <hai.pham.ud at renesas.com>
Cc: Jaehoon Chung <jh80.chung at samsung.com>
Cc: Loic Poulain <loic.poulain at linaro.org>
Cc: Peng Fan <peng.fan at nxp.com>
Cc: Simon Glass <sjg at chromium.org>
Cc: Takeshi Kihara <takeshi.kihara.df at renesas.com>
---
 drivers/mmc/mmc.c | 34 +++++++++++++++++++++-------------
 include/mmc.h     |  2 ++
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 38d85c71402..31cfda28858 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -398,6 +398,26 @@ int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error)
 }
 #endif
 
+int mmc_send_stop_transmission(struct mmc *mmc, bool write)
+{
+	struct mmc_cmd cmd;
+
+	cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+	cmd.cmdarg = 0;
+	/*
+	 * JEDEC Standard No. 84-B51 Page 126
+	 * CMD12 STOP_TRANSMISSION R1/R1b[3]
+	 * NOTE 3 R1 for read cases and R1b for write cases.
+	 *
+	 * Physical Layer Simplified Specification Version 9.00
+	 * 7.3.1.3 Detailed Command Description
+	 * CMD12 R1b
+	 */
+	cmd.resp_type = (IS_SD(mmc) || write) ? MMC_RSP_R1b : MMC_RSP_R1;
+
+	return mmc_send_cmd(mmc, &cmd, NULL);
+}
+
 static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
 			   lbaint_t blkcnt)
 {
@@ -425,19 +445,7 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
 		return 0;
 
 	if (blkcnt > 1) {
-		cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
-		cmd.cmdarg = 0;
-		/*
-		 * JEDEC Standard No. 84-B51 Page 126
-		 * CMD12 STOP_TRANSMISSION R1/R1b[3]
-		 * NOTE 3 R1 for read cases and R1b for write cases.
-		 *
-		 * Physical Layer Simplified Specification Version 9.00
-		 * 7.3.1.3 Detailed Command Description
-		 * CMD12 R1b
-		 */
-		cmd.resp_type = IS_SD(mmc) ? MMC_RSP_R1b : MMC_RSP_R1;
-		if (mmc_send_cmd(mmc, &cmd, NULL)) {
+		if (mmc_send_stop_transmission(mmc, false)) {
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 			pr_err("mmc fail to send stop cmd\n");
 #endif
diff --git a/include/mmc.h b/include/mmc.h
index b8fbff150de..1022db3ffa7 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -558,6 +558,8 @@ int mmc_deferred_probe(struct mmc *mmc);
 int mmc_reinit(struct mmc *mmc);
 int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt);
 int mmc_hs400_prepare_ddr(struct mmc *mmc);
+int mmc_send_stop_transmission(struct mmc *mmc, bool write);
+
 #else
 struct mmc_ops {
 	int (*send_cmd)(struct mmc *mmc,
-- 
2.39.2



More information about the U-Boot mailing list