diff options
author | syn <isaqtm@gmail.com> | 2020-02-02 21:26:43 +0300 |
---|---|---|
committer | syn <isaqtm@gmail.com> | 2020-02-02 21:26:43 +0300 |
commit | e6f96cb31a342eb86e5ea0e74c9203c21bdb9394 (patch) | |
tree | c87debebabb751e781a861a4212ea38c61e7ba6a /mod_add.c | |
parent | f339f5666935584389a4c220af1ab6965e18bf40 (diff) | |
download | sad-master.tar.gz |
Diffstat (limited to 'mod_add.c')
-rw-r--r-- | mod_add.c | 141 |
1 files changed, 0 insertions, 141 deletions
diff --git a/mod_add.c b/mod_add.c deleted file mode 100644 index 096baaf..0000000 --- a/mod_add.c +++ /dev/null @@ -1,141 +0,0 @@ -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/uaccess.h> -#include <linux/cdev.h> -#include <linux/semaphore.h> - -MODULE_LICENSE("GPL"); - -#define DEV_NAME "sad_dev" - -static int sad_open(struct inode *, struct file *); -static int sad_release(struct inode *, struct file *); -static ssize_t sad_read(struct file *, char __user *, size_t, loff_t *); -static ssize_t sad_write(struct file *, const char __user *, size_t, loff_t *); - -static dev_t dev; -static struct cdev *cdev; -static int device_open_count = 0; - -struct sad_buf { - char *buf; - size_t size; - struct semaphore lock; -} *buf; - -static struct file_operations sad_fops = { - .owner = THIS_MODULE, - .read = sad_read, - .write = sad_write, - .open = sad_open, - .release = sad_release -}; - - -static ssize_t sad_read(struct file *flip, char __user *user_buf, size_t len, loff_t *offset) { - size_t bytes_left, read_size, uncopied; - - if (down_interruptible(&buf->lock)) - return -ERESTARTSYS; - - if (*offset >= buf->size) { - up(&buf->lock); - return 0; - } - - bytes_left = buf->size - *offset; - read_size = min(bytes_left, len); - uncopied = copy_to_user(user_buf, buf->buf + *offset, read_size); - - *offset += read_size - uncopied; - - up(&buf->lock); - - return read_size - uncopied; -} - -static ssize_t sad_write(struct file *flip, const char __user *user_buf, size_t len, loff_t *offset) { - size_t uncopied; - - if (down_interruptible(&buf->lock)) - return -ERESTARTSYS; - - if (buf->buf) - kfree(buf->buf); - - buf->buf = kmalloc(len, GFP_KERNEL); - if (!buf->buf) { - up(&buf->lock); - return -ENOMEM; - } - - buf->size = len; - - *offset = 0; - - uncopied = copy_from_user(buf->buf, user_buf, len); - - up(&buf->lock); - - return len - uncopied; -} - -static int sad_open(struct inode *inode, struct file *file) { - device_open_count++; - try_module_get(THIS_MODULE); - return 0; -} - -static int sad_release(struct inode *inode, struct file *file) { - device_open_count--; - if (device_open_count == 0) - module_put(THIS_MODULE); - return 0; -} - -static int __init sad_init(void) { - int rc; - - const unsigned int minor = 0; - const unsigned int count = 1; - - buf = kzalloc(sizeof(*buf), GFP_KERNEL); - if (!buf) - return -ENOMEM; - - sema_init(&buf->lock, 1); - - rc = alloc_chrdev_region(&dev, minor, count, DEV_NAME); - if (rc < 0) { - printk(KERN_ALERT "Could not register device: %d\n", rc); - return rc; - } else { - printk(KERN_INFO "Allocated maj %d\n", MAJOR(dev)); - } - - cdev = cdev_alloc(); - cdev->owner = THIS_MODULE; - cdev->ops = &sad_fops; - rc = cdev_add(cdev, dev, 1); - - if (rc) { - printk(KERN_ALERT "Could not cdev_add: %d\n", rc); - return rc; - } - - return 0; -} -static void __exit sad_exit(void) { - cdev_del(cdev); - if (buf->buf) - kfree(buf->buf); - kfree(buf); - unregister_chrdev_region(dev, 1); - printk(KERN_INFO "okay, bye\n"); -} - -module_init(sad_init); -module_exit(sad_exit); |