kiobuftest.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
- /*
- * Example showing how to pin down a range of virtual pages from user-space
- * to be able to do for example DMA directly into them.
- *
- * It is necessary because the pages the virtual pointers reference, might
- * not exist in memory (could be mapped to the zero-page, filemapped etc)
- * and DMA cannot trigger the MMU to force them in (and would have time
- * contraints making it impossible to wait for it anyway).
- *
- * Author: Bjorn Wesen
- *
- * $Log: kiobuftest.c,v $
- * Revision 1.2 2001/02/27 13:52:50 bjornw
- * malloc.h -> slab.h
- *
- * Revision 1.1 2001/01/19 15:57:49 bjornw
- * Example of how to do direct HW -> user-mode DMA
- *
- *
- */
- #include <linux/module.h>
- #include <linux/sched.h>
- #include <linux/slab.h>
- #include <linux/errno.h>
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #include <linux/string.h>
- #include <linux/init.h>
- #include <linux/mm.h>
- #include <linux/iobuf.h>
- #define KIOBUFTEST_MAJOR 124 /* in the local range, experimental */
- static ssize_t
- kiobuf_read(struct file *filp, char *buf, size_t len, loff_t *ppos)
- {
- struct kiobuf *iobuf;
- int res, i;
-
- /* Make a kiobuf that maps the entire length the reader has given
- * us
- */
- res = alloc_kiovec(1, &iobuf);
- if (res)
- return res;
-
- if((res = map_user_kiobuf(READ, iobuf, (unsigned long)buf, len))) {
- printk("map_user_kiobuf failed, return %dn", res);
- return res;
- }
- /* At this point, the virtual area buf[0] -> buf[len-1] will
- * have corresponding pages mapped in physical memory and locked
- * until we unmap the kiobuf. They cannot be swapped out or moved
- * around.
- */
- printk("nr_pages == %dnoffset == %dnlength == %dn",
- iobuf->nr_pages, iobuf->offset, iobuf->length);
- for(i = 0; i < iobuf->nr_pages; i++) {
- printk("page_add(maplist[%d]) == 0x%xn", i,
- page_address(iobuf->maplist[i]));
- }
- /* This is the place to create the necessary scatter-gather vector
- * for the DMA using the iobuf->maplist array and page_address
- * (don't forget __pa if the DMA needs the actual physical DRAM address)
- * and run it.
- */
- /* Release the mapping and exit */
- unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */
- return len;
- }
- static struct file_operations kiobuf_fops = {
- owner: THIS_MODULE,
- read: kiobuf_read
- };
- static int __init
- kiobuftest_init(void)
- {
- int res;
- /* register char device */
- res = register_chrdev(KIOBUFTEST_MAJOR, "kiobuftest", &kiobuf_fops);
- if(res < 0) {
- printk(KERN_ERR "kiobuftest: couldn't get a major number.n");
- return res;
- }
- printk("Initializing kiobuf-test devicen");
- }
- module_init(kiobuftest_init);