/* virtqueue_get_available_buffer - Returns buffer available for use in the VirtIO queue */
void* virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx, uint32_t *len)
/* virtqueue_get_available_buffer - Returns buffer available for use in the VirtIO queue */
void* virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx, uint32_t *len)
{
	uint16_t head_idx = 0;
	void *buffer;
	atomic_thread_fence(memory_order_seq_cst);
	if (vq->vq_available_idx == vq->vq_ring.avail->idx) {
		return NULL;
	}
	VQUEUE_BUSY(vq);
	head_idx = vq->vq_available_idx++ & (vq->vq_nentries - 1);
	*avail_idx = vq->vq_ring.avail->ring[head_idx];
	buffer = virtqueue_phys_to_virt(vq, vq->vq_ring.desc[*avail_idx].addr);
	*len = vq->vq_ring.desc[*avail_idx].len;
	VQUEUE_IDLE(vq);
	return buffer;
}