Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * Written by Pekka Paalanen, 2008-2009 <pq@iki.fi>
  3  */
  4 #include <linux/module.h>
  5 #include <linux/io.h>
  6 #include <linux/mmiotrace.h>
  7 
  8 #define MODULE_NAME "testmmiotrace"
  9 
 10 static unsigned long mmio_address;
 11 module_param(mmio_address, ulong, 0);
 12 MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
 13                                 "(or 8 MB if read_far is non-zero).");
 14 
 15 static unsigned long read_far = 0x400100;
 16 module_param(read_far, ulong, 0);
 17 MODULE_PARM_DESC(read_far, " Offset of a 32-bit read within 8 MB "
 18                                 "(default: 0x400100).");
 19 
 20 static unsigned v16(unsigned i)
 21 {
 22         return i * 12 + 7;
 23 }
 24 
 25 static unsigned v32(unsigned i)
 26 {
 27         return i * 212371 + 13;
 28 }
 29 
 30 static void do_write_test(void __iomem *p)
 31 {
 32         unsigned int i;
 33         pr_info(MODULE_NAME ": write test.\n");
 34         mmiotrace_printk("Write test.\n");
 35 
 36         for (i = 0; i < 256; i++)
 37                 iowrite8(i, p + i);
 38 
 39         for (i = 1024; i < (5 * 1024); i += 2)
 40                 iowrite16(v16(i), p + i);
 41 
 42         for (i = (5 * 1024); i < (16 * 1024); i += 4)
 43                 iowrite32(v32(i), p + i);
 44 }
 45 
 46 static void do_read_test(void __iomem *p)
 47 {
 48         unsigned int i;
 49         unsigned errs[3] = { 0 };
 50         pr_info(MODULE_NAME ": read test.\n");
 51         mmiotrace_printk("Read test.\n");
 52 
 53         for (i = 0; i < 256; i++)
 54                 if (ioread8(p + i) != i)
 55                         ++errs[0];
 56 
 57         for (i = 1024; i < (5 * 1024); i += 2)
 58                 if (ioread16(p + i) != v16(i))
 59                         ++errs[1];
 60 
 61         for (i = (5 * 1024); i < (16 * 1024); i += 4)
 62                 if (ioread32(p + i) != v32(i))
 63                         ++errs[2];
 64 
 65         mmiotrace_printk("Read errors: 8-bit %d, 16-bit %d, 32-bit %d.\n",
 66                                                 errs[0], errs[1], errs[2]);
 67 }
 68 
 69 static void do_read_far_test(void __iomem *p)
 70 {
 71         pr_info(MODULE_NAME ": read far test.\n");
 72         mmiotrace_printk("Read far test.\n");
 73 
 74         ioread32(p + read_far);
 75 }
 76 
 77 static void do_test(unsigned long size)
 78 {
 79         void __iomem *p = ioremap_nocache(mmio_address, size);
 80         if (!p) {
 81                 pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
 82                 return;
 83         }
 84         mmiotrace_printk("ioremap returned %p.\n", p);
 85         do_write_test(p);
 86         do_read_test(p);
 87         if (read_far && read_far < size - 4)
 88                 do_read_far_test(p);
 89         iounmap(p);
 90 }
 91 
 92 static int __init init(void)
 93 {
 94         unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
 95 
 96         if (mmio_address == 0) {
 97                 pr_err(MODULE_NAME ": you have to use the module argument "
 98                                                         "mmio_address.\n");
 99                 pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS"
100                                 " YOU REALLY KNOW WHAT YOU ARE DOING!\n");
101                 return -ENXIO;
102         }
103 
104         pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI "
105                 "address space, and writing 16 kB of rubbish in there.\n",
106                  size >> 10, mmio_address);
107         do_test(size);
108         pr_info(MODULE_NAME ": All done.\n");
109         return 0;
110 }
111 
112 static void __exit cleanup(void)
113 {
114         pr_debug(MODULE_NAME ": unloaded.\n");
115 }
116 
117 module_init(init);
118 module_exit(cleanup);
119 MODULE_LICENSE("GPL");
120 
  This page was automatically generated by the LXR engine.