aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-12-16 09:59:31 -0500
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-12-26 12:15:17 -0500
commit9f961b57568960a150cc9781c52824c9093a0514 (patch)
tree345d60347d63bdc9973a2447d84024776b73dd2f
parent16f557ecbf96dd13d13788a6f62d4d97ae73b1f9 (diff)
UBI: add UBI control device
This patch is a preparation to make UBI devices dynamic. It adds an UBI control device which has dynamically allocated major number and registers itself as "ubi_ctrl". It does not do anything so far. The idea is that this device will allow to attach/detach MTD devices from userspace. This is symilar to what the Linux device mapper has. The next things to do are: * Fix UBI, because it now assumes UBI devices cannot go away * Implement control device ioctls which will attach/detach MTD devices Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--drivers/mtd/ubi/build.c52
-rw-r--r--drivers/mtd/ubi/cdev.c10
-rw-r--r--drivers/mtd/ubi/ubi.h3
3 files changed, 54 insertions, 11 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index b3efb2fa3c10..3f37b16f8774 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -21,11 +21,16 @@
21 */ 21 */
22 22
23/* 23/*
24 * This file includes UBI initialization and building of UBI devices. At the 24 * This file includes UBI initialization and building of UBI devices.
25 * moment UBI devices may only be added while UBI is initialized, but dynamic 25 *
26 * device add/remove functionality is planned. Also, at the moment we only 26 * When UBI is initialized, it attaches all the MTD devices specified as the
27 * attach UBI devices by scanning, which will become a bottleneck when flashes 27 * module load parameters or the kernel boot parameters. If MTD devices were
28 * reach certain large size. Then one may improve UBI and add other methods. 28 * specified, UBI does not attach any MTD device, but it is possible to do
29 * later using the "UBI control device".
30 *
31 * At the moment we only attach UBI devices by scanning, which will become a
32 * bottleneck when flashes reach certain large size. Then one may improve UBI
33 * and add other methods, although it does not seem to be easy to do.
29 */ 34 */
30 35
31#include <linux/err.h> 36#include <linux/err.h>
@@ -33,6 +38,7 @@
33#include <linux/moduleparam.h> 38#include <linux/moduleparam.h>
34#include <linux/stringify.h> 39#include <linux/stringify.h>
35#include <linux/stat.h> 40#include <linux/stat.h>
41#include <linux/miscdevice.h>
36#include <linux/log2.h> 42#include <linux/log2.h>
37#include "ubi.h" 43#include "ubi.h"
38 44
@@ -70,6 +76,12 @@ struct kmem_cache *ubi_ltree_slab;
70/* Slab cache for wear-leveling entries */ 76/* Slab cache for wear-leveling entries */
71struct kmem_cache *ubi_wl_entry_slab; 77struct kmem_cache *ubi_wl_entry_slab;
72 78
79/* UBI control character device */
80static struct miscdevice ubi_ctrl_cdev = {
81 .minor = MISC_DYNAMIC_MINOR,
82 .name = "ubi_ctrl",
83 .fops = &ubi_ctrl_cdev_operations,
84};
73 85
74/* "Show" method for files in '/<sysfs>/class/ubi/' */ 86/* "Show" method for files in '/<sysfs>/class/ubi/' */
75static ssize_t ubi_version_show(struct class *class, char *buf) 87static ssize_t ubi_version_show(struct class *class, char *buf)
@@ -701,19 +713,31 @@ static int __init ubi_init(void)
701 return -EINVAL; 713 return -EINVAL;
702 } 714 }
703 715
716 /* Create base sysfs directory and sysfs files */
704 ubi_class = class_create(THIS_MODULE, UBI_NAME_STR); 717 ubi_class = class_create(THIS_MODULE, UBI_NAME_STR);
705 if (IS_ERR(ubi_class)) 718 if (IS_ERR(ubi_class)) {
706 return PTR_ERR(ubi_class); 719 err = PTR_ERR(ubi_class);
720 printk(KERN_ERR "UBI error: cannot create UBI class\n");
721 goto out;
722 }
707 723
708 err = class_create_file(ubi_class, &ubi_version); 724 err = class_create_file(ubi_class, &ubi_version);
709 if (err) 725 if (err) {
726 printk(KERN_ERR "UBI error: cannot create sysfs file\n");
710 goto out_class; 727 goto out_class;
728 }
729
730 err = misc_register(&ubi_ctrl_cdev);
731 if (err) {
732 printk(KERN_ERR "UBI error: cannot register device\n");
733 goto out_version;
734 }
711 735
712 ubi_ltree_slab = kmem_cache_create("ubi_ltree_slab", 736 ubi_ltree_slab = kmem_cache_create("ubi_ltree_slab",
713 sizeof(struct ubi_ltree_entry), 0, 737 sizeof(struct ubi_ltree_entry), 0,
714 0, &ltree_entry_ctor); 738 0, &ltree_entry_ctor);
715 if (!ubi_ltree_slab) 739 if (!ubi_ltree_slab)
716 goto out_version; 740 goto out_dev_unreg;
717 741
718 ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", 742 ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
719 sizeof(struct ubi_wl_entry), 743 sizeof(struct ubi_wl_entry),
@@ -727,8 +751,11 @@ static int __init ubi_init(void)
727 751
728 cond_resched(); 752 cond_resched();
729 err = attach_mtd_dev(p->name, p->vid_hdr_offs, p->data_offs); 753 err = attach_mtd_dev(p->name, p->vid_hdr_offs, p->data_offs);
730 if (err) 754 if (err) {
755 printk(KERN_ERR "UBI error: cannot attach %s\n",
756 p->name);
731 goto out_detach; 757 goto out_detach;
758 }
732 } 759 }
733 760
734 return 0; 761 return 0;
@@ -739,10 +766,14 @@ out_detach:
739 kmem_cache_destroy(ubi_wl_entry_slab); 766 kmem_cache_destroy(ubi_wl_entry_slab);
740out_ltree: 767out_ltree:
741 kmem_cache_destroy(ubi_ltree_slab); 768 kmem_cache_destroy(ubi_ltree_slab);
769out_dev_unreg:
770 misc_deregister(&ubi_ctrl_cdev);
742out_version: 771out_version:
743 class_remove_file(ubi_class, &ubi_version); 772 class_remove_file(ubi_class, &ubi_version);
744out_class: 773out_class:
745 class_destroy(ubi_class); 774 class_destroy(ubi_class);
775out:
776 printk(KERN_ERR "UBI error: cannot initialize UBI, error %d\n", err);
746 return err; 777 return err;
747} 778}
748module_init(ubi_init); 779module_init(ubi_init);
@@ -756,6 +787,7 @@ static void __exit ubi_exit(void)
756 detach_mtd_dev(ubi_devices[i]); 787 detach_mtd_dev(ubi_devices[i]);
757 kmem_cache_destroy(ubi_wl_entry_slab); 788 kmem_cache_destroy(ubi_wl_entry_slab);
758 kmem_cache_destroy(ubi_ltree_slab); 789 kmem_cache_destroy(ubi_ltree_slab);
790 misc_deregister(&ubi_ctrl_cdev);
759 class_remove_file(ubi_class, &ubi_version); 791 class_remove_file(ubi_class, &ubi_version);
760 class_destroy(ubi_class); 792 class_destroy(ubi_class);
761} 793}
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 22c15a388f28..bc900d24cdba 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -28,6 +28,11 @@
28 * 28 *
29 * Major and minor numbers are assigned dynamically to both UBI and volume 29 * Major and minor numbers are assigned dynamically to both UBI and volume
30 * character devices. 30 * character devices.
31 *
32 * Well, there is the third kind of character devices - the UBI control
33 * character device, which allows to manipulate by UBI devices - create and
34 * delete them. In other words, it is used for attaching and detaching MTD
35 * devices.
31 */ 36 */
32 37
33#include <linux/module.h> 38#include <linux/module.h>
@@ -693,6 +698,11 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
693 return err; 698 return err;
694} 699}
695 700
701/* UBI control character device operations */
702struct file_operations ubi_ctrl_cdev_operations = {
703 .owner = THIS_MODULE,
704};
705
696/* UBI character device operations */ 706/* UBI character device operations */
697struct file_operations ubi_cdev_operations = { 707struct file_operations ubi_cdev_operations = {
698 .owner = THIS_MODULE, 708 .owner = THIS_MODULE,
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 994233d6e1e3..21c028366fd2 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -235,7 +235,7 @@ struct ubi_wl_entry;
235 235
236/** 236/**
237 * struct ubi_device - UBI device description structure 237 * struct ubi_device - UBI device description structure
238 * @dev: class device object to use the the Linux device model 238 * @dev: UBI device object to use the the Linux device model
239 * @cdev: character device object to create character device 239 * @cdev: character device object to create character device
240 * @ubi_num: UBI device number 240 * @ubi_num: UBI device number
241 * @ubi_name: UBI device name 241 * @ubi_name: UBI device name
@@ -398,6 +398,7 @@ struct ubi_device {
398 398
399extern struct kmem_cache *ubi_ltree_slab; 399extern struct kmem_cache *ubi_ltree_slab;
400extern struct kmem_cache *ubi_wl_entry_slab; 400extern struct kmem_cache *ubi_wl_entry_slab;
401extern struct file_operations ubi_ctrl_cdev_operations;
401extern struct file_operations ubi_cdev_operations; 402extern struct file_operations ubi_cdev_operations;
402extern struct file_operations ubi_vol_cdev_operations; 403extern struct file_operations ubi_vol_cdev_operations;
403extern struct ubi_device *ubi_devices[]; 404extern struct ubi_device *ubi_devices[];