Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/slab.h>
- #include <linux/uaccess.h>
- #include <linux/proc_fs.h>
- #include "m.h"
- #define OPTIMAL_COPY_SIZE (32 * 1024)
- int init_module(void);
- void cleanup_module(void);
- static int m_open(struct inode *, struct file *);
- static int m_release(struct inode *, struct file *);
- static long m_ioctl(struct file *, unsigned int, unsigned long);
- static int display_copy_count(char *buffer, char **start, off_t offset, int len, int *eof, void *data);
- const struct file_operations m_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = m_ioctl,
- .open = m_open,
- .release = m_release,
- };
- struct proc_dir_entry *cavium;
- struct proc_dir_entry *copy_count;
- unsigned long long COPY_COUNT;
- unsigned long long CALL_COUNT;
- static int display_copy_count(char *buffer, char **start, off_t offset, int len, int *eof, void *data)
- {
- int count;
- count = sprintf(buffer, "No of calls .......: %lld\n", CALL_COUNT);
- count += sprintf(buffer + count, "Bytes copied ......: %lld\n", COPY_COUNT);
- *eof = 1;
- COPY_COUNT = 0;
- CALL_COUNT = 0;
- return count;
- }
- static int m_open(struct inode *inode, struct file *file)
- {
- return 0;
- }
- static int m_release(struct inode *inode, struct file *file)
- {
- return 0;
- }
- /* allocate and copy optimal size */
- static long m_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
- {
- void __user *argp = (void __user *)arg;
- struct copy_cmd *ioctl_cmd;
- int rc = -1;
- int data_copied = 0, data_to_copy;
- char *data;
- switch (cmd) {
- case M_COPY_CMS:
- ioctl_cmd = (struct copy_cmd *) argp;
- while (data_copied < ioctl_cmd->copy_bytes) {
- if ((ioctl_cmd->copy_bytes - data_copied) >= OPTIMAL_COPY_SIZE)
- data_to_copy = OPTIMAL_COPY_SIZE;
- else
- data_to_copy = ioctl_cmd->copy_bytes - data_copied;
- data = kmalloc(data_to_copy, GFP_ATOMIC);
- if (data == NULL) {
- pr_info("%s:%d: out of memory\n", __func__, __LINE__);
- return rc;
- }
- if (copy_from_user(data, ioctl_cmd->copy_buffer, data_to_copy) > 0) {
- pr_info("%s:%d: bad memory from user\n", __func__, __LINE__);
- kfree(data);
- return rc;
- }
- kfree(data);
- data_copied += data_to_copy;
- COPY_COUNT += data_to_copy;
- CALL_COUNT++;
- }
- rc = ioctl_cmd->copy_bytes;
- break;
- default:
- pr_info("m:invalid ioctl\n");
- }
- return rc;
- }
- int init_module()
- {
- COPY_COUNT = 0;
- CALL_COUNT = 0;
- if (register_chrdev(M_DEVICE_MAJOR, "m", &m_fops)) {
- pr_info("m: init_module: unable to get major # %d\n", M_DEVICE_MAJOR);
- return -ENODEV;
- }
- cavium = proc_mkdir("cavium", NULL);
- if (cavium == NULL) {
- pr_info("m:unable to creat /proc/cavium");
- goto unregister;
- }
- copy_count = create_proc_entry("copy_count", S_IFREG|S_IRUGO, cavium);
- if (copy_count == NULL) {
- pr_info("m:unable to creat /proc/cavium/copy_count");
- goto remove_cavium;
- }
- copy_count->read_proc = display_copy_count;
- copy_count->write_proc = NULL;
- pr_info("module:m loaded\n");
- normal:
- return 0;
- remove_cavium:
- remove_proc_entry("cavium", NULL);
- unregister:
- unregister_chrdev(M_DEVICE_MAJOR, "m");
- goto normal;
- }
- void cleanup_module()
- {
- remove_proc_entry("copy_count", cavium);
- remove_proc_entry("cavium", NULL);
- unregister_chrdev(M_DEVICE_MAJOR, "m");
- pr_info("module:m unloaded\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement