aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/kernel-api.tmpl4
-rw-r--r--Documentation/DocBook/uio-howto.tmpl611
-rw-r--r--drivers/Kconfig1
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/uio/Kconfig29
-rw-r--r--drivers/uio/Makefile2
-rw-r--r--drivers/uio/uio.c701
-rw-r--r--drivers/uio/uio_cif.c156
-rw-r--r--include/linux/uio_driver.h91
9 files changed, 1596 insertions, 0 deletions
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index fd2ef4d29b6d..a0af560ed740 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -408,6 +408,10 @@ X!Edrivers/pnp/system.c
408!Edrivers/pnp/manager.c 408!Edrivers/pnp/manager.c
409!Edrivers/pnp/support.c 409!Edrivers/pnp/support.c
410 </sect1> 410 </sect1>
411 <sect1><title>Userspace IO devices</title>
412!Edrivers/uio/uio.c
413!Iinclude/linux/uio_driver.h
414 </sect1>
411 </chapter> 415 </chapter>
412 416
413 <chapter id="blkdev"> 417 <chapter id="blkdev">
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
new file mode 100644
index 000000000000..e3bb29a8d8dd
--- /dev/null
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -0,0 +1,611 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
3"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
4
5<book id="index">
6<bookinfo>
7<title>The Userspace I/O HOWTO</title>
8
9<author>
10 <firstname>Hans-Jürgen</firstname>
11 <surname>Koch</surname>
12 <authorblurb><para>Linux developer, Linutronix</para></authorblurb>
13 <affiliation>
14 <orgname>
15 <ulink url="http://www.linutronix.de">Linutronix</ulink>
16 </orgname>
17
18 <address>
19 <email>hjk@linutronix.de</email>
20 </address>
21 </affiliation>
22</author>
23
24<pubdate>2006-12-11</pubdate>
25
26<abstract>
27 <para>This HOWTO describes concept and usage of Linux kernel's
28 Userspace I/O system.</para>
29</abstract>
30
31<revhistory>
32 <revision>
33 <revnumber>0.3</revnumber>
34 <date>2007-04-29</date>
35 <authorinitials>hjk</authorinitials>
36 <revremark>Added section about userspace drivers.</revremark>
37 </revision>
38 <revision>
39 <revnumber>0.2</revnumber>
40 <date>2007-02-13</date>
41 <authorinitials>hjk</authorinitials>
42 <revremark>Update after multiple mappings were added.</revremark>
43 </revision>
44 <revision>
45 <revnumber>0.1</revnumber>
46 <date>2006-12-11</date>
47 <authorinitials>hjk</authorinitials>
48 <revremark>First draft.</revremark>
49 </revision>
50</revhistory>
51</bookinfo>
52
53<chapter id="aboutthisdoc">
54<?dbhtml filename="about.html"?>
55<title>About this document</title>
56
57<sect1 id="copyright">
58<?dbhtml filename="copyright.html"?>
59<title>Copyright and License</title>
60<para>
61 Copyright (c) 2006 by Hans-Jürgen Koch.</para>
62<para>
63This documentation is Free Software licensed under the terms of the
64GPL version 2.
65</para>
66</sect1>
67
68<sect1 id="translations">
69<?dbhtml filename="translations.html"?>
70<title>Translations</title>
71
72<para>If you know of any translations for this document, or you are
73interested in translating it, please email me
74<email>hjk@linutronix.de</email>.
75</para>
76</sect1>
77
78<sect1 id="preface">
79<title>Preface</title>
80 <para>
81 For many types of devices, creating a Linux kernel driver is
82 overkill. All that is really needed is some way to handle an
83 interrupt and provide access to the memory space of the
84 device. The logic of controlling the device does not
85 necessarily have to be within the kernel, as the device does
86 not need to take advantage of any of other resources that the
87 kernel provides. One such common class of devices that are
88 like this are for industrial I/O cards.
89 </para>
90 <para>
91 To address this situation, the userspace I/O system (UIO) was
92 designed. For typical industrial I/O cards, only a very small
93 kernel module is needed. The main part of the driver will run in
94 user space. This simplifies development and reduces the risk of
95 serious bugs within a kernel module.
96 </para>
97</sect1>
98
99<sect1 id="thanks">
100<title>Acknowledgments</title>
101 <para>I'd like to thank Thomas Gleixner and Benedikt Spranger of
102 Linutronix, who have not only written most of the UIO code, but also
103 helped greatly writing this HOWTO by giving me all kinds of background
104 information.</para>
105</sect1>
106
107<sect1 id="feedback">
108<title>Feedback</title>
109 <para>Find something wrong with this document? (Or perhaps something
110 right?) I would love to hear from you. Please email me at
111 <email>hjk@linutronix.de</email>.</para>
112</sect1>
113</chapter>
114
115<chapter id="about">
116<?dbhtml filename="about.html"?>
117<title>About UIO</title>
118
119<para>If you use UIO for your card's driver, here's what you get:</para>
120
121<itemizedlist>
122<listitem>
123 <para>only one small kernel module to write and maintain.</para>
124</listitem>
125<listitem>
126 <para>develop the main part of your driver in user space,
127 with all the tools and libraries you're used to.</para>
128</listitem>
129<listitem>
130 <para>bugs in your driver won't crash the kernel.</para>
131</listitem>
132<listitem>
133 <para>updates of your driver can take place without recompiling
134 the kernel.</para>
135</listitem>
136<listitem>
137 <para>if you need to keep some parts of your driver closed source,
138 you can do so without violating the GPL license on the kernel.</para>
139</listitem>
140</itemizedlist>
141
142<sect1 id="how_uio_works">
143<title>How UIO works</title>
144 <para>
145 Each UIO device is accessed through a device file and several
146 sysfs attribute files. The device file will be called
147 <filename>/dev/uio0</filename> for the first device, and
148 <filename>/dev/uio1</filename>, <filename>/dev/uio2</filename>
149 and so on for subsequent devices.
150 </para>
151
152 <para><filename>/dev/uioX</filename> is used to access the
153 address space of the card. Just use
154 <function>mmap()</function> to access registers or RAM
155 locations of your card.
156 </para>
157
158 <para>
159 Interrupts are handled by reading from
160 <filename>/dev/uioX</filename>. A blocking
161 <function>read()</function> from
162 <filename>/dev/uioX</filename> will return as soon as an
163 interrupt occurs. You can also use
164 <function>select()</function> on
165 <filename>/dev/uioX</filename> to wait for an interrupt. The
166 integer value read from <filename>/dev/uioX</filename>
167 represents the total interrupt count. You can use this number
168 to figure out if you missed some interrupts.
169 </para>
170
171 <para>
172 To handle interrupts properly, your custom kernel module can
173 provide its own interrupt handler. It will automatically be
174 called by the built-in handler.
175 </para>
176
177 <para>
178 For cards that don't generate interrupts but need to be
179 polled, there is the possibility to set up a timer that
180 triggers the interrupt handler at configurable time intervals.
181 See <filename>drivers/uio/uio_dummy.c</filename> for an
182 example of this technique.
183 </para>
184
185 <para>
186 Each driver provides attributes that are used to read or write
187 variables. These attributes are accessible through sysfs
188 files. A custom kernel driver module can add its own
189 attributes to the device owned by the uio driver, but not added
190 to the UIO device itself at this time. This might change in the
191 future if it would be found to be useful.
192 </para>
193
194 <para>
195 The following standard attributes are provided by the UIO
196 framework:
197 </para>
198<itemizedlist>
199<listitem>
200 <para>
201 <filename>name</filename>: The name of your device. It is
202 recommended to use the name of your kernel module for this.
203 </para>
204</listitem>
205<listitem>
206 <para>
207 <filename>version</filename>: A version string defined by your
208 driver. This allows the user space part of your driver to deal
209 with different versions of the kernel module.
210 </para>
211</listitem>
212<listitem>
213 <para>
214 <filename>event</filename>: The total number of interrupts
215 handled by the driver since the last time the device node was
216 read.
217 </para>
218</listitem>
219</itemizedlist>
220<para>
221 These attributes appear under the
222 <filename>/sys/class/uio/uioX</filename> directory. Please
223 note that this directory might be a symlink, and not a real
224 directory. Any userspace code that accesses it must be able
225 to handle this.
226</para>
227<para>
228 Each UIO device can make one or more memory regions available for
229 memory mapping. This is necessary because some industrial I/O cards
230 require access to more than one PCI memory region in a driver.
231</para>
232<para>
233 Each mapping has its own directory in sysfs, the first mapping
234 appears as <filename>/sys/class/uio/uioX/maps/map0/</filename>.
235 Subsequent mappings create directories <filename>map1/</filename>,
236 <filename>map2/</filename>, and so on. These directories will only
237 appear if the size of the mapping is not 0.
238</para>
239<para>
240 Each <filename>mapX/</filename> directory contains two read-only files
241 that show start address and size of the memory:
242</para>
243<itemizedlist>
244<listitem>
245 <para>
246 <filename>addr</filename>: The address of memory that can be mapped.
247 </para>
248</listitem>
249<listitem>
250 <para>
251 <filename>size</filename>: The size, in bytes, of the memory
252 pointed to by addr.
253 </para>
254</listitem>
255</itemizedlist>
256
257<para>
258 From userspace, the different mappings are distinguished by adjusting
259 the <varname>offset</varname> parameter of the
260 <function>mmap()</function> call. To map the memory of mapping N, you
261 have to use N times the page size as your offset:
262</para>
263<programlisting format="linespecific">
264offset = N * getpagesize();
265</programlisting>
266
267</sect1>
268</chapter>
269
270<chapter id="using-uio_dummy" xreflabel="Using uio_dummy">
271<?dbhtml filename="using-uio_dummy.html"?>
272<title>Using uio_dummy</title>
273 <para>
274 Well, there is no real use for uio_dummy. Its only purpose is
275 to test most parts of the UIO system (everything except
276 hardware interrupts), and to serve as an example for the
277 kernel module that you will have to write yourself.
278 </para>
279
280<sect1 id="what_uio_dummy_does">
281<title>What uio_dummy does</title>
282 <para>
283 The kernel module <filename>uio_dummy.ko</filename> creates a
284 device that uses a timer to generate periodic interrupts. The
285 interrupt handler does nothing but increment a counter. The
286 driver adds two custom attributes, <varname>count</varname>
287 and <varname>freq</varname>, that appear under
288 <filename>/sys/devices/platform/uio_dummy/</filename>.
289 </para>
290
291 <para>
292 The attribute <varname>count</varname> can be read and
293 written. The associated file
294 <filename>/sys/devices/platform/uio_dummy/count</filename>
295 appears as a normal text file and contains the total number of
296 timer interrupts. If you look at it (e.g. using
297 <function>cat</function>), you'll notice it is slowly counting
298 up.
299 </para>
300
301 <para>
302 The attribute <varname>freq</varname> can be read and written.
303 The content of
304 <filename>/sys/devices/platform/uio_dummy/freq</filename>
305 represents the number of system timer ticks between two timer
306 interrupts. The default value of <varname>freq</varname> is
307 the value of the kernel variable <varname>HZ</varname>, which
308 gives you an interval of one second. Lower values will
309 increase the frequency. Try the following:
310 </para>
311<programlisting format="linespecific">
312cd /sys/devices/platform/uio_dummy/
313echo 100 > freq
314</programlisting>
315 <para>
316 Use <function>cat count</function> to see how the interrupt
317 frequency changes.
318 </para>
319</sect1>
320</chapter>
321
322<chapter id="custom_kernel_module" xreflabel="Writing your own kernel module">
323<?dbhtml filename="custom_kernel_module.html"?>
324<title>Writing your own kernel module</title>
325 <para>
326 Please have a look at <filename>uio_dummy.c</filename> as an
327 example. The following paragraphs explain the different
328 sections of this file.
329 </para>
330
331<sect1 id="uio_info">
332<title>struct uio_info</title>
333 <para>
334 This structure tells the framework the details of your driver,
335 Some of the members are required, others are optional.
336 </para>
337
338<itemizedlist>
339<listitem><para>
340<varname>char *name</varname>: Required. The name of your driver as
341it will appear in sysfs. I recommend using the name of your module for this.
342</para></listitem>
343
344<listitem><para>
345<varname>char *version</varname>: Required. This string appears in
346<filename>/sys/class/uio/uioX/version</filename>.
347</para></listitem>
348
349<listitem><para>
350<varname>struct uio_mem mem[ MAX_UIO_MAPS ]</varname>: Required if you
351have memory that can be mapped with <function>mmap()</function>. For each
352mapping you need to fill one of the <varname>uio_mem</varname> structures.
353See the description below for details.
354</para></listitem>
355
356<listitem><para>
357<varname>long irq</varname>: Required. If your hardware generates an
358interrupt, it's your modules task to determine the irq number during
359initialization. If you don't have a hardware generated interrupt but
360want to trigger the interrupt handler in some other way, set
361<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>. The
362uio_dummy module does this as it triggers the event mechanism in a timer
363routine. If you had no interrupt at all, you could set
364<varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
365rarely makes sense.
366</para></listitem>
367
368<listitem><para>
369<varname>unsigned long irq_flags</varname>: Required if you've set
370<varname>irq</varname> to a hardware interrupt number. The flags given
371here will be used in the call to <function>request_irq()</function>.
372</para></listitem>
373
374<listitem><para>
375<varname>int (*mmap)(struct uio_info *info, struct vm_area_struct
376*vma)</varname>: Optional. If you need a special
377<function>mmap()</function> function, you can set it here. If this
378pointer is not NULL, your <function>mmap()</function> will be called
379instead of the built-in one.
380</para></listitem>
381
382<listitem><para>
383<varname>int (*open)(struct uio_info *info, struct inode *inode)
384</varname>: Optional. You might want to have your own
385<function>open()</function>, e.g. to enable interrupts only when your
386device is actually used.
387</para></listitem>
388
389<listitem><para>
390<varname>int (*release)(struct uio_info *info, struct inode *inode)
391</varname>: Optional. If you define your own
392<function>open()</function>, you will probably also want a custom
393<function>release()</function> function.
394</para></listitem>
395</itemizedlist>
396
397<para>
398Usually, your device will have one or more memory regions that can be mapped
399to user space. For each region, you have to set up a
400<varname>struct uio_mem</varname> in the <varname>mem[]</varname> array.
401Here's a description of the fields of <varname>struct uio_mem</varname>:
402</para>
403
404<itemizedlist>
405<listitem><para>
406<varname>int memtype</varname>: Required if the mapping is used. Set this to
407<varname>UIO_MEM_PHYS</varname> if you you have physical memory on your
408card to be mapped. Use <varname>UIO_MEM_LOGICAL</varname> for logical
409memory (e.g. allocated with <function>kmalloc()</function>). There's also
410<varname>UIO_MEM_VIRTUAL</varname> for virtual memory.
411</para></listitem>
412
413<listitem><para>
414<varname>unsigned long addr</varname>: Required if the mapping is used.
415Fill in the address of your memory block. This address is the one that
416appears in sysfs.
417</para></listitem>
418
419<listitem><para>
420<varname>unsigned long size</varname>: Fill in the size of the
421memory block that <varname>addr</varname> points to. If <varname>size</varname>
422is zero, the mapping is considered unused. Note that you
423<emphasis>must</emphasis> initialize <varname>size</varname> with zero for
424all unused mappings.
425</para></listitem>
426
427<listitem><para>
428<varname>void *internal_addr</varname>: If you have to access this memory
429region from within your kernel module, you will want to map it internally by
430using something like <function>ioremap()</function>. Addresses
431returned by this function cannot be mapped to user space, so you must not
432store it in <varname>addr</varname>. Use <varname>internal_addr</varname>
433instead to remember such an address.
434</para></listitem>
435</itemizedlist>
436
437<para>
438Please do not touch the <varname>kobj</varname> element of
439<varname>struct uio_mem</varname>! It is used by the UIO framework
440to set up sysfs files for this mapping. Simply leave it alone.
441</para>
442</sect1>
443
444<sect1 id="adding_irq_handler">
445<title>Adding an interrupt handler</title>
446 <para>
447 What you need to do in your interrupt handler depends on your
448 hardware and on how you want to handle it. You should try to
449 keep the amount of code in your kernel interrupt handler low.
450 If your hardware requires no action that you
451 <emphasis>have</emphasis> to perform after each interrupt,
452 then your handler can be empty.</para> <para>If, on the other
453 hand, your hardware <emphasis>needs</emphasis> some action to
454 be performed after each interrupt, then you
455 <emphasis>must</emphasis> do it in your kernel module. Note
456 that you cannot rely on the userspace part of your driver. Your
457 userspace program can terminate at any time, possibly leaving
458 your hardware in a state where proper interrupt handling is
459 still required.
460 </para>
461
462 <para>
463 There might also be applications where you want to read data
464 from your hardware at each interrupt and buffer it in a piece
465 of kernel memory you've allocated for that purpose. With this
466 technique you could avoid loss of data if your userspace
467 program misses an interrupt.
468 </para>
469
470 <para>
471 A note on shared interrupts: Your driver should support
472 interrupt sharing whenever this is possible. It is possible if
473 and only if your driver can detect whether your hardware has
474 triggered the interrupt or not. This is usually done by looking
475 at an interrupt status register. If your driver sees that the
476 IRQ bit is actually set, it will perform its actions, and the
477 handler returns IRQ_HANDLED. If the driver detects that it was
478 not your hardware that caused the interrupt, it will do nothing
479 and return IRQ_NONE, allowing the kernel to call the next
480 possible interrupt handler.
481 </para>
482
483 <para>
484 If you decide not to support shared interrupts, your card
485 won't work in computers with no free interrupts. As this
486 frequently happens on the PC platform, you can save yourself a
487 lot of trouble by supporting interrupt sharing.
488 </para>
489</sect1>
490
491</chapter>
492
493<chapter id="userspace_driver" xreflabel="Writing a driver in user space">
494<?dbhtml filename="userspace_driver.html"?>
495<title>Writing a driver in userspace</title>
496 <para>
497 Once you have a working kernel module for your hardware, you can
498 write the userspace part of your driver. You don't need any special
499 libraries, your driver can be written in any reasonable language,
500 you can use floating point numbers and so on. In short, you can
501 use all the tools and libraries you'd normally use for writing a
502 userspace application.
503 </para>
504
505<sect1 id="getting_uio_information">
506<title>Getting information about your UIO device</title>
507 <para>
508 Information about all UIO devices is available in sysfs. The
509 first thing you should do in your driver is check
510 <varname>name</varname> and <varname>version</varname> to
511 make sure your talking to the right device and that its kernel
512 driver has the version you expect.
513 </para>
514 <para>
515 You should also make sure that the memory mapping you need
516 exists and has the size you expect.
517 </para>
518 <para>
519 There is a tool called <varname>lsuio</varname> that lists
520 UIO devices and their attributes. It is available here:
521 </para>
522 <para>
523 <ulink url="http://www.osadl.org/projects/downloads/UIO/user/">
524 http://www.osadl.org/projects/downloads/UIO/user/</ulink>
525 </para>
526 <para>
527 With <varname>lsuio</varname> you can quickly check if your
528 kernel module is loaded and which attributes it exports.
529 Have a look at the manpage for details.
530 </para>
531 <para>
532 The source code of <varname>lsuio</varname> can serve as an
533 example for getting information about an UIO device.
534 The file <filename>uio_helper.c</filename> contains a lot of
535 functions you could use in your userspace driver code.
536 </para>
537</sect1>
538
539<sect1 id="mmap_device_memory">
540<title>mmap() device memory</title>
541 <para>
542 After you made sure you've got the right device with the
543 memory mappings you need, all you have to do is to call
544 <function>mmap()</function> to map the device's memory
545 to userspace.
546 </para>
547 <para>
548 The parameter <varname>offset</varname> of the
549 <function>mmap()</function> call has a special meaning
550 for UIO devices: It is used to select which mapping of
551 your device you want to map. To map the memory of
552 mapping N, you have to use N times the page size as
553 your offset:
554 </para>
555<programlisting format="linespecific">
556 offset = N * getpagesize();
557</programlisting>
558 <para>
559 N starts from zero, so if you've got only one memory
560 range to map, set <varname>offset = 0</varname>.
561 A drawback of this technique is that memory is always
562 mapped beginning with its start address.
563 </para>
564</sect1>
565
566<sect1 id="wait_for_interrupts">
567<title>Waiting for interrupts</title>
568 <para>
569 After you successfully mapped your devices memory, you
570 can access it like an ordinary array. Usually, you will
571 perform some initialization. After that, your hardware
572 starts working and will generate an interrupt as soon
573 as it's finished, has some data available, or needs your
574 attention because an error occured.
575 </para>
576 <para>
577 <filename>/dev/uioX</filename> is a read-only file. A
578 <function>read()</function> will always block until an
579 interrupt occurs. There is only one legal value for the
580 <varname>count</varname> parameter of
581 <function>read()</function>, and that is the size of a
582 signed 32 bit integer (4). Any other value for
583 <varname>count</varname> causes <function>read()</function>
584 to fail. The signed 32 bit integer read is the interrupt
585 count of your device. If the value is one more than the value
586 you read the last time, everything is OK. If the difference
587 is greater than one, you missed interrupts.
588 </para>
589 <para>
590 You can also use <function>select()</function> on
591 <filename>/dev/uioX</filename>.
592 </para>
593</sect1>
594
595</chapter>
596
597<appendix id="app1">
598<title>Further information</title>
599<itemizedlist>
600 <listitem><para>
601 <ulink url="http://www.osadl.org">
602 OSADL homepage.</ulink>
603 </para></listitem>
604 <listitem><para>
605 <ulink url="http://www.linutronix.de">
606 Linutronix homepage.</ulink>
607 </para></listitem>
608</itemizedlist>
609</appendix>
610
611</book>
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 7916f4b86d23..ae01d86070bb 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -84,4 +84,5 @@ source "drivers/auxdisplay/Kconfig"
84 84
85source "drivers/kvm/Kconfig" 85source "drivers/kvm/Kconfig"
86 86
87source "drivers/uio/Kconfig"
87endmenu 88endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 6d9d7fab77f5..c34c8efff609 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_ATA) += ata/
40obj-$(CONFIG_FUSION) += message/ 40obj-$(CONFIG_FUSION) += message/
41obj-$(CONFIG_FIREWIRE) += firewire/ 41obj-$(CONFIG_FIREWIRE) += firewire/
42obj-$(CONFIG_IEEE1394) += ieee1394/ 42obj-$(CONFIG_IEEE1394) += ieee1394/
43obj-$(CONFIG_UIO) += uio/
43obj-y += cdrom/ 44obj-y += cdrom/
44obj-y += auxdisplay/ 45obj-y += auxdisplay/
45obj-$(CONFIG_MTD) += mtd/ 46obj-$(CONFIG_MTD) += mtd/
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
new file mode 100644
index 000000000000..b778ed71f636
--- /dev/null
+++ b/drivers/uio/Kconfig
@@ -0,0 +1,29 @@
1menu "Userspace I/O"
2 depends on !S390
3
4config UIO
5 tristate "Userspace I/O drivers"
6 default n
7 help
8 Enable this to allow the userspace driver core code to be
9 built. This code allows userspace programs easy access to
10 kernel interrupts and memory locations, allowing some drivers
11 to be written in userspace. Note that a small kernel driver
12 is also required for interrupt handling to work properly.
13
14 If you don't know what to do here, say N.
15
16config UIO_CIF
17 tristate "generic Hilscher CIF Card driver"
18 depends on UIO && PCI
19 default n
20 help
21 Driver for Hilscher CIF DeviceNet and Profibus cards. This
22 driver requires a userspace component that handles all of the
23 heavy lifting and can be found at:
24 http://www.osadl.org/projects/downloads/UIO/user/cif-*
25
26 To compile this driver as a module, choose M here: the module
27 will be called uio_cif.
28
29endmenu
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
new file mode 100644
index 000000000000..7fecfb459da5
--- /dev/null
+++ b/drivers/uio/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_UIO) += uio.o
2obj-$(CONFIG_UIO_CIF) += uio_cif.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
new file mode 100644
index 000000000000..865f32b63b5c
--- /dev/null
+++ b/drivers/uio/uio.c
@@ -0,0 +1,701 @@
1/*
2 * drivers/uio/uio.c
3 *
4 * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
5 * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
6 * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
7 * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
8 *
9 * Userspace IO
10 *
11 * Base Functions
12 *
13 * Licensed under the GPLv2 only.
14 */
15
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/poll.h>
19#include <linux/device.h>
20#include <linux/mm.h>
21#include <linux/idr.h>
22#include <linux/string.h>
23#include <linux/kobject.h>
24#include <linux/uio_driver.h>
25
26#define UIO_MAX_DEVICES 255
27
28struct uio_device {
29 struct module *owner;
30 struct device *dev;
31 int minor;
32 atomic_t event;
33 struct fasync_struct *async_queue;
34 wait_queue_head_t wait;
35 int vma_count;
36 struct uio_info *info;
37 struct kset map_attr_kset;
38};
39
40static int uio_major;
41static DEFINE_IDR(uio_idr);
42static struct file_operations uio_fops;
43
44/* UIO class infrastructure */
45static struct uio_class {
46 struct kref kref;
47 struct class *class;
48} *uio_class;
49
50/*
51 * attributes
52 */
53
54static struct attribute attr_addr = {
55 .name = "addr",
56 .mode = S_IRUGO,
57};
58
59static struct attribute attr_size = {
60 .name = "size",
61 .mode = S_IRUGO,
62};
63
64static struct attribute* map_attrs[] = {
65 &attr_addr, &attr_size, NULL
66};
67
68static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr,
69 char *buf)
70{
71 struct uio_mem *mem = container_of(kobj, struct uio_mem, kobj);
72
73 if (strncmp(attr->name,"addr",4) == 0)
74 return sprintf(buf, "0x%lx\n", mem->addr);
75
76 if (strncmp(attr->name,"size",4) == 0)
77 return sprintf(buf, "0x%lx\n", mem->size);
78
79 return -ENODEV;
80}
81
82static void map_attr_release(struct kobject *kobj)
83{
84 /* TODO ??? */
85}
86
87static struct sysfs_ops map_attr_ops = {
88 .show = map_attr_show,
89};
90
91static struct kobj_type map_attr_type = {
92 .release = map_attr_release,
93 .sysfs_ops = &map_attr_ops,
94 .default_attrs = map_attrs,
95};
96
97static ssize_t show_name(struct device *dev,
98 struct device_attribute *attr, char *buf)
99{
100 struct uio_device *idev = dev_get_drvdata(dev);
101 if (idev)
102 return sprintf(buf, "%s\n", idev->info->name);
103 else
104 return -ENODEV;
105}
106static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
107
108static ssize_t show_version(struct device *dev,
109 struct device_attribute *attr, char *buf)
110{
111 struct uio_device *idev = dev_get_drvdata(dev);
112 if (idev)
113 return sprintf(buf, "%s\n", idev->info->version);
114 else
115 return -ENODEV;
116}
117static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
118
119static ssize_t show_event(struct device *dev,
120 struct device_attribute *attr, char *buf)
121{
122 struct uio_device *idev = dev_get_drvdata(dev);
123 if (idev)
124 return sprintf(buf, "%u\n",
125 (unsigned int)atomic_read(&idev->event));
126 else
127 return -ENODEV;
128}
129static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
130
131static struct attribute *uio_attrs[] = {
132 &dev_attr_name.attr,
133 &dev_attr_version.attr,
134 &dev_attr_event.attr,
135 NULL,
136};
137
138static struct attribute_group uio_attr_grp = {
139 .attrs = uio_attrs,
140};
141
142/*
143 * device functions
144 */
145static int uio_dev_add_attributes(struct uio_device *idev)
146{
147 int ret;
148 int mi;
149 int map_found = 0;
150 struct uio_mem *mem;
151
152 ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp);
153 if (ret)
154 goto err_group;
155
156 for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
157 mem = &idev->info->mem[mi];
158 if (mem->size == 0)
159 break;
160 if (!map_found) {
161 map_found = 1;
162 kobject_set_name(&idev->map_attr_kset.kobj,"maps");
163 idev->map_attr_kset.ktype = &map_attr_type;
164 idev->map_attr_kset.kobj.parent = &idev->dev->kobj;
165 ret = kset_register(&idev->map_attr_kset);
166 if (ret)
167 goto err_remove_group;
168 }
169 kobject_init(&mem->kobj);
170 kobject_set_name(&mem->kobj,"map%d",mi);
171 mem->kobj.parent = &idev->map_attr_kset.kobj;
172 mem->kobj.kset = &idev->map_attr_kset;
173 ret = kobject_add(&mem->kobj);
174 if (ret)
175 goto err_remove_maps;
176 }
177
178 return 0;
179
180err_remove_maps:
181 for (mi--; mi>=0; mi--) {
182 mem = &idev->info->mem[mi];
183 kobject_unregister(&mem->kobj);
184 }
185 kset_unregister(&idev->map_attr_kset); /* Needed ? */
186err_remove_group:
187 sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
188err_group:
189 dev_err(idev->dev, "error creating sysfs files (%d)\n", ret);
190 return ret;
191}
192
193static void uio_dev_del_attributes(struct uio_device *idev)
194{
195 int mi;
196 struct uio_mem *mem;
197 for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
198 mem = &idev->info->mem[mi];
199 if (mem->size == 0)
200 break;
201 kobject_unregister(&mem->kobj);
202 }
203 kset_unregister(&idev->map_attr_kset);
204 sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
205}
206
207static int uio_get_minor(struct uio_device *idev)
208{
209 static DEFINE_MUTEX(minor_lock);
210 int retval = -ENOMEM;
211 int id;
212
213 mutex_lock(&minor_lock);
214 if (idr_pre_get(&uio_idr, GFP_KERNEL) == 0)
215 goto exit;
216
217 retval = idr_get_new(&uio_idr, idev, &id);
218 if (retval < 0) {
219 if (retval == -EAGAIN)
220 retval = -ENOMEM;
221 goto exit;
222 }
223 idev->minor = id & MAX_ID_MASK;
224exit:
225 mutex_unlock(&minor_lock);
226 return retval;
227}
228
229static void uio_free_minor(struct uio_device *idev)
230{
231 idr_remove(&uio_idr, idev->minor);
232}
233
234/**
235 * uio_event_notify - trigger an interrupt event
236 * @info: UIO device capabilities
237 */
238void uio_event_notify(struct uio_info *info)
239{
240 struct uio_device *idev = info->uio_dev;
241
242 atomic_inc(&idev->event);
243 wake_up_interruptible(&idev->wait);
244 kill_fasync(&idev->async_queue, SIGIO, POLL_IN);
245}
246EXPORT_SYMBOL_GPL(uio_event_notify);
247
248/**
249 * uio_interrupt - hardware interrupt handler
250 * @irq: IRQ number, can be UIO_IRQ_CYCLIC for cyclic timer
251 * @dev_id: Pointer to the devices uio_device structure
252 */
253static irqreturn_t uio_interrupt(int irq, void *dev_id)
254{
255 struct uio_device *idev = (struct uio_device *)dev_id;
256 irqreturn_t ret = idev->info->handler(irq, idev->info);
257
258 if (ret == IRQ_HANDLED)
259 uio_event_notify(idev->info);
260
261 return ret;
262}
263
264struct uio_listener {
265 struct uio_device *dev;
266 s32 event_count;
267};
268
269static int uio_open(struct inode *inode, struct file *filep)
270{
271 struct uio_device *idev;
272 struct uio_listener *listener;
273 int ret = 0;
274
275 idev = idr_find(&uio_idr, iminor(inode));
276 if (!idev)
277 return -ENODEV;
278
279 listener = kmalloc(sizeof(*listener), GFP_KERNEL);
280 if (!listener)
281 return -ENOMEM;
282
283 listener->dev = idev;
284 listener->event_count = atomic_read(&idev->event);
285 filep->private_data = listener;
286
287 if (idev->info->open) {
288 if (!try_module_get(idev->owner))
289 return -ENODEV;
290 ret = idev->info->open(idev->info, inode);
291 module_put(idev->owner);
292 }
293
294 if (ret)
295 kfree(listener);
296
297 return ret;
298}
299
300static int uio_fasync(int fd, struct file *filep, int on)
301{
302 struct uio_listener *listener = filep->private_data;
303 struct uio_device *idev = listener->dev;
304
305 return fasync_helper(fd, filep, on, &idev->async_queue);
306}
307
308static int uio_release(struct inode *inode, struct file *filep)
309{
310 int ret = 0;
311 struct uio_listener *listener = filep->private_data;
312 struct uio_device *idev = listener->dev;
313
314 if (idev->info->release) {
315 if (!try_module_get(idev->owner))
316 return -ENODEV;
317 ret = idev->info->release(idev->info, inode);
318 module_put(idev->owner);
319 }
320 if (filep->f_flags & FASYNC)
321 ret = uio_fasync(-1, filep, 0);
322 kfree(listener);
323 return ret;
324}
325
326static unsigned int uio_poll(struct file *filep, poll_table *wait)
327{
328 struct uio_listener *listener = filep->private_data;
329 struct uio_device *idev = listener->dev;
330
331 if (idev->info->irq == UIO_IRQ_NONE)
332 return -EIO;
333
334 poll_wait(filep, &idev->wait, wait);
335 if (listener->event_count != atomic_read(&idev->event))
336 return POLLIN | POLLRDNORM;
337 return 0;
338}
339
340static ssize_t uio_read(struct file *filep, char __user *buf,
341 size_t count, loff_t *ppos)
342{
343 struct uio_listener *listener = filep->private_data;
344 struct uio_device *idev = listener->dev;
345 DECLARE_WAITQUEUE(wait, current);
346 ssize_t retval;
347 s32 event_count;
348
349 if (idev->info->irq == UIO_IRQ_NONE)
350 return -EIO;
351
352 if (count != sizeof(s32))
353 return -EINVAL;
354
355 add_wait_queue(&idev->wait, &wait);
356
357 do {
358 set_current_state(TASK_INTERRUPTIBLE);
359
360 event_count = atomic_read(&idev->event);
361 if (event_count != listener->event_count) {
362 if (copy_to_user(buf, &event_count, count))
363 retval = -EFAULT;
364 else {
365 listener->event_count = event_count;
366 retval = count;
367 }
368 break;
369 }
370
371 if (filep->f_flags & O_NONBLOCK) {
372 retval = -EAGAIN;
373 break;
374 }
375
376 if (signal_pending(current)) {
377 retval = -ERESTARTSYS;
378 break;
379 }
380 schedule();
381 } while (1);
382
383 __set_current_state(TASK_RUNNING);
384 remove_wait_queue(&idev->wait, &wait);
385
386 return retval;
387}
388
389static int uio_find_mem_index(struct vm_area_struct *vma)
390{
391 int mi;
392 struct uio_device *idev = vma->vm_private_data;
393
394 for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
395 if (idev->info->mem[mi].size == 0)
396 return -1;
397 if (vma->vm_pgoff == mi)
398 return mi;
399 }
400 return -1;
401}
402
403static void uio_vma_open(struct vm_area_struct *vma)
404{
405 struct uio_device *idev = vma->vm_private_data;
406 idev->vma_count++;
407}
408
409static void uio_vma_close(struct vm_area_struct *vma)
410{
411 struct uio_device *idev = vma->vm_private_data;
412 idev->vma_count--;
413}
414
415static struct page *uio_vma_nopage(struct vm_area_struct *vma,
416 unsigned long address, int *type)
417{
418 struct uio_device *idev = vma->vm_private_data;
419 struct page* page = NOPAGE_SIGBUS;
420
421 int mi = uio_find_mem_index(vma);
422 if (mi < 0)
423 return page;
424
425 if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
426 page = virt_to_page(idev->info->mem[mi].addr);
427 else
428 page = vmalloc_to_page((void*)idev->info->mem[mi].addr);
429 get_page(page);
430 if (type)
431 *type = VM_FAULT_MINOR;
432 return page;
433}
434
435static struct vm_operations_struct uio_vm_ops = {
436 .open = uio_vma_open,
437 .close = uio_vma_close,
438 .nopage = uio_vma_nopage,
439};
440
441static int uio_mmap_physical(struct vm_area_struct *vma)
442{
443 struct uio_device *idev = vma->vm_private_data;
444 int mi = uio_find_mem_index(vma);
445 if (mi < 0)
446 return -EINVAL;
447
448 vma->vm_flags |= VM_IO | VM_RESERVED;
449
450 return remap_pfn_range(vma,
451 vma->vm_start,
452 idev->info->mem[mi].addr >> PAGE_SHIFT,
453 vma->vm_end - vma->vm_start,
454 vma->vm_page_prot);
455}
456
457static int uio_mmap_logical(struct vm_area_struct *vma)
458{
459 vma->vm_flags |= VM_RESERVED;
460 vma->vm_ops = &uio_vm_ops;
461 uio_vma_open(vma);
462 return 0;
463}
464
465static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
466{
467 struct uio_listener *listener = filep->private_data;
468 struct uio_device *idev = listener->dev;
469 int mi;
470 unsigned long requested_pages, actual_pages;
471 int ret = 0;
472
473 if (vma->vm_end < vma->vm_start)
474 return -EINVAL;
475
476 vma->vm_private_data = idev;
477
478 mi = uio_find_mem_index(vma);
479 if (mi < 0)
480 return -EINVAL;
481
482 requested_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
483 actual_pages = (idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
484 if (requested_pages > actual_pages)
485 return -EINVAL;
486
487 if (idev->info->mmap) {
488 if (!try_module_get(idev->owner))
489 return -ENODEV;
490 ret = idev->info->mmap(idev->info, vma);
491 module_put(idev->owner);
492 return ret;
493 }
494
495 switch (idev->info->mem[mi].memtype) {
496 case UIO_MEM_PHYS:
497 return uio_mmap_physical(vma);
498 case UIO_MEM_LOGICAL:
499 case UIO_MEM_VIRTUAL:
500 return uio_mmap_logical(vma);
501 default:
502 return -EINVAL;
503 }
504}
505
506static struct file_operations uio_fops = {
507 .owner = THIS_MODULE,
508 .open = uio_open,
509 .release = uio_release,
510 .read = uio_read,
511 .mmap = uio_mmap,
512 .poll = uio_poll,
513 .fasync = uio_fasync,
514};
515
516static int uio_major_init(void)
517{
518 uio_major = register_chrdev(0, "uio", &uio_fops);
519 if (uio_major < 0)
520 return uio_major;
521 return 0;
522}
523
524static void uio_major_cleanup(void)
525{
526 unregister_chrdev(uio_major, "uio");
527}
528
529static int init_uio_class(void)
530{
531 int ret = 0;
532
533 if (uio_class != NULL) {
534 kref_get(&uio_class->kref);
535 goto exit;
536 }
537
538 /* This is the first time in here, set everything up properly */
539 ret = uio_major_init();
540 if (ret)
541 goto exit;
542
543 uio_class = kzalloc(sizeof(*uio_class), GFP_KERNEL);
544 if (!uio_class) {
545 ret = -ENOMEM;
546 goto err_kzalloc;
547 }
548
549 kref_init(&uio_class->kref);
550 uio_class->class = class_create(THIS_MODULE, "uio");
551 if (IS_ERR(uio_class->class)) {
552 ret = IS_ERR(uio_class->class);
553 printk(KERN_ERR "class_create failed for uio\n");
554 goto err_class_create;
555 }
556 return 0;
557
558err_class_create:
559 kfree(uio_class);
560 uio_class = NULL;
561err_kzalloc:
562 uio_major_cleanup();
563exit:
564 return ret;
565}
566
567static void release_uio_class(struct kref *kref)
568{
569 /* Ok, we cheat as we know we only have one uio_class */
570 class_destroy(uio_class->class);
571 kfree(uio_class);
572 uio_major_cleanup();
573 uio_class = NULL;
574}
575
576static void uio_class_destroy(void)
577{
578 if (uio_class)
579 kref_put(&uio_class->kref, release_uio_class);
580}
581
582/**
583 * uio_register_device - register a new userspace IO device
584 * @owner: module that creates the new device
585 * @parent: parent device
586 * @info: UIO device capabilities
587 *
588 * returns zero on success or a negative error code.
589 */
590int __uio_register_device(struct module *owner,
591 struct device *parent,
592 struct uio_info *info)
593{
594 struct uio_device *idev;
595 int ret = 0;
596
597 if (!parent || !info || !info->name || !info->version)
598 return -EINVAL;
599
600 info->uio_dev = NULL;
601
602 ret = init_uio_class();
603 if (ret)
604 return ret;
605
606 idev = kzalloc(sizeof(*idev), GFP_KERNEL);
607 if (!idev) {
608 ret = -ENOMEM;
609 goto err_kzalloc;
610 }
611
612 idev->owner = owner;
613 idev->info = info;
614 init_waitqueue_head(&idev->wait);
615 atomic_set(&idev->event, 0);
616
617 ret = uio_get_minor(idev);
618 if (ret)
619 goto err_get_minor;
620
621 idev->dev = device_create(uio_class->class, parent,
622 MKDEV(uio_major, idev->minor),
623 "uio%d", idev->minor);
624 if (IS_ERR(idev->dev)) {
625 printk(KERN_ERR "UIO: device register failed\n");
626 ret = PTR_ERR(idev->dev);
627 goto err_device_create;
628 }
629 dev_set_drvdata(idev->dev, idev);
630
631 ret = uio_dev_add_attributes(idev);
632 if (ret)
633 goto err_uio_dev_add_attributes;
634
635 info->uio_dev = idev;
636
637 if (idev->info->irq >= 0) {
638 ret = request_irq(idev->info->irq, uio_interrupt,
639 idev->info->irq_flags, idev->info->name, idev);
640 if (ret)
641 goto err_request_irq;
642 }
643
644 return 0;
645
646err_request_irq:
647 uio_dev_del_attributes(idev);
648err_uio_dev_add_attributes:
649 device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
650err_device_create:
651 uio_free_minor(idev);
652err_get_minor:
653 kfree(idev);
654err_kzalloc:
655 uio_class_destroy();
656 return ret;
657}
658EXPORT_SYMBOL_GPL(__uio_register_device);
659
660/**
661 * uio_unregister_device - unregister a industrial IO device
662 * @info: UIO device capabilities
663 *
664 */
665void uio_unregister_device(struct uio_info *info)
666{
667 struct uio_device *idev;
668
669 if (!info || !info->uio_dev)
670 return;
671
672 idev = info->uio_dev;
673
674 uio_free_minor(idev);
675
676 if (info->irq >= 0)
677 free_irq(info->irq, idev);
678
679 uio_dev_del_attributes(idev);
680
681 dev_set_drvdata(idev->dev, NULL);
682 device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
683 kfree(idev);
684 uio_class_destroy();
685
686 return;
687}
688EXPORT_SYMBOL_GPL(uio_unregister_device);
689
690static int __init uio_init(void)
691{
692 return 0;
693}
694
695static void __exit uio_exit(void)
696{
697}
698
699module_init(uio_init)
700module_exit(uio_exit)
701MODULE_LICENSE("GPL v2");
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
new file mode 100644
index 000000000000..838bae460831
--- /dev/null
+++ b/drivers/uio/uio_cif.c
@@ -0,0 +1,156 @@
1/*
2 * UIO Hilscher CIF card driver
3 *
4 * (C) 2007 Hans J. Koch <hjk@linutronix.de>
5 * Original code (C) 2005 Benedikt Spranger <b.spranger@linutronix.de>
6 *
7 * Licensed under GPL version 2 only.
8 *
9 */
10
11#include <linux/device.h>
12#include <linux/module.h>
13#include <linux/pci.h>
14#include <linux/uio_driver.h>
15
16#include <asm/io.h>
17
18#ifndef PCI_DEVICE_ID_PLX_9030
19#define PCI_DEVICE_ID_PLX_9030 0x9030
20#endif
21
22#define PLX9030_INTCSR 0x4C
23#define INTSCR_INT1_ENABLE 0x01
24#define INTSCR_INT1_STATUS 0x04
25#define INT1_ENABLED_AND_ACTIVE (INTSCR_INT1_ENABLE | INTSCR_INT1_STATUS)
26
27#define PCI_SUBVENDOR_ID_PEP 0x1518
28#define CIF_SUBDEVICE_PROFIBUS 0x430
29#define CIF_SUBDEVICE_DEVICENET 0x432
30
31
32static irqreturn_t hilscher_handler(int irq, struct uio_info *dev_info)
33{
34 void __iomem *plx_intscr = dev_info->mem[0].internal_addr
35 + PLX9030_INTCSR;
36
37 if ((ioread8(plx_intscr) & INT1_ENABLED_AND_ACTIVE)
38 != INT1_ENABLED_AND_ACTIVE)
39 return IRQ_NONE;
40
41 /* Disable interrupt */
42 iowrite8(ioread8(plx_intscr) & ~INTSCR_INT1_ENABLE, plx_intscr);
43 return IRQ_HANDLED;
44}
45
46static int __devinit hilscher_pci_probe(struct pci_dev *dev,
47 const struct pci_device_id *id)
48{
49 struct uio_info *info;
50
51 info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
52 if (!info)
53 return -ENOMEM;
54
55 if (pci_enable_device(dev))
56 goto out_free;
57
58 if (pci_request_regions(dev, "hilscher"))
59 goto out_disable;
60
61 info->mem[0].addr = pci_resource_start(dev, 0);
62 if (!info->mem[0].addr)
63 goto out_release;
64 info->mem[0].internal_addr = ioremap(pci_resource_start(dev, 0),
65 pci_resource_len(dev, 0));
66 if (!info->mem[0].internal_addr)
67 goto out_release;
68
69 info->mem[0].size = pci_resource_len(dev, 0);
70 info->mem[0].memtype = UIO_MEM_PHYS;
71 info->mem[1].addr = pci_resource_start(dev, 2);
72 info->mem[1].size = pci_resource_len(dev, 2);
73 info->mem[1].memtype = UIO_MEM_PHYS;
74 switch (id->subdevice) {
75 case CIF_SUBDEVICE_PROFIBUS:
76 info->name = "CIF_Profibus";
77 break;
78 case CIF_SUBDEVICE_DEVICENET:
79 info->name = "CIF_Devicenet";
80 break;
81 default:
82 info->name = "CIF_???";
83 }
84 info->version = "0.0.1";
85 info->irq = dev->irq;
86 info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
87 info->handler = hilscher_handler;
88
89 if (uio_register_device(&dev->dev, info))
90 goto out_unmap;
91
92 pci_set_drvdata(dev, info);
93
94 return 0;
95out_unmap:
96 iounmap(info->mem[0].internal_addr);
97out_release:
98 pci_release_regions(dev);
99out_disable:
100 pci_disable_device(dev);
101out_free:
102 kfree (info);
103 return -ENODEV;
104}
105
106static void hilscher_pci_remove(struct pci_dev *dev)
107{
108 struct uio_info *info = pci_get_drvdata(dev);
109
110 uio_unregister_device(info);
111 pci_release_regions(dev);
112 pci_disable_device(dev);
113 pci_set_drvdata(dev, NULL);
114 iounmap(info->mem[0].internal_addr);
115
116 kfree (info);
117}
118
119static struct pci_device_id hilscher_pci_ids[] = {
120 {
121 .vendor = PCI_VENDOR_ID_PLX,
122 .device = PCI_DEVICE_ID_PLX_9030,
123 .subvendor = PCI_SUBVENDOR_ID_PEP,
124 .subdevice = CIF_SUBDEVICE_PROFIBUS,
125 },
126 {
127 .vendor = PCI_VENDOR_ID_PLX,
128 .device = PCI_DEVICE_ID_PLX_9030,
129 .subvendor = PCI_SUBVENDOR_ID_PEP,
130 .subdevice = CIF_SUBDEVICE_DEVICENET,
131 },
132 { 0, }
133};
134
135static struct pci_driver hilscher_pci_driver = {
136 .name = "hilscher",
137 .id_table = hilscher_pci_ids,
138 .probe = hilscher_pci_probe,
139 .remove = hilscher_pci_remove,
140};
141
142static int __init hilscher_init_module(void)
143{
144 return pci_register_driver(&hilscher_pci_driver);
145}
146
147static void __exit hilscher_exit_module(void)
148{
149 pci_unregister_driver(&hilscher_pci_driver);
150}
151
152module_init(hilscher_init_module);
153module_exit(hilscher_exit_module);
154
155MODULE_LICENSE("GPL v2");
156MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger");
diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
new file mode 100644
index 000000000000..44c28e94df50
--- /dev/null
+++ b/include/linux/uio_driver.h
@@ -0,0 +1,91 @@
1/*
2 * include/linux/uio_driver.h
3 *
4 * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
5 * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
6 * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
7 * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
8 *
9 * Userspace IO driver.
10 *
11 * Licensed under the GPLv2 only.
12 */
13
14#ifndef _UIO_DRIVER_H_
15#define _UIO_DRIVER_H_
16
17#include <linux/module.h>
18#include <linux/fs.h>
19#include <linux/interrupt.h>
20
21/**
22 * struct uio_mem - description of a UIO memory region
23 * @kobj: kobject for this mapping
24 * @addr: address of the device's memory
25 * @size: size of IO
26 * @memtype: type of memory addr points to
27 * @internal_addr: ioremap-ped version of addr, for driver internal use
28 */
29struct uio_mem {
30 struct kobject kobj;
31 unsigned long addr;
32 unsigned long size;
33 int memtype;
34 void __iomem *internal_addr;
35};
36
37#define MAX_UIO_MAPS 5
38
39struct uio_device;
40
41/**
42 * struct uio_info - UIO device capabilities
43 * @uio_dev: the UIO device this info belongs to
44 * @name: device name
45 * @version: device driver version
46 * @mem: list of mappable memory regions, size==0 for end of list
47 * @irq: interrupt number or UIO_IRQ_CUSTOM
48 * @irq_flags: flags for request_irq()
49 * @priv: optional private data
50 * @handler: the device's irq handler
51 * @mmap: mmap operation for this uio device
52 * @open: open operation for this uio device
53 * @release: release operation for this uio device
54 */
55struct uio_info {
56 struct uio_device *uio_dev;
57 char *name;
58 char *version;
59 struct uio_mem mem[MAX_UIO_MAPS];
60 long irq;
61 unsigned long irq_flags;
62 void *priv;
63 irqreturn_t (*handler)(int irq, struct uio_info *dev_info);
64 int (*mmap)(struct uio_info *info, struct vm_area_struct *vma);
65 int (*open)(struct uio_info *info, struct inode *inode);
66 int (*release)(struct uio_info *info, struct inode *inode);
67};
68
69extern int __must_check
70 __uio_register_device(struct module *owner,
71 struct device *parent,
72 struct uio_info *info);
73static inline int __must_check
74 uio_register_device(struct device *parent, struct uio_info *info)
75{
76 return __uio_register_device(THIS_MODULE, parent, info);
77}
78extern void uio_unregister_device(struct uio_info *info);
79extern void uio_event_notify(struct uio_info *info);
80
81/* defines for uio_device->irq */
82#define UIO_IRQ_CUSTOM -1
83#define UIO_IRQ_NONE -2
84
85/* defines for uio_device->memtype */
86#define UIO_MEM_NONE 0
87#define UIO_MEM_PHYS 1
88#define UIO_MEM_LOGICAL 2
89#define UIO_MEM_VIRTUAL 3
90
91#endif /* _LINUX_UIO_DRIVER_H_ */