All of lore.kernel.org
 help / color / mirror / Atom feed
From: Loic Poulain <loic.poulain@linaro.org>
To: sjg@chromium.org, peng.fan@nxp.com, jh80.chung@samsung.com
Cc: u-boot@lists.denx.de, Loic Poulain <loic.poulain@linaro.org>
Subject: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
Date: Thu, 26 Jan 2023 10:24:18 +0100	[thread overview]
Message-ID: <20230126092419.534514-2-loic.poulain@linaro.org> (raw)
In-Reply-To: <20230126092419.534514-1-loic.poulain@linaro.org>

The default erase command applies on erase group unit, and
simply round down to erase group size. When the start block
is not aligned to erase group size (e.g. erasing partition)
it causes unwanted erasing of the previous blocks, part of
the same erase group (e.g. owned by other logical partition,
or by the partition table itself).

To prevent this issue, a simple solution is to use TRIM as
argument of the Erase command, which is usually supported
with eMMC > 4.0, and allow to apply erase operation to write
blocks instead of erase group

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
---
v2: Add mmc unit test change to the series

 drivers/mmc/mmc_write.c | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
index 5b7aeeb012..a6f93380dd 100644
--- a/drivers/mmc/mmc_write.c
+++ b/drivers/mmc/mmc_write.c
@@ -15,7 +15,7 @@
 #include <linux/math64.h>
 #include "mmc_private.h"
 
-static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
+static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
 {
 	struct mmc_cmd cmd;
 	ulong end;
@@ -52,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
 		goto err_out;
 
 	cmd.cmdidx = MMC_CMD_ERASE;
-	cmd.cmdarg = MMC_ERASE_ARG;
+	cmd.cmdarg = args ? args : MMC_ERASE_ARG;
 	cmd.resp_type = MMC_RSP_R1b;
 
 	err = mmc_send_cmd(mmc, &cmd, NULL);
@@ -77,7 +77,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
 #endif
 	int dev_num = block_dev->devnum;
 	int err = 0;
-	u32 start_rem, blkcnt_rem;
+	u32 start_rem, blkcnt_rem, erase_args = 0;
 	struct mmc *mmc = find_mmc_device(dev_num);
 	lbaint_t blk = 0, blk_r = 0;
 	int timeout_ms = 1000;
@@ -97,13 +97,25 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
 	 */
 	err = div_u64_rem(start, mmc->erase_grp_size, &start_rem);
 	err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem);
-	if (start_rem || blkcnt_rem)
-		printf("\n\nCaution! Your devices Erase group is 0x%x\n"
-		       "The erase range would be change to "
-		       "0x" LBAF "~0x" LBAF "\n\n",
-		       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
-		       ((start + blkcnt + mmc->erase_grp_size - 1)
-		       & ~(mmc->erase_grp_size - 1)) - 1);
+	if (start_rem || blkcnt_rem) {
+		if (mmc->can_trim) {
+			/* Trim function applies the erase operation to write
+			 * blocks instead of erase groups.
+			 */
+			erase_args = MMC_TRIM_ARG;
+		} else {
+			/* The card ignores all LSB's below the erase group
+			 * size, rounding down the addess to a erase group
+			 * boundary.
+			 */
+			printf("\n\nCaution! Your devices Erase group is 0x%x\n"
+			       "The erase range would be change to "
+			       "0x" LBAF "~0x" LBAF "\n\n",
+			       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
+			       ((start + blkcnt + mmc->erase_grp_size - 1)
+			       & ~(mmc->erase_grp_size - 1)) - 1);
+		}
+	}
 
 	while (blk < blkcnt) {
 		if (IS_SD(mmc) && mmc->ssr.au) {
@@ -113,7 +125,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
 			blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
 				mmc->erase_grp_size : (blkcnt - blk);
 		}
-		err = mmc_erase_t(mmc, start + blk, blk_r);
+		err = mmc_erase_t(mmc, start + blk, blk_r, erase_args);
 		if (err)
 			break;
 
-- 
2.34.1


  reply	other threads:[~2023-01-26  9:24 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20230126092431epcas1p49aa1d01605df7cfcf0d2f2a4e5e8600c@epcas1p4.samsung.com>
2023-01-26  9:24 ` [PATCH v2 1/3] mmc: Check support for TRIM operations Loic Poulain
2023-01-26  9:24   ` Loic Poulain [this message]
2023-01-28 22:01     ` [PATCH v2 2/3] mmc: erase: Use TRIM erase when available Simon Glass
2023-02-01 11:39       ` Loic Poulain
2023-02-06  5:05     ` Jaehoon Chung
2023-02-08  8:08       ` Loic Poulain
2023-02-08  9:03         ` Jaehoon Chung
     [not found]     ` <CGME20230310023122epcas1p2e19d3aa9274c88d14992bd878dc8d1ca@epcas1p2.samsung.com>
2023-03-10  2:31       ` Jaehoon Chung
2023-01-26  9:24   ` [PATCH v2 3/3] test: dm: mmc: Check block erasing boundaries Loic Poulain
2023-01-27 14:30     ` Simon Glass
2023-02-08  8:13       ` Loic Poulain
     [not found]     ` <CGME20230310023206epcas1p1df08c1dbe2cb70efdd91ef47d7e95c78@epcas1p1.samsung.com>
2023-03-10  2:32       ` Jaehoon Chung
2023-01-28 22:01   ` [PATCH v2 1/3] mmc: Check support for TRIM operations Simon Glass
2023-02-06  4:54   ` Jaehoon Chung
     [not found]   ` <CGME20230310023103epcas1p4e4763c672faff833c978f8e91252119c@epcas1p4.samsung.com>
2023-03-10  2:31     ` Jaehoon Chung

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230126092419.534514-2-loic.poulain@linaro.org \
    --to=loic.poulain@linaro.org \
    --cc=jh80.chung@samsung.com \
    --cc=peng.fan@nxp.com \
    --cc=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.