#include #include #include MODULE_LICENSE("GPL v2"); static ssize_t demo_read(struct file *filp, char __user *buff, size_t size, loff_t *pos) { printk("%s %d\n", __func__, __LINE__); return size; } static ssize_t demo_write(struct file *filp, const char __user *buff, size_t size, loff_t *pos) { printk("%s %d\n", __func__, __LINE__); return size; } static int demo_open(struct inode *inode, struct file *filp) { printk("%s %d\n", __func__, __LINE__); return 0; } static int demo_release(struct inode *inode, struct file *filp) { printk("%s %d\n", __func__, __LINE__); return 0; } struct file_operations demo_fops = { .owner = THIS_MODULE, .read = demo_read, .write = demo_write, .open = demo_open, .release = demo_release, }; static dev_t dev; static struct cdev *cdev; int demo_init(void) { int rc; rc = alloc_chrdev_region(&dev, 0, 1, "demo"); if (rc) { printk("failed to alloc chrdev number\n"); return rc; } cdev = cdev_alloc(); if (!cdev) { printk("failed to alloc cdev\n"); rc = -ENOMEM; goto out_unregister_chrdev; } cdev->owner = THIS_MODULE; cdev_init(cdev, &demo_fops); rc = cdev_add(cdev, dev, 1); if (rc) { printk("failed to add char device\n"); goto out_free_cdev; } return 0; out_free_cdev: kobject_put(&cdev->kobj); out_unregister_chrdev: unregister_chrdev_region(dev, 1); return rc; } void demo_exit(void) { cdev_del(cdev); unregister_chrdev_region(dev, 1); } module_init(demo_init); module_exit(demo_exit);