Commit de75c771 authored by Artem Bityutskiy's avatar Artem Bityutskiy

UBI: improve NOR flash erasure quirk

More testing of NOR flash against power cuts showed that sometimes
eraseblocks may be unwritable, and we cannot really invalidate
them before erasure. But in this case the eraseblock probably
contains garbage anyway, and we do not have to invalidate the
headers. This assumption might be not true, but this is at least
what I have observed. So if we cannot invalidate the headers,
we make sure that the PEB does not contain valid VID header.
If this is true, everything is fine, otherwise we panic.
parent 867996b1
...@@ -476,30 +476,46 @@ static int torture_peb(struct ubi_device *ubi, int pnum) ...@@ -476,30 +476,46 @@ static int torture_peb(struct ubi_device *ubi, int pnum)
*/ */
static int nor_erase_prepare(struct ubi_device *ubi, int pnum) static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
{ {
int err; int err, err1;
size_t written; size_t written;
loff_t addr; loff_t addr;
uint32_t data = 0; uint32_t data = 0;
struct ubi_vid_hdr vid_hdr;
addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset; addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset;
err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
if (err) { if (!err) {
ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " addr -= ubi->vid_hdr_aloffset;
"%zd bytes", err, pnum, ubi->vid_hdr_aloffset, written); err = ubi->mtd->write(ubi->mtd, addr, 4, &written,
ubi_dbg_dump_stack(); (void *)&data);
return err; if (!err)
return 0;
} }
addr -= ubi->vid_hdr_aloffset; /*
err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); * We failed to write to the media. This was observed with Spansion
if (err) { * S29GL512N NOR flash. Most probably the eraseblock erasure was
ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " * interrupted at a very inappropriate moment, so it became unwritable.
"%zd bytes", err, pnum, 0, written); * In this case we probably anyway have garbage in this PEB.
ubi_dbg_dump_stack(); */
return err; err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
} if (err1 == UBI_IO_BAD_VID_HDR)
/*
* The VID header is corrupted, so we can safely erase this
* PEB and not afraid that it will be treated as a valid PEB in
* case of an unclean reboot.
*/
return 0;
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.
*/
ubi_err("cannot invalidate PEB %d, write returned %d read returned %d",
pnum, err, err1);
ubi_dbg_dump_flash(ubi, pnum, 0, ubi->peb_size);
return -EIO;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment