diff --git a/lib/include/openamp/virtqueue.h b/lib/include/openamp/virtqueue.h index 819439871..8e6833bee 100644 --- a/lib/include/openamp/virtqueue.h +++ b/lib/include/openamp/virtqueue.h @@ -292,6 +292,21 @@ void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len, uint16_t *idx); void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx, uint32_t *len); +/** + * @internal + * + * @brief Returns next available buffer from VirtIO queue + * + * @param vq Pointer to VirtIO queue control block + * @param idx Index used in vring desc table + * @param next_idx Pointer to index of next buffer in vring desc table + * @param next_len Length of next buffer in vring desc table + * + * @return Pointer to next available buffer + */ +void *virtqueue_get_next_avail_buffer(struct virtqueue *vq, uint16_t idx, + uint16_t *next_idx, uint32_t *next_len) + /** * @internal * diff --git a/lib/virtio/virtqueue.c b/lib/virtio/virtqueue.c index 363fda8a4..898f7705f 100644 --- a/lib/virtio/virtqueue.c +++ b/lib/virtio/virtqueue.c @@ -231,6 +231,28 @@ void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx, return buffer; } +void *virtqueue_get_next_avail_buffer(struct virtqueue *vq, uint16_t idx, + uint16_t *next_idx, uint32_t *next_len) +{ + FAR void *buffer; + uint16_t next; + + VRING_INVALIDATE(vq->vq_ring.desc[idx], sizeof(struct vring_desc)); + if (((vq->vq_ring.desc[idx].flags) & VRING_DESC_F_NEXT) == 0) + return NULL; + + next = vq->vq_ring.desc[idx].next; + if (next_idx != NULL) + *next_idx = next; + + VRING_INVALIDATE(vq->vq_ring.desc[next], sizeof(struct vring_desc)); + buffer = virtqueue_phys_to_virt(vq, vq->vq_ring.desc[next].addr); + if (next_len != NULL) + *next_len = vq->vq_ring.desc[next].len; + + return buffer; +} + int virtqueue_add_consumed_buffer(struct virtqueue *vq, uint16_t head_idx, uint32_t len) {