home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / test / io / dev / dev-mod.c < prev    next >
C/C++ Source or Header  |  2004-07-28  |  5KB  |  225 lines

  1. /*
  2.  * (C) 2001 Clemson University and The University of Chicago
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7. /* this is just a trivial module that provides a character device for 
  8.  * testing the pvfs2/src/io/dev/ code
  9.  */
  10.  
  11. #include <linux/module.h>
  12. #include <linux/config.h>
  13. #include <linux/kernel.h>
  14. #include <linux/version.h>
  15. #include <linux/fs.h>
  16. #include <linux/major.h>
  17. #include <linux/smp_lock.h>
  18. #include <linux/poll.h>
  19. #include <linux/slab.h>
  20. #include <asm/uaccess.h>
  21.  
  22. #include "pint-dev-shared.h"
  23.  
  24. #ifdef MODULE_LICENSE
  25. MODULE_LICENSE("GPL");
  26. #endif
  27.  
  28. EXPORT_NO_SYMBOLS;
  29.  
  30. ssize_t    pdev_read(struct file *, char *, size_t, loff_t *);
  31. ssize_t    pdev_writev(struct file *, const struct iovec *, unsigned long, 
  32.     loff_t *);
  33. int    pdev_open(struct inode *, struct file *);
  34. int    pdev_release(struct inode *, struct file *);
  35. int    pdev_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
  36. unsigned int pdev_poll(struct file *my_file, struct poll_table_struct *wait);
  37. static int __init pdev_init(void);
  38. static void __exit pdev_exit(void);
  39.  
  40. static struct file_operations pdev_fops = {
  41.     read:        pdev_read,
  42.     writev:        pdev_writev,
  43.     open:        pdev_open,
  44.     release:           pdev_release,
  45.     ioctl:        pdev_ioctl,
  46.     poll:        pdev_poll,
  47. };
  48.  
  49. static int pdev_major = 0;
  50. /* note: just picking these arbitrarily for testing */
  51. int32_t pdev_magic = 1234;
  52. int32_t pdev_max_upsize = 1024;
  53. int32_t pdev_max_downsize = 1024;
  54.  
  55. static int __init pdev_init(void)
  56. {
  57.  
  58.     int ret;
  59.    
  60. #ifdef HAVE_DEVFS
  61.     if ((ret = devfs_register_chrdev(0, "pvfs2-req", &pdev_fops)) < 0)
  62. #else
  63.     if ((ret = register_chrdev(0, "pvfs2-req", &pdev_fops)) < 0)
  64. #endif
  65.     {
  66.     printk("PDEV: failed to assign major number\n");
  67.     return -ENODEV;
  68.     }
  69.  
  70.     pdev_major = ret;
  71.  
  72. #ifdef HAVE_DEVFS
  73.     devfs_handle = devfs_register(NULL, "pvfs2-req", DEVFS_FL_DEFAULT,
  74.     pdev_major, 0, (S_IFCHR | S_IRUSR | S_IWUSR), &pdev_fops, NULL);
  75. #endif
  76.  
  77.     printk("PDEV: init successful\n");
  78.  
  79.     return 0;
  80. }
  81.  
  82. static void __exit pdev_exit(void)
  83. {
  84.  
  85. #ifdef HAVE_DEVFS
  86.     devfs_unregister(devfs_handle);
  87.     devfs_unregister_chrdev(pdev_major, "pvfs2-req");
  88. #else
  89.     unregister_chrdev(pdev_major, "pvfs2-req");
  90. #endif
  91.  
  92.     printk("PDEV: exit successful\n");
  93.     return;
  94. }
  95.  
  96. int pdev_open(struct inode *inode, struct file *filp)
  97. {
  98.     printk("PDEV: pdev_open()\n");
  99.     MOD_INC_USE_COUNT;
  100.     return(0);
  101. }
  102.  
  103. int pdev_release(struct inode *inode, struct file *filp)
  104. {
  105.     printk("PDEV: pdev_release()\n");
  106.     MOD_DEC_USE_COUNT;
  107.     return(0);
  108. }
  109.  
  110. int pdev_ioctl(struct inode *inode, 
  111.           struct file *flip,
  112.           unsigned int command, 
  113.           unsigned long arg)
  114. {
  115.     printk("PDEV: pdev_ioctl()\n");
  116.  
  117.     switch(command)
  118.     {
  119.     case(PVFS_DEV_GET_MAGIC):
  120.         copy_to_user((void*)arg, &pdev_magic, sizeof(int32_t)); 
  121.         return(0);
  122.     case(PVFS_DEV_GET_MAX_UPSIZE):
  123.         copy_to_user((void*)arg, &pdev_max_upsize, sizeof(int32_t)); 
  124.         return(0);
  125.     case(PVFS_DEV_GET_MAX_DOWNSIZE):
  126.         copy_to_user((void*)arg, &pdev_max_downsize, sizeof(int32_t)); 
  127.         return(0);
  128.     default:
  129.         return(-ENOSYS);
  130.     }
  131.  
  132.     return(-ENOSYS);
  133.  
  134. ssize_t    pdev_read(struct file *filp, char * buf, size_t size, loff_t *offp)
  135. {
  136.     char test_string[] = "Hello world.";
  137.     int64_t test_tag = 5;
  138.     void* tmp_buf = buf;
  139.  
  140.     printk("PDEV: pdev_read()\n");
  141.  
  142.     if(size < (strlen(test_string) + 1 + sizeof(int32_t) + sizeof(int64_t)))
  143.     {
  144.     return(-EMSGSIZE);
  145.     }
  146.  
  147.     /* copy out magic number */
  148.     copy_to_user(tmp_buf, &pdev_magic, sizeof(int32_t));
  149.     tmp_buf = (void*)((unsigned long)tmp_buf + sizeof(int32_t));
  150.     /* copy out tag */
  151.     copy_to_user(tmp_buf, &test_tag, sizeof(int64_t));
  152.     tmp_buf = (void*)((unsigned long)tmp_buf + sizeof(int64_t));
  153.     /* copy out message payload */
  154.     copy_to_user(tmp_buf, test_string, (strlen(test_string) + 1));
  155.  
  156.     return(strlen(test_string) + 1 + sizeof(int32_t) + sizeof(int64_t));
  157. }
  158.  
  159. ssize_t    pdev_writev(struct file *filp, const struct iovec* iov, 
  160.     unsigned long count, loff_t *offp)
  161. {
  162.     void* buffer = NULL;
  163.     void* offset;
  164.     int remaining = pdev_max_downsize;
  165.     int i;
  166.     int32_t* magic;
  167.     int64_t* tag;
  168.     char* payload = NULL;
  169.  
  170.     printk("PDEV: pdev_writev()\n");
  171.  
  172.     /* for simplicity's sake, lets always dump to a contiguous buffer and 
  173.      * then pull the message apart- logic is a bit complicated for handling 
  174.      * iovec directly 
  175.      */
  176.     buffer = kmalloc(pdev_max_downsize, GFP_KERNEL);
  177.     if(!buffer)
  178.     return(-ENOMEM);
  179.  
  180.     offset = buffer;
  181.     for(i=0; i<count; i++)
  182.     {
  183.     if(iov[i].iov_len > remaining)
  184.         return(-EMSGSIZE);
  185.     copy_from_user(offset, iov[i].iov_base, iov[i].iov_len);
  186.     remaining -= iov[i].iov_len;
  187.     offset = (void*)((unsigned long)offset + iov[i].iov_len);
  188.     }
  189.  
  190.     /* now, lets see what we got */
  191.     magic = (int32_t*)buffer;
  192.     tag = (int64_t*)((unsigned long)buffer + sizeof(int32_t));
  193.     payload = (char*)((unsigned long)tag + sizeof(int64_t));
  194.  
  195.     if(*magic != pdev_magic)
  196.     return(-EINVAL);
  197.  
  198.     printk("PDEV: magic: %d, tag: %d, payload: %s\n", (int)*magic, (int)*tag, 
  199.     payload);
  200.  
  201.     kfree(buffer);
  202.  
  203.     return(pdev_max_downsize - remaining);
  204. }
  205.  
  206. unsigned int pdev_poll(struct file *my_file, struct 
  207.     poll_table_struct *wait){
  208.  
  209.     /* the test module is always ready for IO ... */
  210.     return(POLLOUT|POLLWRNORM|POLLIN|POLLRDNORM);
  211. }
  212.  
  213. module_init(pdev_init);
  214. module_exit(pdev_exit);
  215.  
  216. /*
  217.  * Local variables:
  218.  *  c-indent-level: 4
  219.  *  c-basic-offset: 4
  220.  * End:
  221.  *
  222.  * vim: ts=8 sts=4 sw=4 expandtab
  223.  */
  224.