kiobuftest.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Example showing how to pin down a range of virtual pages from user-space
  3.  * to be able to do for example DMA directly into them.
  4.  *
  5.  * It is necessary because the pages the virtual pointers reference, might
  6.  * not exist in memory (could be mapped to the zero-page, filemapped etc)
  7.  * and DMA cannot trigger the MMU to force them in (and would have time 
  8.  * contraints making it impossible to wait for it anyway).
  9.  *
  10.  * Author:  Bjorn Wesen
  11.  *
  12.  * $Log: kiobuftest.c,v $
  13.  * Revision 1.2  2001/02/27 13:52:50  bjornw
  14.  * malloc.h -> slab.h
  15.  *
  16.  * Revision 1.1  2001/01/19 15:57:49  bjornw
  17.  * Example of how to do direct HW -> user-mode DMA
  18.  *
  19.  *
  20.  */
  21. #include <linux/module.h>
  22. #include <linux/sched.h>
  23. #include <linux/slab.h>
  24. #include <linux/errno.h>
  25. #include <linux/kernel.h>
  26. #include <linux/fs.h>
  27. #include <linux/string.h>
  28. #include <linux/init.h>
  29. #include <linux/mm.h>
  30. #include <linux/iobuf.h>
  31. #define KIOBUFTEST_MAJOR 124  /* in the local range, experimental */
  32. static ssize_t
  33. kiobuf_read(struct file *filp, char *buf, size_t len, loff_t *ppos)
  34. {
  35.      struct kiobuf *iobuf;
  36.      int res, i;
  37.  
  38.      /* Make a kiobuf that maps the entire length the reader has given
  39.       * us
  40.       */
  41.      res = alloc_kiovec(1, &iobuf);
  42.      if (res)
  43.      return res;
  44.      
  45.      if((res = map_user_kiobuf(READ, iobuf, (unsigned long)buf, len))) {
  46.      printk("map_user_kiobuf failed, return %dn", res);
  47.      return res;
  48.      }
  49.      /* At this point, the virtual area buf[0] -> buf[len-1] will
  50.       * have corresponding pages mapped in physical memory and locked
  51.       * until we unmap the kiobuf. They cannot be swapped out or moved
  52.       * around.
  53.       */
  54.      printk("nr_pages == %dnoffset == %dnlength == %dn",
  55.     iobuf->nr_pages, iobuf->offset, iobuf->length);
  56.      for(i = 0; i < iobuf->nr_pages; i++) {
  57.      printk("page_add(maplist[%d]) == 0x%xn", i,
  58.     page_address(iobuf->maplist[i]));
  59.      }
  60.      /* This is the place to create the necessary scatter-gather vector
  61.       * for the DMA using the iobuf->maplist array and page_address
  62.       * (don't forget __pa if the DMA needs the actual physical DRAM address)
  63.       * and run it.
  64.       */
  65.      /* Release the mapping and exit */
  66.      unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */
  67.      return len;
  68. }
  69. static struct file_operations kiobuf_fops = {
  70. owner:    THIS_MODULE,
  71. read:     kiobuf_read
  72. };
  73. static int __init
  74. kiobuftest_init(void)
  75. {
  76. int res;
  77. /* register char device */
  78. res = register_chrdev(KIOBUFTEST_MAJOR, "kiobuftest", &kiobuf_fops);
  79. if(res < 0) {
  80. printk(KERN_ERR "kiobuftest: couldn't get a major number.n");
  81. return res;
  82. }
  83. printk("Initializing kiobuf-test devicen");
  84. }
  85. module_init(kiobuftest_init);