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 "vhd.h"
#include "vhdheader.h"
#include <asm/semaphore.h>
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");