aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Pervushin <dpervushin@embeddedalley.com>2009-05-31 10:32:59 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-06-03 10:45:23 -0400
commit2ba3d76a1e29f2ba64fbc762875cf9fb2d4ba2ba (patch)
tree633d48cb740534827b2a764c74e7b423415c0774
parent518ceef0c9ca97023e45ae46aedaefa240c690a6 (diff)
UBI: make gluebi a separate module
[Artem: re-worked the patch: made it release resources when the module is unloaded, made it do module referencing, made it really independent on UBI, tested it with the UBI test-suite which can be found in ubi-2.6.git/tests/ubi-tests, re-named most of the funcs/variables to get rid of the "ubi" word and make names consistent.] Signed-off-by: Dmitry Pervushin <dpervushin@embeddedalley.com> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--drivers/mtd/ubi/Kconfig13
-rw-r--r--drivers/mtd/ubi/Makefile2
-rw-r--r--drivers/mtd/ubi/gluebi.c378
3 files changed, 295 insertions, 98 deletions
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index 3f063108e95f..b1cd7a1a2191 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -49,15 +49,16 @@ config MTD_UBI_BEB_RESERVE
49 reserved. Leave the default value if unsure. 49 reserved. Leave the default value if unsure.
50 50
51config MTD_UBI_GLUEBI 51config MTD_UBI_GLUEBI
52 bool "Emulate MTD devices" 52 tristate "MTD devices emulation driver (gluebi)"
53 default n 53 default n
54 depends on MTD_UBI 54 depends on MTD_UBI
55 help 55 help
56 This option enables MTD devices emulation on top of UBI volumes: for 56 This option enables gluebi - an additional driver which emulates MTD
57 each UBI volumes an MTD device is created, and all I/O to this MTD 57 devices on top of UBI volumes: for each UBI volumes an MTD device is
58 device is redirected to the UBI volume. This is handy to make 58 created, and all I/O to this MTD device is redirected to the UBI
59 MTD-oriented software (like JFFS2) work on top of UBI. Do not enable 59 volume. This is handy to make MTD-oriented software (like JFFS2)
60 this if no legacy software will be used. 60 work on top of UBI. Do not enable this unless you use legacy
61 software.
61 62
62source "drivers/mtd/ubi/Kconfig.debug" 63source "drivers/mtd/ubi/Kconfig.debug"
63endmenu 64endmenu
diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile
index dd834e04151b..c9302a5452b0 100644
--- a/drivers/mtd/ubi/Makefile
+++ b/drivers/mtd/ubi/Makefile
@@ -4,4 +4,4 @@ ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o scan.o
4ubi-y += misc.o 4ubi-y += misc.o
5 5
6ubi-$(CONFIG_MTD_UBI_DEBUG) += debug.o 6ubi-$(CONFIG_MTD_UBI_DEBUG) += debug.o
7ubi-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o 7obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c
index 49cd55ade9c8..95aaac03f938 100644
--- a/drivers/mtd/ubi/gluebi.c
+++ b/drivers/mtd/ubi/gluebi.c
@@ -19,17 +19,71 @@
19 */ 19 */
20 20
21/* 21/*
22 * This file includes implementation of fake MTD devices for each UBI volume. 22 * This is a small driver which implements fake MTD devices on top of UBI
23 * This sounds strange, but it is in fact quite useful to make MTD-oriented 23 * volumes. This sounds strange, but it is in fact quite useful to make
24 * software (including all the legacy software) to work on top of UBI. 24 * MTD-oriented software (including all the legacy software) work on top of
25 * UBI.
25 * 26 *
26 * Gluebi emulates MTD devices of "MTD_UBIVOLUME" type. Their minimal I/O unit 27 * Gluebi emulates MTD devices of "MTD_UBIVOLUME" type. Their minimal I/O unit
27 * size (mtd->writesize) is equivalent to the UBI minimal I/O unit. The 28 * size (@mtd->writesize) is equivalent to the UBI minimal I/O unit. The
28 * eraseblock size is equivalent to the logical eraseblock size of the volume. 29 * eraseblock size is equivalent to the logical eraseblock size of the volume.
29 */ 30 */
30 31
32#include <linux/err.h>
33#include <linux/list.h>
34#include <linux/sched.h>
31#include <linux/math64.h> 35#include <linux/math64.h>
32#include "ubi.h" 36#include <linux/module.h>
37#include <linux/mutex.h>
38#include <linux/mtd/ubi.h>
39#include <linux/mtd/mtd.h>
40#include "ubi-media.h"
41
42#define err_msg(fmt, ...) \
43 printk(KERN_DEBUG "gluebi (pid %d): %s: " fmt "\n", \
44 current->pid, __func__, ##__VA_ARGS__)
45
46/**
47 * struct gluebi_device - a gluebi device description data structure.
48 * @mtd: emulated MTD device description object
49 * @refcnt: gluebi device reference count
50 * @desc: UBI volume descriptor
51 * @ubi_num: UBI device number this gluebi device works on
52 * @vol_id: ID of UBI volume this gluebi device works on
53 * @list: link in a list of gluebi devices
54 */
55struct gluebi_device {
56 struct mtd_info mtd;
57 int refcnt;
58 struct ubi_volume_desc *desc;
59 int ubi_num;
60 int vol_id;
61 struct list_head list;
62};
63
64/* List of all gluebi devices */
65static LIST_HEAD(gluebi_devices);
66static DEFINE_MUTEX(devices_mutex);
67
68/**
69 * find_gluebi_nolock - find a gluebi device.
70 * @ubi_num: UBI device number
71 * @vol_id: volume ID
72 *
73 * This function seraches for gluebi device corresponding to UBI device
74 * @ubi_num and UBI volume @vol_id. Returns the gluebi device description
75 * object in case of success and %NULL in case of failure. The caller has to
76 * have the &devices_mutex locked.
77 */
78static struct gluebi_device *find_gluebi_nolock(int ubi_num, int vol_id)
79{
80 struct gluebi_device *gluebi;
81
82 list_for_each_entry(gluebi, &gluebi_devices, list)
83 if (gluebi->ubi_num == ubi_num && gluebi->vol_id == vol_id)
84 return gluebi;
85 return NULL;
86}
33 87
34/** 88/**
35 * gluebi_get_device - get MTD device reference. 89 * gluebi_get_device - get MTD device reference.
@@ -41,15 +95,18 @@
41 */ 95 */
42static int gluebi_get_device(struct mtd_info *mtd) 96static int gluebi_get_device(struct mtd_info *mtd)
43{ 97{
44 struct ubi_volume *vol; 98 struct gluebi_device *gluebi;
99 int ubi_mode = UBI_READONLY;
45 100
46 vol = container_of(mtd, struct ubi_volume, gluebi_mtd); 101 if (!try_module_get(THIS_MODULE))
102 return -ENODEV;
47 103
48 /* 104 if (mtd->flags & MTD_WRITEABLE)
49 * We do not introduce locks for gluebi reference count because the 105 ubi_mode = UBI_READWRITE;
50 * get_device()/put_device() calls are already serialized at MTD. 106
51 */ 107 gluebi = container_of(mtd, struct gluebi_device, mtd);
52 if (vol->gluebi_refcount > 0) { 108 mutex_lock(&devices_mutex);
109 if (gluebi->refcnt > 0) {
53 /* 110 /*
54 * The MTD device is already referenced and this is just one 111 * The MTD device is already referenced and this is just one
55 * more reference. MTD allows many users to open the same 112 * more reference. MTD allows many users to open the same
@@ -58,7 +115,8 @@ static int gluebi_get_device(struct mtd_info *mtd)
58 * open the UBI volume again - just increase the reference 115 * open the UBI volume again - just increase the reference
59 * counter and return. 116 * counter and return.
60 */ 117 */
61 vol->gluebi_refcount += 1; 118 gluebi->refcnt += 1;
119 mutex_unlock(&devices_mutex);
62 return 0; 120 return 0;
63 } 121 }
64 122
@@ -66,11 +124,15 @@ static int gluebi_get_device(struct mtd_info *mtd)
66 * This is the first reference to this UBI volume via the MTD device 124 * This is the first reference to this UBI volume via the MTD device
67 * interface. Open the corresponding volume in read-write mode. 125 * interface. Open the corresponding volume in read-write mode.
68 */ 126 */
69 vol->gluebi_desc = ubi_open_volume(vol->ubi->ubi_num, vol->vol_id, 127 gluebi->desc = ubi_open_volume(gluebi->ubi_num, gluebi->vol_id,
70 UBI_READWRITE); 128 ubi_mode);
71 if (IS_ERR(vol->gluebi_desc)) 129 if (IS_ERR(gluebi->desc)) {
72 return PTR_ERR(vol->gluebi_desc); 130 mutex_unlock(&devices_mutex);
73 vol->gluebi_refcount += 1; 131 module_put(THIS_MODULE);
132 return PTR_ERR(gluebi->desc);
133 }
134 gluebi->refcnt += 1;
135 mutex_unlock(&devices_mutex);
74 return 0; 136 return 0;
75} 137}
76 138
@@ -83,13 +145,15 @@ static int gluebi_get_device(struct mtd_info *mtd)
83 */ 145 */
84static void gluebi_put_device(struct mtd_info *mtd) 146static void gluebi_put_device(struct mtd_info *mtd)
85{ 147{
86 struct ubi_volume *vol; 148 struct gluebi_device *gluebi;
87 149
88 vol = container_of(mtd, struct ubi_volume, gluebi_mtd); 150 gluebi = container_of(mtd, struct gluebi_device, mtd);
89 vol->gluebi_refcount -= 1;