#include #include #include #include #include #include #include "bible.h" MODULE_LICENSE("GPL"); //God's Parables and Liturgy int init_module(void); void cleanup_module(void); static int device_open(struct inode *, struct file *); static int device_release(struct inode *, struct file *); static ssize_t device_read(struct file *, char *, size_t, loff_t *); static int on_dev_uevent(struct device*, struct kobj_uevent_env*); #define DEVICE_NAME "bible" static dev_t devt; static struct class* device_class; static struct device* device; static struct cdev character_device; static struct file_operations fops = { .read = device_read, .open = device_open, .release = device_release }; int init_module(void) { int result; if((result = alloc_chrdev_region(&devt, 0, 1, DEVICE_NAME)) < 0) { printk(KERN_ALERT "Couldn't alloc chrdev region: %d\n", result); return result; } if((device_class = class_create(THIS_MODULE, DEVICE_NAME)) == NULL) { printk(KERN_ALERT "Couldn't create device class\n"); unregister_chrdev_region(devt, 1); return -1; } device_class->dev_uevent = on_dev_uevent; if((device = device_create(device_class, NULL, devt, NULL, DEVICE_NAME)) == NULL) { printk(KERN_ALERT "Couldn't create device\n"); class_destroy(device_class); unregister_chrdev_region(devt, 1); return -1; } cdev_init(&character_device, &fops); if((result = cdev_add(&character_device, devt, 1)) < 0) { printk(KERN_ALERT "Couldn't add character device\n"); device_destroy(device_class, devt); class_destroy(device_class); unregister_chrdev_region(devt, 1); return result; } return 0; } void cleanup_module(void) { device_destroy(device_class, devt); class_destroy(device_class); unregister_chrdev_region(devt, 1); } static int on_dev_uevent(struct device *dev, struct kobj_uevent_env *env) { add_uevent_var(env, "DEVMODE=%#o", 0444); return 0; } static int device_open(struct inode *inode, struct file *file) { try_module_get(THIS_MODULE); return 0; } static int device_release(struct inode *inode, struct file *file) { module_put(THIS_MODULE); return 0; } static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { int i = 0; if(*offset + length > bible_txt_len) { length = bible_txt_len - *offset; } for(; i < length; i++) { put_user(*(bible_txt + *offset + i), buffer + i); } *offset += length; return i; }