import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / mtd / ubi / vtbl.c
index d77b1c1d7c7267c3186635497eeba492f539d735..faf253c3f2ea7ee4ad0fa0442be0e7e0ad9b7093 100644 (file)
@@ -60,6 +60,9 @@
 #include <linux/slab.h>
 #include <asm/div64.h>
 #include "ubi.h"
+#ifdef CONFIG_PWR_LOSS_MTK_SPOH
+#include <mach/power_loss_test.h>
+#endif
 
 static void self_vtbl_check(const struct ubi_device *ubi);
 
@@ -99,6 +102,16 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
                err = ubi_eba_unmap_leb(ubi, layout_vol, i);
                if (err)
                        return err;
+#ifdef CONFIG_PWR_LOSS_MTK_SPOH
+        if(i==0)
+        {
+            PL_RESET_ON_CASE("NAND", "CreateVol_1");
+        }
+        else if(i==1)
+        {
+            PL_RESET_ON_CASE("NAND", "CreateVol_2");
+        }
+#endif
 
                err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
                                        ubi->vtbl_size);
@@ -151,6 +164,16 @@ int ubi_vtbl_rename_volumes(struct ubi_device *ubi,
                err = ubi_eba_unmap_leb(ubi, layout_vol, i);
                if (err)
                        return err;
+#ifdef CONFIG_PWR_LOSS_MTK_SPOH
+        if(i==0)
+        {
+            PL_RESET_ON_CASE("NAND", "ModifyVol_1");
+        }
+        else if(i==1)
+        {
+            PL_RESET_ON_CASE("NAND", "ModifyVol_2");
+        }
+#endif
 
                err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0,
                                        ubi->vtbl_size);
@@ -409,7 +432,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
 
        /* Read both LEB 0 and LEB 1 into memory */
        ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) {
-               leb[aeb->lnum] = vzalloc(ubi->vtbl_size);
+               leb[aeb->lnum] = kmalloc(ubi->vtbl_size, GFP_KERNEL);
                if (!leb[aeb->lnum]) {
                        err = -ENOMEM;
                        goto out_free;
@@ -454,7 +477,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
                }
 
                /* Both LEB 1 and LEB 2 are OK and consistent */
-               vfree(leb[1]);
+               kfree(leb[1]);
                return leb[0];
        } else {
                /* LEB 0 is corrupted or does not exist */
@@ -475,13 +498,13 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
                        goto out_free;
                ubi_msg("volume table was restored");
 
-               vfree(leb[0]);
+               kfree(leb[0]);
                return leb[1];
        }
 
 out_free:
-       vfree(leb[0]);
-       vfree(leb[1]);
+       kfree(leb[0]);
+       kfree(leb[1]);
        return ERR_PTR(err);
 }
 
@@ -499,7 +522,7 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi,
        int i;
        struct ubi_vtbl_record *vtbl;
 
-       vtbl = vzalloc(ubi->vtbl_size);
+       vtbl = kmalloc(ubi->vtbl_size, GFP_KERNEL);
        if (!vtbl)
                return ERR_PTR(-ENOMEM);
 
@@ -511,7 +534,7 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi,
 
                err = create_vtbl(ubi, ai, i, vtbl);
                if (err) {
-                       vfree(vtbl);
+                       kfree(vtbl);
                        return ERR_PTR(err);
                }
        }
@@ -645,6 +668,33 @@ static int init_volumes(struct ubi_device *ubi,
        ubi->vol_count += 1;
        vol->ubi = ubi;
 
+#ifdef CONFIG_BLB
+       /* And add the backup volume */
+       vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL);
+       if (!vol)
+               return -ENOMEM;
+
+       vol->reserved_pebs = UBI_BACKUP_VOLUME_EBS;
+       vol->alignment = 1;
+       vol->vol_type = UBI_DYNAMIC_VOLUME;
+       vol->name_len = sizeof(UBI_BACKUP_VOLUME_NAME) - 1;
+       memcpy(vol->name, UBI_BACKUP_VOLUME_NAME, vol->name_len + 1);
+       vol->usable_leb_size = ubi->leb_size;
+       vol->used_ebs = vol->reserved_pebs;
+       vol->last_eb_bytes = vol->reserved_pebs;
+       vol->used_bytes =
+               (long long)vol->used_ebs * (ubi->leb_size - vol->data_pad);
+       vol->vol_id = UBI_BACKUP_VOLUME_ID;
+       vol->ref_count = 1;
+
+       ubi_assert(!ubi->volumes[vol_id2idx(ubi, vol->vol_id)]);
+       ubi->volumes[vol_id2idx(ubi, vol->vol_id)] = vol;
+       reserved_pebs += vol->reserved_pebs;
+       ubi->vol_count += 1;
+       vol->ubi = ubi;
+#endif
+
+
        if (reserved_pebs > ubi->avail_pebs) {
                ubi_err("not enough PEBs, required %d, available %d",
                        reserved_pebs, ubi->avail_pebs);
@@ -844,7 +894,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai)
        return 0;
 
 out_free:
-       vfree(ubi->vtbl);
+       kfree(ubi->vtbl);
        for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
                kfree(ubi->volumes[i]);
                ubi->volumes[i] = NULL;