diff options
| author | Heiko Schocher <hs@denx.de> | 2015-10-22 06:19:21 +0200 | 
|---|---|---|
| committer | Heiko Schocher <hs@denx.de> | 2015-10-26 09:22:36 +0100 | 
| commit | 0195a7bb36a0abc71145da419001377bf56662fd (patch) | |
| tree | bca19320118d4cbeb770d94f6b1e9d3ad91dc151 /drivers/mtd/ubi/debug.c | |
| parent | 5219db8ae802210730b348a888474efc2f9bf0a4 (diff) | |
ubi,ubifs: sync with linux v4.2
sync with linux v4.2
commit 64291f7db5bd8150a74ad2036f1037e6a0428df2
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sun Aug 30 11:34:09 2015 -0700
    Linux 4.2
This update is needed, as it turned out, that fastmap
was in experimental/broken state in kernel v3.15, which
was the last base for U-Boot.
Signed-off-by: Heiko Schocher <hs@denx.de>
Tested-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Diffstat (limited to 'drivers/mtd/ubi/debug.c')
| -rw-r--r-- | drivers/mtd/ubi/debug.c | 115 | 
1 files changed, 108 insertions, 7 deletions
| diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 6dcc4e4844b..c35c85b18c6 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -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 | 
