[PATCH 1/2] mtd: spinand: core: fix Winbond W25N bad block marker (1 byte BBM)

Frieder Schrempf frieder.schrempf at kontron.de
Mon Jun 8 09:12:54 CEST 2026


On 05.06.26 17:23, Zunyi Hu wrote:
> [Sie erhalten nicht häufig E-Mails von roberhu001 at 163.com. Weitere Informationen, warum dies wichtig ist, finden Sie unter https://aka.ms/LearnAboutSenderIdentification ]
> 
> According to the Winbond datasheet, the factory Bad Block Marker
> is strictly a single non-0xFF byte located at spare byte 0.
> The default spinand core assumes a 2-byte marker (byte 0 and 1).

When I look at the datasheet for the W25N01GV for example, it says:

A “Bad Block Marker” is a non-FFh data byte stored at Byte 0 of Page
0 for each bad block. An additional marker is also stored in the first
two bytes of the 64-Byte spare area.

So checking for the first two bytes in the spare area seems correct.

> 
> However, after programming, upper-layer file systems (such as UBI)
> may utilize byte 1 for metadata.

The OOB layout excludes the first two bytes from being used by the
software. So if UBI uses these bytes something is very wrong.

> The default 2-byte check leads to
> false-positive bad block detections on valid blocks. Introduce a
> manufacturer-specific check (Winbond ID: 0xEF) to strictly evaluate
> only marker[0].
> 
> Signed-off-by: Zunyi Hu <roberhu001 at 163.com>

If you want to submit changes to the logic of the SPI NAND drivers,
please also submit them to the Linux kernel driver. We want to stay in
sync with the kernel.

> ---
>  drivers/mtd/nand/spi/core.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> index e5330958c7e..5395a1bdf68 100644
> --- a/drivers/mtd/nand/spi/core.c
> +++ b/drivers/mtd/nand/spi/core.c
> @@ -676,6 +676,17 @@ static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
>         if (ret)
>                 return ret;
> 
> +       /*
> +        * Winbond W25N (incl. W25N01G/GV): factory BBM is a single non-0xFF
> +        * byte at spare byte 0 (see datasheet).  Byte 1 may hold ECC or file
> +        * system markers after programming — do not treat it as BBM.
> +        */
> +       if (spinand->id.data[1] == 0xEF) {
> +               if (marker[0] != 0xff)
> +                       return true;
> +               return false;
> +       }

If this is actually needed (and I dont't think it is), this code should
better be put in the manufacturer driver (windbond.c), not in the core.

> +
>         if (marker[0] != 0xff || marker[1] != 0xff)
>                 return true;
> 
> --
> 2.17.1
> 



More information about the U-Boot mailing list