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 | } |