summaryrefslogtreecommitdiff
path: root/Documentation
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-16 19:27:10 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-16 19:27:10 +0400
commitab86e5765d41a5eb4239a1c04d613db87bea5ed8 (patch)
treea41224d4874c2f90e0b423786f00bedf6f3e8bfa /Documentation
parent7ea61767e41e2baedd6a968d13f56026522e1207 (diff)
parent2b2af54a5bb6f7e80ccf78f20084b93c398c3a8b (diff)
downloadlinux-ab86e5765d41a5eb4239a1c04d613db87bea5ed8.tar.xz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: Driver Core: devtmpfs - kernel-maintained tmpfs-based /dev debugfs: Modify default debugfs directory for debugging pktcdvd. debugfs: Modified default dir of debugfs for debugging UHCI. debugfs: Change debugfs directory of IWMC3200 debugfs: Change debuhgfs directory of trace-events-sample.h debugfs: Fix mount directory of debugfs by default in events.txt hpilo: add poll f_op hpilo: add interrupt handler hpilo: staging for interrupt handling driver core: platform_device_add_data(): use kmemdup() Driver core: Add support for compatibility classes uio: add generic driver for PCI 2.3 devices driver-core: move dma-coherent.c from kernel to driver/base mem_class: fix bug mem_class: use minor as index instead of searching the array driver model: constify attribute groups UIO: remove 'default n' from Kconfig Driver core: Add accessor for device platform data Driver core: move dev_get/set_drvdata to drivers/base/dd.c Driver core: add new device to bus's list before probing
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/DocBook/uio-howto.tmpl163
-rw-r--r--Documentation/trace/events.txt24
2 files changed, 175 insertions, 12 deletions
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index 8f6e3b2403c7..4d4ce0e61e42 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -25,6 +25,10 @@
<year>2006-2008</year>
<holder>Hans-Jürgen Koch.</holder>
</copyright>
+<copyright>
+ <year>2009</year>
+ <holder>Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)</holder>
+</copyright>
<legalnotice>
<para>
@@ -42,6 +46,13 @@ GPL version 2.
<revhistory>
<revision>
+ <revnumber>0.9</revnumber>
+ <date>2009-07-16</date>
+ <authorinitials>mst</authorinitials>
+ <revremark>Added generic pci driver
+ </revremark>
+ </revision>
+ <revision>
<revnumber>0.8</revnumber>
<date>2008-12-24</date>
<authorinitials>hjk</authorinitials>
@@ -809,6 +820,158 @@ framework to set up sysfs files for this region. Simply leave it alone.
</chapter>
+<chapter id="uio_pci_generic" xreflabel="Using Generic driver for PCI cards">
+<?dbhtml filename="uio_pci_generic.html"?>
+<title>Generic PCI UIO driver</title>
+ <para>
+ The generic driver is a kernel module named uio_pci_generic.
+ It can work with any device compliant to PCI 2.3 (circa 2002) and
+ any compliant PCI Express device. Using this, you only need to
+ write the userspace driver, removing the need to write
+ a hardware-specific kernel module.
+ </para>
+
+<sect1 id="uio_pci_generic_binding">
+<title>Making the driver recognize the device</title>
+ <para>
+Since the driver does not declare any device ids, it will not get loaded
+automatically and will not automatically bind to any devices, you must load it
+and allocate id to the driver yourself. For example:
+ <programlisting>
+ modprobe uio_pci_generic
+ echo &quot;8086 10f5&quot; &gt; /sys/bus/pci/drivers/uio_pci_generic/new_id
+ </programlisting>
+ </para>
+ <para>
+If there already is a hardware specific kernel driver for your device, the
+generic driver still won't bind to it, in this case if you want to use the
+generic driver (why would you?) you'll have to manually unbind the hardware
+specific driver and bind the generic driver, like this:
+ <programlisting>
+ echo -n 0000:00:19.0 &gt; /sys/bus/pci/drivers/e1000e/unbind
+ echo -n 0000:00:19.0 &gt; /sys/bus/pci/drivers/uio_pci_generic/bind
+ </programlisting>
+ </para>
+ <para>
+You can verify that the device has been bound to the driver
+by looking for it in sysfs, for example like the following:
+ <programlisting>
+ ls -l /sys/bus/pci/devices/0000:00:19.0/driver
+ </programlisting>
+Which if successful should print
+ <programlisting>
+ .../0000:00:19.0/driver -&gt; ../../../bus/pci/drivers/uio_pci_generic
+ </programlisting>
+Note that the generic driver will not bind to old PCI 2.2 devices.
+If binding the device failed, run the following command:
+ <programlisting>
+ dmesg
+ </programlisting>
+and look in the output for failure reasons
+ </para>
+</sect1>
+
+<sect1 id="uio_pci_generic_internals">
+<title>Things to know about uio_pci_generic</title>
+ <para>
+Interrupts are handled using the Interrupt Disable bit in the PCI command
+register and Interrupt Status bit in the PCI status register. All devices
+compliant to PCI 2.3 (circa 2002) and all compliant PCI Express devices should
+support these bits. uio_pci_generic detects this support, and won't bind to
+devices which do not support the Interrupt Disable Bit in the command register.
+ </para>
+ <para>
+On each interrupt, uio_pci_generic sets the Interrupt Disable bit.
+This prevents the device from generating further interrupts
+until the bit is cleared. The userspace driver should clear this
+bit before blocking and waiting for more interrupts.
+ </para>
+</sect1>
+<sect1 id="uio_pci_generic_userspace">
+<title>Writing userspace driver using uio_pci_generic</title>
+ <para>
+Userspace driver can use pci sysfs interface, or the
+libpci libray that wraps it, to talk to the device and to
+re-enable interrupts by writing to the command register.
+ </para>
+</sect1>
+<sect1 id="uio_pci_generic_example">
+<title>Example code using uio_pci_generic</title>
+ <para>
+Here is some sample userspace driver code using uio_pci_generic:
+<programlisting>
+#include &lt;stdlib.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;fcntl.h&gt;
+#include &lt;errno.h&gt;
+
+int main()
+{
+ int uiofd;
+ int configfd;
+ int err;
+ int i;
+ unsigned icount;
+ unsigned char command_high;
+
+ uiofd = open(&quot;/dev/uio0&quot;, O_RDONLY);
+ if (uiofd &lt; 0) {
+ perror(&quot;uio open:&quot;);
+ return errno;
+ }
+ configfd = open(&quot;/sys/class/uio/uio0/device/config&quot;, O_RDWR);
+ if (uiofd &lt; 0) {
+ perror(&quot;config open:&quot;);
+ return errno;
+ }
+
+ /* Read and cache command value */
+ err = pread(configfd, &amp;command_high, 1, 5);
+ if (err != 1) {
+ perror(&quot;command config read:&quot;);
+ return errno;
+ }
+ command_high &amp;= ~0x4;
+
+ for(i = 0;; ++i) {
+ /* Print out a message, for debugging. */
+ if (i == 0)
+ fprintf(stderr, &quot;Started uio test driver.\n&quot;);
+ else
+ fprintf(stderr, &quot;Interrupts: %d\n&quot;, icount);
+
+ /****************************************/
+ /* Here we got an interrupt from the
+ device. Do something to it. */
+ /****************************************/
+
+ /* Re-enable interrupts. */
+ err = pwrite(configfd, &amp;command_high, 1, 5);
+ if (err != 1) {
+ perror(&quot;config write:&quot;);
+ break;
+ }
+
+ /* Wait for next interrupt. */
+ err = read(uiofd, &amp;icount, 4);
+ if (err != 4) {
+ perror(&quot;uio read:&quot;);
+ break;
+ }
+
+ }
+ return errno;
+}
+
+</programlisting>
+ </para>
+</sect1>
+
+</chapter>
+
<appendix id="app1">
<title>Further information</title>
<itemizedlist>
diff --git a/Documentation/trace/events.txt b/Documentation/trace/events.txt
index 2bcc8d4dea29..90e8b3383ba2 100644
--- a/Documentation/trace/events.txt
+++ b/Documentation/trace/events.txt
@@ -22,12 +22,12 @@ tracing information should be printed.
---------------------------------
The events which are available for tracing can be found in the file
-/debug/tracing/available_events.
+/sys/kernel/debug/tracing/available_events.
To enable a particular event, such as 'sched_wakeup', simply echo it
-to /debug/tracing/set_event. For example:
+to /sys/kernel/debug/tracing/set_event. For example:
- # echo sched_wakeup >> /debug/tracing/set_event
+ # echo sched_wakeup >> /sys/kernel/debug/tracing/set_event
[ Note: '>>' is necessary, otherwise it will firstly disable
all the events. ]
@@ -35,15 +35,15 @@ to /debug/tracing/set_event. For example:
To disable an event, echo the event name to the set_event file prefixed
with an exclamation point:
- # echo '!sched_wakeup' >> /debug/tracing/set_event
+ # echo '!sched_wakeup' >> /sys/kernel/debug/tracing/set_event
To disable all events, echo an empty line to the set_event file:
- # echo > /debug/tracing/set_event
+ # echo > /sys/kernel/debug/tracing/set_event
To enable all events, echo '*:*' or '*:' to the set_event file:
- # echo *:* > /debug/tracing/set_event
+ # echo *:* > /sys/kernel/debug/tracing/set_event
The events are organized into subsystems, such as ext4, irq, sched,
etc., and a full event name looks like this: <subsystem>:<event>. The
@@ -52,29 +52,29 @@ file. All of the events in a subsystem can be specified via the syntax
"<subsystem>:*"; for example, to enable all irq events, you can use the
command:
- # echo 'irq:*' > /debug/tracing/set_event
+ # echo 'irq:*' > /sys/kernel/debug/tracing/set_event
2.2 Via the 'enable' toggle
---------------------------
-The events available are also listed in /debug/tracing/events/ hierarchy
+The events available are also listed in /sys/kernel/debug/tracing/events/ hierarchy
of directories.
To enable event 'sched_wakeup':
- # echo 1 > /debug/tracing/events/sched/sched_wakeup/enable
+ # echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
To disable it:
- # echo 0 > /debug/tracing/events/sched/sched_wakeup/enable
+ # echo 0 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
To enable all events in sched subsystem:
- # echo 1 > /debug/tracing/events/sched/enable
+ # echo 1 > /sys/kernel/debug/tracing/events/sched/enable
To eanble all events:
- # echo 1 > /debug/tracing/events/enable
+ # echo 1 > /sys/kernel/debug/tracing/events/enable
When reading one of these enable files, there are four results: