return next;
}
+/* This actually sends the interrupt for this virtqueue */
+static void trigger_irq(struct virtqueue *vq)
+{
+ unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
+
+ /* If they don't want an interrupt, don't send one, unless empty. */
+ if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
+ && lg_last_avail(vq) != vq->vring.avail->idx)
+ return;
+
+ /* Send the Guest an interrupt tell them we used something up. */
+ if (write(lguest_fd, buf, sizeof(buf)) != 0)
+ err(1, "Triggering irq %i", vq->config.irq);
+}
+
/* This looks in the virtqueue and for the first available buffer, and converts
* it to an iovec for convenient access. Since descriptors consist of some
* number of output then some number of input descriptors, it's actually two
while (last_avail == vq->vring.avail->idx) {
u64 event;
+ /* OK, tell Guest about progress up to now. */
+ trigger_irq(vq);
+
/* Nothing new? Wait for eventfd to tell us they refilled. */
if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event))
errx(1, "Event read failed?");
vq->vring.used->idx++;
}
-/* This actually sends the interrupt for this virtqueue */
-static void trigger_irq(struct virtqueue *vq)
-{
- unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
-
- /* If they don't want an interrupt, don't send one, unless empty. */
- if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
- && lg_last_avail(vq) != vq->vring.avail->idx)
- return;
-
- /* Send the Guest an interrupt tell them we used something up. */
- if (write(lguest_fd, buf, sizeof(buf)) != 0)
- err(1, "Triggering irq %i", vq->config.irq);
-}
-
/* And here's the combo meal deal. Supersize me! */
static void add_used_and_trigger(struct virtqueue *vq, unsigned head, int len)
{
err(1, "Write to stdout gave %i", len);
iov_consume(iov, out, len);
}
- add_used_and_trigger(vq, head, 0);
+ add_used(vq, head, 0);
}
/*
errx(1, "Input buffers in net output queue?");
if (writev(net_info->tunfd, iov, out) < 0)
errx(1, "Write to tun failed?");
- add_used_and_trigger(vq, head, 0);
+ add_used(vq, head, 0);
}
/* This is where we handle packets coming in from the tun device to our
if (out->type & VIRTIO_BLK_T_BARRIER)
fdatasync(vblk->fd);
- add_used_and_trigger(vq, head, wlen);
+ add_used(vq, head, wlen);
}
/*L:198 This actually sets up a virtual block device. */
}
/* Tell the Guest about the new input. */
- add_used_and_trigger(vq, head, totlen);
+ add_used(vq, head, totlen);
}
/* And this creates a "hardware" random number device for the Guest. */