Commit 3ef66af31fea ("virtio_ring: introduce add api for premapped") add functions to add premapped input or output chains to a virtqueue. Add a generic one that supports out+in buffers chains. Signed-off-by: Eugenio Pérez <eperezma@xxxxxxxxxx> --- drivers/virtio/virtio_ring.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/virtio.h | 7 +++++++ 2 files changed, 42 insertions(+) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index fdd2d2b07b5a..7ef1f37e025f 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -2318,6 +2318,41 @@ int virtqueue_add_sgs(struct virtqueue *_vq, } EXPORT_SYMBOL_GPL(virtqueue_add_sgs); +/** + * virtqueue_add_sgs_premapped - expose buffers to other end + * @_vq: the struct virtqueue we're talking about. + * @sgs: array of terminated scatterlists. + * @out_sgs: the number of scatterlists readable by other side + * @in_sgs: the number of scatterlists which are writable (after readable ones) + * @data: the token identifying the buffer. + * @gfp: how to do memory allocations (if necessary). + * + * Caller must ensure we don't call this with other virtqueue operations + * at the same time (except where noted). + * + * Returns zero or a negative error (ie. ENOSPC, ENOMEM, EIO). + */ +int virtqueue_add_sgs_premapped(struct virtqueue *_vq, + struct scatterlist *sgs[], + unsigned int out_sgs, + unsigned int in_sgs, + void *data, + gfp_t gfp) +{ + unsigned int i, total_sg = 0; + + /* Count them first. */ + for (i = 0; i < out_sgs + in_sgs; i++) { + struct scatterlist *sg; + + for (sg = sgs[i]; sg; sg = sg_next(sg)) + total_sg++; + } + return virtqueue_add(_vq, sgs, total_sg, out_sgs, in_sgs, + data, NULL, true, gfp); +} +EXPORT_SYMBOL_GPL(virtqueue_add_sgs_premapped); + /** * virtqueue_add_outbuf - expose output buffers to other end * @vq: the struct virtqueue we're talking about. diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 4d16c13d0df5..7f61f66ddaa2 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -74,6 +74,13 @@ int virtqueue_add_sgs(struct virtqueue *vq, void *data, gfp_t gfp); +int virtqueue_add_sgs_premapped(struct virtqueue *vq, + struct scatterlist *sgs[], + unsigned int out_sgs, + unsigned int in_sgs, + void *data, + gfp_t gfp); + struct device *virtqueue_dma_dev(struct virtqueue *vq); bool virtqueue_kick(struct virtqueue *vq); -- 2.48.1