summaryrefslogtreecommitdiffstats
path: root/mod_add.c
diff options
context:
space:
mode:
Diffstat (limited to 'mod_add.c')
-rw-r--r--mod_add.c141
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);