#include #include #include #include #include #include #include #include "vhd.h" #include "vhd_advanced.h" #include "request.h" char buffer[64]; struct file_operations *fo; struct requ kreq; struct semaphore *mutex, *lock, *reqsem; struct requ *user; struct requ *temp; struct vhd_block wblock; void runrequest(struct vhd_block *inblock) { printk("op %d\n", inblock->operation); /* called when operation is done */ switch(inblock->operation) { case VHD_WRITE: printk("Written: %s\n", inblock->data); break; case VHD_READ: printk("Read: %d\n", inblock->block_number); //printk("Read\n"); break; default: break; } up(lock); up(reqsem); } void write(char out[64], int blocknum) { wblock.block_number = blocknum; wblock.operation = VHD_WRITE; memcpy(wblock.data, out, sizeof(out)); //down(mutex); vhd_request_operation(&wblock); //up(mutex); } void read(int blocknum) { struct vhd_block rblock; rblock.block_number = blocknum; rblock.operation = VHD_READ; down(reqsem); /* wait until a space in vhdqueue*/ down(mutex); vhd_request_operation(&rblock); up(mutex); down(lock); /*wait unil released operation completes*/ strcpy(user->data, rblock.data); copy_to_user(temp, user, sizeof(struct requ)); } int ioctlfunction(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long param) { int blck; copy_from_user(&kreq, (struct requ*)param, sizeof(struct requ)); blck = kreq.blocknum; temp = (struct requ*)param; switch(cmd) { case VHD_WRITE: down(reqsem); down(operation_queue_lock); printk("%d\n", blck); if(vhd_find_block_write_request(blck) != 0) { printk("removing %d \n", blck); vhd_remove_request(vhd_find_block_write_request(blck)); up(reqsem); } up(operation_queue_lock); write(kreq.data, kreq.blocknum); break; case VHD_READ: read(kreq.blocknum); break; default: break; } } int init(void) { if(vhd_init()) { printk("vhd init broke\n"); return -1; } vhd_register_interrupt(&runrequest); mutex = (struct semaphore*)kmalloc(sizeof(struct semaphore), GFP_KERNEL); lock = (struct semaphore*)kmalloc(sizeof(struct semaphore), GFP_KERNEL); reqsem = (struct semaphore*)kmalloc(sizeof(struct semaphore), GFP_KERNEL); sema_init(mutex, 1); sema_init(lock, 0); sema_init(reqsem, 7); fo = (struct file_operations*)kmalloc(sizeof(struct file_operations), GFP_KERNEL); user = (struct requ*)kmalloc(sizeof(struct requ), GFP_KERNEL); memset(fo, 0, sizeof(struct file_operations)); fo->ioctl = &ioctlfunction; register_chrdev(241, "b", fo); return 0; } void cleanup(void) { kfree(fo); vhd_cleanup(); unregister_chrdev(241, "b"); } module_init(init); module_exit(cleanup); MODULE_LICENSE("GPL");