hello tech@, here is a diff that will follow the virtio spec a little closer, and allows 9front's (http://9front.org) virtio-blk driver to correctly find the number of queues. i know that virtio-blk only has one queue, but the virtio probing code is shared between virtio-blk and virtio-scsi.
without this change, the size of the first queue is used for all subsequently probed queues. for completeness i've changed rng and net to do the same as blk. some bits from the spec: 4.1.4.3.1 - "The device MUST present a 0 in queue_size if the virtqueue corresponding to the current queue_select is unavailable." 4.1.5.1.3 - "Write the virtqueue index (first queue is 0) to queue_select. Read the virtqueue size from queue_size. This controls how big the virtqueue is (see 2.4 Virtqueues). If this field is 0, the virtqueue does not exist." Index: virtio.c =================================================================== RCS file: /cvs/src/usr.sbin/vmd/virtio.c,v retrieving revision 1.49 diff -u -p -u -p -r1.49 virtio.c --- virtio.c 30 May 2017 17:56:47 -0000 1.49 +++ virtio.c 27 Jul 2017 04:35:46 -0000 @@ -150,8 +150,10 @@ void viornd_update_qs(void) { /* Invalid queue? */ - if (viornd.cfg.queue_select > 0) + if (viornd.cfg.queue_select > 0) { + viornd.cfg.queue_size = 0; return; + } /* Update queue address/size based on queue select */ viornd.cfg.queue_address = viornd.vq[viornd.cfg.queue_select].qa; @@ -324,8 +326,10 @@ void vioblk_update_qs(struct vioblk_dev *dev) { /* Invalid queue? */ - if (dev->cfg.queue_select > 0) + if (dev->cfg.queue_select > 0) { + dev->cfg.queue_size = 0; return; + } /* Update queue address/size based on queue select */ dev->cfg.queue_address = dev->vq[dev->cfg.queue_select].qa; @@ -1037,8 +1041,10 @@ void vionet_update_qs(struct vionet_dev *dev) { /* Invalid queue? */ - if (dev->cfg.queue_select > 1) + if (dev->cfg.queue_select > 1) { + dev->cfg.queue_size = 0; return; + } /* Update queue address/size based on queue select */ dev->cfg.queue_address = dev->vq[dev->cfg.queue_select].qa;