ubi: Do not zero out EC and VID on ECC-ed NOR flashes
authorPratyush Yadav <p.yadav@ti.com>
Tue, 1 Dec 2020 10:27:09 +0000 (15:57 +0530)
committerRichard Weinberger <richard@nod.at>
Sun, 13 Dec 2020 20:57:21 +0000 (21:57 +0100)
For NOR flashes EC and VID are zeroed out before an erase is issued to
make sure UBI does not mistakenly treat the PEB as used and associate it
with an LEB.

But on some flashes, like the Cypress Semper S28 SPI NOR flash family,
multi-pass page programming is not allowed on the default ECC scheme.
This means zeroing out these magic numbers will result in the flash
throwing a page programming error.

Do not zero out EC and VID for such flashes. A writesize > 1 is an
indication of an ECC-ed flash.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
drivers/mtd/ubi/build.c
drivers/mtd/ubi/io.c

index 46a6dd75e533fe39995f47805b2698e7dd0dab1a..04e3e48aab45d742b647e2aed47d716c34882db2 100644 (file)
@@ -628,10 +628,8 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
                ubi->bad_peb_limit = get_bad_peb_limit(ubi, max_beb_per1024);
        }
 
-       if (ubi->mtd->type == MTD_NORFLASH) {
-               ubi_assert(ubi->mtd->writesize == 1);
+       if (ubi->mtd->type == MTD_NORFLASH)
                ubi->nor_flash = 1;
-       }
 
        ubi->min_io_size = ubi->mtd->writesize;
        ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft;
index 14d890b00d2cb54d380c13fcb60011884241306a..2f3312c31e51c18b88dbc3bb63b3cefe064b2513 100644 (file)
@@ -535,7 +535,14 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture)
                return -EROFS;
        }
 
-       if (ubi->nor_flash) {
+       /*
+        * If the flash is ECC-ed then we have to erase the ECC block before we
+        * can write to it. But the write is in preparation to an erase in the
+        * first place. This means we cannot zero out EC and VID before the
+        * erase and we just have to hope the flash starts erasing from the
+        * start of the page.
+        */
+       if (ubi->nor_flash && ubi->mtd->writesize == 1) {
                err = nor_erase_prepare(ubi, pnum);
                if (err)
                        return err;