#include #include #include #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"); }