[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20090716170346.GA22095@redhat.com>
Date:	Thu, 16 Jul 2009 20:03:46 +0300
From:	"Michael S. Tsirkin" <mst@...hat.com>
To:	Greg KH <gregkh@...e.de>
Cc:	"Hans J. Koch" <hjk@...utronix.de>, anthony@...emonkey.ws,
	avi@...hat.com, kvm@...r.kernel.org, chrisw@...hat.com,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCHv4] uio: add generic driver for PCI 2.3 devices
On Thu, Jul 16, 2009 at 08:52:08AM -0700, Greg KH wrote:
> On Thu, Jul 16, 2009 at 05:12:55PM +0200, Hans J. Koch wrote:
> > On Thu, Jul 16, 2009 at 05:07:10PM +0300, Michael S. Tsirkin wrote:
> > > On Wed, Jul 15, 2009 at 03:08:29PM -0700, Greg KH wrote:
> > > > How about moving that documentation into a place that people will notice
> > > > it, like the rest of the UIO documentation?
> > > 
> > > Greg,
> > > 
> > > would it make more sense to add this to
> > > Documentation/DocBook/uio-howto.xml, or to create
> > > Documentation/uio_pci_generic.txt ?
> > 
> > Hi Michael,
> > I'd prefer to have it in uio-howto.xml so that people only have to look in
> > one place. In does not have to be very detailled, just a short explanation
> > what this driver is all about and a short example how to use it.
> 
> I agree, that would be the best place for it.
> 
> thanks,
> 
> greg k-h
OK. Could you take a look at the following please?
-->
doc: Document uio_pci_generic
Signed-off-by: Michael S. Tsirkin <mst@...hat.com>
---
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index 8f6e3b2..4d4ce0e 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@...hat.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 "8086 10f5" > /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 > /sys/bus/pci/drivers/e1000e/unbind
+    echo -n 0000:00:19.0 > /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 -> ../../../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 <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+int main()
+{
+	int uiofd;
+	int configfd;
+	int err;
+	int i;
+	unsigned icount;
+	unsigned char command_high;
+
+	uiofd = open("/dev/uio0", O_RDONLY);
+	if (uiofd < 0) {
+		perror("uio open:");
+		return errno;
+	}
+	configfd = open("/sys/class/uio/uio0/device/config", O_RDWR);
+	if (uiofd < 0) {
+		perror("config open:");
+		return errno;
+	}
+
+	/* Read and cache command value */
+	err = pread(configfd, &command_high, 1, 5);
+	if (err != 1) {
+		perror("command config read:");
+		return errno;
+	}
+	command_high &= ~0x4;
+
+	for(i = 0;; ++i) {
+		/* Print out a message, for debugging. */
+		if (i == 0)
+			fprintf(stderr, "Started uio test driver.\n");
+		else
+			fprintf(stderr, "Interrupts: %d\n", icount);
+
+		/****************************************/
+		/* Here we got an interrupt from the
+		   device. Do something to it. */
+		/****************************************/
+
+		/* Re-enable interrupts. */
+		err = pwrite(configfd, &command_high, 1, 5);
+		if (err != 1) {
+			perror("config write:");
+			break;
+		}
+
+		/* Wait for next interrupt. */
+		err = read(uiofd, &icount, 4);
+		if (err != 4) {
+			perror("uio read:");
+			break;
+		}
+
+	}
+	return errno;
+}
+
+</programlisting>
+	</para>
+</sect1>
+
+</chapter>
+
 <appendix id="app1">
 <title>Further information</title>
 <itemizedlist>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Powered by blists - more mailing lists
 
