[PATCH v2 04/14] nand: move nand_erase_opts() to core NAND folder
Alexey Romanov
avromanov at salutedevices.com
Tue Jan 9 18:32:16 CET 2024
Currently nand_erase_opts() placed in the nand/raw/ folder,
because it uses the RAW NAND specific API (struct nand_chip).
This patch move it to core NAND folder and make function generic,
for both RAW/SPI NAND's usage.
Also, nand_erase_opts() used in fastboot/fb_nand.c, cmd/nand.c
and env/nand.c code. This is also the reason why we should move
it to core folder and make it more general.
Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
Reviewed-By: Michael Trimarchi <michael at amarulasolutions.com>
---
drivers/mtd/nand/raw/nand_util.c | 153 ----------------------------
drivers/mtd/nand/util.c | 166 +++++++++++++++++++++++++++++++
2 files changed, 166 insertions(+), 153 deletions(-)
diff --git a/drivers/mtd/nand/raw/nand_util.c b/drivers/mtd/nand/raw/nand_util.c
index 9c18ce63b9..f7704d4697 100644
--- a/drivers/mtd/nand/raw/nand_util.c
+++ b/drivers/mtd/nand/raw/nand_util.c
@@ -32,159 +32,6 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <nand.h>
-#include <jffs2/jffs2.h>
-
-typedef struct erase_info erase_info_t;
-
-/* support only for native endian JFFS2 */
-#define cpu_to_je16(x) (x)
-#define cpu_to_je32(x) (x)
-
-/**
- * nand_erase_opts: - erase NAND flash with support for various options
- * (jffs2 formatting)
- *
- * @param mtd nand mtd instance to erase
- * @param opts options, @see struct nand_erase_options
- * Return: 0 in case of success
- *
- * This code is ported from flash_eraseall.c from Linux mtd utils by
- * Arcom Control System Ltd.
- */
-int nand_erase_opts(struct mtd_info *mtd,
- const nand_erase_options_t *opts)
-{
- struct jffs2_unknown_node cleanmarker;
- erase_info_t erase;
- unsigned long erase_length, erased_length; /* in blocks */
- int result;
- int percent_complete = -1;
- const char *mtd_device = mtd->name;
- struct mtd_oob_ops oob_opts;
- struct nand_chip *chip = mtd_to_nand(mtd);
-
- if ((opts->offset & (mtd->erasesize - 1)) != 0) {
- printf("Attempt to erase non block-aligned data\n");
- return -1;
- }
-
- memset(&erase, 0, sizeof(erase));
- memset(&oob_opts, 0, sizeof(oob_opts));
-
- erase.mtd = mtd;
- erase.len = mtd->erasesize;
- erase.addr = opts->offset;
- erase_length = lldiv(opts->length + mtd->erasesize - 1,
- mtd->erasesize);
-
- cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
- cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
- cleanmarker.totlen = cpu_to_je32(8);
-
- /* scrub option allows to erase badblock. To prevent internal
- * check from erase() method, set block check method to dummy
- * and disable bad block table while erasing.
- */
- if (opts->scrub) {
- erase.scrub = opts->scrub;
- /*
- * We don't need the bad block table anymore...
- * after scrub, there are no bad blocks left!
- */
- if (chip->bbt) {
- kfree(chip->bbt);
- }
- chip->bbt = NULL;
- chip->options &= ~NAND_BBT_SCANNED;
- }
-
- for (erased_length = 0;
- erased_length < erase_length;
- erase.addr += mtd->erasesize) {
-
- schedule();
-
- if (opts->lim && (erase.addr >= (opts->offset + opts->lim))) {
- puts("Size of erase exceeds limit\n");
- return -EFBIG;
- }
- if (!opts->scrub) {
- int ret = mtd_block_isbad(mtd, erase.addr);
- if (ret > 0) {
- if (!opts->quiet)
- printf("\rSkipping %s at "
- "0x%08llx "
- " \n",
- ret == 1 ? "bad block" : "bbt reserved",
- erase.addr);
-
- if (!opts->spread)
- erased_length++;
-
- continue;
-
- } else if (ret < 0) {
- printf("\n%s: MTD get bad block failed: %d\n",
- mtd_device,
- ret);
- return -1;
- }
- }
-
- erased_length++;
-
- result = mtd_erase(mtd, &erase);
- if (result != 0) {
- printf("\n%s: MTD Erase failure: %d\n",
- mtd_device, result);
- continue;
- }
-
- /* format for JFFS2 ? */
- if (opts->jffs2 && chip->ecc.layout->oobavail >= 8) {
- struct mtd_oob_ops ops;
- ops.ooblen = 8;
- ops.datbuf = NULL;
- ops.oobbuf = (uint8_t *)&cleanmarker;
- ops.ooboffs = 0;
- ops.mode = MTD_OPS_AUTO_OOB;
-
- result = mtd_write_oob(mtd, erase.addr, &ops);
- if (result != 0) {
- printf("\n%s: MTD writeoob failure: %d\n",
- mtd_device, result);
- continue;
- }
- }
-
- if (!opts->quiet) {
- unsigned long long n = erased_length * 100ULL;
- int percent;
-
- do_div(n, erase_length);
- percent = (int)n;
-
- /* output progress message only at whole percent
- * steps to reduce the number of messages printed
- * on (slow) serial consoles
- */
- if (percent != percent_complete) {
- percent_complete = percent;
-
- printf("\rErasing at 0x%llx -- %3d%% complete.",
- erase.addr, percent);
-
- if (opts->jffs2 && result == 0)
- printf(" Cleanmarker written at 0x%llx.",
- erase.addr);
- }
- }
- }
- if (!opts->quiet)
- printf("\n");
-
- return 0;
-}
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
diff --git a/drivers/mtd/nand/util.c b/drivers/mtd/nand/util.c
index 4a372bb67d..f02c1ef4ca 100644
--- a/drivers/mtd/nand/util.c
+++ b/drivers/mtd/nand/util.c
@@ -28,10 +28,176 @@
#include <asm/cache.h>
#include <dm/devres.h>
+#include <jffs2/jffs2.h>
#include <linux/errno.h>
#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <nand.h>
+typedef struct erase_info erase_info_t;
+
+/* support only for native endian JFFS2 */
+#define cpu_to_je16(x) (x)
+#define cpu_to_je32(x) (x)
+
+/**
+ * nand_erase_opts: - erase NAND flash with support for various options
+ * (jffs2 formatting)
+ *
+ * @param mtd nand mtd instance to erase
+ * @param opts options, @see struct nand_erase_options
+ * Return: 0 in case of success
+ *
+ * This code is ported from flash_eraseall.c from Linux mtd utils by
+ * Arcom Control System Ltd.
+ */
+int nand_erase_opts(struct mtd_info *mtd,
+ const nand_erase_options_t *opts)
+{
+ struct jffs2_unknown_node cleanmarker;
+ erase_info_t erase;
+ unsigned long erase_length, erased_length; /* in blocks */
+ int result;
+ int percent_complete = -1;
+ const char *mtd_device = mtd->name;
+ struct mtd_oob_ops oob_opts;
+ u32 oobavail = mtd->oobavail;
+#if CONFIG_IS_ENABLED(MTD_RAW_NAND)
+ struct nand_chip *chip = mtd_to_nand(mtd);
+#elif CONFIG_IS_ENABLED(MTD_SPI_NAND)
+ struct nand_device *nand = mtd_to_nanddev(mtd);
+#endif
+
+ if ((opts->offset & (mtd->erasesize - 1)) != 0) {
+ printf("Attempt to erase non block-aligned data\n");
+ return -1;
+ }
+
+ memset(&erase, 0, sizeof(erase));
+ memset(&oob_opts, 0, sizeof(oob_opts));
+
+ erase.mtd = mtd;
+ erase.len = mtd->erasesize;
+ erase.addr = opts->offset;
+ erase_length = lldiv(opts->length + mtd->erasesize - 1,
+ mtd->erasesize);
+
+ cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+ cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
+ cleanmarker.totlen = cpu_to_je32(8);
+
+ /* scrub option allows to erase badblock. To prevent internal
+ * check from erase() method, set block check method to dummy
+ * and disable bad block table while erasing.
+ */
+ if (opts->scrub) {
+ erase.scrub = opts->scrub;
+
+ /*
+ * We don't need the bad block table anymore...
+ * after scrub, there are no bad blocks left!
+ */
+#if CONFIG_IS_ENABLED(MTD_RAW_NAND)
+ if (chip->bbt) {
+ kfree(chip->bbt);
+ }
+ chip->bbt = NULL;
+ chip->options &= ~NAND_BBT_SCANNED;
+#elif CONFIG_IS_ENABLED(MTD_SPI_NAND)
+ if (nanddev_bbt_is_initialized(nand))
+ nanddev_bbt_cleanup(nand);
+#endif
+ }
+
+ for (erased_length = 0;
+ erased_length < erase_length;
+ erase.addr += mtd->erasesize) {
+
+ schedule();
+
+ if (opts->lim && (erase.addr >= (opts->offset + opts->lim))) {
+ puts("Size of erase exceeds limit\n");
+ return -EFBIG;
+ }
+ if (!opts->scrub) {
+ int ret = mtd_block_isbad(mtd, erase.addr);
+ if (ret > 0) {
+ if (!opts->quiet)
+ printf("\rSkipping %s at "
+ "0x%08llx "
+ " \n",
+ ret == 1 ? "bad block" : "bbt reserved",
+ erase.addr);
+
+ if (!opts->spread)
+ erased_length++;
+
+ continue;
+
+ } else if (ret < 0) {
+ printf("\n%s: MTD get bad block failed: %d\n",
+ mtd_device,
+ ret);
+ return -1;
+ }
+ }
+
+ erased_length++;
+
+ result = mtd_erase(mtd, &erase);
+ if (result != 0) {
+ printf("\n%s: MTD Erase failure: %d\n",
+ mtd_device, result);
+ continue;
+ }
+
+ /* format for JFFS2 ? */
+ if (opts->jffs2 && oobavail >= 8) {
+ struct mtd_oob_ops ops;
+ ops.ooblen = 8;
+ ops.datbuf = NULL;
+ ops.oobbuf = (uint8_t *)&cleanmarker;
+ ops.ooboffs = 0;
+ ops.mode = MTD_OPS_AUTO_OOB;
+
+ result = mtd_write_oob(mtd, erase.addr, &ops);
+ if (result != 0) {
+ printf("\n%s: MTD writeoob failure: %d\n",
+ mtd_device, result);
+ continue;
+ }
+ }
+
+ if (!opts->quiet) {
+ unsigned long long n = erased_length * 100ULL;
+ int percent;
+
+ do_div(n, erase_length);
+ percent = (int)n;
+
+ /* output progress message only at whole percent
+ * steps to reduce the number of messages printed
+ * on (slow) serial consoles
+ */
+ if (percent != percent_complete) {
+ percent_complete = percent;
+
+ printf("\rErasing at 0x%llx -- %3d%% complete.",
+ erase.addr, percent);
+
+ if (opts->jffs2 && result == 0)
+ printf(" Cleanmarker written at 0x%llx.",
+ erase.addr);
+ }
+ }
+ }
+ if (!opts->quiet)
+ printf("\n");
+
+ return 0;
+}
+
/**
* check_skip_len
*
--
2.30.1
More information about the U-Boot
mailing list