X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmtd%2Fubi%2Fscan.c;h=96d410e106ab1cb72cf9f6bda211e756eaa8c98d;hb=49997d75152b3d23c53b0fa730599f2f74c92c65;hp=29c41eeb09fe2c82523d877d020af5238d1c8f77;hpb=440fdb53b4ae58602711b5b8c3a139ace2404dbb;p=linux-2.6-omap-h63xx.git diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 29c41eeb09f..96d410e106a 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -42,11 +42,11 @@ #include #include +#include #include "ubi.h" #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID -static int paranoid_check_si(const struct ubi_device *ubi, - struct ubi_scan_info *si); +static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); #else #define paranoid_check_si(ubi, si) 0 #endif @@ -92,27 +92,6 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, return 0; } -/** - * commit_to_mean_value - commit intermediate results to the final mean erase - * counter value. - * @si: scanning information - * - * This is a helper function which calculates partial mean erase counter mean - * value and adds it to the resulting mean value. As we can work only in - * integer arithmetic and we want to calculate the mean value of erase counter - * accurately, we first sum erase counter values in @si->ec_sum variable and - * count these components in @si->ec_count. If this temporary @si->ec_sum is - * going to overflow, we calculate the partial mean value - * (@si->ec_sum/@si->ec_count) and add it to @si->mean_ec. - */ -static void commit_to_mean_value(struct ubi_scan_info *si) -{ - si->ec_sum /= si->ec_count; - if (si->ec_sum % si->ec_count >= si->ec_count / 2) - si->mean_ec += 1; - si->mean_ec += si->ec_sum; -} - /** * validate_vid_hdr - check that volume identifier header is correct and * consistent. @@ -259,14 +238,13 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id, * o bit 2 is cleared: the older LEB is not corrupted; * o bit 2 is set: the older LEB is corrupted. */ -static int compare_lebs(const struct ubi_device *ubi, - const struct ubi_scan_leb *seb, int pnum, - const struct ubi_vid_hdr *vid_hdr) +static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, + int pnum, const struct ubi_vid_hdr *vid_hdr) { void *buf; int len, err, second_is_newer, bitflips = 0, corrupted = 0; uint32_t data_crc, crc; - struct ubi_vid_hdr *vidh = NULL; + struct ubi_vid_hdr *vh = NULL; unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); if (seb->sqnum == 0 && sqnum2 == 0) { @@ -288,9 +266,14 @@ static int compare_lebs(const struct ubi_device *ubi, * FIXME: but this is anyway obsolete and will be removed at * some point. */ - dbg_bld("using old crappy leb_ver stuff"); + if (v1 == v2) { + ubi_err("PEB %d and PEB %d have the same version %lld", + seb->pnum, pnum, v1); + return -EINVAL; + } + abs = v1 - v2; if (abs < 0) abs = -abs; @@ -323,11 +306,11 @@ static int compare_lebs(const struct ubi_device *ubi, } else { pnum = seb->pnum; - vidh = ubi_zalloc_vid_hdr(ubi); - if (!vidh) + vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vh) return -ENOMEM; - err = ubi_io_read_vid_hdr(ubi, pnum, vidh, 0); + err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); if (err) { if (err == UBI_IO_BITFLIPS) bitflips = 1; @@ -341,7 +324,7 @@ static int compare_lebs(const struct ubi_device *ubi, } } - if (!vidh->copy_flag) { + if (!vh->copy_flag) { /* It is not a copy, so it is newer */ dbg_bld("first PEB %d is newer, copy_flag is unset", pnum); @@ -349,7 +332,7 @@ static int compare_lebs(const struct ubi_device *ubi, goto out_free_vidh; } - vid_hdr = vidh; + vid_hdr = vh; } /* Read the data of the copy and check the CRC */ @@ -379,7 +362,7 @@ static int compare_lebs(const struct ubi_device *ubi, } vfree(buf); - ubi_free_vid_hdr(ubi, vidh); + ubi_free_vid_hdr(ubi, vh); if (second_is_newer) dbg_bld("second PEB %d is newer, copy_flag is set", pnum); @@ -391,8 +374,7 @@ static int compare_lebs(const struct ubi_device *ubi, out_free_buf: vfree(buf); out_free_vidh: - ubi_free_vid_hdr(ubi, vidh); - ubi_assert(err < 0); + ubi_free_vid_hdr(ubi, vh); return err; } @@ -413,7 +395,7 @@ out_free_vidh: * to be picked, while the older one has to be dropped. This function returns * zero in case of success and a negative error code in case of failure. */ -int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, +int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips) { @@ -667,16 +649,12 @@ void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv) * function returns zero in case of success and a negative error code in case * of failure. */ -int ubi_scan_erase_peb(const struct ubi_device *ubi, - const struct ubi_scan_info *si, int pnum, int ec) +int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, + int pnum, int ec) { int err; struct ubi_ec_hdr *ec_hdr; - ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); - if (!ec_hdr) - return -ENOMEM; - if ((long long)ec >= UBI_MAX_ERASECOUNTER) { /* * Erase counter overflow. Upgrade UBI and use 64-bit @@ -686,6 +664,10 @@ int ubi_scan_erase_peb(const struct ubi_device *ubi, return -EINVAL; } + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ec_hdr) + return -ENOMEM; + ec_hdr->ec = cpu_to_be64(ec); err = ubi_io_sync_erase(ubi, pnum, 0); @@ -712,7 +694,7 @@ out_free: * This function returns scanning physical eraseblock information in case of * success and an error code in case of failure. */ -struct ubi_scan_leb *ubi_scan_get_free_peb(const struct ubi_device *ubi, +struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_scan_info *si) { int err = 0, i; @@ -771,7 +753,7 @@ struct ubi_scan_leb *ubi_scan_get_free_peb(const struct ubi_device *ubi, */ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum) { - long long ec; + long long uninitialized_var(ec); int err, bitflips = 0, vol_id, ec_corr = 0; dbg_bld("scan PEB %d", pnum); @@ -856,7 +838,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum } vol_id = be32_to_cpu(vidh->vol_id); - if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOL_ID) { + if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) { int lnum = be32_to_cpu(vidh->lnum); /* Unsupported internal volume */ @@ -899,15 +881,8 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum adjust_mean_ec: if (!ec_corr) { - if (si->ec_sum + ec < ec) { - commit_to_mean_value(si); - si->ec_sum = 0; - si->ec_count = 0; - } else { - si->ec_sum += ec; - si->ec_count += 1; - } - + si->ec_sum += ec; + si->ec_count += 1; if (ec > si->max_ec) si->max_ec = ec; if (ec < si->min_ec) @@ -948,7 +923,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) if (!ech) goto out_si; - vidh = ubi_zalloc_vid_hdr(ubi); + vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); if (!vidh) goto out_ech; @@ -963,9 +938,11 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) dbg_msg("scanning is finished"); - /* Finish mean erase counter calculations */ - if (si->ec_count) - commit_to_mean_value(si); + /* Calculate mean erase counter */ + if (si->ec_count) { + do_div(si->ec_sum, si->ec_count); + si->mean_ec = si->ec_sum; + } if (si->is_empty) ubi_msg("empty MTD device detected"); @@ -1110,8 +1087,7 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) * This function returns zero if the scanning information is all right, %1 if * not and a negative error code if an error occurred. */ -static int paranoid_check_si(const struct ubi_device *ubi, - struct ubi_scan_info *si) +static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) { int pnum, err, vols_found = 0; struct rb_node *rb1, *rb2;