#include "char.h" #include "linux/cdev.h" #include "linux/device.h" #include "linux/fs.h" #include "util.h" #define DOOMDEV_COUNT 256 #define DOOMDEV_NAME "doom" dev_t first; int major; int next_minor = 0; long doom_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { return -1; } int doom_open(struct inode *inode, struct file *filp) { return -1; } struct file_operations doomdev_fops = { .owner = THIS_MODULE, .unlocked_ioctl = doom_ioctl, .compat_ioctl = doom_ioctl, .open = doom_open }; struct class *doom_class; int new_doomdev(void) { int err = 0; int minor; dev_t devt; struct cdev *doom_cdev; struct device *doomdev; if (next_minor >= DOOMDEV_COUNT) { return -ENOMEM; } doom_cdev = cdev_alloc(); if (doom_cdev == NULL) { return -ENOMEM; } doom_cdev->ops = &doomdev_fops; ORFAIL(cdev_add(doom_cdev, first, 1), error_add); minor = next_minor++; devt = MKDEV(major, minor); ORFAIL_PTR(device_create(doom_class, NULL, devt, NULL, "doom%d", minor), doomdev, error_create); error_create: cdev_del(doom_cdev); error_add: return err; } void destroy_doomdev(void) { device_destroy(doom_class, first); } int char_init(void) { int err = 0; ORFAIL(alloc_chrdev_region(&first, 0, DOOMDEV_COUNT, DOOMDEV_NAME), error_region); major = MAJOR(first); doom_class = class_create(THIS_MODULE, "doom"); if (IS_ERR(doom_class)) { err = PTR_ERR(doom_class); goto error_create; } error_create: unregister_chrdev_region(first, DOOMDEV_COUNT); error_region: return err; } void char_cleanup(void) { unregister_chrdev_region(first, DOOMDEV_COUNT); class_unregister(doom_class); }