m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/char.c
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-03 12:52:32 +0200
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-03 12:52:32 +0200
commit391f8bee7ef5a2e92d24d73f0072915b7cb12b6b (patch)
tree33f48bf55069bc3a2f26d7d3e3866f519959fa3a /char.c
parent66bcebae16314268dfc64ed89072feca862be108 (diff)
Create basic char device
Diffstat (limited to 'char.c')
-rw-r--r--char.c92
1 files changed, 92 insertions, 0 deletions
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);
+}