Skip to content

Commit

Permalink
Merge branch 'linux-next' of git://git.infradead.org/ubi-2.6
Browse files Browse the repository at this point in the history
* 'linux-next' of git://git.infradead.org/ubi-2.6:
  UBI: fix corrupted PEB detection for NOR flash
  • Loading branch information
torvalds committed Dec 3, 2010
2 parents df9d38e + 7ac760c commit 88063dd
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
37 changes: 25 additions & 12 deletions drivers/mtd/ubi/io.c
Expand Up @@ -482,10 +482,17 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
uint32_t data = 0;
struct ubi_vid_hdr vid_hdr;

addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset;
/*
* 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 (see
* the header comment in scan.c for more information).
*/
addr = (loff_t)pnum * ubi->peb_size;
err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
if (!err) {
addr -= ubi->vid_hdr_aloffset;
addr += ubi->vid_hdr_aloffset;
err = ubi->mtd->write(ubi->mtd, addr, 4, &written,
(void *)&data);
if (!err)
Expand All @@ -494,18 +501,24 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)

/*
* 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.
* S29GL512N NOR flash. 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.
*/
err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_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;
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR) {
struct ubi_ec_hdr ec_hdr;

err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
/*
* Both VID and EC headers are 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;
}

/*
* The PEB contains a valid VID header, but we cannot invalidate it.
Expand Down
4 changes: 4 additions & 0 deletions drivers/mtd/ubi/scan.c
Expand Up @@ -953,6 +953,10 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
* impossible to distinguish it from a PEB which just
* contains garbage because of a power cut during erase
* operation. So we just schedule this PEB for erasure.
*
* Besides, in case of NOR flash, we deliberatly
* corrupt both headers because NOR flash erasure is
* slow and can start from the end.
*/
err = 0;
else
Expand Down

0 comments on commit 88063dd

Please sign in to comment.