From 391f8bee7ef5a2e92d24d73f0072915b7cb12b6b Mon Sep 17 00:00:00 2001 From: Marcin Chrzanowski Date: Thu, 3 May 2018 12:52:32 +0200 Subject: Create basic char device --- char.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 char.c (limited to 'char.c') diff --git a/char.c b/char.c new file mode 100644 index 0000000..7fe7652 --- /dev/null +++ b/char.c @@ -0,0 +1,92 @@ +#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); +} -- cgit v1.2.3