diff options
| -rw-r--r-- | drivers/mtd/ubi/io.c | 54 |
1 files changed, 22 insertions, 32 deletions
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index bf79def40126..d36134925d31 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
| @@ -495,10 +495,12 @@ out: | |||
| 495 | */ | 495 | */ |
| 496 | static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | 496 | static int nor_erase_prepare(struct ubi_device *ubi, int pnum) |
| 497 | { | 497 | { |
| 498 | int err, err1; | 498 | int err; |
| 499 | size_t written; | 499 | size_t written; |
| 500 | loff_t addr; | 500 | loff_t addr; |
| 501 | uint32_t data = 0; | 501 | uint32_t data = 0; |
| 502 | struct ubi_ec_hdr ec_hdr; | ||
| 503 | |||
| 502 | /* | 504 | /* |
| 503 | * Note, we cannot generally define VID header buffers on stack, | 505 | * Note, we cannot generally define VID header buffers on stack, |
| 504 | * because of the way we deal with these buffers (see the header | 506 | * because of the way we deal with these buffers (see the header |
| @@ -509,50 +511,38 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | |||
| 509 | struct ubi_vid_hdr vid_hdr; | 511 | struct ubi_vid_hdr vid_hdr; |
| 510 | 512 | ||
| 511 | /* | 513 | /* |
| 514 | * If VID or EC is valid, we have to corrupt them before erasing. | ||
| 512 | * It is important to first invalidate the EC header, and then the VID | 515 | * It is important to first invalidate the EC header, and then the VID |
| 513 | * header. Otherwise a power cut may lead to valid EC header and | 516 | * header. Otherwise a power cut may lead to valid EC header and |
| 514 | * invalid VID header, in which case UBI will treat this PEB as | 517 | * invalid VID header, in which case UBI will treat this PEB as |
| 515 | * corrupted and will try to preserve it, and print scary warnings. | 518 | * corrupted and will try to preserve it, and print scary warnings. |
| 516 | */ | 519 | */ |
| 517 | addr = (loff_t)pnum * ubi->peb_size; | 520 | addr = (loff_t)pnum * ubi->peb_size; |
| 518 | err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); | 521 | err = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); |
| 519 | if (!err) { | 522 | if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR && |
| 520 | addr += ubi->vid_hdr_aloffset; | 523 | err != UBI_IO_FF){ |
| 521 | err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); | 524 | err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); |
| 522 | if (!err) | 525 | if(err) |
| 523 | return 0; | 526 | goto error; |
| 524 | } | 527 | } |
| 525 | 528 | ||
| 526 | /* | 529 | err = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); |
| 527 | * We failed to write to the media. This was observed with Spansion | 530 | if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR && |
| 528 | * S29GL512N NOR flash. Most probably the previously eraseblock erasure | 531 | err != UBI_IO_FF){ |
| 529 | * was interrupted at a very inappropriate moment, so it became | 532 | addr += ubi->vid_hdr_aloffset; |
| 530 | * unwritable. In this case we probably anyway have garbage in this | 533 | err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); |
| 531 | * PEB. | 534 | if (err) |
| 532 | */ | 535 | goto error; |
| 533 | err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); | ||
| 534 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || | ||
| 535 | err1 == UBI_IO_FF) { | ||
| 536 | struct ubi_ec_hdr ec_hdr; | ||
| 537 | |||
| 538 | err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); | ||
| 539 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || | ||
| 540 | err1 == UBI_IO_FF) | ||
| 541 | /* | ||
| 542 | * Both VID and EC headers are corrupted, so we can | ||
| 543 | * safely erase this PEB and not afraid that it will be | ||
| 544 | * treated as a valid PEB in case of an unclean reboot. | ||
| 545 | */ | ||
| 546 | return 0; | ||
| 547 | } | 536 | } |
| 537 | return 0; | ||
| 548 | 538 | ||
| 539 | error: | ||
| 549 | /* | 540 | /* |
| 550 | * The PEB contains a valid VID header, but we cannot invalidate it. | 541 | * The PEB contains a valid VID or EC header, but we cannot invalidate |
| 551 | * Supposedly the flash media or the driver is screwed up, so return an | 542 | * it. Supposedly the flash media or the driver is screwed up, so |
| 552 | * error. | 543 | * return an error. |
| 553 | */ | 544 | */ |
| 554 | ubi_err("cannot invalidate PEB %d, write returned %d read returned %d", | 545 | ubi_err("cannot invalidate PEB %d, write returned %d", pnum, err); |
| 555 | pnum, err, err1); | ||
| 556 | ubi_dump_flash(ubi, pnum, 0, ubi->peb_size); | 546 | ubi_dump_flash(ubi, pnum, 0, ubi->peb_size); |
| 557 | return -EIO; | 547 | return -EIO; |
| 558 | } | 548 | } |
