📄 kiobuftest.c
字号:
/* * 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.1.1.1 2004/02/04 12:55:29 laputa * rel-1-0-0 laputa: s3c2410 smdk * - the file for default configuration is "arch/arm/def-configs/smdk2410" * - the default lcd controller is set the aiji board base * - if you need to support the meritech board you should be * changed aiji item off of menuconfig * * Revision 1.1.1.1 2004/01/14 04:41:38 laputa * dev-0-0-1 laputa: initial import of 2410 kernel * - the file for default configuration is "arch/arm/def-configs/smdk2410" * - the default lcd controller is set the aiji board base * * 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_tkiobuf_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 %d\n", 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 == %d\noffset == %d\nlength == %d\n", iobuf->nr_pages, iobuf->offset, iobuf->length); for(i = 0; i < iobuf->nr_pages; i++) { printk("page_add(maplist[%d]) == 0x%x\n", 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 __initkiobuftest_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 device\n");}module_init(kiobuftest_init);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -