#include #include #include #include #include "chardev.h" #define SUCCESS 0 #define DEVICE_NAME "chardev" #define BUF_LEN 80 static int Major; static int opened = 0; static char msg[BUF_LEN]; static char* msg_ptr; static struct file_operations fops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release }; int init_module(void) { Major = register_chrdev(0, DEVICE_NAME, &fops); if (Major < 0) { printk(KERN_ALERT "Registering char device failed with %d\n", Major); return Major; } printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major); printk(KERN_INFO "the driver, create a dev file with\n"); printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major); printk(KERN_INFO "Try to cat and echo to the device file.\n"); printk(KERN_INFO "Remove the device file and module when done.\n"); return SUCCESS; } void cleanup_module(void) { unregister_chrdev(Major, DEVICE_NAME); } static int device_open(struct inode* inode, struct file* filp) { static int counter = 0; if (opened) return -EBUSY; opened++; if (counter++ == 0) sprintf(msg, "Come on, write something here :D\n"); msg_ptr = msg; try_module_get(THIS_MODULE); return SUCCESS; } static int device_release(struct inode* inode, struct file* filp) { opened--; module_put(THIS_MODULE); return 0; } static ssize_t device_read(struct file* filp, char* buffer, size_t len, loff_t* off) { int bytes = 0; if (*msg_ptr == 0) return 0; while (len-- && *msg_ptr) { put_user(*msg_ptr++, buffer++); bytes++; } return bytes; } static ssize_t device_write(struct file* filp, const char* buff, size_t len, loff_t* off) { int bytes = 0; if (len > BUF_LEN) { printk(KERN_ALERT "Error: dude you tried to overflow my buffer!\n"); return -ENOBUFS; } while (len--) { get_user(msg[bytes], buff++); bytes++; } msg[bytes] = '\0'; msg_ptr = msg; return bytes; }