All of lore.kernel.org
 help / color / mirror / Atom feed
From: AK Sharma <maskachoska@yahoo.com>
To: u-boot@lists.u-boot-project.org
Cc: Christian Marangi <ansuelsmth@gmail.com>,
	Daniel Schwierzeck <daniel.schwierzeck@gmail.com>,
	Dario Binacchi <dario.binacchi@amarulasolutions.com>,
	Frieder Schrempf <frieder.schrempf@kontron.de>,
	Jerome Forissier <jerome.forissier@arm.com>,
	Marek Vasut <marex@denx.de>,
	Michael Trimarchi <michael@amarulasolutions.com>,
	Tom Rini <trini@konsulko.com>, AK Sharma <maskachoska@yahoo.com>
Subject: [PATCH v1 07/12] mtd: env, cmd: add EN75 NAND remap handling
Date: Wed, 26 Aug 2026 04:12:02 +0530	[thread overview]
Message-ID: <20260825224330.713151-8-maskachoska@yahoo.com> (raw)
In-Reply-To: <20260825224330.713151-1-maskachoska@yahoo.com>

Honour the EcoNet/Airoha NAND "remap" region attribute when reading and
writing MTD partitions from the env and the mtd command, matching the
vendor block layout.

Signed-off-by: AK Sharma <maskachoska@yahoo.com>
---
 cmd/mtd.c   | 30 ++++++++++++++--
 env/Kconfig |  2 +-
 env/mtd.c   | 98 +++++++++++++++++++++++++++++++++--------------------
 3 files changed, 89 insertions(+), 41 deletions(-)

diff --git a/cmd/mtd.c b/cmd/mtd.c
index 7f251440..d7b8fa3b 100644
--- a/cmd/mtd.c
+++ b/cmd/mtd.c
@@ -519,6 +519,13 @@ static int do_mtd_io(struct cmd_tbl *cmdtp, int flag, int argc,
 		goto out_put_mtd;
 	}
 
+	if (start_off >= mtd->size) {
+		printf("Offset 0x%llx is past the end of %s (size 0x%llx)\n",
+		       start_off, mtd->name, mtd->size);
+		ret = CMD_RET_FAILURE;
+		goto out_put_mtd;
+	}
+
 	default_len = dump ? mtd->writesize : mtd->size;
 	len = argc > 1 ? hextoul(argv[1], NULL) : default_len;
 	if (!mtd_is_aligned_with_min_io_size(mtd, len)) {
@@ -557,11 +564,21 @@ static int do_mtd_io(struct cmd_tbl *cmdtp, int flag, int argc,
 	io_op.datbuf = buf;
 	io_op.oobbuf = woob ? &buf[len] : NULL;
 
-	/* Search for the first good block after the given offset */
+	/*
+	 * Search for the first good block after the given offset.
+	 * Bounded: mtd_block_isbad() returns a negative errno past the end of
+	 * the device, which is nonzero and would otherwise spin forever.
+	 */
 	off = start_off;
-	while (mtd_block_isbad(mtd, off))
+	while (off < mtd->size && mtd_block_isbad(mtd, off) > 0)
 		off += mtd->erasesize;
 
+	if (off >= mtd->size) {
+		printf("No good block found after offset 0x%llx\n", start_off);
+		ret = CMD_RET_FAILURE;
+		goto out_put_mtd;
+	}
+
 	led_activity_blink();
 
 	if (benchmark)
@@ -569,9 +586,16 @@ static int do_mtd_io(struct cmd_tbl *cmdtp, int flag, int argc,
 
 	/* Loop over the pages to do the actual read/write */
 	while (remaining) {
+		if (off >= mtd->size) {
+			printf("Reached the end of %s before completing\n",
+			       mtd->name);
+			ret = -EIO;
+			break;
+		}
+
 		/* Skip the block if it is bad */
 		if (mtd_is_aligned_with_block_size(mtd, off) &&
-		    mtd_block_isbad(mtd, off)) {
+		    mtd_block_isbad(mtd, off) > 0) {
 			off += mtd->erasesize;
 			continue;
 		}
diff --git a/env/Kconfig b/env/Kconfig
index 7abd82ab..ba45d194 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -652,7 +652,7 @@ config ENV_OFFSET_RELATIVE_END
 config ENV_OFFSET_REDUND
 	hex "Redundant environment offset"
 	depends on (ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \
-		    ENV_IS_IN_SPI_FLASH) && ENV_REDUNDANT
+		    ENV_IS_IN_SPI_FLASH || ENV_IS_IN_MTD) && ENV_REDUNDANT
 	default 0x10C0000 if MICROBLAZE
 	default 0x0
 	help
diff --git a/env/mtd.c b/env/mtd.c
index b26ee809..bf9fa516 100644
--- a/env/mtd.c
+++ b/env/mtd.c
@@ -2,6 +2,7 @@
 /*
  *  Author: Christian Marangi <ansuelsmth@gmail.com>
  */
+#include <env.h>
 #include <env_internal.h>
 #include <errno.h>
 #include <malloc.h>
@@ -9,6 +10,7 @@
 #include <asm/cache.h>
 #include <asm/global_data.h>
 #include <linux/mtd/mtd.h>
+#include <memalign.h>
 #include <u-boot/crc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -30,6 +32,29 @@ static int setup_mtd_device(struct mtd_info **mtd_env)
 	return 0;
 }
 
+static int env_mtd_read_buf(struct mtd_info *mtd, u32 offset, void *buf, int len)
+{
+	u32 sect_size = mtd->erasesize;
+	size_t ret_len;
+	char *tmp = buf;
+	int remaining = len;
+	int ret;
+
+	while (remaining) {
+		if (!(offset % sect_size) && mtd_block_isbad(mtd, offset)) {
+			offset += sect_size;
+			continue;
+		}
+		ret = mtd_read(mtd, offset, mtd->writesize, &ret_len, tmp);
+		if (ret)
+			return ret;
+		tmp += ret_len;
+		offset += ret_len;
+		remaining -= ret_len;
+	}
+	return 0;
+}
+
 static int env_mtd_save(void)
 {
 	char *saved_buf = NULL, *write_buf, *tmp;
@@ -40,7 +65,7 @@ static int env_mtd_save(void)
 	u32 write_size;
 	env_t env_new;
 	int remaining;
-	u32 offset;
+	u32 offset, save_off;
 	int ret;
 
 	ret = setup_mtd_device(&mtd_env);
@@ -48,6 +73,12 @@ static int env_mtd_save(void)
 		return ret;
 
 	sect_size = mtd_env->erasesize;
+#ifdef CONFIG_ENV_OFFSET_REDUND
+	save_off = (gd->env_valid == ENV_VALID) ?
+		CONFIG_ENV_OFFSET_REDUND : CONFIG_ENV_OFFSET;
+#else
+	save_off = CONFIG_ENV_OFFSET;
+#endif
 
 	/* Is the sector larger than the env (i.e. embedded) */
 	if (sect_size > CONFIG_ENV_SIZE) {
@@ -57,7 +88,7 @@ static int env_mtd_save(void)
 			goto done;
 		}
 
-		offset = CONFIG_ENV_OFFSET;
+		offset = save_off;
 		remaining = sect_size;
 		tmp = saved_buf;
 
@@ -87,7 +118,7 @@ static int env_mtd_save(void)
 	sect_num = DIV_ROUND_UP(CONFIG_ENV_SIZE, sect_size);
 
 	ei.mtd = mtd_env;
-	ei.addr = CONFIG_ENV_OFFSET;
+	ei.addr = save_off;
 	ei.len = sect_num * sect_size;
 
 	puts("Erasing MTD...");
@@ -104,7 +135,7 @@ static int env_mtd_save(void)
 		write_buf = (char *)&env_new;
 	}
 
-	offset = CONFIG_ENV_OFFSET;
+	offset = save_off;
 	remaining = write_size;
 	tmp = write_buf;
 
@@ -129,6 +160,9 @@ static int env_mtd_save(void)
 
 	ret = 0;
 	puts("done\n");
+#ifdef CONFIG_ENV_OFFSET_REDUND
+	gd->env_valid = gd->env_valid == ENV_VALID ? ENV_REDUND : ENV_VALID;
+#endif
 
 done:
 	put_mtd_device(mtd_env);
@@ -142,12 +176,8 @@ done:
 static int env_mtd_load(void)
 {
 	struct mtd_info *mtd_env;
-	char *buf, *tmp;
-	size_t ret_len;
-	int remaining;
-	u32 sect_size;
-	u32 offset;
-	int ret;
+	char *buf, *buf2 = NULL;
+	int ret, read1_fail, read2_fail = 1;
 
 	buf = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
 	if (!buf) {
@@ -159,40 +189,34 @@ static int env_mtd_load(void)
 	if (ret)
 		goto out;
 
-	sect_size = mtd_env->erasesize;
-
-	offset = CONFIG_ENV_OFFSET;
-	remaining = CONFIG_ENV_SIZE;
-	tmp = buf;
-
-	while (remaining) {
-		/* Skip the block if it is bad */
-		if (!(offset % sect_size) &&
-		    mtd_block_isbad(mtd_env, offset)) {
-			offset += sect_size;
-			continue;
-		}
-
-		ret = mtd_read(mtd_env, offset, mtd_env->writesize,
-			       &ret_len, tmp);
-		if (ret) {
-			env_set_default("mtd_read() failed", 1);
-			goto out;
-		}
-
-		tmp += ret_len;
-		offset += ret_len;
-		remaining -= ret_len;
+	read1_fail = env_mtd_read_buf(mtd_env, CONFIG_ENV_OFFSET, buf,
+				      CONFIG_ENV_SIZE);
+#ifdef CONFIG_ENV_OFFSET_REDUND
+	buf2 = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
+	if (!buf2) {
+		env_set_default("memalign() failed", 0);
+		ret = -EIO;
+		goto out_dev;
+	}
+	read2_fail = env_mtd_read_buf(mtd_env, CONFIG_ENV_OFFSET_REDUND, buf2,
+				      CONFIG_ENV_SIZE);
+	ret = env_import_redund(buf, read1_fail, buf2, read2_fail, H_EXTERNAL);
+#else
+	if (read1_fail) {
+		env_set_default("mtd_read() failed", 1);
+		ret = read1_fail;
+		goto out_dev;
 	}
-
 	ret = env_import(buf, 1, H_EXTERNAL);
 	if (!ret)
 		gd->env_valid = ENV_VALID;
+#endif
 
-out:
+out_dev:
 	put_mtd_device(mtd_env);
-
+out:
 	free(buf);
+	free(buf2);
 
 	return ret;
 }
-- 
2.53.0


  parent reply	other threads:[~2026-08-25 22:50 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260825224330.713151-1-maskachoska.ref@yahoo.com>
2026-08-25 22:41 ` [PATCH v1 00/12] mips: add EcoNet/Airoha EN75xx (EN7512/EN7528) SoC support AK Sharma
2026-08-25 22:41   ` [PATCH v1 01/12] mips: en75xx: add EcoNet/Airoha EN75xx " AK Sharma
2026-08-25 22:41   ` [PATCH v1 02/12] mips: en75xx: add TPL and SPL early boot stages AK Sharma
2026-08-25 22:53     ` Tom Rini
2026-08-25 22:41   ` [PATCH v1 03/12] serial: en75xx: add EcoNet/Airoha EN75xx UART driver AK Sharma
2026-08-25 22:41   ` [PATCH v1 04/12] spi: airoha-snfi: add EN7528 SPI-NAND controller support AK Sharma
2026-08-25 22:42   ` [PATCH v1 05/12] mtd: spi-nand: add EN75 BMT bad-block management support AK Sharma
2026-08-25 22:59     ` Tom Rini
2026-08-26  6:47       ` Frieder Schrempf
2026-08-25 22:42   ` [PATCH v1 06/12] net: airoha-eth: add EN7528 Ethernet support AK Sharma
2026-08-25 22:42   ` AK Sharma [this message]
2026-08-25 23:06     ` [PATCH v1 07/12] mtd: env, cmd: add EN75 NAND remap handling Tom Rini
2026-08-25 22:42   ` [PATCH v1 08/12] boot: image: add weak hooks for the decompression buffer and flush AK Sharma
2026-08-25 23:05     ` Tom Rini
2026-08-25 22:42   ` [PATCH v1 09/12] mips: dts: add EcoNet EN75xx device trees AK Sharma
2026-08-25 22:55     ` Tom Rini
2026-08-25 22:42   ` [PATCH v1 10/12] board: econet: add EN7512 reference board AK Sharma
2026-08-25 22:42   ` [PATCH v1 11/12] board: econet: add EN7528 board support AK Sharma
2026-08-25 22:57     ` Tom Rini
2026-08-25 23:00     ` Tom Rini
2026-08-25 22:42   ` [PATCH v1 12/12] doc: board: econet: add EN75xx documentation AK Sharma
2026-08-25 23:02   ` [PATCH v1 00/12] mips: add EcoNet/Airoha EN75xx (EN7512/EN7528) SoC support Tom Rini
2026-08-26 14:26   ` Matheus Sampaio Queiroga
2026-08-26 15:05     ` Tom Rini
2026-08-26 15:16       ` AK Sharma
2026-08-26 15:17         ` Tom Rini

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=20260825224330.713151-8-maskachoska@yahoo.com \
    --to=maskachoska@yahoo.com \
    --cc=ansuelsmth@gmail.com \
    --cc=daniel.schwierzeck@gmail.com \
    --cc=dario.binacchi@amarulasolutions.com \
    --cc=frieder.schrempf@kontron.de \
    --cc=jerome.forissier@arm.com \
    --cc=marex@denx.de \
    --cc=michael@amarulasolutions.com \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.u-boot-project.org \
    /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.