diff options
Diffstat (limited to 'drivers/mtd/ubi/scan.c')
-rw-r--r-- | drivers/mtd/ubi/scan.c | 131 |
1 files changed, 101 insertions, 30 deletions
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index aed19f33b8f3..372a15ac9995 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/crc32.h> | 45 | #include <linux/crc32.h> |
46 | #include <linux/math64.h> | 46 | #include <linux/math64.h> |
47 | #include <linux/random.h> | ||
47 | #include "ubi.h" | 48 | #include "ubi.h" |
48 | 49 | ||
49 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 50 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID |
@@ -72,16 +73,19 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, | |||
72 | { | 73 | { |
73 | struct ubi_scan_leb *seb; | 74 | struct ubi_scan_leb *seb; |
74 | 75 | ||
75 | if (list == &si->free) | 76 | if (list == &si->free) { |
76 | dbg_bld("add to free: PEB %d, EC %d", pnum, ec); | 77 | dbg_bld("add to free: PEB %d, EC %d", pnum, ec); |
77 | else if (list == &si->erase) | 78 | si->free_peb_count += 1; |
79 | } else if (list == &si->erase) { | ||
78 | dbg_bld("add to erase: PEB %d, EC %d", pnum, ec); | 80 | dbg_bld("add to erase: PEB %d, EC %d", pnum, ec); |
79 | else if (list == &si->corr) { | 81 | si->erase_peb_count += 1; |
82 | } else if (list == &si->corr) { | ||
80 | dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); | 83 | dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); |
81 | si->corr_count += 1; | 84 | si->corr_peb_count += 1; |
82 | } else if (list == &si->alien) | 85 | } else if (list == &si->alien) { |
83 | dbg_bld("add to alien: PEB %d, EC %d", pnum, ec); | 86 | dbg_bld("add to alien: PEB %d, EC %d", pnum, ec); |
84 | else | 87 | si->alien_peb_count += 1; |
88 | } else | ||
85 | BUG(); | 89 | BUG(); |
86 | 90 | ||
87 | seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL); | 91 | seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL); |
@@ -517,6 +521,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
517 | sv->leb_count += 1; | 521 | sv->leb_count += 1; |
518 | rb_link_node(&seb->u.rb, parent, p); | 522 | rb_link_node(&seb->u.rb, parent, p); |
519 | rb_insert_color(&seb->u.rb, &sv->root); | 523 | rb_insert_color(&seb->u.rb, &sv->root); |
524 | si->used_peb_count += 1; | ||
520 | return 0; | 525 | return 0; |
521 | } | 526 | } |
522 | 527 | ||
@@ -745,19 +750,17 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
745 | bitflips = 1; | 750 | bitflips = 1; |
746 | else if (err == UBI_IO_PEB_EMPTY) | 751 | else if (err == UBI_IO_PEB_EMPTY) |
747 | return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, &si->erase); | 752 | return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, &si->erase); |
748 | else if (err == UBI_IO_BAD_EC_HDR) { | 753 | else if (err == UBI_IO_BAD_HDR_READ || err == UBI_IO_BAD_HDR) { |
749 | /* | 754 | /* |
750 | * We have to also look at the VID header, possibly it is not | 755 | * We have to also look at the VID header, possibly it is not |
751 | * corrupted. Set %bitflips flag in order to make this PEB be | 756 | * corrupted. Set %bitflips flag in order to make this PEB be |
752 | * moved and EC be re-created. | 757 | * moved and EC be re-created. |
753 | */ | 758 | */ |
754 | ec_corr = 1; | 759 | ec_corr = err; |
755 | ec = UBI_SCAN_UNKNOWN_EC; | 760 | ec = UBI_SCAN_UNKNOWN_EC; |
756 | bitflips = 1; | 761 | bitflips = 1; |
757 | } | 762 | } |
758 | 763 | ||
759 | si->is_empty = 0; | ||
760 | |||
761 | if (!ec_corr) { | 764 | if (!ec_corr) { |
762 | int image_seq; | 765 | int image_seq; |
763 | 766 | ||
@@ -813,9 +816,12 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
813 | return err; | 816 | return err; |
814 | else if (err == UBI_IO_BITFLIPS) | 817 | else if (err == UBI_IO_BITFLIPS) |
815 | bitflips = 1; | 818 | bitflips = 1; |
816 | else if (err == UBI_IO_BAD_VID_HDR || | 819 | else if (err == UBI_IO_BAD_HDR_READ || err == UBI_IO_BAD_HDR || |
817 | (err == UBI_IO_PEB_FREE && ec_corr)) { | 820 | (err == UBI_IO_PEB_FREE && ec_corr)) { |
818 | /* VID header is corrupted */ | 821 | /* VID header is corrupted */ |
822 | if (err == UBI_IO_BAD_HDR_READ || | ||
823 | ec_corr == UBI_IO_BAD_HDR_READ) | ||
824 | si->read_err_count += 1; | ||
819 | err = add_to_list(si, pnum, ec, &si->corr); | 825 | err = add_to_list(si, pnum, ec, &si->corr); |
820 | if (err) | 826 | if (err) |
821 | return err; | 827 | return err; |
@@ -836,11 +842,11 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
836 | switch (vidh->compat) { | 842 | switch (vidh->compat) { |
837 | case UBI_COMPAT_DELETE: | 843 | case UBI_COMPAT_DELETE: |
838 | ubi_msg("\"delete\" compatible internal volume %d:%d" | 844 | ubi_msg("\"delete\" compatible internal volume %d:%d" |
839 | " found, remove it", vol_id, lnum); | 845 | " found, will remove it", vol_id, lnum); |
840 | err = add_to_list(si, pnum, ec, &si->corr); | 846 | err = add_to_list(si, pnum, ec, &si->corr); |
841 | if (err) | 847 | if (err) |
842 | return err; | 848 | return err; |
843 | break; | 849 | return 0; |
844 | 850 | ||
845 | case UBI_COMPAT_RO: | 851 | case UBI_COMPAT_RO: |
846 | ubi_msg("read-only compatible internal volume %d:%d" | 852 | ubi_msg("read-only compatible internal volume %d:%d" |
@@ -855,7 +861,6 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
855 | err = add_to_list(si, pnum, ec, &si->alien); | 861 | err = add_to_list(si, pnum, ec, &si->alien); |
856 | if (err) | 862 | if (err) |
857 | return err; | 863 | return err; |
858 | si->alien_peb_count += 1; | ||
859 | return 0; | 864 | return 0; |
860 | 865 | ||
861 | case UBI_COMPAT_REJECT: | 866 | case UBI_COMPAT_REJECT: |
@@ -886,6 +891,85 @@ adjust_mean_ec: | |||
886 | } | 891 | } |
887 | 892 | ||
888 | /** | 893 | /** |
894 | * check_what_we_have - check what PEB were found by scanning. | ||
895 | * @ubi: UBI device description object | ||
896 | * @si: scanning information | ||
897 | * | ||
898 | * This is a helper function which takes a look what PEBs were found by | ||
899 | * scanning, and decides whether the flash is empty and should be formatted and | ||
900 | * whether there are too many corrupted PEBs and we should not attach this | ||
901 | * MTD device. Returns zero if we should proceed with attaching the MTD device, | ||
902 | * and %-EINVAL if we should not. | ||
903 | */ | ||
904 | static int check_what_we_have(struct ubi_device *ubi, struct ubi_scan_info *si) | ||
905 | { | ||
906 | struct ubi_scan_leb *seb; | ||
907 | int max_corr; | ||
908 | |||
909 | max_corr = ubi->peb_count - si->bad_peb_count - si->alien_peb_count; | ||
910 | max_corr = max_corr / 20 ?: 8; | ||
911 | |||
912 | /* | ||
913 | * Few corrupted PEBs are not a problem and may be just a result of | ||
914 | * unclean reboots. However, many of them may indicate some problems | ||
915 | * with the flash HW or driver. | ||
916 | */ | ||
917 | if (si->corr_peb_count >= 8) { | ||
918 | ubi_warn("%d PEBs are corrupted", si->corr_peb_count); | ||
919 | printk(KERN_WARNING "corrupted PEBs are:"); | ||
920 | list_for_each_entry(seb, &si->corr, u.list) | ||
921 | printk(KERN_CONT " %d", seb->pnum); | ||
922 | printk(KERN_CONT "\n"); | ||
923 | |||
924 | /* | ||
925 | * If too many PEBs are corrupted, we refuse attaching, | ||
926 | * otherwise, only print a warning. | ||
927 | */ | ||
928 | if (si->corr_peb_count >= max_corr) { | ||
929 | ubi_err("too many corrupted PEBs, refusing this device"); | ||
930 | return -EINVAL; | ||
931 | } | ||
932 | } | ||
933 | |||
934 | if (si->free_peb_count + si->used_peb_count + | ||
935 | si->alien_peb_count == 0) { | ||
936 | /* No UBI-formatted eraseblocks were found */ | ||
937 | if (si->corr_peb_count == si->read_err_count && | ||
938 | si->corr_peb_count < 8) { | ||
939 | /* No or just few corrupted PEBs, and all of them had a | ||
940 | * read error. We assume that those are bad PEBs, which | ||
941 | * were just not marked as bad so far. | ||
942 | * | ||
943 | * This piece of code basically tries to distinguish | ||
944 | * between the following 2 situations: | ||
945 | * | ||
946 | * 1. Flash is empty, but there are few bad PEBs, which | ||
947 | * are not marked as bad so far, and which were read | ||
948 | * with error. We want to go ahead and format this | ||
949 | * flash. While formating, the faulty PEBs will | ||
950 | * probably be marked as bad. | ||
951 | * | ||
952 | * 2. Flash probably contains non-UBI data and we do | ||
953 | * not want to format it and destroy possibly needed | ||
954 | * data (e.g., consider the case when the bootloader | ||
955 | * MTD partition was accidentally fed to UBI). | ||
956 | */ | ||
957 | si->is_empty = 1; | ||
958 | ubi_msg("empty MTD device detected"); | ||
959 | get_random_bytes(&ubi->image_seq, sizeof(ubi->image_seq)); | ||
960 | } else { | ||
961 | ubi_err("MTD device possibly contains non-UBI data, " | ||
962 | "refusing it"); | ||
963 | return -EINVAL; | ||
964 | } | ||
965 | } | ||
966 | |||
967 | if (si->corr_peb_count > 0) | ||
968 | ubi_msg("corrupted PEBs will be formatted"); | ||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | /** | ||
889 | * ubi_scan - scan an MTD device. | 973 | * ubi_scan - scan an MTD device. |
890 | * @ubi: UBI device description object | 974 | * @ubi: UBI device description object |
891 | * | 975 | * |
@@ -909,7 +993,6 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) | |||
909 | INIT_LIST_HEAD(&si->erase); | 993 | INIT_LIST_HEAD(&si->erase); |
910 | INIT_LIST_HEAD(&si->alien); | 994 | INIT_LIST_HEAD(&si->alien); |
911 | si->volumes = RB_ROOT; | 995 | si->volumes = RB_ROOT; |
912 | si->is_empty = 1; | ||
913 | 996 | ||
914 | err = -ENOMEM; | 997 | err = -ENOMEM; |
915 | ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); | 998 | ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); |
@@ -935,21 +1018,9 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) | |||
935 | if (si->ec_count) | 1018 | if (si->ec_count) |
936 | si->mean_ec = div_u64(si->ec_sum, si->ec_count); | 1019 | si->mean_ec = div_u64(si->ec_sum, si->ec_count); |
937 | 1020 | ||
938 | if (si->is_empty) | 1021 | err = check_what_we_have(ubi, si); |
939 | ubi_msg("empty MTD device detected"); | 1022 | if (err) |
940 | 1023 | goto out_vidh; | |
941 | /* | ||
942 | * Few corrupted PEBs are not a problem and may be just a result of | ||
943 | * unclean reboots. However, many of them may indicate some problems | ||
944 | * with the flash HW or driver. Print a warning in this case. | ||
945 | */ | ||
946 | if (si->corr_count >= 8 || si->corr_count >= ubi->peb_count / 4) { | ||
947 | ubi_warn("%d PEBs are corrupted", si->corr_count); | ||
948 | printk(KERN_WARNING "corrupted PEBs are:"); | ||
949 | list_for_each_entry(seb, &si->corr, u.list) | ||
950 | printk(KERN_CONT " %d", seb->pnum); | ||
951 | printk(KERN_CONT "\n"); | ||
952 | } | ||
953 | 1024 | ||
954 | /* | 1025 | /* |
955 | * In case of unknown erase counter we use the mean erase counter | 1026 | * In case of unknown erase counter we use the mean erase counter |