Advertisement
utroz

char dev driver

Jan 28th, 2012
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.90 KB | None | 0 0
  1. /*
  2.  *  chardev.c: Creates a read-write char device
  3.  *  You can write a data into buffer and read it later.
  4.  *
  5.  *  PS: Write features: Added by Raphael S.Carvalho
  6.  */
  7.  
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/fs.h>
  11. #include <asm/uaccess.h>    /* for put_user */
  12.  
  13. MODULE_LICENSE("GPL");
  14. MODULE_AUTHOR("Raphael S.Carvalho <[email protected]>");
  15.  
  16. /*  
  17.  *  Prototypes - this would normally go in a .h file
  18.  */
  19. int init_module(void);
  20. void cleanup_module(void);
  21. static int device_open(struct inode *, struct file *);
  22. static int device_release(struct inode *, struct file *);
  23. static ssize_t device_read(struct file *, char *, size_t, loff_t *);
  24. static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
  25.  
  26. #define SUCCESS 0
  27. #define BUF_LEN 80      /* Max length of the message from the device */
  28.  
  29. /*
  30.  * Global variables are declared as static, so are global within the file.
  31.  */
  32.  
  33. static int Major;       /* Major number assigned to our device driver */
  34. static int Device_Open = 0; /* Is device open?  
  35.                  * Used to prevent multiple access to device */
  36. static char msg[BUF_LEN];   /* The msg the device will give when asked */
  37. static char *msg_Ptr;
  38.  
  39. /* Device Name */
  40. static char *dev_name = "default_name";
  41.  
  42. module_param(dev_name, charp, 0000);
  43. MODULE_PARM_DESC(dev_name, "Specify the character device name.");
  44.  
  45. static struct file_operations fops = {
  46.     .read = device_read,
  47.     .write = device_write,
  48.     .open = device_open,
  49.     .release = device_release
  50. };
  51.  
  52. /*
  53.  * This function is called when the module is loaded
  54.  */
  55. int init_module(void)
  56. {
  57.         Major = register_chrdev(0, dev_name, &fops);
  58.  
  59.     if (Major < 0) {
  60.       printk(KERN_ALERT "Registering char device failed with %d\n", Major);
  61.       return Major;
  62.     }
  63.  
  64.     printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major);
  65.     printk(KERN_INFO "the driver, create a dev file with\n");
  66.     printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", dev_name, Major);
  67.     printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n");
  68.     printk(KERN_INFO "the device file.\n");
  69.     printk(KERN_INFO "Remove the device file and module when done.\n");
  70.  
  71.     return SUCCESS;
  72. }
  73.  
  74. /*
  75.  * This function is called when the module is unloaded
  76.  */
  77. void cleanup_module(void)
  78. {
  79.     /*
  80.      * Unregister the device
  81.      */
  82.     //int ret;
  83.     unregister_chrdev(Major, dev_name);
  84.     //if (ret < 0)
  85.     //  printk(KERN_ALERT "Error in unregister_chrdev: %d\n", ret);
  86. }
  87.  
  88. /*
  89.  * Methods
  90.  */
  91.  
  92. /*
  93.  * Called when a process tries to open the device file, like
  94.  * "cat /dev/mycharfile"
  95.  */
  96. static int device_open(struct inode *inode, struct file *file)
  97. {
  98.     //static int counter = 0;
  99.  
  100.     if (Device_Open)
  101.         return -EBUSY;
  102.  
  103.     Device_Open++;
  104.     //sprintf(msg, "I already told you %d times Hello world!\n", counter++);
  105.     msg_Ptr = msg;
  106.     try_module_get(THIS_MODULE);
  107.  
  108.     return SUCCESS;
  109. }
  110.  
  111. /*
  112.  * Called when a process closes the device file.
  113.  */
  114. static int device_release(struct inode *inode, struct file *file)
  115. {
  116.     Device_Open--;      /* We're now ready for our next caller */
  117.  
  118.     /*
  119.      * Decrement the usage count, or else once you opened the file, you'll
  120.      * never get get rid of the module.
  121.      */
  122.     module_put(THIS_MODULE);
  123.  
  124.     return 0;
  125. }
  126.  
  127. /*
  128.  * Called when a process, which already opened the dev file, attempts to
  129.  * read from it.
  130.  */
  131. static ssize_t device_read(struct file *filp,   /* see include/linux/fs.h   */
  132.                char *buffer,    /* buffer to fill with data */
  133.                size_t length,   /* length of the buffer     */
  134.                loff_t * offset)
  135. {
  136.     /*
  137.      * Number of bytes actually written to the buffer
  138.      */
  139.     int bytes_read = 0;
  140.  
  141.     /*
  142.      * If we're at the end of the message,
  143.      * return 0 signifying end of file
  144.      */
  145.     if (*msg_Ptr == 0)
  146.         return 0;
  147.  
  148.     /*
  149.      * Actually put the data into the buffer
  150.      */
  151.     while (length && *msg_Ptr) {
  152.  
  153.         /*
  154.          * The buffer is in the user data segment, not the kernel
  155.          * segment so "*" assignment won't work.  We have to use
  156.          * put_user which copies data from the kernel data segment to
  157.          * the user data segment.
  158.          */
  159.         put_user(*(msg_Ptr++), buffer++);
  160.  
  161.         length--;
  162.         bytes_read++;
  163.     }
  164.  
  165.     /*
  166.      * Most read functions return the number of bytes put into the buffer
  167.      */
  168.     return bytes_read;
  169. }
  170.  
  171. /*  
  172.  * Called when a process writes to dev file: echo "hi" > /dev/hello
  173.  */
  174. static ssize_t
  175. device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
  176. {
  177.         /*
  178.      * Number of bytes actually written to the buffer
  179.      */
  180.     int bytes_write = 0;
  181.    
  182.     if(len > BUF_LEN) {
  183.         printk(KERN_ALERT "Sorry, the buffer has more length than permitted by the module.\n");
  184.         return -EINVAL;
  185.     }
  186.    
  187.     /*
  188.      * Actually put the data into the buffer
  189.      */
  190.     while (len && *buff) {
  191.  
  192.         /* We'll write data in the buffer now */
  193.         *(msg_Ptr++) = *(buff++);
  194.        
  195.         len--;
  196.         bytes_write++;
  197.     }
  198.  
  199.     /*
  200.      * Most write functions return the number of bytes put into the buffer
  201.      */
  202.     return bytes_write;
  203. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement