diff options
Diffstat (limited to 'drivers/mtd/ubi/wl.c')
-rw-r--r-- | drivers/mtd/ubi/wl.c | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 97a435672eaf..655bbbe415d9 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -745,7 +745,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
745 | 745 | ||
746 | err = ubi_io_read_vid_hdr(ubi, e1->pnum, vid_hdr, 0); | 746 | err = ubi_io_read_vid_hdr(ubi, e1->pnum, vid_hdr, 0); |
747 | if (err && err != UBI_IO_BITFLIPS) { | 747 | if (err && err != UBI_IO_BITFLIPS) { |
748 | if (err == UBI_IO_PEB_FREE) { | 748 | if (err == UBI_IO_FF) { |
749 | /* | 749 | /* |
750 | * We are trying to move PEB without a VID header. UBI | 750 | * We are trying to move PEB without a VID header. UBI |
751 | * always write VID headers shortly after the PEB was | 751 | * always write VID headers shortly after the PEB was |
@@ -759,6 +759,16 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
759 | dbg_wl("PEB %d has no VID header", e1->pnum); | 759 | dbg_wl("PEB %d has no VID header", e1->pnum); |
760 | protect = 1; | 760 | protect = 1; |
761 | goto out_not_moved; | 761 | goto out_not_moved; |
762 | } else if (err == UBI_IO_FF_BITFLIPS) { | ||
763 | /* | ||
764 | * The same situation as %UBI_IO_FF, but bit-flips were | ||
765 | * detected. It is better to schedule this PEB for | ||
766 | * scrubbing. | ||
767 | */ | ||
768 | dbg_wl("PEB %d has no VID header but has bit-flips", | ||
769 | e1->pnum); | ||
770 | scrubbing = 1; | ||
771 | goto out_not_moved; | ||
762 | } | 772 | } |
763 | 773 | ||
764 | ubi_err("error %d while reading VID header from PEB %d", | 774 | ubi_err("error %d while reading VID header from PEB %d", |
@@ -1468,22 +1478,6 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
1468 | ubi->lookuptbl[e->pnum] = e; | 1478 | ubi->lookuptbl[e->pnum] = e; |
1469 | } | 1479 | } |
1470 | 1480 | ||
1471 | list_for_each_entry(seb, &si->corr, u.list) { | ||
1472 | cond_resched(); | ||
1473 | |||
1474 | e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); | ||
1475 | if (!e) | ||
1476 | goto out_free; | ||
1477 | |||
1478 | e->pnum = seb->pnum; | ||
1479 | e->ec = seb->ec; | ||
1480 | ubi->lookuptbl[e->pnum] = e; | ||
1481 | if (schedule_erase(ubi, e, 0)) { | ||
1482 | kmem_cache_free(ubi_wl_entry_slab, e); | ||
1483 | goto out_free; | ||
1484 | } | ||
1485 | } | ||
1486 | |||
1487 | ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { | 1481 | ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { |
1488 | ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { | 1482 | ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { |
1489 | cond_resched(); | 1483 | cond_resched(); |
@@ -1510,6 +1504,9 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
1510 | if (ubi->avail_pebs < WL_RESERVED_PEBS) { | 1504 | if (ubi->avail_pebs < WL_RESERVED_PEBS) { |
1511 | ubi_err("no enough physical eraseblocks (%d, need %d)", | 1505 | ubi_err("no enough physical eraseblocks (%d, need %d)", |
1512 | ubi->avail_pebs, WL_RESERVED_PEBS); | 1506 | ubi->avail_pebs, WL_RESERVED_PEBS); |
1507 | if (ubi->corr_peb_count) | ||
1508 | ubi_err("%d PEBs are corrupted and not used", | ||
1509 | ubi->corr_peb_count); | ||
1513 | goto out_free; | 1510 | goto out_free; |
1514 | } | 1511 | } |
1515 | ubi->avail_pebs -= WL_RESERVED_PEBS; | 1512 | ubi->avail_pebs -= WL_RESERVED_PEBS; |