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).

However, after programming, upper-layer file systems (such as UBI)
may utilize byte 1 for metadata. 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 <[email protected]>
---
 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 (marker[0] != 0xff || marker[1] != 0xff)
                return true;
 
-- 
2.17.1

Reply via email to