@@ -132,6 +132,24 @@ static void mtd_blktrans_request(struct request_queue *rq)
wake_up_process(tr->blkcore_priv->thread);
}
+static int mtd_blktrans_get(struct mtd_info *mtd)
+{
+ if (mtd) {
+ if (!try_module_get(mtd->owner))
+ return -ENODEV;
+ mtd->usecount++;
+ }
+ return 0;
+}
+
+static int mtd_blktrans_put(struct mtd_info *mtd)
+{
+ if (mtd) {
+ mtd->usecount--;
+ module_put(mtd->owner);
+ }
+ return 0;
+}
static int blktrans_open(struct block_device *bdev, fmode_t mode)
{
@@ -139,25 +157,26 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
struct mtd_blktrans_ops *tr = dev->tr;
int ret = -ENODEV;
- if (!try_module_get(dev->mtd->owner))
- goto out;
-
- if (!try_module_get(tr->owner))
- goto out_tr;
-
/* FIXME: Locking. A hot pluggable device can go away
(del_mtd_device can be called for it) without its module
being unloaded. */
- dev->mtd->usecount++;
+ if (dev->mtd)
+ if (!mtd_blktrans_get(dev->mtd))
+ goto out;
+
+ if (!try_module_get(tr->owner))
+ goto out_tr;
ret = 0;
- if (tr->open && (ret = tr->open(dev))) {
- dev->mtd->usecount--;
- module_put(dev->mtd->owner);
- out_tr:
- module_put(tr->owner);
- }
- out:
+ if (tr->open && (ret = tr->open(dev)))
+ goto out_all;
+ return ret;
+
+out_all:
+ module_put(tr->owner);
+out_tr:
+ mtd_blktrans_put(dev->mtd);
+out:
return ret;
}
@@ -171,8 +190,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
ret = tr->release(dev);
if (!ret) {
- dev->mtd->usecount--;
- module_put(dev->mtd->owner);
+ mtd_blktrans_put(dev->mtd);
module_put(tr->owner);
}
@@ -354,13 +372,15 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
mutex_lock(&mtd_table_mutex);
ret = register_blkdev(tr->major, tr->name);
- if (ret) {
+ if (ret < 0) {
printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
tr->name, tr->major, ret);
kfree(tr->blkcore_priv);
mutex_unlock(&mtd_table_mutex);
return ret;
}
+ if (!tr->major)
+ tr->major = ret;
spin_lock_init(&tr->blkcore_priv->queue_lock);
tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock);
Signed-off-by: dmitry pervushin <dimka@embeddedalley.com> drivers/mtd/mtd_blkdevs.c | 54 ++++++++++++++++++++++++++++++-------------- 1 files changed, 37 insertions(+), 17 deletions(-)