struct packet *p;
/* Put the received packets into the recv list */
- while (virtio_from_queue(net_dev, RX_Q, (void **)&p) == 0) {
+ while (virtio_from_queue(net_dev, RX_Q, (void **)&p, NULL) == 0) {
STAILQ_INSERT_TAIL(&recv_list, p, next);
in_rx--;
virtio_net_stats.ets_packetR++;
/* Packets from the TX queue just indicated they are free to
* be reused now. inet already knows about them as being sent.
*/
- while (virtio_from_queue(net_dev, TX_Q, (void **)&p) == 0) {
+ while (virtio_from_queue(net_dev, TX_Q, (void **)&p, NULL) == 0) {
memset(p->vhdr, 0, sizeof(*p->vhdr));
memset(p->vdata, 0, MAX_PACK_SIZE);
STAILQ_INSERT_HEAD(&free_list, p, next);
thread_id_t *tid;
/* Multiple requests might have finished */
- while (!virtio_from_queue(blk_dev, 0, (void**)&tid))
+ while (!virtio_from_queue(blk_dev, 0, (void**)&tid, NULL))
blockdriver_mt_wakeup(*tid);
}
struct vumap_phys *bufs, size_t num, void *data);
/*
- * If the host used a chain of descriptors, return 0 and set data
- * as was given to virtio_to_queue(). If the host has not processed
- * any element returns -1.
+ * If the host used a chain of descriptors, return 0, set data as was given to
+ * virtio_to_queue(), and if len is not NULL, set it to the resulting length.
+ * If the host has not processed any element, return -1.
*/
-int virtio_from_queue(struct virtio_device *dev, int qidx, void **data);
+int virtio_from_queue(struct virtio_device *dev, int qidx, void **data,
+ size_t *len);
/* IRQ related functions */
void virtio_irq_enable(struct virtio_device *dev);
}
int
-virtio_from_queue(struct virtio_device *dev, int qidx, void **data)
+virtio_from_queue(struct virtio_device *dev, int qidx, void **data,
+ size_t *len)
{
struct virtio_queue *q;
struct vring *vring;
*data = q->data[uel->id];
q->data[uel->id] = NULL;
+ if (len != NULL)
+ *len = uel->len;
+
return 0;
}