Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 255085
b: refs/heads/master
c: 2a734bb
h: refs/heads/master
i:
  255083: 808cb98
v: v3
  • Loading branch information
Artem Bityutskiy authored and Artem Bityutskiy committed Jun 1, 2011
1 parent e66c6d6 commit 965509f
Show file tree
Hide file tree
Showing 10 changed files with 311 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d99383b00eba9c6ac3dea462d718b2849012ee03
refs/heads/master: 2a734bb8d502b645c061fa329e87c5d651498e68
26 changes: 24 additions & 2 deletions trunk/drivers/mtd/ubi/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,10 +953,14 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
if (!ubi->peb_buf2)
goto out_free;

err = ubi_debugging_init_dev(ubi);
if (err)
goto out_free;

err = attach_by_scanning(ubi);
if (err) {
dbg_err("failed to attach by scanning, error %d", err);
goto out_free;
goto out_debugging;
}

if (ubi->autoresize_vol_id != -1) {
Expand All @@ -969,12 +973,16 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
if (err)
goto out_detach;

err = ubi_debugfs_init_dev(ubi);
if (err)
goto out_uif;

ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
if (IS_ERR(ubi->bgt_thread)) {
err = PTR_ERR(ubi->bgt_thread);
ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name,
err);
goto out_uif;
goto out_debugfs;
}

ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num);
Expand Down Expand Up @@ -1008,12 +1016,16 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL);
return ubi_num;

out_debugfs:
ubi_debugfs_exit_dev(ubi);
out_uif:
uif_close(ubi);
out_detach:
ubi_wl_close(ubi);
free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_debugging:
ubi_debugging_exit_dev(ubi);
out_free:
vfree(ubi->peb_buf1);
vfree(ubi->peb_buf2);
Expand Down Expand Up @@ -1080,11 +1092,13 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
*/
get_device(&ubi->dev);

ubi_debugfs_exit_dev(ubi);
uif_close(ubi);
ubi_wl_close(ubi);
free_internal_volumes(ubi);
vfree(ubi->vtbl);
put_mtd_device(ubi->mtd);
ubi_debugging_exit_dev(ubi);
vfree(ubi->peb_buf1);
vfree(ubi->peb_buf2);
ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
Expand Down Expand Up @@ -1199,6 +1213,11 @@ static int __init ubi_init(void)
if (!ubi_wl_entry_slab)
goto out_dev_unreg;

err = ubi_debugfs_init();
if (err)
goto out_slab;


/* Attach MTD devices */
for (i = 0; i < mtd_devs; i++) {
struct mtd_dev_param *p = &mtd_dev_param[i];
Expand Down Expand Up @@ -1247,6 +1266,8 @@ static int __init ubi_init(void)
ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1);
mutex_unlock(&ubi_devices_mutex);
}
ubi_debugfs_exit();
out_slab:
kmem_cache_destroy(ubi_wl_entry_slab);
out_dev_unreg:
misc_deregister(&ubi_ctrl_cdev);
Expand All @@ -1270,6 +1291,7 @@ static void __exit ubi_exit(void)
ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1);
mutex_unlock(&ubi_devices_mutex);
}
ubi_debugfs_exit();
kmem_cache_destroy(ubi_wl_entry_slab);
misc_deregister(&ubi_ctrl_cdev);
class_remove_file(ubi_class, &ubi_version);
Expand Down
231 changes: 227 additions & 4 deletions trunk/drivers/mtd/ubi/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,15 @@
#ifdef CONFIG_MTD_UBI_DEBUG

#include "ubi.h"
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/moduleparam.h>

unsigned int ubi_chk_flags;
unsigned int ubi_tst_flags;

module_param_named(debug_chks, ubi_chk_flags, uint, S_IRUGO | S_IWUSR);
module_param_named(debug_tsts, ubi_chk_flags, uint, S_IRUGO | S_IWUSR);
module_param_named(debug_tsts, ubi_tst_flags, uint, S_IRUGO | S_IWUSR);

MODULE_PARM_DESC(debug_chks, "Debug check flags");
MODULE_PARM_DESC(debug_tsts, "Debug special test flags");

/**
Expand Down Expand Up @@ -239,4 +238,228 @@ void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
return;
}

/**
* ubi_debugging_init_dev - initialize debugging for an UBI device.
* @ubi: UBI device description object
*
* This function initializes debugging-related data for UBI device @ubi.
* Returns zero in case of success and a negative error code in case of
* failure.
*/
int ubi_debugging_init_dev(struct ubi_device *ubi)
{
ubi->dbg = kzalloc(sizeof(struct ubi_debug_info), GFP_KERNEL);
if (!ubi->dbg)
return -ENOMEM;

return 0;
}

/**
* ubi_debugging_exit_dev - free debugging data for an UBI device.
* @ubi: UBI device description object
*/
void ubi_debugging_exit_dev(struct ubi_device *ubi)
{
kfree(ubi->dbg);
}

/*
* Root directory for UBI stuff in debugfs. Contains sub-directories which
* contain the stuff specific to particular UBI devices.
*/
static struct dentry *dfs_rootdir;

/**
* ubi_debugfs_init - create UBI debugfs directory.
*
* Create UBI debugfs directory. Returns zero in case of success and a negative
* error code in case of failure.
*/
int ubi_debugfs_init(void)
{
dfs_rootdir = debugfs_create_dir("ubi", NULL);
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);
return err;
}

return 0;
}

/**
* ubi_debugfs_exit - remove UBI debugfs directory.
*/
void ubi_debugfs_exit(void)
{
debugfs_remove(dfs_rootdir);
}

/* Read an UBI debugfs file */
static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
unsigned long ubi_num = (unsigned long)file->private_data;
struct dentry *dent = file->f_path.dentry;
struct ubi_device *ubi;
struct ubi_debug_info *d;
char buf[3];
int val;

ubi = ubi_get_device(ubi_num);
if (!ubi)
return -ENODEV;
d = ubi->dbg;

if (dent == d->dfs_chk_gen)
val = d->chk_gen;
else if (dent == d->dfs_chk_io)
val = d->chk_io;
else {
count = -EINVAL;
goto out;
}

if (val)
buf[0] = '1';
else
buf[0] = '0';
buf[1] = '\n';
buf[2] = 0x00;

count = simple_read_from_buffer(user_buf, count, ppos, buf, 2);

out:
ubi_put_device(ubi);
return count;
}

/* Write an UBI debugfs file */
static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
unsigned long ubi_num = (unsigned long)file->private_data;
struct dentry *dent = file->f_path.dentry;
struct ubi_device *ubi;
struct ubi_debug_info *d;
size_t buf_size;
char buf[8];
int val;

ubi = ubi_get_device(ubi_num);
if (!ubi)
return -ENODEV;
d = ubi->dbg;

buf_size = min_t(size_t, count, (sizeof(buf) - 1));
if (copy_from_user(buf, user_buf, buf_size)) {
count = -EFAULT;
goto out;
}

if (buf[0] == '1')
val = 1;
else if (buf[0] == '0')
val = 0;
else {
count = -EINVAL;
goto out;
}

if (dent == d->dfs_chk_gen)
d->chk_gen = val;
else if (dent == d->dfs_chk_io)
d->chk_io = val;
else
count = -EINVAL;

out:
ubi_put_device(ubi);
return count;
}

static int default_open(struct inode *inode, struct file *file)
{
if (inode->i_private)
file->private_data = inode->i_private;

return 0;
}

/* File operations for all UBI debugfs files */
static const struct file_operations dfs_fops = {
.read = dfs_file_read,
.write = dfs_file_write,
.open = default_open,
.llseek = no_llseek,
.owner = THIS_MODULE,
};

/**
* ubi_debugfs_init_dev - initialize debugfs for an UBI device.
* @ubi: UBI device description object
*
* This function creates all debugfs files for UBI device @ubi. Returns zero in
* case of success and a negative error code in case of failure.
*/
int ubi_debugfs_init_dev(struct ubi_device *ubi)
{
int err, n;
unsigned long ubi_num = ubi->ubi_num;
const char *fname;
struct dentry *dent;
struct ubi_debug_info *d = ubi->dbg;

n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME,
ubi->ubi_num);
if (n == UBI_DFS_DIR_LEN) {
/* The array size is too small */
fname = UBI_DFS_DIR_NAME;
dent = ERR_PTR(-EINVAL);
goto out;
}

fname = d->dfs_dir_name;
dent = debugfs_create_dir(fname, dfs_rootdir);
if (IS_ERR_OR_NULL(dent))
goto out;
d->dfs_dir = dent;

fname = "chk_gen";
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_gen = dent;

fname = "chk_io";
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_io = 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",
fname, err);
return err;
}

/**
* dbg_debug_exit_dev - free all debugfs files corresponding to device @ubi
* @ubi: UBI device description object
*/
void ubi_debugfs_exit_dev(struct ubi_device *ubi)
{
debugfs_remove_recursive(ubi->dbg->dfs_dir);
}

#endif /* CONFIG_MTD_UBI_DEBUG */
Loading

0 comments on commit 965509f

Please sign in to comment.