Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
[linux-2.6-block.git] / drivers / mtd / ubi / scan.c
index b24af2104a2a865e9060c0db94c7f08607719d3a..05aa3e7daba1edefb88a3b97befb6d4f717fc25c 100644 (file)
@@ -45,8 +45,7 @@
 #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
@@ -132,9 +131,9 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr,
                            const struct ubi_scan_volume *sv, int pnum)
 {
        int vol_type = vid_hdr->vol_type;
-       int vol_id = ubi32_to_cpu(vid_hdr->vol_id);
-       int used_ebs = ubi32_to_cpu(vid_hdr->used_ebs);
-       int data_pad = ubi32_to_cpu(vid_hdr->data_pad);
+       int vol_id = be32_to_cpu(vid_hdr->vol_id);
+       int used_ebs = be32_to_cpu(vid_hdr->used_ebs);
+       int data_pad = be32_to_cpu(vid_hdr->data_pad);
 
        if (sv->leb_count != 0) {
                int sv_vol_type;
@@ -200,7 +199,7 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id,
        struct ubi_scan_volume *sv;
        struct rb_node **p = &si->volumes.rb_node, *parent = NULL;
 
-       ubi_assert(vol_id == ubi32_to_cpu(vid_hdr->vol_id));
+       ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id));
 
        /* Walk the volume RB-tree to look if this volume is already present */
        while (*p) {
@@ -222,11 +221,10 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id,
                return ERR_PTR(-ENOMEM);
 
        sv->highest_lnum = sv->leb_count = 0;
-       si->max_sqnum = 0;
        sv->vol_id = vol_id;
        sv->root = RB_ROOT;
-       sv->used_ebs = ubi32_to_cpu(vid_hdr->used_ebs);
-       sv->data_pad = ubi32_to_cpu(vid_hdr->data_pad);
+       sv->used_ebs = be32_to_cpu(vid_hdr->used_ebs);
+       sv->data_pad = be32_to_cpu(vid_hdr->data_pad);
        sv->compat = vid_hdr->compat;
        sv->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME
                                                            : UBI_STATIC_VOLUME;
@@ -260,18 +258,17 @@ 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;
-       unsigned long long sqnum2 = ubi64_to_cpu(vid_hdr->sqnum);
+       struct ubi_vid_hdr *vh = NULL;
+       unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum);
 
        if (seb->sqnum == 0 && sqnum2 == 0) {
-               long long abs, v1 = seb->leb_ver, v2 = ubi32_to_cpu(vid_hdr->leb_ver);
+               long long abs, v1 = seb->leb_ver, v2 = be32_to_cpu(vid_hdr->leb_ver);
 
                /*
                 * UBI constantly increases the logical eraseblock version
@@ -289,9 +286,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;
@@ -324,11 +326,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;
@@ -342,7 +344,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);
@@ -350,13 +352,13 @@ 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 */
 
-       len = ubi32_to_cpu(vid_hdr->data_size);
-       buf = kmalloc(len, GFP_KERNEL);
+       len = be32_to_cpu(vid_hdr->data_size);
+       buf = vmalloc(len);
        if (!buf) {
                err = -ENOMEM;
                goto out_free_vidh;
@@ -366,7 +368,7 @@ static int compare_lebs(const struct ubi_device *ubi,
        if (err && err != UBI_IO_BITFLIPS)
                goto out_free_buf;
 
-       data_crc = ubi32_to_cpu(vid_hdr->data_crc);
+       data_crc = be32_to_cpu(vid_hdr->data_crc);
        crc = crc32(UBI_CRC32_INIT, buf, len);
        if (crc != data_crc) {
                dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x",
@@ -379,8 +381,8 @@ static int compare_lebs(const struct ubi_device *ubi,
                bitflips = !!err;
        }
 
-       kfree(buf);
-       ubi_free_vid_hdr(ubi, vidh);
+       vfree(buf);
+       ubi_free_vid_hdr(ubi, vh);
 
        if (second_is_newer)
                dbg_bld("second PEB %d is newer, copy_flag is set", pnum);
@@ -390,10 +392,9 @@ static int compare_lebs(const struct ubi_device *ubi,
        return second_is_newer | (bitflips << 1) | (corrupted << 2);
 
 out_free_buf:
-       kfree(buf);
+       vfree(buf);
 out_free_vidh:
-       ubi_free_vid_hdr(ubi, vidh);
-       ubi_assert(err < 0);
+       ubi_free_vid_hdr(ubi, vh);
        return err;
 }
 
@@ -414,7 +415,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)
 {
@@ -425,10 +426,10 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si,
        struct ubi_scan_leb *seb;
        struct rb_node **p, *parent = NULL;
 
-       vol_id = ubi32_to_cpu(vid_hdr->vol_id);
-       lnum = ubi32_to_cpu(vid_hdr->lnum);
-       sqnum = ubi64_to_cpu(vid_hdr->sqnum);
-       leb_ver = ubi32_to_cpu(vid_hdr->leb_ver);
+       vol_id = be32_to_cpu(vid_hdr->vol_id);
+       lnum = be32_to_cpu(vid_hdr->lnum);
+       sqnum = be64_to_cpu(vid_hdr->sqnum);
+       leb_ver = be32_to_cpu(vid_hdr->leb_ver);
 
        dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, ver %u, bitflips %d",
                pnum, vol_id, lnum, ec, sqnum, leb_ver, bitflips);
@@ -437,6 +438,9 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si,
        if (IS_ERR(sv) < 0)
                return PTR_ERR(sv);
 
+       if (si->max_sqnum < sqnum)
+               si->max_sqnum = sqnum;
+
        /*
         * Walk the RB-tree of logical eraseblocks of volume @vol_id to look
         * if this is the first instance of this logical eraseblock or not.
@@ -523,7 +527,7 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si,
 
                        if (sv->highest_lnum == lnum)
                                sv->last_data_size =
-                                       ubi32_to_cpu(vid_hdr->data_size);
+                                       be32_to_cpu(vid_hdr->data_size);
 
                        return 0;
                } else {
@@ -560,12 +564,9 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si,
 
        if (sv->highest_lnum <= lnum) {
                sv->highest_lnum = lnum;
-               sv->last_data_size = ubi32_to_cpu(vid_hdr->data_size);
+               sv->last_data_size = be32_to_cpu(vid_hdr->data_size);
        }
 
-       if (si->max_sqnum < sqnum)
-               si->max_sqnum = sqnum;
-
        sv->leb_count += 1;
        rb_link_node(&seb->u.rb, parent, p);
        rb_insert_color(&seb->u.rb, &sv->root);
@@ -668,16 +669,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
@@ -687,7 +684,11 @@ int ubi_scan_erase_peb(const struct ubi_device *ubi,
                return -EINVAL;
        }
 
-       ec_hdr->ec = cpu_to_ubi64(ec);
+       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);
        if (err < 0)
@@ -713,7 +714,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;
@@ -772,7 +773,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);
@@ -818,7 +819,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum
                        return -EINVAL;
                }
 
-               ec = ubi64_to_cpu(ech->ec);
+               ec = be64_to_cpu(ech->ec);
                if (ec > UBI_MAX_ERASECOUNTER) {
                        /*
                         * Erase counter overflow. The EC headers have 64 bits
@@ -856,9 +857,9 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum
                goto adjust_mean_ec;
        }
 
-       vol_id = ubi32_to_cpu(vidh->vol_id);
-       if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOL_ID) {
-               int lnum = ubi32_to_cpu(vidh->lnum);
+       vol_id = be32_to_cpu(vidh->vol_id);
+       if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) {
+               int lnum = be32_to_cpu(vidh->lnum);
 
                /* Unsupported internal volume */
                switch (vidh->compat) {
@@ -949,7 +950,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;
 
@@ -1111,8 +1112,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;
@@ -1261,12 +1261,12 @@ static int paranoid_check_si(const struct ubi_device *ubi,
                                goto bad_vid_hdr;
                        }
 
-                       if (seb->sqnum != ubi64_to_cpu(vidh->sqnum)) {
+                       if (seb->sqnum != be64_to_cpu(vidh->sqnum)) {
                                ubi_err("bad sqnum %llu", seb->sqnum);
                                goto bad_vid_hdr;
                        }
 
-                       if (sv->vol_id != ubi32_to_cpu(vidh->vol_id)) {
+                       if (sv->vol_id != be32_to_cpu(vidh->vol_id)) {
                                ubi_err("bad vol_id %d", sv->vol_id);
                                goto bad_vid_hdr;
                        }
@@ -1276,22 +1276,22 @@ static int paranoid_check_si(const struct ubi_device *ubi,
                                goto bad_vid_hdr;
                        }
 
-                       if (seb->lnum != ubi32_to_cpu(vidh->lnum)) {
+                       if (seb->lnum != be32_to_cpu(vidh->lnum)) {
                                ubi_err("bad lnum %d", seb->lnum);
                                goto bad_vid_hdr;
                        }
 
-                       if (sv->used_ebs != ubi32_to_cpu(vidh->used_ebs)) {
+                       if (sv->used_ebs != be32_to_cpu(vidh->used_ebs)) {
                                ubi_err("bad used_ebs %d", sv->used_ebs);
                                goto bad_vid_hdr;
                        }
 
-                       if (sv->data_pad != ubi32_to_cpu(vidh->data_pad)) {
+                       if (sv->data_pad != be32_to_cpu(vidh->data_pad)) {
                                ubi_err("bad data_pad %d", sv->data_pad);
                                goto bad_vid_hdr;
                        }
 
-                       if (seb->leb_ver != ubi32_to_cpu(vidh->leb_ver)) {
+                       if (seb->leb_ver != be32_to_cpu(vidh->leb_ver)) {
                                ubi_err("bad leb_ver %u", seb->leb_ver);
                                goto bad_vid_hdr;
                        }
@@ -1300,12 +1300,12 @@ static int paranoid_check_si(const struct ubi_device *ubi,
                if (!last_seb)
                        continue;
 
-               if (sv->highest_lnum != ubi32_to_cpu(vidh->lnum)) {
+               if (sv->highest_lnum != be32_to_cpu(vidh->lnum)) {
                        ubi_err("bad highest_lnum %d", sv->highest_lnum);
                        goto bad_vid_hdr;
                }
 
-               if (sv->last_data_size != ubi32_to_cpu(vidh->data_size)) {
+               if (sv->last_data_size != be32_to_cpu(vidh->data_size)) {
                        ubi_err("bad last_data_size %d", sv->last_data_size);
                        goto bad_vid_hdr;
                }
@@ -1315,11 +1315,10 @@ static int paranoid_check_si(const struct ubi_device *ubi,
         * Make sure that all the physical eraseblocks are in one of the lists
         * or trees.
         */
-       buf = kmalloc(ubi->peb_count, GFP_KERNEL);
+       buf = kzalloc(ubi->peb_count, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
 
-       memset(buf, 1, ubi->peb_count);
        for (pnum = 0; pnum < ubi->peb_count; pnum++) {
                err = ubi_io_is_bad(ubi, pnum);
                if (err < 0) {
@@ -1327,28 +1326,28 @@ static int paranoid_check_si(const struct ubi_device *ubi,
                        return err;
                }
                else if (err)
-                       buf[pnum] = 0;
+                       buf[pnum] = 1;
        }
 
        ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb)
                ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb)
-                       buf[seb->pnum] = 0;
+                       buf[seb->pnum] = 1;
 
        list_for_each_entry(seb, &si->free, u.list)
-               buf[seb->pnum] = 0;
+               buf[seb->pnum] = 1;
 
        list_for_each_entry(seb, &si->corr, u.list)
-               buf[seb->pnum] = 0;
+               buf[seb->pnum] = 1;
 
        list_for_each_entry(seb, &si->erase, u.list)
-               buf[seb->pnum] = 0;
+               buf[seb->pnum] = 1;
 
        list_for_each_entry(seb, &si->alien, u.list)
-               buf[seb->pnum] = 0;
+               buf[seb->pnum] = 1;
 
        err = 0;
        for (pnum = 0; pnum < ubi->peb_count; pnum++)
-               if (buf[pnum]) {
+               if (!buf[pnum]) {
                        ubi_err("PEB %d is not referred", pnum);
                        err = 1;
                }