Index: uspace/lib/virtio/virtio-pci.h
===================================================================
--- uspace/lib/virtio/virtio-pci.h	(revision 9364ced7cdbe1145d830467590ebd2fc6b31acbf)
+++ uspace/lib/virtio/virtio-pci.h	(revision c1ba24a6c8f4bb5f17a0cc0a518297de16004fb0)
@@ -174,4 +174,9 @@
 } virtio_dev_t;
 
+extern void virtio_virtq_set_desc(virtio_dev_t *vdev, uint16_t, uint16_t,
+    uint64_t, uint32_t, uint16_t, uint16_t);
+
+extern void virtio_virtq_produce_available(virtio_dev_t *, uint16_t, uint16_t);
+
 extern errno_t virtio_virtq_setup(virtio_dev_t *, uint16_t, uint16_t);
 extern void virtio_virtq_teardown(virtio_dev_t *, uint16_t);
Index: uspace/lib/virtio/virtio.c
===================================================================
--- uspace/lib/virtio/virtio.c	(revision 9364ced7cdbe1145d830467590ebd2fc6b31acbf)
+++ uspace/lib/virtio/virtio.c	(revision c1ba24a6c8f4bb5f17a0cc0a518297de16004fb0)
@@ -37,4 +37,28 @@
 
 #include <ddf/log.h>
+#include <libarch/barrier.h>
+
+void virtio_virtq_set_desc(virtio_dev_t *vdev, uint16_t num, uint16_t descno,
+    uint64_t addr, uint32_t len, uint16_t flags, uint16_t next)
+{
+	virtq_desc_t *d = &vdev->queues[num].desc[descno];
+	pio_write_64(&d->addr, addr);
+	pio_write_32(&d->len, len);
+	pio_write_16(&d->flags, flags);
+	pio_write_16(&d->next, next);
+}
+
+void virtio_virtq_produce_available(virtio_dev_t *vdev, uint16_t num,
+    uint16_t descno)
+{
+	virtq_t *q = &vdev->queues[num];
+
+	uint16_t idx = pio_read_16(&q->avail->idx);
+	pio_write_16(&q->avail->ring[idx], descno);
+	write_barrier();
+	pio_write_16(&q->avail->idx, (idx + 1) % q->queue_size);
+	write_barrier();
+	pio_write_16(&q->notify, num);
+}
 
 errno_t virtio_virtq_setup(virtio_dev_t *vdev, uint16_t num, uint16_t size)
