rendered paste body#include <linux/kernel.h>#include <linux/sched.h>#include <linux/module.h>#include <linux/config.h>#include <linux/init.h>#include <linux/fs.h>#include <asm/semaphore.h>#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");