diff options
| author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-05-18 07:53:05 -0400 |
|---|---|---|
| committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-06-01 04:21:47 -0400 |
| commit | 2a734bb8d502b645c061fa329e87c5d651498e68 (patch) | |
| tree | d87ee3ddd7c5ccee224044e2178aaf131407b91a /drivers/mtd | |
| parent | d99383b00eba9c6ac3dea462d718b2849012ee03 (diff) | |
UBI: use debugfs for the extra checks knobs
This patch introduces debugfs support to UBI. All the UBI stuff is kept in the
"ubi" debugfs directory, which contains per-UBI device "ubi/ubiX"
sub-directories, containing debugging files. This file also creates
"ubi/ubiX/chk_gen" and "ubi/ubiX/chk_io" knobs for switching general and I/O
extra checks on and off. And it removes the 'debug_chks' UBI module parameters.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd')
| -rw-r--r-- | drivers/mtd/ubi/build.c | 26 | ||||
| -rw-r--r-- | drivers/mtd/ubi/debug.c | 231 | ||||
| -rw-r--r-- | drivers/mtd/ubi/debug.h | 59 | ||||
| -rw-r--r-- | drivers/mtd/ubi/io.c | 14 | ||||
| -rw-r--r-- | drivers/mtd/ubi/scan.c | 2 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi.h | 4 | ||||
| -rw-r--r-- | drivers/mtd/ubi/vmt.c | 2 | ||||
| -rw-r--r-- | drivers/mtd/ubi/vtbl.c | 2 | ||||
| -rw-r--r-- | drivers/mtd/ubi/wl.c | 6 |
9 files changed, 310 insertions, 36 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 65626c1c446d..6d0d48395d8c 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
| @@ -953,10 +953,14 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
| 953 | if (!ubi->peb_buf2) | 953 | if (!ubi->peb_buf2) |
| 954 | goto out_free; | 954 | goto out_free; |
| 955 | 955 | ||
| 956 | err = ubi_debugging_init_dev(ubi); | ||
| 957 | if (err) | ||
| 958 | goto out_free; | ||
| 959 | |||
| 956 | err = attach_by_scanning(ubi); | 960 | err = attach_by_scanning(ubi); |
| 957 | if (err) { | 961 | if (err) { |
| 958 | dbg_err("failed to attach by scanning, error %d", err); | 962 | dbg_err("failed to attach by scanning, error %d", err); |
| 959 | goto out_free; | 963 | goto out_debugging; |
| 960 | } | 964 | } |
| 961 | 965 | ||
| 962 | if (ubi->autoresize_vol_id != -1) { | 966 | if (ubi->autoresize_vol_id != -1) { |
| @@ -969,12 +973,16 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
| 969 | if (err) | 973 | if (err) |
| 970 | goto out_detach; | 974 | goto out_detach; |
| 971 | 975 | ||
| 976 | err = ubi_debugfs_init_dev(ubi); | ||
| 977 | if (err) | ||
| 978 | goto out_uif; | ||
| 979 | |||
| 972 | ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); | 980 | ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); |
| 973 | if (IS_ERR(ubi->bgt_thread)) { | 981 | if (IS_ERR(ubi->bgt_thread)) { |
| 974 | err = PTR_ERR(ubi->bgt_thread); | 982 | err = PTR_ERR(ubi->bgt_thread); |
| 975 | ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name, | 983 | ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name, |
| 976 | err); | 984 | err); |
| 977 | goto out_uif; | 985 | goto out_debugfs; |
| 978 | } | 986 | } |
| 979 | 987 | ||
| 980 | ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num); | 988 | ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num); |
| @@ -1008,12 +1016,16 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
| 1008 | ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL); | 1016 | ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL); |
| 1009 | return ubi_num; | 1017 | return ubi_num; |
| 1010 | 1018 | ||
| 1019 | out_debugfs: | ||
| 1020 | ubi_debugfs_exit_dev(ubi); | ||
| 1011 | out_uif: | 1021 | out_uif: |
| 1012 | uif_close(ubi); | 1022 | uif_close(ubi); |
| 1013 | out_detach: | 1023 | out_detach: |
| 1014 | ubi_wl_close(ubi); | 1024 | ubi_wl_close(ubi); |
| 1015 | free_internal_volumes(ubi); | 1025 | free_internal_volumes(ubi); |
| 1016 | vfree(ubi->vtbl); | 1026 | vfree(ubi->vtbl); |
| 1027 | out_debugging: | ||
| 1028 | ubi_debugging_exit_dev(ubi); | ||
| 1017 | out_free: | 1029 | out_free: |
| 1018 | vfree(ubi->peb_buf1); | 1030 | vfree(ubi->peb_buf1); |
| 1019 | vfree(ubi->peb_buf2); | 1031 | vfree(ubi->peb_buf2); |
| @@ -1080,11 +1092,13 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
| 1080 | */ | 1092 | */ |
| 1081 | get_device(&ubi->dev); | 1093 | get_device(&ubi->dev); |
| 1082 | 1094 | ||
| 1095 | ubi_debugfs_exit_dev(ubi); | ||
| 1083 | uif_close(ubi); | 1096 | uif_close(ubi); |
| 1084 | ubi_wl_close(ubi); | 1097 | ubi_wl_close(ubi); |
| 1085 | free_internal_volumes(ubi); | 1098 | free_internal_volumes(ubi); |
| 1086 | vfree(ubi->vtbl); | 1099 | vfree(ubi->vtbl); |
| 1087 | put_mtd_device(ubi->mtd); | 1100 | put_mtd_device(ubi->mtd); |
| 1101 | ubi_debugging_exit_dev(ubi); | ||
| 1088 | vfree(ubi->peb_buf1); | 1102 | vfree(ubi->peb_buf1); |
| 1089 | vfree(ubi->peb_buf2); | 1103 | vfree(ubi->peb_buf2); |
| 1090 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); | 1104 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); |
| @@ -1199,6 +1213,11 @@ static int __init ubi_init(void) | |||
| 1199 | if (!ubi_wl_entry_slab) | 1213 | if (!ubi_wl_entry_slab) |
| 1200 | goto out_dev_unreg; | 1214 | goto out_dev_unreg; |
| 1201 | 1215 | ||
| 1216 | err = ubi_debugfs_init(); | ||
| 1217 | if (err) | ||
| 1218 | goto out_slab; | ||
| 1219 | |||
| 1220 | |||
| 1202 | /* Attach MTD devices */ | 1221 | /* Attach MTD devices */ |
| 1203 | for (i = 0; i < mtd_devs; i++) { | 1222 | for (i = 0; i < mtd_devs; i++) { |
| 1204 | struct mtd_dev_param *p = &mtd_dev_param[i]; | 1223 | struct mtd_dev_param *p = &mtd_dev_param[i]; |
| @@ -1247,6 +1266,8 @@ out_detach: | |||
| 1247 | ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1); | 1266 | ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1); |
| 1248 | mutex_unlock(&ubi_devices_mutex); | 1267 | mutex_unlock(&ubi_devices_mutex); |
| 1249 | } | 1268 | } |
| 1269 | ubi_debugfs_exit(); | ||
| 1270 | out_slab: | ||
| 1250 | kmem_cache_destroy(ubi_wl_entry_slab); | 1271 | kmem_cache_destroy(ubi_wl_entry_slab); |
| 1251 | out_dev_unreg: | 1272 | out_dev_unreg: |
| 1252 | misc_deregister(&ubi_ctrl_cdev); | 1273 | misc_deregister(&ubi_ctrl_cdev); |
| @@ -1270,6 +1291,7 @@ static void __exit ubi_exit(void) | |||
| 1270 | ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1); | 1291 | ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1); |
| 1271 | mutex_unlock(&ubi_devices_mutex); | 1292 | mutex_unlock(&ubi_devices_mutex); |
| 1272 | } | 1293 | } |
| 1294 | ubi_debugfs_exit(); | ||
| 1273 | kmem_cache_destroy(ubi_wl_entry_slab); | 1295 | kmem_cache_destroy(ubi_wl_entry_slab); |
| 1274 | misc_deregister(&ubi_ctrl_cdev); | 1296 | misc_deregister(&ubi_ctrl_cdev); |
| 1275 | class_remove_file(ubi_class, &ubi_version); | 1297 | class_remove_file(ubi_class, &ubi_version); |
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 2224cbe41ddf..dce1227929f1 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c | |||
| @@ -27,16 +27,15 @@ | |||
| 27 | #ifdef CONFIG_MTD_UBI_DEBUG | 27 | #ifdef CONFIG_MTD_UBI_DEBUG |
| 28 | 28 | ||
| 29 | #include "ubi.h" | 29 | #include "ubi.h" |
| 30 | #include <linux/debugfs.h> | ||
| 31 | #include <linux/uaccess.h> | ||
| 30 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 31 | #include <linux/moduleparam.h> | 33 | #include <linux/moduleparam.h> |
| 32 | 34 | ||
| 33 | unsigned int ubi_chk_flags; | ||
| 34 | unsigned int ubi_tst_flags; | 35 | unsigned int ubi_tst_flags; |
| 35 | 36 | ||
| 36 | module_param_named(debug_chks, ubi_chk_flags, uint, S_IRUGO | S_IWUSR); | 37 | module_param_named(debug_tsts, ubi_tst_flags, uint, S_IRUGO | S_IWUSR); |
| 37 | module_param_named(debug_tsts, ubi_chk_flags, uint, S_IRUGO | S_IWUSR); | ||
| 38 | 38 | ||
| 39 | MODULE_PARM_DESC(debug_chks, "Debug check flags"); | ||
| 40 | MODULE_PARM_DESC(debug_tsts, "Debug special test flags"); | 39 | MODULE_PARM_DESC(debug_tsts, "Debug special test flags"); |
| 41 | 40 | ||
| 42 | /** | 41 | /** |
| @@ -239,4 +238,228 @@ out: | |||
| 239 | return; | 238 | return; |
| 240 | } | 239 | } |
| 241 | 240 | ||
| 241 | /** | ||
| 242 | * ubi_debugging_init_dev - initialize debugging for an UBI device. | ||
| 243 | * @ubi: UBI device description object | ||
| 244 | * | ||
| 245 | * This function initializes debugging-related data for UBI device @ubi. | ||
| 246 | * Returns zero in case of success and a negative error code in case of | ||
| 247 | * failure. | ||
| 248 | */ | ||
| 249 | int ubi_debugging_init_dev(struct ubi_device *ubi) | ||
| 250 | { | ||
| 251 | ubi->dbg = kzalloc(sizeof(struct ubi_debug_info), GFP_KERNEL); | ||
| 252 | if (!ubi->dbg) | ||
| 253 | return -ENOMEM; | ||
| 254 | |||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | |||
| 258 | /** | ||
| 259 | * ubi_debugging_exit_dev - free debugging data for an UBI device. | ||
| 260 | * @ubi: UBI device description object | ||
| 261 | */ | ||
| 262 | void ubi_debugging_exit_dev(struct ubi_device *ubi) | ||
| 263 | { | ||
| 264 | kfree(ubi->dbg); | ||
| 265 | } | ||
| 266 | |||
| 267 | /* | ||
| 268 | * Root directory for UBI stuff in debugfs. Contains sub-directories which | ||
| 269 | * contain the stuff specific to particular UBI devices. | ||
| 270 | */ | ||
| 271 | static struct dentry *dfs_rootdir; | ||
| 272 | |||
| 273 | /** | ||
| 274 | * ubi_debugfs_init - create UBI debugfs directory. | ||
| 275 | * | ||
| 276 | * Create UBI debugfs directory. Returns zero in case of success and a negative | ||
| 277 | * error code in case of failure. | ||
| 278 | */ | ||
| 279 | int ubi_debugfs_init(void) | ||
| 280 | { | ||
| 281 | dfs_rootdir = debugfs_create_dir("ubi", NULL); | ||
| 282 | if (IS_ERR_OR_NULL(dfs_rootdir)) { | ||
| 283 | int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir); | ||
| 284 | |||
| 285 | ubi_err("cannot create \"ubi\" debugfs directory, error %d\n", | ||
| 286 | err); | ||
| 287 | return err; | ||
| 288 | } | ||
| 289 | |||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | |||
| 293 | /** | ||
| 294 | * ubi_debugfs_exit - remove UBI debugfs directory. | ||
| 295 | */ | ||
| 296 | void ubi_debugfs_exit(void) | ||
| 297 | { | ||
| 298 | debugfs_remove(dfs_rootdir); | ||
| 299 | } | ||
| 300 | |||
| 301 | /* Read an UBI debugfs file */ | ||
| 302 | static ssize_t dfs_file_read(struct file *file, char __user *user_buf, | ||
| 303 | size_t count, loff_t *ppos) | ||
| 304 | { | ||
| 305 | unsigned long ubi_num = (unsigned long)file->private_data; | ||
| 306 | struct dentry *dent = file->f_path.dentry; | ||
| 307 | struct ubi_device *ubi; | ||
| 308 | struct ubi_debug_info *d; | ||
| 309 | char buf[3]; | ||
| 310 | int val; | ||
| 311 | |||
| 312 | ubi = ubi_get_device(ubi_num); | ||
| 313 | if (!ubi) | ||
| 314 | return -ENODEV; | ||
| 315 | d = ubi->dbg; | ||
| 316 | |||
| 317 | if (dent == d->dfs_chk_gen) | ||
| 318 | val = d->chk_gen; | ||
| 319 | else if (dent == d->dfs_chk_io) | ||
| 320 | val = d->chk_io; | ||
| 321 | else { | ||
| 322 | count = -EINVAL; | ||
| 323 | goto out; | ||
| 324 | } | ||
| 325 | |||
| 326 | if (val) | ||
| 327 | buf[0] = '1'; | ||
| 328 | else | ||
| 329 | buf[0] = '0'; | ||
| 330 | buf[1] = '\n'; | ||
| 331 | buf[2] = 0x00; | ||
| 332 | |||
| 333 | count = simple_read_from_buffer(user_buf, count, ppos, buf, 2); | ||
| 334 | |||
| 335 | out: | ||
| 336 | ubi_put_device(ubi); | ||
| 337 | return count; | ||
| 338 | } | ||
| 339 | |||
| 340 | /* Write an UBI debugfs file */ | ||
| 341 | static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, | ||
| 342 | size_t count, loff_t *ppos) | ||
| 343 | { | ||
| 344 | unsigned long ubi_num = (unsigned long)file->private_data; | ||
| 345 | struct dentry *dent = file->f_path.dentry; | ||
| 346 | struct ubi_device *ubi; | ||
| 347 | struct ubi_debug_info *d; | ||
| 348 | size_t buf_size; | ||
| 349 | char buf[8]; | ||
| 350 | int val; | ||
| 351 | |||
| 352 | ubi = ubi_get_device(ubi_num); | ||
| 353 | if (!ubi) | ||
| 354 | return -ENODEV; | ||
| 355 | d = ubi->dbg; | ||
| 356 | |||
| 357 | buf_size = min_t(size_t, count, (sizeof(buf) - 1)); | ||
| 358 | if (copy_from_user(buf, user_buf, buf_size)) { | ||
| 359 | count = -EFAULT; | ||
| 360 | goto out; | ||
| 361 | } | ||
| 362 | |||
| 363 | if (buf[0] == '1') | ||
| 364 | val = 1; | ||
| 365 | else if (buf[0] == '0') | ||
| 366 | val = 0; | ||
| 367 | else { | ||
| 368 | count = -EINVAL; | ||
| 369 | goto out; | ||
| 370 | } | ||
| 371 | |||
| 372 | if (dent == d->dfs_chk_gen) | ||
| 373 | d->chk_gen = val; | ||
| 374 | else if (dent == d->dfs_chk_io) | ||
| 375 | d->chk_io = val; | ||
| 376 | else | ||
| 377 | count = -EINVAL; | ||
| 378 | |||
| 379 | out: | ||
| 380 | ubi_put_device(ubi); | ||
| 381 | return count; | ||
| 382 | } | ||
| 383 | |||
| 384 | static int default_open(struct inode *inode, struct file *file) | ||
| 385 | { | ||
| 386 | if (inode->i_private) | ||
| 387 | file->private_data = inode->i_private; | ||
| 388 | |||
| 389 | return 0; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* File operations for all UBI debugfs files */ | ||
| 393 | static const struct file_operations dfs_fops = { | ||
| 394 | .read = dfs_file_read, | ||
| 395 | .write = dfs_file_write, | ||
| 396 | .open = default_open, | ||
| 397 | .llseek = no_llseek, | ||
| 398 | .owner = THIS_MODULE, | ||
| 399 | }; | ||
| 400 | |||
| 401 | /** | ||
| 402 | * ubi_debugfs_init_dev - initialize debugfs for an UBI device. | ||
| 403 | * @ubi: UBI device description object | ||
| 404 | * | ||
| 405 | * This function creates all debugfs files for UBI device @ubi. Returns zero in | ||
| 406 | * case of success and a negative error code in case of failure. | ||
| 407 | */ | ||
| 408 | int ubi_debugfs_init_dev(struct ubi_device *ubi) | ||
| 409 | { | ||
| 410 | int err, n; | ||
| 411 | unsigned long ubi_num = ubi->ubi_num; | ||
| 412 | const char *fname; | ||
| 413 | struct dentry *dent; | ||
| 414 | struct ubi_debug_info *d = ubi->dbg; | ||
| 415 | |||
| 416 | n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, | ||
| 417 | ubi->ubi_num); | ||
| 418 | if (n == UBI_DFS_DIR_LEN) { | ||
| 419 | /* The array size is too small */ | ||
| 420 | fname = UBI_DFS_DIR_NAME; | ||
| 421 | dent = ERR_PTR(-EINVAL); | ||
| 422 | goto out; | ||
| 423 | } | ||
| 424 | |||
| 425 | fname = d->dfs_dir_name; | ||
| 426 | dent = debugfs_create_dir(fname, dfs_rootdir); | ||
| 427 | if (IS_ERR_OR_NULL(dent)) | ||
| 428 | goto out; | ||
| 429 | d->dfs_dir = dent; | ||
| 430 | |||
| 431 | fname = "chk_gen"; | ||
| 432 | dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, | ||
| 433 | &dfs_fops); | ||
| 434 | if (IS_ERR_OR_NULL(dent)) | ||
| 435 | goto out_remove; | ||
| 436 | d->dfs_chk_gen = dent; | ||
| 437 | |||
| 438 | fname = "chk_io"; | ||
| 439 | dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, | ||
| 440 | &dfs_fops); | ||
| 441 | if (IS_ERR_OR_NULL(dent)) | ||
| 442 | goto out_remove; | ||
| 443 | d->dfs_chk_io = dent; | ||
| 444 | |||
| 445 | return 0; | ||
| 446 | |||
| 447 | out_remove: | ||
| 448 | debugfs_remove_recursive(d->dfs_dir); | ||
| 449 | out: | ||
| 450 | err = dent ? PTR_ERR(dent) : -ENODEV; | ||
| 451 | ubi_err("cannot create \"%s\" debugfs file or directory, error %d\n", | ||
| 452 | fname, err); | ||
| 453 | return err; | ||
| 454 | } | ||
| 455 | |||
| 456 | /** | ||
| 457 | * dbg_debug_exit_dev - free all debugfs files corresponding to device @ubi | ||
| 458 | * @ubi: UBI device description object | ||
| 459 | */ | ||
| 460 | void ubi_debugfs_exit_dev(struct ubi_device *ubi) | ||
| 461 | { | ||
| 462 | debugfs_remove_recursive(ubi->dbg->dfs_dir); | ||
| 463 | } | ||
| 464 | |||
| 242 | #endif /* CONFIG_MTD_UBI_DEBUG */ | 465 | #endif /* CONFIG_MTD_UBI_DEBUG */ |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 3f1a09c5c438..cb6c87977be6 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h | |||
| @@ -71,24 +71,42 @@ void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); | |||
| 71 | void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); | 71 | void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); |
| 72 | void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); | 72 | void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); |
| 73 | void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); | 73 | void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); |
| 74 | 74 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); | |
| 75 | extern unsigned int ubi_chk_flags; | 75 | int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, |
| 76 | int offset, int len); | ||
| 77 | int ubi_debugging_init_dev(struct ubi_device *ubi); | ||
| 78 | void ubi_debugging_exit_dev(struct ubi_device *ubi); | ||
| 79 | int ubi_debugfs_init(void); | ||
| 80 | void ubi_debugfs_exit(void); | ||
| 81 | int ubi_debugfs_init_dev(struct ubi_device *ubi); | ||
| 82 | void ubi_debugfs_exit_dev(struct ubi_device *ubi); | ||
| 76 | 83 | ||
| 77 | /* | 84 | /* |
| 78 | * Debugging check flags. | 85 | * The UBI debugfs directory name pattern and maximum name length (3 for "ubi" |
| 86 | * + 2 for the number plus 1 for the trailing zero byte. | ||
| 87 | */ | ||
| 88 | #define UBI_DFS_DIR_NAME "ubi%d" | ||
| 89 | #define UBI_DFS_DIR_LEN (3 + 2 + 1) | ||
| 90 | |||
| 91 | /** | ||
| 92 | * struct ubi_debug_info - debugging information for an UBI device. | ||
| 79 | * | 93 | * |
| 80 | * UBI_CHK_GEN: general checks | 94 | * @chk_gen: if UBI general extra checks are enabled |
| 81 | * UBI_CHK_IO: check writes and erases | 95 | * @chk_io: if UBI I/O extra checks are enabled |
| 96 | * @dfs_dir_name: name of debugfs directory containing files of this UBI device | ||
| 97 | * @dfs_dir: direntry object of the UBI device debugfs directory | ||
| 98 | * @dfs_chk_gen: debugfs knob to enable UBI general extra checks | ||
| 99 | * @dfs_chk_io: debugfs knob to enable UBI I/O extra checks | ||
| 82 | */ | 100 | */ |
| 83 | enum { | 101 | struct ubi_debug_info { |
| 84 | UBI_CHK_GEN = 0x1, | 102 | unsigned int chk_gen:1; |
| 85 | UBI_CHK_IO = 0x2, | 103 | unsigned int chk_io:1; |
| 104 | char dfs_dir_name[UBI_DFS_DIR_LEN + 1]; | ||
| 105 | struct dentry *dfs_dir; | ||
| 106 | struct dentry *dfs_chk_gen; | ||
| 107 | struct dentry *dfs_chk_io; | ||
| 86 | }; | 108 | }; |
| 87 | 109 | ||
| 88 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); | ||
| 89 | int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, | ||
| 90 | int offset, int len); | ||
| 91 | |||
| 92 | extern unsigned int ubi_tst_flags; | 110 | extern unsigned int ubi_tst_flags; |
| 93 | 111 | ||
| 94 | /* | 112 | /* |
| @@ -201,11 +219,6 @@ static inline void ubi_dbg_dump_flash(struct ubi_device *ubi, | |||
| 201 | static inline void | 219 | static inline void |
| 202 | ubi_dbg_print_hex_dump(const char *l, const char *ps, int pt, int r, | 220 | ubi_dbg_print_hex_dump(const char *l, const char *ps, int pt, int r, |
| 203 | int g, const void *b, size_t len, bool a) { return; } | 221 | int g, const void *b, size_t len, bool a) { return; } |
| 204 | |||
| 205 | static inline int ubi_dbg_is_bgt_disabled(void) { return 0; } | ||
| 206 | static inline int ubi_dbg_is_bitflip(void) { return 0; } | ||
| 207 | static inline int ubi_dbg_is_write_failure(void) { return 0; } | ||
| 208 | static inline int ubi_dbg_is_erase_failure(void) { return 0; } | ||
| 209 | static inline int ubi_dbg_check_all_ff(struct ubi_device *ubi, | 222 | static inline int ubi_dbg_check_all_ff(struct ubi_device *ubi, |
| 210 | int pnum, int offset, | 223 | int pnum, int offset, |
| 211 | int len) { return 0; } | 224 | int len) { return 0; } |
| @@ -213,5 +226,17 @@ static inline int ubi_dbg_check_write(struct ubi_device *ubi, | |||
| 213 | const void *buf, int pnum, | 226 | const void *buf, int pnum, |
| 214 | int offset, int len) { return 0; } | 227 | int offset, int len) { return 0; } |
| 215 | 228 | ||
| 229 | static inline int ubi_debugging_init_dev(struct ubi_device *ubi) { return 0; } | ||
| 230 | static inline void ubi_debugging_exit_dev(struct ubi_device *ubi) { return; } | ||
| 231 | static inline int ubi_debugfs_init(void) { return 0; } | ||
| 232 | static inline void ubi_debugfs_exit(void) { return; } | ||
| 233 | static inline int ubi_debugfs_init_dev(struct ubi_device *ubi) { return 0; } | ||
| 234 | static inline void ubi_debugfs_exit_dev(struct ubi_device *ubi) { return; } | ||
| 235 | |||
| 236 | static inline int ubi_dbg_is_bgt_disabled(void) { return 0; } | ||
| 237 | static inline int ubi_dbg_is_bitflip(void) { return 0; } | ||
| 238 | static inline int ubi_dbg_is_write_failure(void) { return 0; } | ||
| 239 | static inline int ubi_dbg_is_erase_failure(void) { return 0; } | ||
| 240 | |||
| 216 | #endif /* !CONFIG_MTD_UBI_DEBUG */ | 241 | #endif /* !CONFIG_MTD_UBI_DEBUG */ |
| 217 | #endif /* !__UBI_DEBUG_H__ */ | 242 | #endif /* !__UBI_DEBUG_H__ */ |
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 8c1b1c7bc4a7..e23d6118224f 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
| @@ -1146,7 +1146,7 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) | |||
| 1146 | { | 1146 | { |
| 1147 | int err; | 1147 | int err; |
| 1148 | 1148 | ||
| 1149 | if (!(ubi_chk_flags & UBI_CHK_IO)) | 1149 | if (!ubi->dbg->chk_io) |
| 1150 | return 0; | 1150 | return 0; |
| 1151 | 1151 | ||
| 1152 | err = ubi_io_is_bad(ubi, pnum); | 1152 | err = ubi_io_is_bad(ubi, pnum); |
| @@ -1173,7 +1173,7 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
| 1173 | int err; | 1173 | int err; |
| 1174 | uint32_t magic; | 1174 | uint32_t magic; |
| 1175 | 1175 | ||
| 1176 | if (!(ubi_chk_flags & UBI_CHK_IO)) | 1176 | if (!ubi->dbg->chk_io) |
| 1177 | return 0; | 1177 | return 0; |
| 1178 | 1178 | ||
| 1179 | magic = be32_to_cpu(ec_hdr->magic); | 1179 | magic = be32_to_cpu(ec_hdr->magic); |
| @@ -1211,7 +1211,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) | |||
| 1211 | uint32_t crc, hdr_crc; | 1211 | uint32_t crc, hdr_crc; |
| 1212 | struct ubi_ec_hdr *ec_hdr; | 1212 | struct ubi_ec_hdr *ec_hdr; |
| 1213 | 1213 | ||
| 1214 | if (!(ubi_chk_flags & UBI_CHK_IO)) | 1214 | if (!ubi->dbg->chk_io) |
| 1215 | return 0; | 1215 | return 0; |
| 1216 | 1216 | ||
| 1217 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); | 1217 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
| @@ -1255,7 +1255,7 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
| 1255 | int err; | 1255 | int err; |
| 1256 | uint32_t magic; | 1256 | uint32_t magic; |
| 1257 | 1257 | ||
| 1258 | if (!(ubi_chk_flags & UBI_CHK_IO)) | 1258 | if (!ubi->dbg->chk_io) |
| 1259 | return 0; | 1259 | return 0; |
| 1260 | 1260 | ||
| 1261 | magic = be32_to_cpu(vid_hdr->magic); | 1261 | magic = be32_to_cpu(vid_hdr->magic); |
| @@ -1296,7 +1296,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) | |||
| 1296 | struct ubi_vid_hdr *vid_hdr; | 1296 | struct ubi_vid_hdr *vid_hdr; |
| 1297 | void *p; | 1297 | void *p; |
| 1298 | 1298 | ||
| 1299 | if (!(ubi_chk_flags & UBI_CHK_IO)) | 1299 | if (!ubi->dbg->chk_io) |
| 1300 | return 0; | 1300 | return 0; |
| 1301 | 1301 | ||
| 1302 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); | 1302 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
| @@ -1348,7 +1348,7 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, | |||
| 1348 | void *buf1; | 1348 | void *buf1; |
| 1349 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | 1349 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; |
| 1350 | 1350 | ||
| 1351 | if (!(ubi_chk_flags & UBI_CHK_IO)) | 1351 | if (!ubi->dbg->chk_io) |
| 1352 | return 0; | 1352 | return 0; |
| 1353 | 1353 | ||
| 1354 | buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); | 1354 | buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); |
| @@ -1412,7 +1412,7 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) | |||
| 1412 | void *buf; | 1412 | void *buf; |
| 1413 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | 1413 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; |
| 1414 | 1414 | ||
| 1415 | if (!(ubi_chk_flags & UBI_CHK_IO)) | 1415 | if (!ubi->dbg->chk_io) |
| 1416 | return 0; | 1416 | return 0; |
| 1417 | 1417 | ||
| 1418 | buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); | 1418 | buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 2135a53732ff..a3a198f9b98d 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
| @@ -1347,7 +1347,7 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
| 1347 | struct ubi_scan_leb *seb, *last_seb; | 1347 | struct ubi_scan_leb *seb, *last_seb; |
| 1348 | uint8_t *buf; | 1348 | uint8_t *buf; |
| 1349 | 1349 | ||
| 1350 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | 1350 | if (!ubi->dbg->chk_gen) |
| 1351 | return 0; | 1351 | return 0; |
| 1352 | 1352 | ||
| 1353 | /* | 1353 | /* |
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index c6c22295898e..d0e321885fd6 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
| @@ -390,6 +390,8 @@ struct ubi_wl_entry; | |||
| 390 | * @peb_buf2: another buffer of PEB size used for different purposes | 390 | * @peb_buf2: another buffer of PEB size used for different purposes |
| 391 | * @buf_mutex: protects @peb_buf1 and @peb_buf2 | 391 | * @buf_mutex: protects @peb_buf1 and @peb_buf2 |
| 392 | * @ckvol_mutex: serializes static volume checking when opening | 392 | * @ckvol_mutex: serializes static volume checking when opening |
| 393 | * | ||
| 394 | * @dbg: debugging information for this UBI device | ||
| 393 | */ | 395 | */ |
| 394 | struct ubi_device { | 396 | struct ubi_device { |
| 395 | struct cdev cdev; | 397 | struct cdev cdev; |
| @@ -472,6 +474,8 @@ struct ubi_device { | |||
| 472 | void *peb_buf2; | 474 | void *peb_buf2; |
| 473 | struct mutex buf_mutex; | 475 | struct mutex buf_mutex; |
| 474 | struct mutex ckvol_mutex; | 476 | struct mutex ckvol_mutex; |
| 477 | |||
| 478 | struct ubi_debug_info *dbg; | ||
| 475 | }; | 479 | }; |
| 476 | 480 | ||
| 477 | extern struct kmem_cache *ubi_wl_entry_slab; | 481 | extern struct kmem_cache *ubi_wl_entry_slab; |
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 366eb70219a6..97e093d19672 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c | |||
| @@ -871,7 +871,7 @@ static int paranoid_check_volumes(struct ubi_device *ubi) | |||
| 871 | { | 871 | { |
| 872 | int i, err = 0; | 872 | int i, err = 0; |
| 873 | 873 | ||
| 874 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | 874 | if (!ubi->dbg->chk_gen) |
| 875 | return 0; | 875 | return 0; |
| 876 | 876 | ||
| 877 | for (i = 0; i < ubi->vtbl_slots; i++) { | 877 | for (i = 0; i < ubi->vtbl_slots; i++) { |
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index fd3bf770f518..d704ad275932 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
| @@ -876,7 +876,7 @@ out_free: | |||
| 876 | */ | 876 | */ |
| 877 | static void paranoid_vtbl_check(const struct ubi_device *ubi) | 877 | static void paranoid_vtbl_check(const struct ubi_device *ubi) |
| 878 | { | 878 | { |
| 879 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | 879 | if (!ubi->dbg->chk_gen) |
| 880 | return; | 880 | return; |
| 881 | 881 | ||
| 882 | if (vtbl_check(ubi, ubi->vtbl)) { | 882 | if (vtbl_check(ubi, ubi->vtbl)) { |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index d5076d2cce39..bf13ca275f85 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -1582,7 +1582,7 @@ static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) | |||
| 1582 | long long read_ec; | 1582 | long long read_ec; |
| 1583 | struct ubi_ec_hdr *ec_hdr; | 1583 | struct ubi_ec_hdr *ec_hdr; |
| 1584 | 1584 | ||
| 1585 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | 1585 | if (!ubi->dbg->chk_gen) |
| 1586 | return 0; | 1586 | return 0; |
| 1587 | 1587 | ||
| 1588 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); | 1588 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
| @@ -1623,7 +1623,7 @@ static int paranoid_check_in_wl_tree(const struct ubi_device *ubi, | |||
| 1623 | struct ubi_wl_entry *e, | 1623 | struct ubi_wl_entry *e, |
| 1624 | struct rb_root *root) | 1624 | struct rb_root *root) |
| 1625 | { | 1625 | { |
| 1626 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | 1626 | if (!ubi->dbg->chk_gen) |
| 1627 | return 0; | 1627 | return 0; |
| 1628 | 1628 | ||
| 1629 | if (in_wl_tree(e, root)) | 1629 | if (in_wl_tree(e, root)) |
| @@ -1649,7 +1649,7 @@ static int paranoid_check_in_pq(const struct ubi_device *ubi, | |||
| 1649 | struct ubi_wl_entry *p; | 1649 | struct ubi_wl_entry *p; |
| 1650 | int i; | 1650 | int i; |
| 1651 | 1651 | ||
| 1652 | if (!(ubi_chk_flags & UBI_CHK_GEN)) | 1652 | if (!ubi->dbg->chk_gen) |
| 1653 | return 0; | 1653 | return 0; |
| 1654 | 1654 | ||
| 1655 | for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) | 1655 | for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) |
