Use misc device.
[cascardo/kernel/samples/02.char/.git] / helloc.c
1 #include <linux/module.h>
2 /* Needed for struct file_operations and others */
3 #include <linux/fs.h>
4 /* Needed for struct cdev */
5 #include <linux/cdev.h>
6 /* Needed for copying to/from user space */
7 #include <asm/uaccess.h>
8 /* Needed for using misc device stuff */
9 #include <linux/miscdevice.h>
10
11 MODULE_LICENSE("GPL");
12 MODULE_AUTHOR("Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>");
13 MODULE_DESCRIPTION("A hello world char device");
14 MODULE_VERSION("1.0.0");
15
16 /* Message buffer we send to upstream */
17 static char helloc_message[] = "hello, world\n";
18
19 /* our read function writes our message to the user buffer */
20 static ssize_t helloc_read(struct file *filp, char __user *buf, size_t len,
21                            loff_t *pos)
22 {
23         int r;
24         /* do not read pass through the size of the message */
25         if (*pos >= sizeof(helloc_message))
26         /* return end of file */
27                 return 0;
28         /* if len is bigger than the rest of the message, clamp it */
29         if (len > sizeof(helloc_message) - *pos)
30                 len = sizeof(helloc_message) - *pos;
31         /* copy message to user space and return error if it fails */
32         r = copy_to_user(buf, helloc_message + *pos, len);
33         if (r)
34                 return -EFAULT;
35         /* update the file position */
36         *pos += len;
37         return len;
38 }
39
40 /* we only implement read */
41 static struct file_operations helloc_fops = {
42         .owner = THIS_MODULE,
43         .read = helloc_read,
44 };
45
46 static struct miscdevice hello_misc = {
47         .minor = MISC_DYNAMIC_MINOR,
48         .name = "helloc",
49         .fops = &helloc_fops,
50 };
51
52 static int __init helloc_init(void)
53 {
54         int r;
55         r = misc_register(&hello_misc);
56         return r;
57 }
58
59 static void __exit helloc_exit(void)
60 {
61         misc_deregister(&hello_misc);
62 }
63
64 module_init(helloc_init);
65 module_exit(helloc_exit);