67 lines
1.6 KiB
C
67 lines
1.6 KiB
C
#include <linux/device.h>
|
|
#include "my-ioctl.h"
|
|
|
|
MODULE_DESCRIPTION("Chardev Ioctl kernel module.");
|
|
MODULE_VERSION("0.0.1");
|
|
MODULE_AUTHOR("Imbus");
|
|
MODULE_LICENSE("GPL");
|
|
|
|
#define DEVICE_NAME "hello_ioctl"
|
|
|
|
static int major; /* Dynamically assigned */
|
|
static struct class *cls;
|
|
|
|
static long my_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
|
|
|
|
/* See: https://elixir.bootlin.com/linux/v6.14.5/source/include/linux/fs.h#L2131 */
|
|
static struct file_operations fops = {
|
|
.owner = THIS_MODULE,
|
|
.unlocked_ioctl = my_ioctl,
|
|
};
|
|
|
|
static long my_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|
{
|
|
pr_info("Ioctl called by %s...\n", current->comm);
|
|
|
|
switch (cmd) {
|
|
case MY_IOCTL_FILL:
|
|
pr_info("Ioctl FILL by %s...\n", current->comm);
|
|
break;
|
|
case MY_IOCTL_WIPE:
|
|
pr_info("Ioctl WIPE by %s...\n", current->comm);
|
|
break;
|
|
default:
|
|
return -ENOTTY; // Invalid command
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int __init demo_mod_init(void)
|
|
{
|
|
major = register_chrdev(0, DEVICE_NAME, &fops);
|
|
if (major < 0) {
|
|
pr_info(DEVICE_NAME " - Error registering chrdev\n");
|
|
return major;
|
|
}
|
|
|
|
pr_info(DEVICE_NAME " was assigned major number %d.\n", major);
|
|
|
|
cls = class_create(DEVICE_NAME);
|
|
device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
|
|
|
|
pr_info(DEVICE_NAME " created on /dev/%s\n", DEVICE_NAME);
|
|
|
|
pr_info(DEVICE_NAME " major nbr %d loaded successfully...\n", major);
|
|
return 0;
|
|
}
|
|
|
|
static void __exit demo_mod_exit(void)
|
|
{
|
|
device_destroy(cls, MKDEV(major, 0));
|
|
class_destroy(cls);
|
|
unregister_chrdev(major, DEVICE_NAME);
|
|
pr_info(DEVICE_NAME " unloaded successfully...\n");
|
|
}
|
|
|
|
module_init(demo_mod_init);
|
|
module_exit(demo_mod_exit);
|