1 #include <linux/module.h>
2 #include <linux/miscdevice.h>
6 static DEFINE_SPINLOCK(blktap_control_lock);
7 struct blktap *blktaps[CONFIG_XEN_NR_TAP2_DEVICES];
10 static int device_major;
11 static int blktap_control_registered;
14 blktap_control_initialize_tap(struct blktap *tap)
16 int minor = tap->minor;
18 memset(tap, 0, sizeof(*tap));
19 set_bit(BLKTAP_CONTROL, &tap->dev_inuse);
20 init_rwsem(&tap->tap_sem);
21 sg_init_table(tap->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
22 init_waitqueue_head(&tap->wq);
23 atomic_set(&tap->refcnt, 0);
28 static struct blktap *
29 blktap_control_create_tap(void)
34 tap = kmalloc(sizeof(*tap), GFP_KERNEL);
38 blktap_control_initialize_tap(tap);
40 spin_lock_irq(&blktap_control_lock);
41 for (minor = 0; minor < CONFIG_XEN_NR_TAP2_DEVICES; minor++)
45 if (minor == CONFIG_XEN_NR_TAP2_DEVICES) {
55 spin_unlock_irq(&blktap_control_lock);
59 static struct blktap *
60 blktap_control_allocate_tap(void)
66 * This is called only from the ioctl, which
67 * means we should always have interrupts enabled.
69 BUG_ON(irqs_disabled());
71 spin_lock_irq(&blktap_control_lock);
73 for (minor = 0; minor < CONFIG_XEN_NR_TAP2_DEVICES; minor++) {
78 if (!tap->dev_inuse) {
79 blktap_control_initialize_tap(tap);
87 spin_unlock_irq(&blktap_control_lock);
90 tap = blktap_control_create_tap();
95 err = blktap_ring_create(tap);
97 BTERR("ring creation failed: %d\n", err);
98 clear_bit(BLKTAP_CONTROL, &tap->dev_inuse);
102 BTINFO("allocated tap %p\n", tap);
107 blktap_control_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
113 case BLKTAP2_IOCTL_ALLOC_TAP: {
114 struct blktap_handle h;
116 tap = blktap_control_allocate_tap();
118 BTERR("error allocating device\n");
123 h.device = device_major;
124 h.minor = tap->minor;
126 if (copy_to_user((struct blktap_handle __user *)arg,
128 blktap_control_destroy_device(tap);
135 case BLKTAP2_IOCTL_FREE_TAP:
138 if (dev >= CONFIG_XEN_NR_TAP2_DEVICES || !blktaps[dev])
141 blktap_control_destroy_device(blktaps[dev]);
148 static const struct file_operations blktap_control_file_operations = {
149 .owner = THIS_MODULE,
150 .unlocked_ioctl = blktap_control_ioctl,
153 static struct miscdevice blktap_misc = {
154 .minor = MISC_DYNAMIC_MINOR,
155 .name = "blktap-control",
156 .nodename = BLKTAP2_DEV_DIR "control",
157 .fops = &blktap_control_file_operations,
161 blktap_control_destroy_device(struct blktap *tap)
169 set_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse);
172 inuse = tap->dev_inuse;
173 err = blktap_device_destroy(tap);
177 inuse = tap->dev_inuse;
178 err = blktap_ring_destroy(tap);
182 inuse = tap->dev_inuse;
183 err = blktap_sysfs_destroy(tap);
190 BTDBG("inuse: 0x%lx, dev_inuse: 0x%lx\n",
191 inuse, tap->dev_inuse);
192 if (wait_event_interruptible(tap->wq, tap->dev_inuse != inuse))
196 clear_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse);
198 if (blktap_control_finish_destroy(tap))
205 blktap_control_finish_destroy(struct blktap *tap)
207 if (tap->dev_inuse == (1UL << BLKTAP_CONTROL))
208 clear_bit(BLKTAP_CONTROL, &tap->dev_inuse);
209 return !tap->dev_inuse;
213 blktap_control_init(void)
217 err = misc_register(&blktap_misc);
219 BTERR("misc_register failed for control device");
223 blktap_control_registered = 1;
228 blktap_control_free(void)
232 for (i = 0; i < CONFIG_XEN_NR_TAP2_DEVICES; i++)
233 blktap_control_destroy_device(blktaps[i]);
235 if (blktap_control_registered)
236 if (misc_deregister(&blktap_misc) < 0)
237 BTERR("misc_deregister failed for control device");
243 blktap_control_free();
246 blktap_device_free();
247 blktap_request_pool_free();
255 err = blktap_request_pool_init();
259 err = blktap_device_init(&device_major);
263 err = blktap_ring_init(&ring_major);
267 err = blktap_sysfs_init();
271 err = blktap_control_init();
282 module_init(blktap_init);
283 module_exit(blktap_exit);
284 MODULE_LICENSE("Dual BSD/GPL");
285 MODULE_ALIAS("devname:" BLKTAP2_DEV_DIR "control");