patch-2.4.4 linux/arch/cris/drivers/examples/kiobuftest.c
Next file: linux/arch/cris/drivers/gpio.c
Previous file: linux/arch/cris/drivers/ethernet.c
Back to the patch index
Back to the overall index
- Lines: 109
- Date:
Fri Apr 6 10:42:55 2001
- Orig file:
v2.4.3/linux/arch/cris/drivers/examples/kiobuftest.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/examples/kiobuftest.c linux/arch/cris/drivers/examples/kiobuftest.c
@@ -0,0 +1,108 @@
+/*
+ * 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 %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 __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 device\n");
+}
+
+module_init(kiobuftest_init);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)