X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fkernel%2Fsamples%2F02.char%2F.git;a=blobdiff_plain;f=helloc.c;h=afcca8303fc3286119b244ec4b7fe7aeb5170465;hp=9f983a204f6fbab652aa75248db8047682bae9df;hb=b6af013197d7fd10c5a647e60acef13e5e2a6bac;hpb=0f97392e9082dbf08807986bad7e1a20e781a807 diff --git a/helloc.c b/helloc.c index 9f983a2..afcca83 100644 --- a/helloc.c +++ b/helloc.c @@ -6,6 +6,9 @@ /* Needed for copying to/from user space */ #include #include +#include +#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Thadeu Lima de Souza Cascardo "); @@ -13,7 +16,6 @@ MODULE_DESCRIPTION("A hello world char device"); MODULE_VERSION("1.0.0"); #define BUFFER_SIZE 4096 -#define DEVICE_NUMBER 2 struct message { char *text; @@ -21,15 +23,13 @@ struct message { }; /* Message buffer we send to upstream */ -static struct message *hello_message[DEVICE_NUMBER]; +static struct message *hello_message; static int helloc_open(struct inode *ino, struct file *filp) { struct message *msg; printk(KERN_INFO "Opened file with minor %d\n", iminor(ino)); - if (iminor(ino) >= DEVICE_NUMBER) - return -ENODEV; - msg = hello_message[iminor(ino)]; + msg = hello_message; filp->private_data = msg; if (filp->f_flags & O_TRUNC) { memset(msg->text, 0, msg->len); @@ -108,83 +108,78 @@ static struct file_operations helloc_fops = { .write = helloc_write, }; -/* the device number and the char device struct */ -static dev_t dev; -static struct cdev *cdev; +static int hello_len_show(struct seq_file *seq, void *data) +{ + struct message *msg = seq->private; + seq_printf(seq, "%d\n", msg->len); + return 0; +} + +static int hello_proc_open(struct inode *ino, struct file *filp) +{ + return single_open(filp, hello_len_show, hello_message); +} + +static struct file_operations hello_proc_fops = { + .owner = THIS_MODULE, + .open = hello_proc_open, + .llseek = seq_lseek, + .read = seq_read, + .release = seq_release, +}; static void helloc_free(void) { - int i; - for (i = 0; i < DEVICE_NUMBER; i++) { - if (hello_message[i]) - kfree(hello_message[i]->text); - kfree(hello_message[i]); - } + if (hello_message) + kfree(hello_message->text); + kfree(hello_message); } static int __init helloc_alloc(void) { - int i; - for (i = 0; i < DEVICE_NUMBER; i++) { - hello_message[i] = kzalloc(sizeof(struct message), GFP_KERNEL); - if (!hello_message[i]) - goto out; - hello_message[i]->text = kzalloc(BUFFER_SIZE, GFP_KERNEL); - if (!hello_message[i]->text) - goto out; - } + hello_message = kzalloc(sizeof(struct message), GFP_KERNEL); + if (!hello_message) + return -ENOMEM; + hello_message->text = kzalloc(BUFFER_SIZE, GFP_KERNEL); + if (!hello_message->text) + goto out; return 0; out: - for (; i >= 0; i--) { - if (hello_message[i]) - kfree(hello_message[i]->text); - kfree(hello_message[i]); - } + kfree(hello_message); return -ENOMEM; } +static struct miscdevice hello_misc = { + .name = "hello", + .fops = &helloc_fops, + .minor = MISC_DYNAMIC_MINOR, +}; + static int __init helloc_init(void) { + struct proc_dir_entry *hello_pde; int r; r = helloc_alloc(); if (r) - goto out_alloc2; - /* allocate any major number with only one minor */ - r = alloc_chrdev_region(&dev, 0, DEVICE_NUMBER, "helloc"); - if (r) - goto out_region; - r = -ENOMEM; - /* print the major number allocated so we can create our device node */ - printk(KERN_INFO "Allocated major number %d\n", MAJOR(dev)); - /* allocate the character device struct */ - cdev = cdev_alloc(); - if (!cdev) goto out_alloc; - /* set the module owner and the file operations of our chardev */ - cdev->owner = THIS_MODULE; - cdev->ops = &helloc_fops; - /* register the chardev to the system */ - r = cdev_add(cdev, dev, DEVICE_NUMBER); + r = misc_register(&hello_misc); if (r) - goto out_add; + goto out_reg; + hello_pde = proc_create("hello_len", 0666, NULL, &hello_proc_fops); + if (!hello_pde) + goto out_pde; return 0; -out_add: - /* release memory allocated to the cdev device */ - kfree(cdev); +out_pde: + misc_deregister(&hello_misc); +out_reg: out_alloc: - /* release the device number allocated */ - unregister_chrdev_region(dev, DEVICE_NUMBER); -out_region: -out_alloc2: return r; } static void __exit helloc_exit(void) { - /* remove the chardev from the system */ - cdev_del(cdev); - /* release the device number allocated */ - unregister_chrdev_region(dev, DEVICE_NUMBER); + remove_proc_entry("hello_len", NULL); + misc_deregister(&hello_misc); helloc_free(); }