rendered paste body#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include "hhv.h"
int init_module(void);
void cleanup_module(void);
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static int dev_open = 0;
static int last_ret = 2323;
static int
device_open(struct inode *inode, struct file *file)
{
printk(KERN_ALERT "device_open(%p)\n", file);
if (dev_open)
{
printk(KERN_ALERT "Device is busy\n");
return -EBUSY;
}
dev_open++;
printk(KERN_ALERT "Opened char device ...\n");
try_module_get(THIS_MODULE);
return 0;
}
static int
device_release(struct inode *inode, struct file *file)
{
dev_open--;
last_ret = 0;
printk(KERN_ALERT "Closed char device ...\n");
module_put(THIS_MODULE);
return 0;
}
int device_ioctl(struct inode *inode, struct file *file,
unsigned int ioctl_num,
unsigned long ioctl_param)
{
unsigned long num;
printk(KERN_ALERT "ioctl num=%d ioctl_param%d\n", ioctl_num,
ioctl_param);
switch (ioctl_num)
{
case IOCTL_SET_NUMCALL:
num = ioctl_param;
__asm__ volatile("mr %%r11,%0;\n" \
"sc 1;\n" \
"mr %1,%%r3;\n"
: "=r" (last_ret)
: "r" (num));
break;
case IOCTL_GET_RETVAL:
return last_ret;
break;
}
return 0;
}
static struct file_operations fops =
{
ioctl : device_ioctl,
open : device_open,
release : device_release
};
int init_module(void)
{
int ret;
if ((ret = register_chrdev(MAJOR_NUM, DEVNAME, &fops)) < 0)
{
printk(KERN_ALERT "Can't register character device\n");
return ret;
}
printk("Run : \"mknod /dev/%s c %d 0\"\n", DEVNAME, MAJOR_NUM);
return 0;
}
void cleanup_module(void)
{
int ret;
if ((ret = unregister_chrdev(MAJOR_NUM, DEVNAME)) < 0)
printk(KERN_ALERT "Can't unregister char device\n");
printk(KERN_ALERT "Removin module\n");
}