Advertisement
Guest User

m.c

a guest
Jun 7th, 2012
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.33 KB | None | 0 0
  1. #include <linux/module.h>
  2. #include <linux/fs.h>
  3. #include <linux/slab.h>
  4. #include <linux/uaccess.h>
  5. #include <linux/proc_fs.h>
  6. #include "m.h"
  7.  
  8. #define OPTIMAL_COPY_SIZE   (32 * 1024)
  9.  
  10. int     init_module(void);
  11. void        cleanup_module(void);
  12. static int  m_open(struct inode *, struct file *);
  13. static int  m_release(struct inode *, struct file *);
  14. static long m_ioctl(struct file *, unsigned int, unsigned long);
  15. static int display_copy_count(char *buffer, char **start, off_t offset, int len, int *eof, void *data);
  16.  
  17. const struct file_operations m_fops = {
  18.     .owner   = THIS_MODULE,
  19.     .unlocked_ioctl   = m_ioctl,
  20.     .open    = m_open,
  21.     .release = m_release,
  22. };
  23.  
  24. struct proc_dir_entry *cavium;
  25. struct proc_dir_entry *copy_count;
  26. unsigned long long COPY_COUNT;
  27. unsigned long long CALL_COUNT;
  28.  
  29. static int display_copy_count(char *buffer, char **start, off_t offset, int len, int *eof, void *data)
  30. {
  31.     int count;
  32.  
  33.     count = sprintf(buffer, "No of calls .......: %lld\n", CALL_COUNT);
  34.     count += sprintf(buffer + count, "Bytes copied ......: %lld\n", COPY_COUNT);
  35.     *eof = 1;
  36.     COPY_COUNT = 0;
  37.     CALL_COUNT = 0;
  38.  
  39.     return count;
  40. }
  41.  
  42. static int m_open(struct inode *inode, struct file *file)
  43. {
  44.     return 0;
  45. }
  46.  
  47. static int m_release(struct inode *inode, struct file *file)
  48. {
  49.     return 0;
  50. }
  51.  
  52. /* allocate and copy optimal size */
  53. static long m_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  54. {
  55.     void __user *argp = (void __user *)arg;
  56.     struct copy_cmd *ioctl_cmd;
  57.     int rc = -1;
  58.  
  59.     int data_copied = 0, data_to_copy;
  60.     char *data;
  61.  
  62.     switch (cmd) {
  63.     case M_COPY_CMS:
  64.         ioctl_cmd = (struct copy_cmd *) argp;
  65.  
  66.         while (data_copied < ioctl_cmd->copy_bytes) {
  67.             if ((ioctl_cmd->copy_bytes - data_copied) >= OPTIMAL_COPY_SIZE)
  68.                 data_to_copy = OPTIMAL_COPY_SIZE;
  69.             else
  70.                 data_to_copy = ioctl_cmd->copy_bytes - data_copied;
  71.  
  72.             data = kmalloc(data_to_copy, GFP_ATOMIC);
  73.             if (data == NULL) {
  74.                 pr_info("%s:%d: out of memory\n", __func__, __LINE__);
  75.                 return rc;
  76.             }
  77.  
  78.             if (copy_from_user(data, ioctl_cmd->copy_buffer, data_to_copy)  > 0) {
  79.                 pr_info("%s:%d: bad memory from user\n", __func__, __LINE__);
  80.                 kfree(data);
  81.                 return rc;
  82.             }
  83.  
  84.             kfree(data);
  85.             data_copied += data_to_copy;
  86.             COPY_COUNT += data_to_copy;
  87.             CALL_COUNT++;
  88.         }
  89.  
  90.         rc = ioctl_cmd->copy_bytes;
  91.     break;
  92.  
  93.     default:
  94.         pr_info("m:invalid ioctl\n");
  95.     }
  96.     return rc;
  97. }
  98.  
  99. int init_module()
  100. {
  101.     COPY_COUNT = 0;
  102.     CALL_COUNT = 0;
  103.     if (register_chrdev(M_DEVICE_MAJOR, "m", &m_fops)) {
  104.         pr_info("m: init_module: unable to get major # %d\n", M_DEVICE_MAJOR);
  105.         return -ENODEV;
  106.     }
  107.  
  108.     cavium = proc_mkdir("cavium", NULL);
  109.     if (cavium == NULL) {
  110.         pr_info("m:unable to creat /proc/cavium");
  111.         goto unregister;
  112.     }
  113.  
  114.     copy_count = create_proc_entry("copy_count", S_IFREG|S_IRUGO, cavium);
  115.     if (copy_count == NULL) {
  116.         pr_info("m:unable to creat /proc/cavium/copy_count");
  117.         goto remove_cavium;
  118.     }
  119.  
  120.     copy_count->read_proc = display_copy_count;
  121.     copy_count->write_proc = NULL;
  122.  
  123.     pr_info("module:m loaded\n");
  124.  
  125. normal:
  126.     return 0;
  127.  
  128. remove_cavium:
  129.     remove_proc_entry("cavium", NULL);
  130.  
  131. unregister:
  132.     unregister_chrdev(M_DEVICE_MAJOR, "m");
  133.  
  134.     goto normal;
  135. }
  136.  
  137. void cleanup_module()
  138. {
  139.     remove_proc_entry("copy_count", cavium);
  140.     remove_proc_entry("cavium", NULL);
  141.     unregister_chrdev(M_DEVICE_MAJOR, "m");
  142.     pr_info("module:m unloaded\n");
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement