diff options
author | lonkaars <loek@pipeframe.xyz> | 2024-04-18 17:34:40 +0200 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2024-04-18 17:34:40 +0200 |
commit | bfb105b36e902ffc1aec9424a38245db693eea02 (patch) | |
tree | 33cb1b9c5d2002ce1c76dc3575760e3c6a57f125 /1 | |
parent | 2d8b061d0f442d8a8853025460a836e3482cc09b (diff) |
dynamically get major:minor numbers + register /dev node + /sys/class node
Diffstat (limited to '1')
-rw-r--r-- | 1/config.h | 3 | ||||
-rw-r--r-- | 1/main.c | 42 |
2 files changed, 36 insertions, 9 deletions
@@ -1,5 +1,4 @@ #pragma once -#define NODE_MAJOR 500 -#define NODE_MINOR 0 +#define DRV_NAME "lork" @@ -6,6 +6,9 @@ #include "config.h" struct cdev *cdev; +struct device *dev; +struct class *class; +dev_t node; struct file_operations fops = { .read = fop_read, .write = fop_write, @@ -15,38 +18,63 @@ struct file_operations fops = { static int mod_init(void) { int err; - cdev = cdev_alloc(); - dev_t node = MKDEV(NODE_MAJOR, NODE_MINOR); + err = alloc_chrdev_region(&node, 0, 1, DRV_NAME); + if (err < 0) { + printk(KERN_ERR "alloc_chrdev_region error %d\n", err); + goto return_err; + } + + class = class_create(DRV_NAME); + if (IS_ERR_OR_NULL(class)) { + err = PTR_ERR(class); + printk(KERN_ERR "class_create error %d\n", err); + goto free_class; + } + + cdev = cdev_alloc(); if (!cdev) { err = ENOMEM; goto free_cdev; } cdev->ops = &fops; - + cdev_init(cdev, &fops); err = cdev_add(cdev, node, 1); if (err < 0) { - printk(KERN_ERR "cdev_add failed w/ error code %d\n", err); + printk(KERN_ERR "cdev_add error %d\n", err); goto free_cdev; } - printk("%s\n", __PRETTY_FUNCTION__); + dev = device_create(class, NULL, node, NULL, DRV_NAME); + if (IS_ERR_OR_NULL(dev)) { + err = PTR_ERR(dev); + printk(KERN_ERR "device_create error %d\n", err); + goto free_device; + } + + printk("%s %d:%d\n", __PRETTY_FUNCTION__, MAJOR(node), MINOR(node)); return 0; +free_device: + device_destroy(class, node); free_cdev: cdev_del(cdev); - +free_class: + class_destroy(class); +return_err: printk("%s: %d\n", __PRETTY_FUNCTION__, err); return err; } static void mod_exit(void) { + device_destroy(class, node); cdev_del(cdev); + class_destroy(class); printk("%s\n", __PRETTY_FUNCTION__); } module_init(mod_init); module_exit(mod_exit); -MODULE_LICENSE("MIT"); +MODULE_LICENSE("Dual MIT/GPL"); |