Commit 282edb36499042a92b71f052f51754ae7ed936e4
1 parent
13816c768d
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
virtio_ring: virtqueue_add_outbuf / virtqueue_add_inbuf.
These are specialized versions of virtqueue_add_buf(), which cover over 80% of cases and are far clearer. In particular, the scatterlists passed to these functions don't have to be clean (ie. we ignore end markers). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Showing 2 changed files with 54 additions and 0 deletions Side-by-side Diff
drivers/virtio/virtio_ring.c
... | ... | @@ -366,6 +366,50 @@ |
366 | 366 | EXPORT_SYMBOL_GPL(virtqueue_add_sgs); |
367 | 367 | |
368 | 368 | /** |
369 | + * virtqueue_add_outbuf - expose output buffers to other end | |
370 | + * @vq: the struct virtqueue we're talking about. | |
371 | + * @sgs: array of scatterlists (need not be terminated!) | |
372 | + * @num: the number of scatterlists readable by other side | |
373 | + * @data: the token identifying the buffer. | |
374 | + * @gfp: how to do memory allocations (if necessary). | |
375 | + * | |
376 | + * Caller must ensure we don't call this with other virtqueue operations | |
377 | + * at the same time (except where noted). | |
378 | + * | |
379 | + * Returns zero or a negative error (ie. ENOSPC, ENOMEM). | |
380 | + */ | |
381 | +int virtqueue_add_outbuf(struct virtqueue *vq, | |
382 | + struct scatterlist sg[], unsigned int num, | |
383 | + void *data, | |
384 | + gfp_t gfp) | |
385 | +{ | |
386 | + return virtqueue_add(vq, &sg, sg_next_arr, num, 0, 1, 0, data, gfp); | |
387 | +} | |
388 | +EXPORT_SYMBOL_GPL(virtqueue_add_outbuf); | |
389 | + | |
390 | +/** | |
391 | + * virtqueue_add_inbuf - expose input buffers to other end | |
392 | + * @vq: the struct virtqueue we're talking about. | |
393 | + * @sgs: array of scatterlists (need not be terminated!) | |
394 | + * @num: the number of scatterlists writable by other side | |
395 | + * @data: the token identifying the buffer. | |
396 | + * @gfp: how to do memory allocations (if necessary). | |
397 | + * | |
398 | + * Caller must ensure we don't call this with other virtqueue operations | |
399 | + * at the same time (except where noted). | |
400 | + * | |
401 | + * Returns zero or a negative error (ie. ENOSPC, ENOMEM). | |
402 | + */ | |
403 | +int virtqueue_add_inbuf(struct virtqueue *vq, | |
404 | + struct scatterlist sg[], unsigned int num, | |
405 | + void *data, | |
406 | + gfp_t gfp) | |
407 | +{ | |
408 | + return virtqueue_add(vq, &sg, sg_next_arr, 0, num, 0, 1, data, gfp); | |
409 | +} | |
410 | +EXPORT_SYMBOL_GPL(virtqueue_add_inbuf); | |
411 | + | |
412 | +/** | |
369 | 413 | * virtqueue_kick_prepare - first half of split virtqueue_kick call. |
370 | 414 | * @vq: the struct virtqueue |
371 | 415 | * |
include/linux/virtio.h
... | ... | @@ -41,6 +41,16 @@ |
41 | 41 | void *data, |
42 | 42 | gfp_t gfp); |
43 | 43 | |
44 | +int virtqueue_add_outbuf(struct virtqueue *vq, | |
45 | + struct scatterlist sg[], unsigned int num, | |
46 | + void *data, | |
47 | + gfp_t gfp); | |
48 | + | |
49 | +int virtqueue_add_inbuf(struct virtqueue *vq, | |
50 | + struct scatterlist sg[], unsigned int num, | |
51 | + void *data, | |
52 | + gfp_t gfp); | |
53 | + | |
44 | 54 | int virtqueue_add_sgs(struct virtqueue *vq, |
45 | 55 | struct scatterlist *sgs[], |
46 | 56 | unsigned int out_sgs, |