@@ -509,26 +509,10 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
struct ubi_vid_hdr vid_hdr;
/*
- * It is important to first invalidate the EC header, and then the VID
- * header. Otherwise a power cut may lead to valid EC header and
- * invalid VID header, in which case UBI will treat this PEB as
- * corrupted and will try to preserve it, and print scary warnings.
- */
- addr = (loff_t)pnum * ubi->peb_size;
- err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
- if (!err) {
- addr += ubi->vid_hdr_aloffset;
- err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
- if (!err)
- return 0;
- }
-
- /*
- * We failed to write to the media. This was observed with Spansion
- * S29GL512N NOR flash. Most probably the previously eraseblock erasure
+ * Most probably the previously eraseblock erasure
* was interrupted at a very inappropriate moment, so it became
- * unwritable. In this case we probably anyway have garbage in this
- * PEB.
+ * unwritable. In order to avoid program data into a unwritable block,
+ * read this block first, and check if do need to program it.
*/
err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
@@ -547,6 +531,22 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
}
/*
+ * VID or EC is valid, need to corrupt these header before erase operation.
+ * It is important to first invalidate the EC header, and then the VID
+ * header. Otherwise a power cut may lead to valid EC header and
+ * invalid VID header, in which case UBI will treat this PEB as
+ * corrupted and will try to preserve it, and print scary warnings.
+ */
+ addr = (loff_t)pnum * ubi->peb_size;
+ err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
+ if (!err) {
+ addr += ubi->vid_hdr_aloffset;
+ err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
+ if (!err)
+ return 0;
+ }
+
+ /*
* The PEB contains a valid VID header, but we cannot invalidate it.
* Supposedly the flash media or the driver is screwed up, so return an
* error.