1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Chapter 3. Writing your own kernel module</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="The Userspace I/O HOWTO"><link rel="up" href="index.html" title="The Userspace I/O HOWTO"><link rel="prev" href="about.html" title="Chapter 2. About UIO"><link rel="next" href="adding_irq_handler.html" title="Adding an interrupt handler"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 3. Writing your own kernel module</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="about.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="adding_irq_handler.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="custom_kernel_module"></a>Chapter 3. Writing your own kernel module</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="custom_kernel_module.html#uio_info">struct uio_info</a></span></dt><dt><span class="sect1"><a href="adding_irq_handler.html">Adding an interrupt handler</a></span></dt><dt><span class="sect1"><a href="using_uio_pdrv.html">Using uio_pdrv for platform devices</a></span></dt><dt><span class="sect1"><a href="using_uio_pdrv_genirq.html">Using uio_pdrv_genirq for platform devices</a></span></dt><dt><span class="sect1"><a href="using-uio_dmem_genirq.html">Using uio_dmem_genirq for platform devices</a></span></dt></dl></div><p> 2 Please have a look at <code class="filename">uio_cif.c</code> as an 3 example. The following paragraphs explain the different 4 sections of this file. 5 </p><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="uio_info"></a>struct uio_info</h2></div></div></div><p> 6 This structure tells the framework the details of your driver, 7 Some of the members are required, others are optional. 8 </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> 9<code class="varname">const char *name</code>: Required. The name of your driver as 10it will appear in sysfs. I recommend using the name of your module for this. 11</p></li><li class="listitem"><p> 12<code class="varname">const char *version</code>: Required. This string appears in 13<code class="filename">/sys/class/uio/uioX/version</code>. 14</p></li><li class="listitem"><p> 15<code class="varname">struct uio_mem mem[ MAX_UIO_MAPS ]</code>: Required if you 16have memory that can be mapped with <code class="function">mmap()</code>. For each 17mapping you need to fill one of the <code class="varname">uio_mem</code> structures. 18See the description below for details. 19</p></li><li class="listitem"><p> 20<code class="varname">struct uio_port port[ MAX_UIO_PORTS_REGIONS ]</code>: Required 21if you want to pass information about ioports to userspace. For each port 22region you need to fill one of the <code class="varname">uio_port</code> structures. 23See the description below for details. 24</p></li><li class="listitem"><p> 25<code class="varname">long irq</code>: Required. If your hardware generates an 26interrupt, it's your modules task to determine the irq number during 27initialization. If you don't have a hardware generated interrupt but 28want to trigger the interrupt handler in some other way, set 29<code class="varname">irq</code> to <code class="varname">UIO_IRQ_CUSTOM</code>. 30If you had no interrupt at all, you could set 31<code class="varname">irq</code> to <code class="varname">UIO_IRQ_NONE</code>, though this 32rarely makes sense. 33</p></li><li class="listitem"><p> 34<code class="varname">unsigned long irq_flags</code>: Required if you've set 35<code class="varname">irq</code> to a hardware interrupt number. The flags given 36here will be used in the call to <code class="function">request_irq()</code>. 37</p></li><li class="listitem"><p> 38<code class="varname">int (*mmap)(struct uio_info *info, struct vm_area_struct 39*vma)</code>: Optional. If you need a special 40<code class="function">mmap()</code> function, you can set it here. If this 41pointer is not NULL, your <code class="function">mmap()</code> will be called 42instead of the built-in one. 43</p></li><li class="listitem"><p> 44<code class="varname">int (*open)(struct uio_info *info, struct inode *inode) 45</code>: Optional. You might want to have your own 46<code class="function">open()</code>, e.g. to enable interrupts only when your 47device is actually used. 48</p></li><li class="listitem"><p> 49<code class="varname">int (*release)(struct uio_info *info, struct inode *inode) 50</code>: Optional. If you define your own 51<code class="function">open()</code>, you will probably also want a custom 52<code class="function">release()</code> function. 53</p></li><li class="listitem"><p> 54<code class="varname">int (*irqcontrol)(struct uio_info *info, s32 irq_on) 55</code>: Optional. If you need to be able to enable or disable 56interrupts from userspace by writing to <code class="filename">/dev/uioX</code>, 57you can implement this function. The parameter <code class="varname">irq_on</code> 58will be 0 to disable interrupts and 1 to enable them. 59</p></li></ul></div><p> 60Usually, your device will have one or more memory regions that can be mapped 61to user space. For each region, you have to set up a 62<code class="varname">struct uio_mem</code> in the <code class="varname">mem[]</code> array. 63Here's a description of the fields of <code class="varname">struct uio_mem</code>: 64</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> 65<code class="varname">const char *name</code>: Optional. Set this to help identify 66the memory region, it will show up in the corresponding sysfs node. 67</p></li><li class="listitem"><p> 68<code class="varname">int memtype</code>: Required if the mapping is used. Set this to 69<code class="varname">UIO_MEM_PHYS</code> if you you have physical memory on your 70card to be mapped. Use <code class="varname">UIO_MEM_LOGICAL</code> for logical 71memory (e.g. allocated with <code class="function">kmalloc()</code>). There's also 72<code class="varname">UIO_MEM_VIRTUAL</code> for virtual memory. 73</p></li><li class="listitem"><p> 74<code class="varname">phys_addr_t addr</code>: Required if the mapping is used. 75Fill in the address of your memory block. This address is the one that 76appears in sysfs. 77</p></li><li class="listitem"><p> 78<code class="varname">resource_size_t size</code>: Fill in the size of the 79memory block that <code class="varname">addr</code> points to. If <code class="varname">size</code> 80is zero, the mapping is considered unused. Note that you 81<span class="emphasis"><em>must</em></span> initialize <code class="varname">size</code> with zero for 82all unused mappings. 83</p></li><li class="listitem"><p> 84<code class="varname">void *internal_addr</code>: If you have to access this memory 85region from within your kernel module, you will want to map it internally by 86using something like <code class="function">ioremap()</code>. Addresses 87returned by this function cannot be mapped to user space, so you must not 88store it in <code class="varname">addr</code>. Use <code class="varname">internal_addr</code> 89instead to remember such an address. 90</p></li></ul></div><p> 91Please do not touch the <code class="varname">map</code> element of 92<code class="varname">struct uio_mem</code>! It is used by the UIO framework 93to set up sysfs files for this mapping. Simply leave it alone. 94</p><p> 95Sometimes, your device can have one or more port regions which can not be 96mapped to userspace. But if there are other possibilities for userspace to 97access these ports, it makes sense to make information about the ports 98available in sysfs. For each region, you have to set up a 99<code class="varname">struct uio_port</code> in the <code class="varname">port[]</code> array. 100Here's a description of the fields of <code class="varname">struct uio_port</code>: 101</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> 102<code class="varname">char *porttype</code>: Required. Set this to one of the predefined 103constants. Use <code class="varname">UIO_PORT_X86</code> for the ioports found in x86 104architectures. 105</p></li><li class="listitem"><p> 106<code class="varname">unsigned long start</code>: Required if the port region is used. 107Fill in the number of the first port of this region. 108</p></li><li class="listitem"><p> 109<code class="varname">unsigned long size</code>: Fill in the number of ports in this 110region. If <code class="varname">size</code> is zero, the region is considered unused. 111Note that you <span class="emphasis"><em>must</em></span> initialize <code class="varname">size</code> 112with zero for all unused regions. 113</p></li></ul></div><p> 114Please do not touch the <code class="varname">portio</code> element of 115<code class="varname">struct uio_port</code>! It is used internally by the UIO 116framework to set up sysfs files for this region. Simply leave it alone. 117</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="about.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="adding_irq_handler.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. About UIO </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Adding an interrupt handler</td></tr></table></div></body></html> 118