#include #include #include #include #include #include #include "vhd.h" #include "vhdheader.h" #include struct file_operations *fileOp; struct vhd_block *rBlock; struct vhd_block *wBlock; struct semaphore *sem0; struct semaphore *sem1; int ioctl_function(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long param) { struct vhd_header *userSpace = (struct vhd_header *)kmalloc(sizeof(struct vhd_header), GFP_KERNEL); printk("ioctl function called\n"); copy_from_user(userSpace, (struct vhd_header *)param, sizeof(struct vhd_header)); down(sem1); printk("copied ok\n"); if (cmd == VHD_WRITE) { printk("WriteIOCTL\n"); wBlock -> block_number = userSpace->block_number; wBlock -> operation = VHD_WRITE; memcpy(wBlock->data, userSpace->data, 64); printk(">>>%s and %s\n", wBlock->data, userSpace->data); //down(sem0); vhd_request_operation(wBlock); //down(sem1); //up(sem0); } if (cmd == VHD_READ) { printk("ReadIOCTL\n"); rBlock -> block_number = userSpace->block_number; rBlock -> operation = VHD_READ; vhd_request_operation(rBlock); down(sem0); printk("IOCTL read data: %s\n", rBlock->data); copy_to_user((struct vhd_header *)param, rBlock, sizeof(struct vhd_header)); } printk("end of ioctl\n"); } void callBack(struct vhd_block *block) { if (block->operation == VHD_READ) { printk("Data read: %s\n", block->data); up(sem0); } else if (block->operation == VHD_WRITE) { printk("Data: %s - Written to: %d\n", block->data, block->block_number); //up(sem1); } kfree(block); up(sem1); } int init(void) { fileOp = (struct file_operations *)kmalloc(sizeof(struct file_operations), GFP_KERNEL); sem0 = (struct semaphore *)kmalloc(sizeof(struct semaphore), GFP_KERNEL); sem1 = (struct semaphore *)kmalloc(sizeof(struct semaphore), GFP_KERNEL); memset(fileOp, 0, sizeof (struct file_operations)); sema_init(sem0, 0); sema_init(sem1, 1); fileOp->ioctl = ioctl_function; register_chrdev (241, "VHD", fileOp); rBlock = (struct vhd_block *)kmalloc(sizeof(struct vhd_block), GFP_KERNEL); wBlock = (struct vhd_block *)kmalloc(sizeof(struct vhd_block), GFP_KERNEL); vhd_init(); vhd_register_interrupt(callBack); return 0; } void cleanup(void) { unregister_chrdev(241, "VHD"); vhd_cleanup(); } module_init(init); module_exit(cleanup); MODULE_LICENSE("GPL");