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

Peng Fan peng.fan at nxp.com
Tue Jun 20 03:03:51 CEST 2023


> Subject: [PATCH v3 2/3] mmc: Introduce mmc_send_stop_transmission()
> 
> 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,
 
Reviewed-by:  Peng Fan <peng.fan at nxp.com>

> --
> 2.39.2



More information about the U-Boot mailing list