[U-Boot] [PATCH] cmd: mtd: solve bad block support in erase command

Patrick DELAUNAY patrick.delaunay at st.com
Fri Sep 27 11:23:09 UTC 2019


Hi Miquel

> From: Miquel Raynal <miquel.raynal at bootlin.com>
> Sent: jeudi 26 septembre 2019 11:43
> 
> Hi Patrick,
> 
> Patrick DELAUNAY <patrick.delaunay at st.com> wrote on Thu, 26 Sep 2019
> 09:31:46 +0000:
> 
> > Hi Stefan,
> >
> > > From: Stefan Roese <sr at denx.de>
> > > Sent: vendredi 20 septembre 2019 11:20
> > >
> > > Hi Patrick,
> > >
> > > On 20.09.19 09:20, Patrick Delaunay wrote:
> > > > 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.
> > >
> > > So here is the difference? I remember testing this on a board with
> > > SPI NAND and here it worked correctly. But your test case is with RAW
> NAND?
> >
> > Yes with RAW nand.
> >
> > it is the difference the U-Boot code, for SPI nan use:
> > 	int nanddev_mtd_erase()
> >
> > the fail address is always updated
> > 	=> einfo->fail_addr = nanddev_pos_to_offs(nand, &pos);
> >
> >
> > > Do you have a change to also test this on a board with SPI NAND?
> >
> > I do the test  a SPI-NAND today.
> >
> > The mtd erase command was functional on SPI-ANND before my patch :
> > I create 2 bad block manually and they are correctly skipped.
> >
> > STM32MP> mtd list
> > List of MTD devices:
> > * spi-nand0
> >   - device: spi-nand at 0
> >   - parent: qspi at 58003000
> >   - driver: spi_nand
> >   - type: NAND flash
> >   - block size: 0x20000 bytes
> >   - min I/O: 0x800 bytes
> >   - OOB size: 128 bytes
> >   - OOB available: 62 bytes
> >   - 0x000000000000-0x000010000000 : "spi-nand0"
> > 	  - 0x000000000000-0x000000200000 : "fsbl"
> > 	  - 0x000000200000-0x000000400000 : "ssbl1"
> > 	  - 0x000000400000-0x000000600000 : "ssbl2"
> > 	  - 0x000000600000-0x000010000000 : "UBI"
> >
> > STM32MP> mtd erase spi-nand0 0x00000000 0x10000000
> > Erasing 0x00000000 ... 0x0fffffff (2048 eraseblock(s))
> > 0x0fd00000: bad block
> > 0x0fd20000: bad block
> > attempt to erase a bad/reserved block @fd00000 Skipping bad block at
> > 0x0fd00000 attempt to erase a bad/reserved block @fd20000 Skipping bad
> > block at 0x0fd20000
> > 0x0fd00000: bad block
> > 0x0fd20000: bad block
> >
> >
> > > Thanks,
> > > Stefan
> > >
> >
> > What it is the better solution for you ?
> >
> >  update the MTD command (my patch) or allign the behavior of the 2 MTD
> > devices
> > - MTD RAW NAND (nand_base.c:: nand_erase_nand)
> > - MTD SPI NAND (core.c:: nanddev_mtd_erase)
> 
> Do you think it is easy to make use of nanddev_mtd_erase() from the raw NAND
> core? It is probably a little bit more elegant (and efficient) to do all in one go than
> iterating over each block (while there is a helper in the core to do that).


Yes, I agree: it will be more elegant.

But,  I am not comfortable with MTD Raw NAND framework.

Based on a quick check between Linux Kernel 5.3 and U-Boot, it seems that U-Boot
Raw NAND framework is aligned with Kernel 4.19 Raw NAND framework.
To be able to use nanddev_mtd_erase API, we should backport Raw NAND framework
from Kernel 5.3 because nanddev_mtd_erase can be used only if memorg structure
is properly set (has been done on Kernel 5.2).

I have not checked all potential impacts to use this API, but a backport form Kernel
Raw NAND framework is needed in U-Boot in a first step.

As  I am not comfortable with MTD frameworks, I think that my patch could be currently
applied to solve this issue, and in a second step, when a MTD expert will backport the
framework, it could be removed.

PS: A other solution with minimize the impacts in MTD, it is to change
      only nand_base.c:nand_erase_nand(), to update the fail_addr:

----------------------- drivers/mtd/nand/raw/nand_base.c ----------------------- index aba8ac019d..50542a2b9a 100644 @@ -3554,6 +3554,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 			pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
 				    __func__, page);
 			instr->state = MTD_ERASE_FAILED;
+			instr->fail_addr =
+				((loff_t)page << chip->page_shift);
 			goto erase_exit;
 		}

But as it is also a common MTD part with Linux kernel so I continue to prefer
my patch on U-Boot only code.

> 
> Thanks,
> Miquèl

Regards
Patrick


More information about the U-Boot mailing list