Skip to content

Commit

Permalink
virtqueue: add virtqueue_get_next_avail_buffer() API
Browse files Browse the repository at this point in the history
In virtio device side, we always need to get the next avaiable
buffer based on current buffer index. So add this API for
convinience use.

For example, virtio blk driver origanize the buffer:
+----------+
| Reqeust  | (Flags: Read | Next)
+----------+
| Buffer   | (Flags: Read/Write | Next)
+----------+
| Response | (Flags: Write)
+----------+

For the virtio blk device size, we need get the Buffer and Response buffer
based on the Request buffer index.

Signed-off-by: Bowen Wang <[email protected]>
Signed-off-by: Yongrong Wang <[email protected]>
  • Loading branch information
CV-Bowen committed Nov 4, 2024
1 parent 71887e7 commit c485436
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
15 changes: 15 additions & 0 deletions lib/include/openamp/virtqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
22 changes: 22 additions & 0 deletions lib/virtio/virtqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down

0 comments on commit c485436

Please sign in to comment.