summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/ethervirtio.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2021-07-11 11:24:13 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2021-07-11 11:24:13 +0000
commitf58d99aa7a97ba5f79af89f38b78d5924d4e35a2 (patch)
tree42aeb9f910f45bee8073edf3fa118e28cced6af4 /sys/src/9/pc/ethervirtio.c
parentc3589ef3cf33189d342a3ab638b558fd9249b220 (diff)
virtio: add non-legacy virtio 1.0 drivers for disk and ethernet
The new interface uses pci capability structures to locate the registers in a rather fine granular way making it more complicated as they can be located anywhere in any pci bar at any offset. As far as i can see, qemu (6.0.50) never uses i/o bars in non-legacy mode, so only mmio is implemented for now. The previous virtio drivers implemented the legacy interface only which uses i/o ports for all register accesses. This is still the preferred method (and also qemu default) as it is easier to emulate and most likely faster. However, some vps providers like vultr force the legacy interface to disabled with qemu -device option "disable-legacy=on" resulting on a system without a disk and ethernet.
Diffstat (limited to 'sys/src/9/pc/ethervirtio.c')
-rw-r--r--sys/src/9/pc/ethervirtio.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/sys/src/9/pc/ethervirtio.c b/sys/src/9/pc/ethervirtio.c
index 871f6d884..db9dc2cba 100644
--- a/sys/src/9/pc/ethervirtio.c
+++ b/sys/src/9/pc/ethervirtio.c
@@ -1,3 +1,7 @@
+/*
+ * virtio ethernet driver implementing the legacy interface:
+ * http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html
+ */
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
@@ -9,11 +13,6 @@
#include "../port/netif.h"
#include "../port/etherif.h"
-/*
- * virtio ethernet driver
- * http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html
- */
-
typedef struct Vring Vring;
typedef struct Vdesc Vdesc;
typedef struct Vused Vused;
@@ -555,13 +554,14 @@ pciprobe(int typ)
h = t = nil;
/* §4.1.2 PCI Device Discovery */
- for(p = nil; p = pcimatch(p, 0, 0);){
- if(p->vid != 0x1AF4)
- continue;
+ for(p = nil; p = pcimatch(p, 0x1AF4, 0);){
/* the two possible DIDs for virtio-net */
if(p->did != 0x1000 && p->did != 0x1041)
continue;
- /* non-transitional devices will have a revision > 0 */
+ /*
+ * non-transitional devices will have a revision > 0,
+ * these are handled by ethervirtio10 driver.
+ */
if(p->rid != 0)
continue;
/* first membar needs to be I/O */
@@ -588,6 +588,8 @@ pciprobe(int typ)
/* §3.1.2 Legacy Device Initialization */
outb(c->port+Qstatus, 0);
+ while(inb(c->port+Qstatus) != 0)
+ delay(1);
outb(c->port+Qstatus, Sacknowledge|Sdriver);
/* negotiate feature bits */