public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Patrick Delaunay <patrick.delaunay@st.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] cmd: mtd: solve bad block support in erase command
Date: Fri, 20 Sep 2019 09:20:12 +0200	[thread overview]
Message-ID: <20190920072012.17841-1-patrick.delaunay@st.com> (raw)

This patch modify the loop in mtd erase command to erase one by one
the blocks in the requested area.

It solves issue on "mtd erase" command on nand with existing bad block,
the command is interrupted on the first bad block with the trace:
	"Skipping bad block at 0xffffffffffffffff"

In MTD driver (nand/raw), when a bad block is present on the MTD
device, the erase_op.fail_addr is not updated and we have the initial
value MTD_FAIL_ADDR_UNKNOWN = (ULL)-1.

This case seems normal in nand_base.c:nand_erase_nand(),
we have the 2 exit cases during the loop:

1/ we have a bad block (nand_block_checkbad)
	instr->state = MTD_ERASE_FAILED
	loop interrupted (goto erase_exit)

2/ if block erase failed (status & NAND_STATUS_FAIL)
	instr->state = MTD_ERASE_FAILED;
	instr->fail_addr =
				((loff_t)page << chip->page_shift);
	loop interrupted (goto erase_exit)

So erase_op.fail_addr can't be used if bad blocks were present
in the erased area; we need to use mtd_erase only one block to detect
and skip these existing bad blocks (as it is done in nand_util.c).

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

Hi,

Found a correct in the mtd erase command.

I detect the issue and test the patch on STM32MP157C-EV1 board,
with nor and nand. We have the block table at the end of the nand
so the 4 last blocks are marked bad.

And I try to erase all the nand with the command "mtd erase".

Before the patch:

The "nand erase" command behavior is OK:

STM32MP> nand erase 0x0 0x000040000000

NAND erase: device 0 whole chip
Skipping bad block at  0x3ff00000
Skipping bad block at  0x3ff40000
Skipping bad block at  0x3ff80000
Skipping bad block at  0x3ffc0000

But the "mtd erase" command is not correct:

STM32MP> mtd list
SF: Detected mx66l51235l with page size 256 Bytes, erase size 64 KiB, total 64 MiB
List of MTD devices:
* nand0
  - type: NAND flash
  - block size: 0x40000 bytes
  - min I/O: 0x1000 bytes
  - OOB size: 224 bytes
  - OOB available: 118 bytes
  - ECC strength: 8 bits
  - ECC step size: 512 bytes
  - bitflip threshold: 6 bits
  - 0x000000000000-0x000040000000 : "nand0"
          - 0x000000000000-0x000000200000 : "fsbl"
          - 0x000000200000-0x000000400000 : "ssbl1"
          - 0x000000400000-0x000000600000 : "ssbl2"
          - 0x000000600000-0x000040000000 : "UBI"
* nor0
  - type: NOR flash
  - block size: 0x10000 bytes
  - min I/O: 0x1 bytes
  - 0x000000000000-0x000004000000 : "nor0"
          - 0x000000000000-0x000000040000 : "fsbl1"
          - 0x000000040000-0x000000080000 : "fsbl2"
          - 0x000000080000-0x000000280000 : "ssbl"
          - 0x000000280000-0x000000300000 : "u-boot-env"
          - 0x000000300000-0x000004000000 : "nor_user"

STM32MP> mtd erase nand0 0x0 0x000040000000
Erasing 0x00000000 ... 0x3fffffff (4096 eraseblock(s))
Skipping bad block at 0xffffffffffffffff

OK

The 4 bad blocks are not correctly skipped,
the command is stopped on the first error.

After the patch, the "mtd erase" command skips the 4 bad block
exactly as the "nand erase" command:

STM32MP> mtd erase nand0 0x000000000000 0x000040000000
SF: Detected mx66l51235l with page size 256 Bytes, erase size 64 KiB, total 64 MiB
Erasing 0x00000000 ... 0x3fffffff (4096 eraseblock(s))
Skipping bad block at 0x3ff00000
Skipping bad block at 0x3ff40000
Skipping bad block at 0x3ff80000
Skipping bad block at 0x3ffc0000

Regards

Patrick


 cmd/mtd.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/cmd/mtd.c b/cmd/mtd.c
index 1b6b8dda2b..a559b5a4a3 100644
--- a/cmd/mtd.c
+++ b/cmd/mtd.c
@@ -387,7 +387,7 @@ static int do_mtd_erase(cmd_tbl_t *cmdtp, int flag, int argc,
 	struct mtd_info *mtd;
 	u64 off, len;
 	bool scrub;
-	int ret;
+	int ret = 0;
 
 	if (argc < 2)
 		return CMD_RET_USAGE;
@@ -423,22 +423,22 @@ static int do_mtd_erase(cmd_tbl_t *cmdtp, int flag, int argc,
 
 	erase_op.mtd = mtd;
 	erase_op.addr = off;
-	erase_op.len = len;
+	erase_op.len = mtd->erasesize;
 	erase_op.scrub = scrub;
 
-	while (erase_op.len) {
+	while (len) {
 		ret = mtd_erase(mtd, &erase_op);
 
-		/* Abort if its not a bad block error */
-		if (ret != -EIO)
-			break;
-
-		printf("Skipping bad block at 0x%08llx\n", erase_op.fail_addr);
+		if (ret) {
+			/* Abort if its not a bad block error */
+			if (ret != -EIO)
+				break;
+			printf("Skipping bad block at 0x%08llx\n",
+			       erase_op.addr);
+		}
 
-		/* Skip bad block and continue behind it */
-		erase_op.len -= erase_op.fail_addr - erase_op.addr;
-		erase_op.len -= mtd->erasesize;
-		erase_op.addr = erase_op.fail_addr + mtd->erasesize;
+		len -= mtd->erasesize;
+		erase_op.addr += mtd->erasesize;
 	}
 
 	if (ret && ret != -EIO)
-- 
2.17.1

             reply	other threads:[~2019-09-20  7:20 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-20  7:20 Patrick Delaunay [this message]
2019-09-20  9:20 ` [U-Boot] [PATCH] cmd: mtd: solve bad block support in erase command Stefan Roese
2019-09-26  9:31   ` Patrick DELAUNAY
2019-09-26  9:42     ` Miquel Raynal
2019-09-27 11:23       ` Patrick DELAUNAY
2019-09-29 19:46         ` Miquel Raynal
2019-09-20  9:55 ` Miquel Raynal
2020-01-25 17:08 ` 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=20190920072012.17841-1-patrick.delaunay@st.com \
    --to=patrick.delaunay@st.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox