diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/ubi/build.c | 2 | ||||
-rw-r--r-- | drivers/mtd/ubi/eba.c | 6 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.c | 48 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 3 | ||||
-rw-r--r-- | drivers/mtd/ubi/vmt.c | 6 | ||||
-rw-r--r-- | drivers/mtd/ubi/vtbl.c | 8 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 19 |
7 files changed, 45 insertions, 47 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index f247c4e7b40d..5ebe280225d6 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -591,6 +591,7 @@ static int attach_by_scanning(struct ubi_device *ubi) | |||
591 | 591 | ||
592 | ubi->bad_peb_count = si->bad_peb_count; | 592 | ubi->bad_peb_count = si->bad_peb_count; |
593 | ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; | 593 | ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; |
594 | ubi->corr_peb_count = si->corr_peb_count; | ||
594 | ubi->max_ec = si->max_ec; | 595 | ubi->max_ec = si->max_ec; |
595 | ubi->mean_ec = si->mean_ec; | 596 | ubi->mean_ec = si->mean_ec; |
596 | ubi_msg("max. sequence number: %llu", si->max_sqnum); | 597 | ubi_msg("max. sequence number: %llu", si->max_sqnum); |
@@ -972,6 +973,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
972 | ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); | 973 | ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); |
973 | ubi_msg("number of good PEBs: %d", ubi->good_peb_count); | 974 | ubi_msg("number of good PEBs: %d", ubi->good_peb_count); |
974 | ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); | 975 | ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); |
976 | ubi_msg("number of corrupted PEBs: %d", ubi->corr_peb_count); | ||
975 | ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); | 977 | ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); |
976 | ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); | 978 | ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); |
977 | ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); | 979 | ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); |
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 334865ef5220..4be671815014 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
@@ -1201,6 +1201,9 @@ static void print_rsvd_warning(struct ubi_device *ubi, | |||
1201 | 1201 | ||
1202 | ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d," | 1202 | ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d," |
1203 | " need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); | 1203 | " need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); |
1204 | if (ubi->corr_peb_count) | ||
1205 | ubi_warn("%d PEBs are corrupted and not used", | ||
1206 | ubi->corr_peb_count); | ||
1204 | } | 1207 | } |
1205 | 1208 | ||
1206 | /** | 1209 | /** |
@@ -1263,6 +1266,9 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
1263 | if (ubi->avail_pebs < EBA_RESERVED_PEBS) { | 1266 | if (ubi->avail_pebs < EBA_RESERVED_PEBS) { |
1264 | ubi_err("no enough physical eraseblocks (%d, need %d)", | 1267 | ubi_err("no enough physical eraseblocks (%d, need %d)", |
1265 | ubi->avail_pebs, EBA_RESERVED_PEBS); | 1268 | ubi->avail_pebs, EBA_RESERVED_PEBS); |
1269 | if (ubi->corr_peb_count) | ||
1270 | ubi_err("%d PEBs are corrupted and not used", | ||
1271 | ubi->corr_peb_count); | ||
1266 | err = -ENOSPC; | 1272 | err = -ENOSPC; |
1267 | goto out_free; | 1273 | goto out_free; |
1268 | } | 1274 | } |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index def0bf03d7fe..30b710216f26 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -706,8 +706,8 @@ out_free: | |||
706 | struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, | 706 | struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, |
707 | struct ubi_scan_info *si) | 707 | struct ubi_scan_info *si) |
708 | { | 708 | { |
709 | int err = 0, i; | 709 | int err = 0; |
710 | struct ubi_scan_leb *seb; | 710 | struct ubi_scan_leb *seb, *tmp_seb; |
711 | 711 | ||
712 | if (!list_empty(&si->free)) { | 712 | if (!list_empty(&si->free)) { |
713 | seb = list_entry(si->free.next, struct ubi_scan_leb, u.list); | 713 | seb = list_entry(si->free.next, struct ubi_scan_leb, u.list); |
@@ -716,37 +716,27 @@ struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, | |||
716 | return seb; | 716 | return seb; |
717 | } | 717 | } |
718 | 718 | ||
719 | for (i = 0; i < 2; i++) { | 719 | /* |
720 | struct list_head *head; | 720 | * We try to erase the first physical eraseblock from the erase list |
721 | struct ubi_scan_leb *tmp_seb; | 721 | * and pick it if we succeed, or try to erase the next one if not. And |
722 | 722 | * so forth. We don't want to take care about bad eraseblocks here - | |
723 | if (i == 0) | 723 | * they'll be handled later. |
724 | head = &si->erase; | 724 | */ |
725 | else | 725 | list_for_each_entry_safe(seb, tmp_seb, &si->erase, u.list) { |
726 | head = &si->corr; | 726 | if (seb->ec == UBI_SCAN_UNKNOWN_EC) |
727 | 727 | seb->ec = si->mean_ec; | |
728 | /* | ||
729 | * We try to erase the first physical eraseblock from the @head | ||
730 | * list and pick it if we succeed, or try to erase the | ||
731 | * next one if not. And so forth. We don't want to take care | ||
732 | * about bad eraseblocks here - they'll be handled later. | ||
733 | */ | ||
734 | list_for_each_entry_safe(seb, tmp_seb, head, u.list) { | ||
735 | if (seb->ec == UBI_SCAN_UNKNOWN_EC) | ||
736 | seb->ec = si->mean_ec; | ||
737 | 728 | ||
738 | err = ubi_scan_erase_peb(ubi, si, seb->pnum, seb->ec+1); | 729 | err = ubi_scan_erase_peb(ubi, si, seb->pnum, seb->ec+1); |
739 | if (err) | 730 | if (err) |
740 | continue; | 731 | continue; |
741 | 732 | ||
742 | seb->ec += 1; | 733 | seb->ec += 1; |
743 | list_del(&seb->u.list); | 734 | list_del(&seb->u.list); |
744 | dbg_bld("return PEB %d, EC %d", seb->pnum, seb->ec); | 735 | dbg_bld("return PEB %d, EC %d", seb->pnum, seb->ec); |
745 | return seb; | 736 | return seb; |
746 | } | ||
747 | } | 737 | } |
748 | 738 | ||
749 | ubi_err("no eraseblocks found"); | 739 | ubi_err("no free eraseblocks"); |
750 | return ERR_PTR(-ENOSPC); | 740 | return ERR_PTR(-ENOSPC); |
751 | } | 741 | } |
752 | 742 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 8831d7ba9f21..0b0149c41fe3 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -361,6 +361,8 @@ struct ubi_wl_entry; | |||
361 | * @peb_size: physical eraseblock size | 361 | * @peb_size: physical eraseblock size |
362 | * @bad_peb_count: count of bad physical eraseblocks | 362 | * @bad_peb_count: count of bad physical eraseblocks |
363 | * @good_peb_count: count of good physical eraseblocks | 363 | * @good_peb_count: count of good physical eraseblocks |
364 | * @corr_peb_count: count of corrupted physical eraseblocks (preserved and not | ||
365 | * used by UBI) | ||
364 | * @erroneous_peb_count: count of erroneous physical eraseblocks in @erroneous | 366 | * @erroneous_peb_count: count of erroneous physical eraseblocks in @erroneous |
365 | * @max_erroneous: maximum allowed amount of erroneous physical eraseblocks | 367 | * @max_erroneous: maximum allowed amount of erroneous physical eraseblocks |
366 | * @min_io_size: minimal input/output unit size of the underlying MTD device | 368 | * @min_io_size: minimal input/output unit size of the underlying MTD device |
@@ -447,6 +449,7 @@ struct ubi_device { | |||
447 | int peb_size; | 449 | int peb_size; |
448 | int bad_peb_count; | 450 | int bad_peb_count; |
449 | int good_peb_count; | 451 | int good_peb_count; |
452 | int corr_peb_count; | ||
450 | int erroneous_peb_count; | 453 | int erroneous_peb_count; |
451 | int max_erroneous; | 454 | int max_erroneous; |
452 | int min_io_size; | 455 | int min_io_size; |
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index e42afab9a9fe..c47620dfc722 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c | |||
@@ -261,6 +261,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
261 | /* Reserve physical eraseblocks */ | 261 | /* Reserve physical eraseblocks */ |
262 | if (vol->reserved_pebs > ubi->avail_pebs) { | 262 | if (vol->reserved_pebs > ubi->avail_pebs) { |
263 | dbg_err("not enough PEBs, only %d available", ubi->avail_pebs); | 263 | dbg_err("not enough PEBs, only %d available", ubi->avail_pebs); |
264 | if (ubi->corr_peb_count) | ||
265 | dbg_err("%d PEBs are corrupted and not used", | ||
266 | ubi->corr_peb_count); | ||
264 | err = -ENOSPC; | 267 | err = -ENOSPC; |
265 | goto out_unlock; | 268 | goto out_unlock; |
266 | } | 269 | } |
@@ -527,6 +530,9 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) | |||
527 | if (pebs > ubi->avail_pebs) { | 530 | if (pebs > ubi->avail_pebs) { |
528 | dbg_err("not enough PEBs: requested %d, available %d", | 531 | dbg_err("not enough PEBs: requested %d, available %d", |
529 | pebs, ubi->avail_pebs); | 532 | pebs, ubi->avail_pebs); |
533 | if (ubi->corr_peb_count) | ||
534 | dbg_err("%d PEBs are corrupted and not used", | ||
535 | ubi->corr_peb_count); | ||
530 | spin_unlock(&ubi->volumes_lock); | 536 | spin_unlock(&ubi->volumes_lock); |
531 | err = -ENOSPC; | 537 | err = -ENOSPC; |
532 | goto out_free; | 538 | goto out_free; |
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 3bfe00a94667..fcdb7f65fe0b 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -662,9 +662,13 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, | |||
662 | ubi->vol_count += 1; | 662 | ubi->vol_count += 1; |
663 | vol->ubi = ubi; | 663 | vol->ubi = ubi; |
664 | 664 | ||
665 | if (reserved_pebs > ubi->avail_pebs) | 665 | if (reserved_pebs > ubi->avail_pebs) { |
666 | ubi_err("not enough PEBs, required %d, available %d", | 666 | ubi_err("not enough PEBs, required %d, available %d", |
667 | reserved_pebs, ubi->avail_pebs); | 667 | reserved_pebs, ubi->avail_pebs); |
668 | if (ubi->corr_peb_count) | ||
669 | ubi_err("%d PEBs are corrupted and not used", | ||
670 | ubi->corr_peb_count); | ||
671 | } | ||
668 | ubi->rsvd_pebs += reserved_pebs; | 672 | ubi->rsvd_pebs += reserved_pebs; |
669 | ubi->avail_pebs -= reserved_pebs; | 673 | ubi->avail_pebs -= reserved_pebs; |
670 | 674 | ||
@@ -837,7 +841,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
837 | return PTR_ERR(ubi->vtbl); | 841 | return PTR_ERR(ubi->vtbl); |
838 | } | 842 | } |
839 | 843 | ||
840 | ubi->avail_pebs = ubi->good_peb_count; | 844 | ubi->avail_pebs = ubi->good_peb_count - ubi->corr_peb_count; |
841 | 845 | ||
842 | /* | 846 | /* |
843 | * The layout volume is OK, initialize the corresponding in-RAM data | 847 | * The layout volume is OK, initialize the corresponding in-RAM data |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 605ecb1e22bb..655bbbe415d9 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -1478,22 +1478,6 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
1478 | ubi->lookuptbl[e->pnum] = e; | 1478 | ubi->lookuptbl[e->pnum] = e; |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | list_for_each_entry(seb, &si->corr, u.list) { | ||
1482 | cond_resched(); | ||
1483 | |||
1484 | e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); | ||
1485 | if (!e) | ||
1486 | goto out_free; | ||
1487 | |||
1488 | e->pnum = seb->pnum; | ||
1489 | e->ec = seb->ec; | ||
1490 | ubi->lookuptbl[e->pnum] = e; | ||
1491 | if (schedule_erase(ubi, e, 0)) { | ||
1492 | kmem_cache_free(ubi_wl_entry_slab, e); | ||
1493 | goto out_free; | ||
1494 | } | ||
1495 | } | ||
1496 | |||
1497 | ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { | 1481 | ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { |
1498 | ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { | 1482 | ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { |
1499 | cond_resched(); | 1483 | cond_resched(); |
@@ -1520,6 +1504,9 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
1520 | if (ubi->avail_pebs < WL_RESERVED_PEBS) { | 1504 | if (ubi->avail_pebs < WL_RESERVED_PEBS) { |
1521 | ubi_err("no enough physical eraseblocks (%d, need %d)", | 1505 | ubi_err("no enough physical eraseblocks (%d, need %d)", |
1522 | 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); | ||
1523 | goto out_free; | 1510 | goto out_free; |
1524 | } | 1511 | } |
1525 | ubi->avail_pebs -= WL_RESERVED_PEBS; | 1512 | ubi->avail_pebs -= WL_RESERVED_PEBS; |