summaryrefslogtreecommitdiff
path: root/drivers/mtd/ubi/block.c
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-09-08 01:01:14 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-09-08 01:01:14 -0300
commite5fd91f1ef340da553f7a79da9540c3db711c937 (patch)
treeb11842027dc6641da63f4bcc524f8678263304a3 /drivers/mtd/ubi/block.c
parent2a9b0348e685a63d97486f6749622b61e9e3292f (diff)
Linux-libre 4.2-gnu
Diffstat (limited to 'drivers/mtd/ubi/block.c')
-rw-r--r--drivers/mtd/ubi/block.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index c9eb78f10..ebf46ad2d 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -48,6 +48,7 @@
#include <linux/blk-mq.h>
#include <linux/hdreg.h>
#include <linux/scatterlist.h>
+#include <linux/idr.h>
#include <asm/div64.h>
#include "ubi-media.h"
@@ -161,7 +162,7 @@ static int __init ubiblock_set_param(const char *val,
return 0;
}
-static struct kernel_param_ops ubiblock_param_ops = {
+static const struct kernel_param_ops ubiblock_param_ops = {
.set = ubiblock_set_param,
};
module_param_cb(block, &ubiblock_param_ops, NULL, 0);
@@ -353,6 +354,8 @@ static struct blk_mq_ops ubiblock_mq_ops = {
.map_queue = blk_mq_map_queue,
};
+static DEFINE_IDR(ubiblock_minor_idr);
+
int ubiblock_create(struct ubi_volume_info *vi)
{
struct ubiblock *dev;
@@ -390,7 +393,13 @@ int ubiblock_create(struct ubi_volume_info *vi)
gd->fops = &ubiblock_ops;
gd->major = ubiblock_major;
- gd->first_minor = dev->ubi_num * UBI_MAX_VOLUMES + dev->vol_id;
+ gd->first_minor = idr_alloc(&ubiblock_minor_idr, dev, 0, 0, GFP_KERNEL);
+ if (gd->first_minor < 0) {
+ dev_err(disk_to_dev(gd),
+ "block: dynamic minor allocation failed");
+ ret = -ENODEV;
+ goto out_put_disk;
+ }
gd->private_data = dev;
sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
set_capacity(gd, disk_capacity);
@@ -407,7 +416,7 @@ int ubiblock_create(struct ubi_volume_info *vi)
ret = blk_mq_alloc_tag_set(&dev->tag_set);
if (ret) {
dev_err(disk_to_dev(dev->gd), "blk_mq_alloc_tag_set failed");
- goto out_put_disk;
+ goto out_remove_minor;
}
dev->rq = blk_mq_init_queue(&dev->tag_set);
@@ -445,6 +454,8 @@ out_free_queue:
blk_cleanup_queue(dev->rq);
out_free_tags:
blk_mq_free_tag_set(&dev->tag_set);
+out_remove_minor:
+ idr_remove(&ubiblock_minor_idr, gd->first_minor);
out_put_disk:
put_disk(dev->gd);
out_free_dev:
@@ -463,6 +474,7 @@ static void ubiblock_cleanup(struct ubiblock *dev)
blk_cleanup_queue(dev->rq);
blk_mq_free_tag_set(&dev->tag_set);
dev_info(disk_to_dev(dev->gd), "released");
+ idr_remove(&ubiblock_minor_idr, dev->gd->first_minor);
put_disk(dev->gd);
}