Code to implement the most simple device block, based on printk's.
[vdi_driver.git] / src / driver / vdi.c
blob4d1fa70ec35d474fe25600a68eeb9f784298d388
1 /*
2 * vdi.h - The driver for virtual disks of VirtualBox
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef __KERNEL__
19 # define __KERNEL__
20 #endif
21 #ifndef MODULE
22 # define MODULE
23 #endif
25 //TODO: Remove? #include <linux/config.h>
26 #include <linux/module.h>
27 #include <linux/init.h>
30 #include <linux/blkdev.h>
31 #include <linux/errno.h>
32 #include <linux/fs.h>
33 #include <linux/genhd.h>
34 #include <linux/hdreg.h>
35 #include <linux/kernel.h>
36 #include <linux/types.h>
38 static int vdi_major;
40 #include "vdi.h"
44 * Some disk parameters
46 static int major = VDI_MAJOR;
47 // TODO: Remove below variables?
48 //static int size = VDI_SIZE;
49 //static int blksize = VDI_BLKSIZE;
51 static vdi_dev vdi;
52 static struct request_queue *Queue;
54 void vdi_request(request_queue_t *q)
56 struct request *req;
58 while ( (req = elv_next_request(q)) != NULL ) {
59 if (!blk_fs_request(req)) {
60 end_request(req, 0);
61 continue;
64 printk("vdi request: sec %lu (nr, %u)\n", req->nr_sectors,
65 req->current_nr_sectors);
66 // TODO: send data to the daemon
69 end_request(req, 1);
74 int vdi_ioctl (struct inode *inode, struct file *filp, unsigned int cmd,
75 unsigned long arg)
77 // Unknown command
78 return -ENOTTY;
82 static struct block_device_operations vdi_oper = {
83 .owner = THIS_MODULE,
84 .ioctl = vdi_ioctl
88 static int __init vdi_init(void)
90 // TODO: Remove this? int result, i;
92 vdi.size = VDI_SECTORS * VDI_HARDSECT_SIZE;
94 spin_lock_init(&vdi.lock);
96 Queue = blk_init_queue(vdi_request, &vdi.lock);
97 if (Queue == NULL) {
98 printk(KERN_WARNING "vdi: Unable to create request queue.\n");
99 return -ENOMEM;
101 blk_queue_hardsect_size(Queue, VDI_HARDSECT_SIZE);
105 * Register your major, and accept a dynamic number
107 major = register_blkdev(vdi_major, "vdi");
108 if (major < 0) {
109 printk(KERN_WARNING "vdi: Unable to get major %d\n", major);
110 return major;
113 // Create the gendisk structure
114 vdi.gd = alloc_disk(16);
115 if (!vdi.gd) {
116 // TODO: Unregister it
117 unregister_blkdev(major, "vdi");
120 // Set gendisk fields
121 vdi.gd->major = major;
122 vdi.gd->first_minor = 0;
123 vdi.gd->fops = &vdi_oper;
124 vdi.gd->private_data = &vdi;
125 strcpy(vdi.gd->disk_name, "vdi0");
126 set_capacity(vdi.gd, VDI_SECTORS*(VDI_HARDSECT_SIZE/KERNEL_SECTOR_SIZE));
127 vdi.gd->queue = Queue;
129 add_disk(vdi.gd);
130 printk("vdi: init complete\n");
131 return 0; /* succeed */
134 static void __exit vdi_exit(void)
136 del_gendisk(vdi.gd);
137 put_disk(vdi.gd);
138 unregister_blkdev(major, "vdi");
139 blk_cleanup_queue(Queue);
140 printk("vdi: exit complete\n");
143 module_init(vdi_init);
144 module_exit(vdi_exit);