diff options
| -rw-r--r-- | drivers/mtd/ubi/scan.c | 46 | ||||
| -rw-r--r-- | drivers/mtd/ubi/scan.h | 2 | ||||
| -rw-r--r-- | drivers/mtd/ubi/vtbl.c | 14 |
3 files changed, 35 insertions, 27 deletions
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index e4456869e753..30d536ee10fc 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | * This unit is responsible for scanning the flash media, checking UBI | 24 | * This unit is responsible for scanning the flash media, checking UBI |
| 25 | * headers and providing complete information about the UBI flash image. | 25 | * headers and providing complete information about the UBI flash image. |
| 26 | * | 26 | * |
| 27 | * The scanning information is reoresented by a &struct ubi_scan_info' object. | 27 | * The scanning information is represented by a &struct ubi_scan_info' object. |
| 28 | * Information about found volumes is represented by &struct ubi_scan_volume | 28 | * Information about found volumes is represented by &struct ubi_scan_volume |
| 29 | * objects which are kept in volume RB-tree with root at the @volumes field. | 29 | * objects which are kept in volume RB-tree with root at the @volumes field. |
| 30 | * The RB-tree is indexed by the volume ID. | 30 | * The RB-tree is indexed by the volume ID. |
| @@ -55,8 +55,19 @@ static int paranoid_check_si(const struct ubi_device *ubi, | |||
| 55 | static struct ubi_ec_hdr *ech; | 55 | static struct ubi_ec_hdr *ech; |
| 56 | static struct ubi_vid_hdr *vidh; | 56 | static struct ubi_vid_hdr *vidh; |
| 57 | 57 | ||
| 58 | int ubi_scan_add_to_list(struct ubi_scan_info *si, int pnum, int ec, | 58 | /* |
| 59 | struct list_head *list) | 59 | * add_to_list - add physical eraseblock to a list. |
| 60 | * @si: scanning information | ||
| 61 | * @pnum: physical eraseblock number to add | ||
| 62 | * @ec: erase counter of the physical eraseblock | ||
| 63 | * @list: the list to add to | ||
| 64 | * | ||
| 65 | * This function adds physical eraseblock @pnum to free, erase, corrupted or | ||
| 66 | * alien lists. Returns zero in case of success and a negative error code in | ||
| 67 | * case of failure. | ||
| 68 | */ | ||
| 69 | static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, | ||
| 70 | struct list_head *list) | ||
| 60 | { | 71 | { |
| 61 | struct ubi_scan_leb *seb; | 72 | struct ubi_scan_leb *seb; |
| 62 | 73 | ||
| @@ -492,11 +503,11 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | |||
| 492 | return err; | 503 | return err; |
| 493 | 504 | ||
| 494 | if (cmp_res & 4) | 505 | if (cmp_res & 4) |
| 495 | err = ubi_scan_add_to_list(si, seb->pnum, | 506 | err = add_to_list(si, seb->pnum, seb->ec, |
| 496 | seb->ec, &si->corr); | 507 | &si->corr); |
| 497 | else | 508 | else |
| 498 | err = ubi_scan_add_to_list(si, seb->pnum, | 509 | err = add_to_list(si, seb->pnum, seb->ec, |
| 499 | seb->ec, &si->erase); | 510 | &si->erase); |
| 500 | if (err) | 511 | if (err) |
| 501 | return err; | 512 | return err; |
| 502 | 513 | ||
| @@ -517,11 +528,9 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | |||
| 517 | * previously. | 528 | * previously. |
| 518 | */ | 529 | */ |
| 519 | if (cmp_res & 4) | 530 | if (cmp_res & 4) |
| 520 | return ubi_scan_add_to_list(si, pnum, ec, | 531 | return add_to_list(si, pnum, ec, &si->corr); |
| 521 | &si->corr); | ||
| 522 | else | 532 | else |
| 523 | return ubi_scan_add_to_list(si, pnum, ec, | 533 | return add_to_list(si, pnum, ec, &si->erase); |
| 524 | &si->erase); | ||
| 525 | } | 534 | } |
| 526 | } | 535 | } |
| 527 | 536 | ||
| @@ -754,7 +763,7 @@ struct ubi_scan_leb *ubi_scan_get_free_peb(const struct ubi_device *ubi, | |||
| 754 | * @si: scanning information | 763 | * @si: scanning information |
| 755 | * @pnum: the physical eraseblock number | 764 | * @pnum: the physical eraseblock number |
| 756 | * | 765 | * |
| 757 | * This function returns a zero if the physical eraseblock was succesfully | 766 | * This function returns a zero if the physical eraseblock was successfully |
| 758 | * handled and a negative error code in case of failure. | 767 | * handled and a negative error code in case of failure. |
| 759 | */ | 768 | */ |
| 760 | static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum) | 769 | static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum) |
| @@ -783,8 +792,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum | |||
| 783 | else if (err == UBI_IO_BITFLIPS) | 792 | else if (err == UBI_IO_BITFLIPS) |
| 784 | bitflips = 1; | 793 | bitflips = 1; |
| 785 | else if (err == UBI_IO_PEB_EMPTY) | 794 | else if (err == UBI_IO_PEB_EMPTY) |
| 786 | return ubi_scan_add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, | 795 | return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, &si->erase); |
| 787 | &si->erase); | ||
| 788 | else if (err == UBI_IO_BAD_EC_HDR) { | 796 | else if (err == UBI_IO_BAD_EC_HDR) { |
| 789 | /* | 797 | /* |
| 790 | * We have to also look at the VID header, possibly it is not | 798 | * We have to also look at the VID header, possibly it is not |
| @@ -832,13 +840,13 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum | |||
| 832 | else if (err == UBI_IO_BAD_VID_HDR || | 840 | else if (err == UBI_IO_BAD_VID_HDR || |
| 833 | (err == UBI_IO_PEB_FREE && ec_corr)) { | 841 | (err == UBI_IO_PEB_FREE && ec_corr)) { |
| 834 | /* VID header is corrupted */ | 842 | /* VID header is corrupted */ |
| 835 | err = ubi_scan_add_to_list(si, pnum, ec, &si->corr); | 843 | err = add_to_list(si, pnum, ec, &si->corr); |
| 836 | if (err) | 844 | if (err) |
| 837 | return err; | 845 | return err; |
| 838 | goto adjust_mean_ec; | 846 | goto adjust_mean_ec; |
| 839 | } else if (err == UBI_IO_PEB_FREE) { | 847 | } else if (err == UBI_IO_PEB_FREE) { |
| 840 | /* No VID header - the physical eraseblock is free */ | 848 | /* No VID header - the physical eraseblock is free */ |
| 841 | err = ubi_scan_add_to_list(si, pnum, ec, &si->free); | 849 | err = add_to_list(si, pnum, ec, &si->free); |
| 842 | if (err) | 850 | if (err) |
| 843 | return err; | 851 | return err; |
| 844 | goto adjust_mean_ec; | 852 | goto adjust_mean_ec; |
| @@ -853,7 +861,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum | |||
| 853 | case UBI_COMPAT_DELETE: | 861 | case UBI_COMPAT_DELETE: |
| 854 | ubi_msg("\"delete\" compatible internal volume %d:%d" | 862 | ubi_msg("\"delete\" compatible internal volume %d:%d" |
| 855 | " found, remove it", vol_id, lnum); | 863 | " found, remove it", vol_id, lnum); |
| 856 | err = ubi_scan_add_to_list(si, pnum, ec, &si->corr); | 864 | err = add_to_list(si, pnum, ec, &si->corr); |
| 857 | if (err) | 865 | if (err) |
| 858 | return err; | 866 | return err; |
| 859 | break; | 867 | break; |
| @@ -868,7 +876,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum | |||
| 868 | case UBI_COMPAT_PRESERVE: | 876 | case UBI_COMPAT_PRESERVE: |
| 869 | ubi_msg("\"preserve\" compatible internal volume %d:%d" | 877 | ubi_msg("\"preserve\" compatible internal volume %d:%d" |
| 870 | " found", vol_id, lnum); | 878 | " found", vol_id, lnum); |
| 871 | err = ubi_scan_add_to_list(si, pnum, ec, &si->alien); | 879 | err = add_to_list(si, pnum, ec, &si->alien); |
| 872 | if (err) | 880 | if (err) |
| 873 | return err; | 881 | return err; |
| 874 | si->alien_peb_count += 1; | 882 | si->alien_peb_count += 1; |
| @@ -1109,7 +1117,7 @@ static int paranoid_check_si(const struct ubi_device *ubi, | |||
| 1109 | uint8_t *buf; | 1117 | uint8_t *buf; |
| 1110 | 1118 | ||
| 1111 | /* | 1119 | /* |
| 1112 | * At first, check that scanning information is ok. | 1120 | * At first, check that scanning information is OK. |
| 1113 | */ | 1121 | */ |
| 1114 | ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { | 1122 | ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { |
| 1115 | int leb_count = 0; | 1123 | int leb_count = 0; |
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 3949f6192c76..140e82e26534 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h | |||
| @@ -147,8 +147,6 @@ static inline void ubi_scan_move_to_list(struct ubi_scan_volume *sv, | |||
| 147 | list_add_tail(&seb->u.list, list); | 147 | list_add_tail(&seb->u.list, list); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | int ubi_scan_add_to_list(struct ubi_scan_info *si, int pnum, int ec, | ||
| 151 | struct list_head *list); | ||
| 152 | int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | 150 | int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, |
| 153 | int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, | 151 | int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, |
| 154 | int bitflips); | 152 | int bitflips); |
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 83236c31c892..9926f1f9aad8 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
| @@ -317,13 +317,15 @@ retry: | |||
| 317 | return err; | 317 | return err; |
| 318 | 318 | ||
| 319 | write_error: | 319 | write_error: |
| 320 | /* Maybe this physical eraseblock went bad, try to pick another one */ | 320 | if (err == -EIO && ++tries <= 5) { |
| 321 | if (++tries <= 5) | 321 | /* |
| 322 | err = ubi_scan_add_to_list(si, new_seb->pnum, new_seb->ec, | 322 | * Probably this physical eraseblock went bad, try to pick |
| 323 | &si->corr); | 323 | * another one. |
| 324 | kfree(new_seb); | 324 | */ |
| 325 | if (!err) | 325 | list_add_tail(&new_seb->u.list, &si->corr); |
| 326 | goto retry; | 326 | goto retry; |
| 327 | } | ||
| 328 | kfree(new_seb); | ||
| 327 | out_free: | 329 | out_free: |
| 328 | ubi_free_vid_hdr(ubi, vid_hdr); | 330 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 329 | return err; | 331 | return err; |
