aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/build.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/ubi/build.c')
-rw-r--r--drivers/mtd/ubi/build.c133
1 files changed, 87 insertions, 46 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 14cec04c34f9..bc45ef9af17d 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -37,6 +37,7 @@
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/moduleparam.h> 38#include <linux/moduleparam.h>
39#include <linux/stringify.h> 39#include <linux/stringify.h>
40#include <linux/namei.h>
40#include <linux/stat.h> 41#include <linux/stat.h>
41#include <linux/miscdevice.h> 42#include <linux/miscdevice.h>
42#include <linux/log2.h> 43#include <linux/log2.h>
@@ -50,7 +51,8 @@
50 51
51/** 52/**
52 * struct mtd_dev_param - MTD device parameter description data structure. 53 * struct mtd_dev_param - MTD device parameter description data structure.
53 * @name: MTD device name or number string 54 * @name: MTD character device node path, MTD device name, or MTD device number
55 * string
54 * @vid_hdr_offs: VID header offset 56 * @vid_hdr_offs: VID header offset
55 */ 57 */
56struct mtd_dev_param { 58struct mtd_dev_param {
@@ -59,10 +61,10 @@ struct mtd_dev_param {
59}; 61};
60 62
61/* Numbers of elements set in the @mtd_dev_param array */ 63/* Numbers of elements set in the @mtd_dev_param array */
62static int mtd_devs; 64static int __initdata mtd_devs;
63 65
64/* MTD devices specification parameters */ 66/* MTD devices specification parameters */
65static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES]; 67static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES];
66 68
67/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ 69/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */
68struct class *ubi_class; 70struct class *ubi_class;
@@ -363,11 +365,13 @@ static void dev_release(struct device *dev)
363/** 365/**
364 * ubi_sysfs_init - initialize sysfs for an UBI device. 366 * ubi_sysfs_init - initialize sysfs for an UBI device.
365 * @ubi: UBI device description object 367 * @ubi: UBI device description object
368 * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was
369 * taken
366 * 370 *
367 * This function returns zero in case of success and a negative error code in 371 * This function returns zero in case of success and a negative error code in
368 * case of failure. 372 * case of failure.
369 */ 373 */
370static int ubi_sysfs_init(struct ubi_device *ubi) 374static int ubi_sysfs_init(struct ubi_device *ubi, int *ref)
371{ 375{
372 int err; 376 int err;
373 377
@@ -379,6 +383,7 @@ static int ubi_sysfs_init(struct ubi_device *ubi)
379 if (err) 383 if (err)
380 return err; 384 return err;
381 385
386 *ref = 1;
382 err = device_create_file(&ubi->dev, &dev_eraseblock_size); 387 err = device_create_file(&ubi->dev, &dev_eraseblock_size);
383 if (err) 388 if (err)
384 return err; 389 return err;
@@ -434,7 +439,7 @@ static void ubi_sysfs_close(struct ubi_device *ubi)
434} 439}
435 440
436/** 441/**
437 * kill_volumes - destroy all volumes. 442 * kill_volumes - destroy all user volumes.
438 * @ubi: UBI device description object 443 * @ubi: UBI device description object
439 */ 444 */
440static void kill_volumes(struct ubi_device *ubi) 445static void kill_volumes(struct ubi_device *ubi)
@@ -447,36 +452,29 @@ static void kill_volumes(struct ubi_device *ubi)
447} 452}
448 453
449/** 454/**
450 * free_user_volumes - free all user volumes.
451 * @ubi: UBI device description object
452 *
453 * Normally the volumes are freed at the release function of the volume device
454 * objects. However, on error paths the volumes have to be freed before the
455 * device objects have been initialized.
456 */
457static void free_user_volumes(struct ubi_device *ubi)
458{
459 int i;
460
461 for (i = 0; i < ubi->vtbl_slots; i++)
462 if (ubi->volumes[i]) {
463 kfree(ubi->volumes[i]->eba_tbl);
464 kfree(ubi->volumes[i]);
465 }
466}
467
468/**
469 * uif_init - initialize user interfaces for an UBI device. 455 * uif_init - initialize user interfaces for an UBI device.
470 * @ubi: UBI device description object 456 * @ubi: UBI device description object
457 * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was
458 * taken, otherwise set to %0
459 *
460 * This function initializes various user interfaces for an UBI device. If the
461 * initialization fails at an early stage, this function frees all the
462 * resources it allocated, returns an error, and @ref is set to %0. However,
463 * if the initialization fails after the UBI device was registered in the
464 * driver core subsystem, this function takes a reference to @ubi->dev, because
465 * otherwise the release function ('dev_release()') would free whole @ubi
466 * object. The @ref argument is set to %1 in this case. The caller has to put
467 * this reference.
471 * 468 *
472 * This function returns zero in case of success and a negative error code in 469 * This function returns zero in case of success and a negative error code in
473 * case of failure. Note, this function destroys all volumes if it fails. 470 * case of failure.
474 */ 471 */
475static int uif_init(struct ubi_device *ubi) 472static int uif_init(struct ubi_device *ubi, int *ref)
476{ 473{
477 int i, err; 474 int i, err;
478 dev_t dev; 475 dev_t dev;
479 476
477 *ref = 0;
480 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); 478 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
481 479
482 /* 480 /*
@@ -504,7 +502,7 @@ static int uif_init(struct ubi_device *ubi)
504 goto out_unreg; 502 goto out_unreg;
505 } 503 }
506 504
507 err = ubi_sysfs_init(ubi); 505 err = ubi_sysfs_init(ubi, ref);
508 if (err) 506 if (err)
509 goto out_sysfs; 507 goto out_sysfs;
510 508
@@ -522,6 +520,8 @@ static int uif_init(struct ubi_device *ubi)
522out_volumes: 520out_volumes:
523 kill_volumes(ubi); 521 kill_volumes(ubi);
524out_sysfs: 522out_sysfs:
523 if (*ref)
524 get_device(&ubi->dev);
525 ubi_sysfs_close(ubi); 525 ubi_sysfs_close(ubi);
526 cdev_del(&ubi->cdev); 526 cdev_del(&ubi->cdev);
527out_unreg: 527out_unreg:
@@ -875,7 +875,7 @@ static int ubi_reboot_notifier(struct notifier_block *n, unsigned long state,
875int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) 875int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
876{ 876{
877 struct ubi_device *ubi; 877 struct ubi_device *ubi;
878 int i, err, do_free = 1; 878 int i, err, ref = 0;
879 879
880 /* 880 /*
881 * Check if we already have the same MTD device attached. 881 * Check if we already have the same MTD device attached.
@@ -975,9 +975,9 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
975 goto out_detach; 975 goto out_detach;
976 } 976 }
977 977
978 err = uif_init(ubi); 978 err = uif_init(ubi, &ref);
979 if (err) 979 if (err)
980 goto out_nofree; 980 goto out_detach;
981 981
982 ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); 982 ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
983 if (IS_ERR(ubi->bgt_thread)) { 983 if (IS_ERR(ubi->bgt_thread)) {
@@ -1025,12 +1025,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
1025 1025
1026out_uif: 1026out_uif:
1027 uif_close(ubi); 1027 uif_close(ubi);
1028out_nofree:
1029 do_free = 0;
1030out_detach: 1028out_detach:
1031 ubi_wl_close(ubi); 1029 ubi_wl_close(ubi);
1032 if (do_free)
1033 free_user_volumes(ubi);
1034 free_internal_volumes(ubi); 1030 free_internal_volumes(ubi);
1035 vfree(ubi->vtbl); 1031 vfree(ubi->vtbl);
1036out_free: 1032out_free:
@@ -1039,7 +1035,10 @@ out_free:
1039#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID 1035#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
1040 vfree(ubi->dbg_peb_buf); 1036 vfree(ubi->dbg_peb_buf);
1041#endif 1037#endif
1042 kfree(ubi); 1038 if (ref)
1039 put_device(&ubi->dev);
1040 else
1041 kfree(ubi);
1043 return err; 1042 return err;
1044} 1043}
1045 1044
@@ -1096,7 +1095,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
1096 1095
1097 /* 1096 /*
1098 * Get a reference to the device in order to prevent 'dev_release()' 1097 * Get a reference to the device in order to prevent 'dev_release()'
1099 * from freeing @ubi object. 1098 * from freeing the @ubi object.
1100 */ 1099 */
1101 get_device(&ubi->dev); 1100 get_device(&ubi->dev);
1102 1101
@@ -1116,13 +1115,50 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
1116} 1115}
1117 1116
1118/** 1117/**
1119 * find_mtd_device - open an MTD device by its name or number. 1118 * open_mtd_by_chdev - open an MTD device by its character device node path.
1120 * @mtd_dev: name or number of the device 1119 * @mtd_dev: MTD character device node path
1120 *
1121 * This helper function opens an MTD device by its character node device path.
1122 * Returns MTD device description object in case of success and a negative
1123 * error code in case of failure.
1124 */
1125static struct mtd_info * __init open_mtd_by_chdev(const char *mtd_dev)
1126{
1127 int err, major, minor, mode;
1128 struct path path;
1129
1130 /* Probably this is an MTD character device node path */
1131 err = kern_path(mtd_dev, LOOKUP_FOLLOW, &path);
1132 if (err)
1133 return ERR_PTR(err);
1134
1135 /* MTD device number is defined by the major / minor numbers */
1136 major = imajor(path.dentry->d_inode);
1137 minor = iminor(path.dentry->d_inode);
1138 mode = path.dentry->d_inode->i_mode;
1139 path_put(&path);
1140 if (major != MTD_CHAR_MAJOR || !S_ISCHR(mode))
1141 return ERR_PTR(-EINVAL);
1142
1143 if (minor & 1)
1144 /*
1145 * Just do not think the "/dev/mtdrX" devices support is need,
1146 * so do not support them to avoid doing extra work.
1147 */
1148 return ERR_PTR(-EINVAL);
1149
1150 return get_mtd_device(NULL, minor / 2);
1151}
1152
1153/**
1154 * open_mtd_device - open MTD device by name, character device path, or number.
1155 * @mtd_dev: name, character device node path, or MTD device device number
1121 * 1156 *
1122 * This function tries to open and MTD device described by @mtd_dev string, 1157 * This function tries to open and MTD device described by @mtd_dev string,
1123 * which is first treated as an ASCII number, and if it is not true, it is 1158 * which is first treated as ASCII MTD device number, and if it is not true, it
1124 * treated as MTD device name. Returns MTD device description object in case of 1159 * is treated as MTD device name, and if that is also not true, it is treated
1125 * success and a negative error code in case of failure. 1160 * as MTD character device node path. Returns MTD device description object in
1161 * case of success and a negative error code in case of failure.
1126 */ 1162 */
1127static struct mtd_info * __init open_mtd_device(const char *mtd_dev) 1163static struct mtd_info * __init open_mtd_device(const char *mtd_dev)
1128{ 1164{
@@ -1137,6 +1173,9 @@ static struct mtd_info * __init open_mtd_device(const char *mtd_dev)
1137 * MTD device name. 1173 * MTD device name.
1138 */ 1174 */
1139 mtd = get_mtd_device_nm(mtd_dev); 1175 mtd = get_mtd_device_nm(mtd_dev);
1176 if (IS_ERR(mtd) && PTR_ERR(mtd) == -ENODEV)
1177 /* Probably this is an MTD character device node path */
1178 mtd = open_mtd_by_chdev(mtd_dev);
1140 } else 1179 } else
1141 mtd = get_mtd_device(NULL, mtd_num); 1180 mtd = get_mtd_device(NULL, mtd_num);
1142 1181
@@ -1352,13 +1391,15 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
1352 1391
1353module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000); 1392module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000);
1354MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: " 1393MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: "
1355 "mtd=<name|num>[,<vid_hdr_offs>].\n" 1394 "mtd=<name|num|path>[,<vid_hdr_offs>].\n"
1356 "Multiple \"mtd\" parameters may be specified.\n" 1395 "Multiple \"mtd\" parameters may be specified.\n"
1357 "MTD devices may be specified by their number or name.\n" 1396 "MTD devices may be specified by their number, name, or "
1397 "path to the MTD character device node.\n"
1358 "Optional \"vid_hdr_offs\" parameter specifies UBI VID " 1398 "Optional \"vid_hdr_offs\" parameter specifies UBI VID "
1359 "header position and data starting position to be used " 1399 "header position to be used by UBI.\n"
1360 "by UBI.\n" 1400 "Example 1: mtd=/dev/mtd0 - attach MTD device "
1361 "Example: mtd=content,1984 mtd=4 - attach MTD device" 1401 "/dev/mtd0.\n"
1402 "Example 2: mtd=content,1984 mtd=4 - attach MTD device "
1362 "with name \"content\" using VID header offset 1984, and " 1403 "with name \"content\" using VID header offset 1984, and "
1363 "MTD device number 4 with default VID header offset."); 1404 "MTD device number 4 with default VID header offset.");
1364 1405