aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorQi Wang 王起 (qiwang) <qiwang@micron.com>2014-01-01 08:06:11 -0500
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2014-01-09 11:25:38 -0500
commit2c7ca5cc3624e05a5235f70039adce30725972d6 (patch)
tree97d43cb7b5e6616370011544d0e8d6a8f37b630f /drivers/mtd
parentb6b44e0ad27881d4649b2afa15a27fb8867210ea (diff)
UBI: avoid program operation on NOR flash after erasure interrupted
nor_erase_prepare() will be called before erase a NOR flash, it will program '0' into a block to mark this block. But program data into a erasure interrupted block can cause program timtout(several minutes at most) error, could impact other operation on NOR flash. So UBIFS can read this block first to avoid unneeded program operation. This patch try to put read operation at head of write operation in nor_erase_prepare(), read out the data. If the data is already corrupt, then no need to program any data into this block, just go to erase this block. This patch is validated on Micron NOR flash, part number is:JS28F512M29EWHA Signed-off-by: Qi Wang <qiwang@micron.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/ubi/io.c54
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 */
496static int nor_erase_prepare(struct ubi_device *ubi, int pnum) 496static 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
539error:
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}