Merge branch 'for-4.9/block-irq' of git://git.kernel.dk/linux-block
[cascardo/linux.git] / drivers / block / null_blk.c
index 7d3b7d6..ba6f4a2 100644 (file)
@@ -34,6 +34,7 @@ struct nullb {
        unsigned int index;
        struct request_queue *q;
        struct gendisk *disk;
+       struct nvm_dev *ndev;
        struct blk_mq_tag_set tag_set;
        struct hrtimer timer;
        unsigned int queue_depth;
@@ -413,23 +414,6 @@ static void cleanup_queues(struct nullb *nullb)
        kfree(nullb->queues);
 }
 
-static void null_del_dev(struct nullb *nullb)
-{
-       list_del_init(&nullb->list);
-
-       if (use_lightnvm)
-               nvm_unregister(nullb->disk_name);
-       else
-               del_gendisk(nullb->disk);
-       blk_cleanup_queue(nullb->q);
-       if (queue_mode == NULL_Q_MQ)
-               blk_mq_free_tag_set(&nullb->tag_set);
-       if (!use_lightnvm)
-               put_disk(nullb->disk);
-       cleanup_queues(nullb);
-       kfree(nullb);
-}
-
 #ifdef CONFIG_NVM
 
 static void null_lnvm_end_io(struct request *rq, int error)
@@ -563,10 +547,58 @@ static struct nvm_dev_ops null_lnvm_dev_ops = {
        /* Simulate nvme protocol restriction */
        .max_phys_sect          = 64,
 };
+
+static int null_nvm_register(struct nullb *nullb)
+{
+       struct nvm_dev *dev;
+       int rv;
+
+       dev = nvm_alloc_dev(0);
+       if (!dev)
+               return -ENOMEM;
+
+       dev->q = nullb->q;
+       memcpy(dev->name, nullb->disk_name, DISK_NAME_LEN);
+       dev->ops = &null_lnvm_dev_ops;
+
+       rv = nvm_register(dev);
+       if (rv) {
+               kfree(dev);
+               return rv;
+       }
+       nullb->ndev = dev;
+       return 0;
+}
+
+static void null_nvm_unregister(struct nullb *nullb)
+{
+       nvm_unregister(nullb->ndev);
+}
 #else
-static struct nvm_dev_ops null_lnvm_dev_ops;
+static int null_nvm_register(struct nullb *nullb)
+{
+       return -EINVAL;
+}
+static void null_nvm_unregister(struct nullb *nullb) {}
 #endif /* CONFIG_NVM */
 
+static void null_del_dev(struct nullb *nullb)
+{
+       list_del_init(&nullb->list);
+
+       if (use_lightnvm)
+               null_nvm_unregister(nullb);
+       else
+               del_gendisk(nullb->disk);
+       blk_cleanup_queue(nullb->q);
+       if (queue_mode == NULL_Q_MQ)
+               blk_mq_free_tag_set(&nullb->tag_set);
+       if (!use_lightnvm)
+               put_disk(nullb->disk);
+       cleanup_queues(nullb);
+       kfree(nullb);
+}
+
 static int null_open(struct block_device *bdev, fmode_t mode)
 {
        return 0;
@@ -639,11 +671,32 @@ static int init_driver_queues(struct nullb *nullb)
        return 0;
 }
 
-static int null_add_dev(void)
+static int null_gendisk_register(struct nullb *nullb)
 {
        struct gendisk *disk;
-       struct nullb *nullb;
        sector_t size;
+
+       disk = nullb->disk = alloc_disk_node(1, home_node);
+       if (!disk)
+               return -ENOMEM;
+       size = gb * 1024 * 1024 * 1024ULL;
+       set_capacity(disk, size >> 9);
+
+       disk->flags |= GENHD_FL_EXT_DEVT | GENHD_FL_SUPPRESS_PARTITION_INFO;
+       disk->major             = null_major;
+       disk->first_minor       = nullb->index;
+       disk->fops              = &null_fops;
+       disk->private_data      = nullb;
+       disk->queue             = nullb->q;
+       strncpy(disk->disk_name, nullb->disk_name, DISK_NAME_LEN);
+
+       add_disk(disk);
+       return 0;
+}
+
+static int null_add_dev(void)
+{
+       struct nullb *nullb;
        int rv;
 
        nullb = kzalloc_node(sizeof(*nullb), GFP_KERNEL, home_node);
@@ -715,42 +768,19 @@ static int null_add_dev(void)
 
        sprintf(nullb->disk_name, "nullb%d", nullb->index);
 
-       if (use_lightnvm) {
-               rv = nvm_register(nullb->q, nullb->disk_name,
-                                                       &null_lnvm_dev_ops);
-               if (rv)
-                       goto out_cleanup_blk_queue;
-               goto done;
-       }
-
-       disk = nullb->disk = alloc_disk_node(1, home_node);
-       if (!disk) {
-               rv = -ENOMEM;
-               goto out_cleanup_lightnvm;
-       }
-       size = gb * 1024 * 1024 * 1024ULL;
-       set_capacity(disk, size >> 9);
-
-       disk->flags |= GENHD_FL_EXT_DEVT | GENHD_FL_SUPPRESS_PARTITION_INFO;
-       disk->major             = null_major;
-       disk->first_minor       = nullb->index;
-       disk->fops              = &null_fops;
-       disk->private_data      = nullb;
-       disk->queue             = nullb->q;
-       strncpy(disk->disk_name, nullb->disk_name, DISK_NAME_LEN);
+       if (use_lightnvm)
+               rv = null_nvm_register(nullb);
+       else
+               rv = null_gendisk_register(nullb);
 
-       add_disk(disk);
+       if (rv)
+               goto out_cleanup_blk_queue;
 
-done:
        mutex_lock(&lock);
        list_add_tail(&nullb->list, &nullb_list);
        mutex_unlock(&lock);
 
        return 0;
-
-out_cleanup_lightnvm:
-       if (use_lightnvm)
-               nvm_unregister(nullb->disk_name);
 out_cleanup_blk_queue:
        blk_cleanup_queue(nullb->q);
 out_cleanup_tags: