root@gobgp:~# lspci | grep -i ether
01:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
07:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
root@gobgp:~# lspci -s 07:00.0
07:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
root@gobgp:~# lspci -s 07:00.0 -v
07:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
Subsystem: Red Hat, Inc. Virtio network device
Physical Slot: 0-6
Flags: bus master, fast devsel, latency 0, IRQ 38
Memory at 10c40000 (32-bit, non-prefetchable) [size=4K]
Memory at 8000c00000 (64-bit, prefetchable) [size=16K]
Expansion ROM at 10c00000 [disabled] [size=256K]
Capabilities: [dc] MSI-X: Enable- Count=3 Masked-
Capabilities: [c8] Vendor Specific Information: VirtIO: <unknown>
Capabilities: [b4] Vendor Specific Information: VirtIO: Notify
Capabilities: [a4] Vendor Specific Information: VirtIO: DeviceCfg
Capabilities: [94] Vendor Specific Information: VirtIO: ISR
Capabilities: [84] Vendor Specific Information: VirtIO: CommonCfg
Capabilities: [7c] Power Management version 3
Capabilities: [40] Express Endpoint, MSI 00
Kernel driver in use: uio_pci_generic
root@gobgp:~#
root@gobgp:~# cat /sys/bus/pci/drivers/uio_pci_generic/bind
cat: /sys/bus/pci/drivers/uio_pci_generic/bind: Permission denied
root@gobgp:~# ls -l /sys/bus/pci/devices/0000\:07\:00.0
lrwxrwxrwx 1 root root 0 Aug 24 14:20 /sys/bus/pci/devices/0000:07:00.0 -> ../../../devices/pci0000:00/0000:00:01.6/0000:07:00.0
root@gobgp:~# ls -l /sys/bus/pci/devices/0000\:07\:00.0/driver
lrwxrwxrwx 1 root root 0 Aug 24 14:20 /sys/bus/pci/devices/0000:07:00.0/driver -> ../../../../bus/pci/drivers/uio_pci_generic
root@gobgp:~#
root@gobgp:~# cat /dev/uio0
cat: /dev/uio0: Invalid argument
root@gobgp:~#
Example code using uio_pci_generic
Here is some sample userspace driver code using uio_pci_generic:
#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 (configfd < 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. *