Support for drivers in user space
Thomas Gleixner has written an interface module which may help to change that situation. With this code in place, PCI drivers (some of them, at least) can be written almost entirely in user space, with only a small stub module loaded into the kernel.
That module has two specific jobs to carry out. The first is to register the device to be driven, with a couple of bits of important information. To that end, it should fill out an iio_device structure, which contains the following fields:
struct iio_device {
char *name;
char *version;
unsigned long physaddr;
void *virtaddr;
unsigned long size;
long irq;
irqreturn_t (*handler)(int irq, void *dev_id, struct pt_regs *regs);
ssize_t (*event_write)(struct file *filep, const char __user * buf,
size_t count, loff_t *ppos);
struct file_operations *fops;
void *priv;
/* ... */
};
The first part of the structure provides information about the hardware to be driven - its name, where its I/O memory area lives (physaddr), where that area has been mapped into the kernel (virtaddr), its size, and the interrupt being used by the device. If virtaddr is zero, then physaddr is interpreted as the beginning of a range of I/O ports, rather than a memory address.
The fops field provides the file operations for the device; normally, they are set to the generic versions provided by the IIO (for "industrial I/O") driver: iio_open(), iio_read(), iio_mmap(), etc. With this setup, the driver can create a basic device which allows a user-space program to read from or write to device memory (or ports). I/O memory can also be mapped into user space.
The capabilities described thus far are not all that different from what can be done with /dev/mem; the main difference is that the stub driver can enable the PCI device and perform any other needed initialization. The real hitch in writing user-space PCI drivers, however, has been in the handling of interrupts. There is currently no way to write a user-space interrupt handler, and the IIO patch doesn't really change that. Instead, the stub driver is expected to provide a minimal interrupt handler of its own.
This handler is needed because every device requires its own specific interrupt acknowledgment ritual. The kernel must respond quickly to an interrupt and give the device the attention it craves so that said device will stop asserting the interrupt. After that, any additional processing can be done at relative leisure. So, once the handler provided with the stub driver acknowledges the interrupt, the rest of the work can normally be done by the user-space driver.
All that is needed is to let this driver know that the interrupt has happened. The IIO module provides a couple of mechanisms for that purpose. One is a second device node associated with the device; whenever an interrupt happens, a byte can be read from this "event device." So a user-space driver can simply block on a read from that device, or it can use poll() in more complicated situations. It is also possible for the user-space driver to receive SIGIO signals when an interrupt happens, but using signals will normally increase the ultimate response time to the interrupt.
So, to make all this happen, the stub driver provides a minimal interrupt handler in the handler() field of the iio_device structure. When an interrupt happens, the IIO module will call this handler; if it returns IRQ_HANDLED, user space will be notified. If the stub driver provides an event_write() function, that function will be called in response to a write operation on the event device. This capability can be used to further control the kernel-space response to interrupts, request that interrupts be masked, etc.
Readers who think that the event mechanism shares some features with the proposed kevent subsystem are right. It is probable that the IIO event handling code will be rewritten to use kevents, if and when kevents are merged into the mainline.
Meanwhile, however, the IIO driver works. Thomas has posted an example driver (or parts of one, anyway) to
show how this mechanism can be used. The real question which appears to be
on a number of minds, however, is: could ATI and nVidia use IIO to move
their drivers out of the kernel. Only those vendors can answer that
question, however, so, until they say something, nobody really knows.
| Index entries for this article | |
|---|---|
| Kernel | Device drivers/In user space |
