diff options
| -rw-r--r-- | drivers/mtd/ubi/scan.c | 101 | 
1 files changed, 82 insertions, 19 deletions
| diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index a20f278d0c6c..6b7c0c4baf07 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
| @@ -760,8 +760,6 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
| 760 | bitflips = 1; | 760 | bitflips = 1; | 
| 761 | } | 761 | } | 
| 762 | 762 | ||
| 763 | si->is_empty = 0; | ||
| 764 | |||
| 765 | if (!ec_corr) { | 763 | if (!ec_corr) { | 
| 766 | int image_seq; | 764 | int image_seq; | 
| 767 | 765 | ||
| @@ -892,6 +890,85 @@ adjust_mean_ec: | |||
| 892 | } | 890 | } | 
| 893 | 891 | ||
| 894 | /** | 892 | /** | 
| 893 | * check_what_we_have - check what PEB were found by scanning. | ||
| 894 | * @ubi: UBI device description object | ||
| 895 | * @si: scanning information | ||
| 896 | * | ||
| 897 | * This is a helper function which takes a look what PEBs were found by | ||
| 898 | * scanning, and decides whether the flash is empty and should be formatted and | ||
| 899 | * whether there are too many corrupted PEBs and we should not attach this | ||
| 900 | * MTD device. Returns zero if we should proceed with attaching the MTD device, | ||
| 901 | * and %-EINVAL if we should not. | ||
| 902 | */ | ||
| 903 | static int check_what_we_have(const struct ubi_device *ubi, | ||
| 904 | 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 | } else { | ||
| 960 | ubi_err("MTD device possibly contains non-UBI data, " | ||
| 961 | "refusing it"); | ||
| 962 | return -EINVAL; | ||
| 963 | } | ||
| 964 | } | ||
| 965 | |||
| 966 | if (si->corr_peb_count >= 0) | ||
| 967 | ubi_msg("corrupted PEBs will be formatted"); | ||
| 968 | return 0; | ||
| 969 | } | ||
| 970 | |||
| 971 | /** | ||
| 895 | * ubi_scan - scan an MTD device. | 972 | * ubi_scan - scan an MTD device. | 
| 896 | * @ubi: UBI device description object | 973 | * @ubi: UBI device description object | 
| 897 | * | 974 | * | 
| @@ -915,7 +992,6 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) | |||
| 915 | INIT_LIST_HEAD(&si->erase); | 992 | INIT_LIST_HEAD(&si->erase); | 
| 916 | INIT_LIST_HEAD(&si->alien); | 993 | INIT_LIST_HEAD(&si->alien); | 
| 917 | si->volumes = RB_ROOT; | 994 | si->volumes = RB_ROOT; | 
| 918 | si->is_empty = 1; | ||
| 919 | 995 | ||
| 920 | err = -ENOMEM; | 996 | err = -ENOMEM; | 
| 921 | ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); | 997 | ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); | 
| @@ -941,22 +1017,9 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) | |||
| 941 | if (si->ec_count) | 1017 | if (si->ec_count) | 
| 942 | si->mean_ec = div_u64(si->ec_sum, si->ec_count); | 1018 | si->mean_ec = div_u64(si->ec_sum, si->ec_count); | 
| 943 | 1019 | ||
| 944 | if (si->is_empty) | 1020 | err = check_what_we_have(ubi, si); | 
| 945 | ubi_msg("empty MTD device detected"); | 1021 | if (err) | 
| 946 | 1022 | goto out_vidh; | |
| 947 | /* | ||
| 948 | * Few corrupted PEBs are not a problem and may be just a result of | ||
| 949 | * unclean reboots. However, many of them may indicate some problems | ||
| 950 | * with the flash HW or driver. Print a warning in this case. | ||
| 951 | */ | ||
| 952 | if (si->corr_peb_count >= 8 || | ||
| 953 | si->corr_peb_count >= ubi->peb_count / 4) { | ||
| 954 | ubi_warn("%d PEBs are corrupted", si->corr_peb_count); | ||
| 955 | printk(KERN_WARNING "corrupted PEBs are:"); | ||
| 956 | list_for_each_entry(seb, &si->corr, u.list) | ||
| 957 | printk(KERN_CONT " %d", seb->pnum); | ||
| 958 | printk(KERN_CONT "\n"); | ||
| 959 | } | ||
| 960 | 1023 | ||
| 961 | /* | 1024 | /* | 
| 962 | * In case of unknown erase counter we use the mean erase counter | 1025 | * In case of unknown erase counter we use the mean erase counter | 
