aboutsummaryrefslogtreecommitdiff
path: root/1
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2024-04-18 17:34:40 +0200
committerlonkaars <loek@pipeframe.xyz>2024-04-18 17:34:40 +0200
commitbfb105b36e902ffc1aec9424a38245db693eea02 (patch)
tree33cb1b9c5d2002ce1c76dc3575760e3c6a57f125 /1
parent2d8b061d0f442d8a8853025460a836e3482cc09b (diff)
dynamically get major:minor numbers + register /dev node + /sys/class node
Diffstat (limited to '1')
-rw-r--r--1/config.h3
-rw-r--r--1/main.c42
2 files changed, 36 insertions, 9 deletions
diff --git a/1/config.h b/1/config.h
index 1d15f75..7302134 100644
--- a/1/config.h
+++ b/1/config.h
@@ -1,5 +1,4 @@
#pragma once
-#define NODE_MAJOR 500
-#define NODE_MINOR 0
+#define DRV_NAME "lork"
diff --git a/1/main.c b/1/main.c
index 66ceac4..101f675 100644
--- a/1/main.c
+++ b/1/main.c
@@ -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");