]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
cmd: mtd: add markbad command support
authorMikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Wed, 24 Sep 2025 04:20:31 +0000 (07:20 +0300)
committerMichael Trimarchi <michael@amarulasolutions.com>
Sun, 5 Oct 2025 18:26:40 +0000 (20:26 +0200)
Some nand flashes (like spi-nand one) are registered with mtd
subsystem only, thus nand command can't be used to work with
such flashes. As result some functionality is missing.

This patch implements 'nand markbad' functionality for mtd command.

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
cmd/Kconfig
cmd/mtd.c

index 29de857ba7c2da5fb84a5b7b966e345b41c90263..8f2a35d780b1ab440be5e0ecbf31e29a787bbb0c 100644 (file)
@@ -1511,6 +1511,14 @@ config CMD_MTD_OTP
        help
          MTD commands for OTP access.
 
+config CMD_MTD_MARKBAD
+       bool "mtd markbad"
+       depends on CMD_MTD
+       help
+         MTD markbad command support.
+
+         This is a clone of "nand markbad" command, but for 'mtd' subsystem.
+
 config CMD_MUX
        bool "mux"
        depends on MULTIPLEXER
index 2520b89eed2cebf0833255c85511a7180a3bf689..95e4be9863df11f8257327ef88c9f7a9475af1d6 100644 (file)
--- a/cmd/mtd.c
+++ b/cmd/mtd.c
@@ -711,6 +711,57 @@ out_put_mtd:
        return ret;
 }
 
+#ifdef CONFIG_CMD_MTD_MARKBAD
+static int do_mtd_markbad(struct cmd_tbl *cmdtp, int flag, int argc,
+                         char *const argv[])
+{
+       struct mtd_info *mtd;
+       loff_t off;
+       int ret = 0;
+
+       if (argc < 3)
+               return CMD_RET_USAGE;
+
+       mtd = get_mtd_by_name(argv[1]);
+       if (IS_ERR_OR_NULL(mtd))
+               return CMD_RET_FAILURE;
+
+       if (!mtd_can_have_bb(mtd)) {
+               printf("Only NAND-based devices can have bad blocks\n");
+               goto out_put_mtd;
+       }
+
+       argc -= 2;
+       argv += 2;
+       while (argc > 0) {
+               off = hextoul(argv[0], NULL);
+               if (!mtd_is_aligned_with_block_size(mtd, off)) {
+                       printf("Offset not aligned with a block (0x%x)\n",
+                              mtd->erasesize);
+                       ret = CMD_RET_FAILURE;
+                       goto out_put_mtd;
+               }
+
+               ret = mtd_block_markbad(mtd, off);
+               if (ret) {
+                       printf("block 0x%08llx NOT marked as bad! ERROR %d\n",
+                              off, ret);
+                       ret = CMD_RET_FAILURE;
+               } else {
+                       printf("block 0x%08llx successfully marked as bad\n",
+                              off);
+               }
+               --argc;
+               ++argv;
+       }
+
+out_put_mtd:
+       put_mtd_device(mtd);
+
+       return ret;
+}
+#endif
+
 static int do_mtd_bad(struct cmd_tbl *cmdtp, int flag, int argc,
                      char *const argv[])
 {
@@ -793,6 +844,9 @@ U_BOOT_LONGHELP(mtd,
        "mtd otpwrite                          <name> <off> <hex string>\n"
        "mtd otplock                           <name> <off> <size>\n"
        "mtd otpinfo                           <name> [u|f]\n"
+#endif
+#if CONFIG_IS_ENABLED(CMD_MTD_MARKBAD)
+       "mtd markbad                           <name>         <off> [<off> ...]\n"
 #endif
        "\n"
        "With:\n"
@@ -827,5 +881,9 @@ U_BOOT_CMD_WITH_SUBCMDS(mtd, "MTD utils", mtd_help_text,
                                             mtd_name_complete),
                U_BOOT_SUBCMD_MKENT_COMPLETE(erase, 4, 0, do_mtd_erase,
                                             mtd_name_complete),
+#if CONFIG_IS_ENABLED(CMD_MTD_MARKBAD)
+               U_BOOT_SUBCMD_MKENT_COMPLETE(markbad, 20, 0, do_mtd_markbad,
+                                            mtd_name_complete),
+#endif
                U_BOOT_SUBCMD_MKENT_COMPLETE(bad, 2, 1, do_mtd_bad,
                                             mtd_name_complete));