diff options
| -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; |
