From 7a3d808fa98a5beef5e13a33446cf8bf44b741d5 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 24 Jul 2009 16:18:04 +0300 Subject: [PATCH] --- yaml --- r: 164044 b: refs/heads/master c: de75c771b4cc4da963164a538a8448128301bc35 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/mtd/ubi/io.c | 46 +++++++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/[refs] b/[refs] index bbcee1d88c9a..4d75833f545d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 867996b15c1f0a98d2c405bada907e97499ba8c2 +refs/heads/master: de75c771b4cc4da963164a538a8448128301bc35 diff --git a/trunk/drivers/mtd/ubi/io.c b/trunk/drivers/mtd/ubi/io.c index b693138fc519..8aa51e7a6a7d 100644 --- a/trunk/drivers/mtd/ubi/io.c +++ b/trunk/drivers/mtd/ubi/io.c @@ -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) { - int err; + int err, err1; size_t written; loff_t addr; uint32_t data = 0; + struct ubi_vid_hdr vid_hdr; addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset; err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); - if (err) { - ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " - "%zd bytes", err, pnum, ubi->vid_hdr_aloffset, written); - ubi_dbg_dump_stack(); - return err; + if (!err) { + addr -= ubi->vid_hdr_aloffset; + err = ubi->mtd->write(ubi->mtd, addr, 4, &written, + (void *)&data); + if (!err) + return 0; } - addr -= ubi->vid_hdr_aloffset; - err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); - if (err) { - ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " - "%zd bytes", err, pnum, 0, written); - ubi_dbg_dump_stack(); - return err; - } + /* + * We failed to write to the media. This was observed with Spansion + * S29GL512N NOR flash. Most probably the eraseblock erasure was + * interrupted at a very inappropriate moment, so it became unwritable. + * In this case we probably anyway have garbage in this PEB. + */ + 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; } /**