Change to misc device. master
authorThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Wed, 9 Dec 2009 10:59:09 +0000 (08:59 -0200)
committerThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Wed, 9 Dec 2009 10:59:09 +0000 (08:59 -0200)
helloc.c

index b0271df..afcca83 100644 (file)
--- a/helloc.c
+++ b/helloc.c
@@ -8,6 +8,7 @@
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/miscdevice.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>");
@@ -15,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;
@@ -23,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);
@@ -119,7 +117,7 @@ static int hello_len_show(struct seq_file *seq, void *data)
 
 static int hello_proc_open(struct inode *ino, struct file *filp)
 {
-       return single_open(filp, hello_len_show, hello_message[0]);
+       return single_open(filp, hello_len_show, hello_message);
 }
 
 static struct file_operations hello_proc_fops = {
@@ -130,91 +128,58 @@ static struct file_operations hello_proc_fops = {
        .release = seq_release,
 };
 
-
-/* the device number and the char device struct */
-static dev_t dev;
-static struct cdev *cdev;
-
 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_pde:
-       cdev_del(cdev);
-out_add:
-       /* release memory allocated to the cdev device */
-       kfree(cdev);
+       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_proc_entry("hello_len", NULL);
-       /* remove the chardev from the system */
-       cdev_del(cdev);
-       /* release the device number allocated */
-       unregister_chrdev_region(dev, DEVICE_NUMBER);
+       misc_deregister(&hello_misc);
        helloc_free();
 }