]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/ubi/debug.c
ubi,ubifs: sync with linux v4.2
[u-boot] / drivers / mtd / ubi / debug.c
index 6dcc4e4844bd33a3bdaccdd3b2a564a89452fcc7..c35c85b18c68ea10f17dbcac4346f9d029d8ad2b 100644 (file)
@@ -33,12 +33,12 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
                return;
        err = mtd_read(ubi->mtd, addr, len, &read, buf);
        if (err && err != -EUCLEAN) {
-               ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes",
+               ubi_err(ubi, "err %d while reading %d bytes from PEB %d:%d, read %zd bytes",
                        err, len, pnum, offset, read);
                goto out;
        }
 
-       ubi_msg("dumping %d bytes of data from PEB %d, offset %d",
+       ubi_msg(ubi, "dumping %d bytes of data from PEB %d, offset %d",
                len, pnum, offset);
        print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1);
 out:
@@ -229,8 +229,8 @@ int ubi_debugfs_init(void)
        if (IS_ERR_OR_NULL(dfs_rootdir)) {
                int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir);
 
-               ubi_err("cannot create \"ubi\" debugfs directory, error %d\n",
-                       err);
+               pr_err("UBI error: cannot create \"ubi\" debugfs directory, error %d\n",
+                      err);
                return err;
        }
 
@@ -254,7 +254,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
        struct dentry *dent = file->f_path.dentry;
        struct ubi_device *ubi;
        struct ubi_debug_info *d;
-       char buf[3];
+       char buf[8];
        int val;
 
        ubi = ubi_get_device(ubi_num);
@@ -266,12 +266,30 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
                val = d->chk_gen;
        else if (dent == d->dfs_chk_io)
                val = d->chk_io;
+       else if (dent == d->dfs_chk_fastmap)
+               val = d->chk_fastmap;
        else if (dent == d->dfs_disable_bgt)
                val = d->disable_bgt;
        else if (dent == d->dfs_emulate_bitflips)
                val = d->emulate_bitflips;
        else if (dent == d->dfs_emulate_io_failures)
                val = d->emulate_io_failures;
+       else if (dent == d->dfs_emulate_power_cut) {
+               snprintf(buf, sizeof(buf), "%u\n", d->emulate_power_cut);
+               count = simple_read_from_buffer(user_buf, count, ppos,
+                                               buf, strlen(buf));
+               goto out;
+       } else if (dent == d->dfs_power_cut_min) {
+               snprintf(buf, sizeof(buf), "%u\n", d->power_cut_min);
+               count = simple_read_from_buffer(user_buf, count, ppos,
+                                               buf, strlen(buf));
+               goto out;
+       } else if (dent == d->dfs_power_cut_max) {
+               snprintf(buf, sizeof(buf), "%u\n", d->power_cut_max);
+               count = simple_read_from_buffer(user_buf, count, ppos,
+                                               buf, strlen(buf));
+               goto out;
+       }
        else {
                count = -EINVAL;
                goto out;
@@ -300,7 +318,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
        struct ubi_device *ubi;
        struct ubi_debug_info *d;
        size_t buf_size;
-       char buf[8];
+       char buf[8] = {0};
        int val;
 
        ubi = ubi_get_device(ubi_num);
@@ -314,6 +332,21 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
                goto out;
        }
 
+       if (dent == d->dfs_power_cut_min) {
+               if (kstrtouint(buf, 0, &d->power_cut_min) != 0)
+                       count = -EINVAL;
+               goto out;
+       } else if (dent == d->dfs_power_cut_max) {
+               if (kstrtouint(buf, 0, &d->power_cut_max) != 0)
+                       count = -EINVAL;
+               goto out;
+       } else if (dent == d->dfs_emulate_power_cut) {
+               if (kstrtoint(buf, 0, &val) != 0)
+                       count = -EINVAL;
+               d->emulate_power_cut = val;
+               goto out;
+       }
+
        if (buf[0] == '1')
                val = 1;
        else if (buf[0] == '0')
@@ -327,6 +360,8 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
                d->chk_gen = val;
        else if (dent == d->dfs_chk_io)
                d->chk_io = val;
+       else if (dent == d->dfs_chk_fastmap)
+               d->chk_fastmap = val;
        else if (dent == d->dfs_disable_bgt)
                d->disable_bgt = val;
        else if (dent == d->dfs_emulate_bitflips)
@@ -397,6 +432,13 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
                goto out_remove;
        d->dfs_chk_io = dent;
 
+       fname = "chk_fastmap";
+       dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
+                                  &dfs_fops);
+       if (IS_ERR_OR_NULL(dent))
+               goto out_remove;
+       d->dfs_chk_fastmap = dent;
+
        fname = "tst_disable_bgt";
        dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
                                   &dfs_fops);
@@ -418,13 +460,34 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
                goto out_remove;
        d->dfs_emulate_io_failures = dent;
 
+       fname = "tst_emulate_power_cut";
+       dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
+                                  &dfs_fops);
+       if (IS_ERR_OR_NULL(dent))
+               goto out_remove;
+       d->dfs_emulate_power_cut = dent;
+
+       fname = "tst_emulate_power_cut_min";
+       dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
+                                  &dfs_fops);
+       if (IS_ERR_OR_NULL(dent))
+               goto out_remove;
+       d->dfs_power_cut_min = dent;
+
+       fname = "tst_emulate_power_cut_max";
+       dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
+                                  &dfs_fops);
+       if (IS_ERR_OR_NULL(dent))
+               goto out_remove;
+       d->dfs_power_cut_max = dent;
+
        return 0;
 
 out_remove:
        debugfs_remove_recursive(d->dfs_dir);
 out:
        err = dent ? PTR_ERR(dent) : -ENODEV;
-       ubi_err("cannot create \"%s\" debugfs file or directory, error %d\n",
+       ubi_err(ubi, "cannot create \"%s\" debugfs file or directory, error %d\n",
                fname, err);
        return err;
 }
@@ -438,6 +501,39 @@ void ubi_debugfs_exit_dev(struct ubi_device *ubi)
        if (IS_ENABLED(CONFIG_DEBUG_FS))
                debugfs_remove_recursive(ubi->dbg.dfs_dir);
 }
+
+/**
+ * ubi_dbg_power_cut - emulate a power cut if it is time to do so
+ * @ubi: UBI device description object
+ * @caller: Flags set to indicate from where the function is being called
+ *
+ * Returns non-zero if a power cut was emulated, zero if not.
+ */
+int ubi_dbg_power_cut(struct ubi_device *ubi, int caller)
+{
+       unsigned int range;
+
+       if ((ubi->dbg.emulate_power_cut & caller) == 0)
+               return 0;
+
+       if (ubi->dbg.power_cut_counter == 0) {
+               ubi->dbg.power_cut_counter = ubi->dbg.power_cut_min;
+
+               if (ubi->dbg.power_cut_max > ubi->dbg.power_cut_min) {
+                       range = ubi->dbg.power_cut_max - ubi->dbg.power_cut_min;
+                       ubi->dbg.power_cut_counter += prandom_u32() % range;
+               }
+               return 0;
+       }
+
+       ubi->dbg.power_cut_counter--;
+       if (ubi->dbg.power_cut_counter)
+               return 0;
+
+       ubi_msg(ubi, "XXXXXXXXXXXXXXX emulating a power cut XXXXXXXXXXXXXXXX");
+       ubi_ro_mode(ubi);
+       return 1;
+}
 #else
 int ubi_debugfs_init(void)
 {
@@ -456,4 +552,9 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
 void ubi_debugfs_exit_dev(struct ubi_device *ubi)
 {
 }
+
+int ubi_dbg_power_cut(struct ubi_device *ubi, int caller)
+{
+       return 0;
+}
 #endif