1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0+ 2 3 /* 4 * Scatterlist filler helpers for virtio-media. 5 * 6 * Copyright (c) 2023-2024 Google LLC. 7 */ 8 9 #ifndef __VIRTIO_MEDIA_SCATTERLIST_FILLER_H 10 #define __VIRTIO_MEDIA_SCATTERLIST_FILLER_H 11 12 #include <linux/scatterlist.h> 13 14 #include "session.h" 15 16 /** 17 * struct scatterlist_filler - helper to fill a scatterlist from data. 18 * 19 * @descs: array of scatterlist that will be filled. 20 * @num_descs: number of entries in descs. 21 * @cur_desc: next descriptor to be written in descs. 22 * @shadow_buffer: pointer to a shadow buffer where elements that cannot be 23 * mapped directly into the scatterlist get copied. 24 * @shadow_buffer_size: size of shadow_buffer. 25 * @shadow_buffer_pos: current position in shadow_buffer. 26 * @sgs: list of scatterlist pointers to eventually pass to virtio. 27 * @num_sgs: total number of entries in sgs. 28 * @cur_sg: next entry in @sgs to be written into. 29 * 30 */ 31 struct scatterlist_filler { 32 struct scatterlist *descs; 33 size_t num_descs; 34 size_t cur_desc; 35 36 void *shadow_buffer; 37 size_t shadow_buffer_size; 38 size_t shadow_buffer_pos; 39 40 struct scatterlist **sgs; 41 size_t num_sgs; 42 size_t cur_sg; 43 }; 44 45 /** 46 * scatterlist_filler_add_sg - Add a scatterlist to the list of sgs. 47 */ 48 int scatterlist_filler_add_sg(struct scatterlist_filler *filler, 49 struct scatterlist *sg); 50 51 /** 52 * scatterlist_filler_add_ioctl_cmd - Add an ioctl command to the list. 53 */ 54 int scatterlist_filler_add_ioctl_cmd(struct scatterlist_filler *filler, 55 struct virtio_media_session *session, 56 u32 ioctl_code); 57 58 /** 59 * scatterlist_filler_add_ioctl_resp - Add storage to receive an ioctl response to the list. 60 */ 61 int scatterlist_filler_add_ioctl_resp(struct scatterlist_filler *filler, 62 struct virtio_media_session *session); 63 64 /** 65 * scatterlist_filler_add_data - Add arbitrary data to the list. 66 * 67 * The data will either be directly mapped, or copied into the shadow buffer to be mapped there. 68 */ 69 int scatterlist_filler_add_data(struct scatterlist_filler *filler, void *data, 70 size_t len); 71 72 /** 73 * scatterlist_filler_add_buffer - Add a v4l2_buffer and its planes to the list. 74 * 75 * The buffer and its pointers will be either directly mapped, or copied into the shadow buffer to be mapped there. 76 */ 77 int scatterlist_filler_add_buffer(struct scatterlist_filler *filler, 78 struct v4l2_buffer *buffer); 79 80 /** 81 * scatterlist_filler_add_buffer_userptr - Add a USERPTR v4l2_buffer's content to the list. 82 * 83 * For performance reasons the shadow buffer is never used. 84 */ 85 int scatterlist_filler_add_buffer_userptr(struct scatterlist_filler *filler, 86 struct v4l2_buffer *b); 87 88 /** 89 * scatterlist_filler_add_ext_ctrls - Add a v4l2_ext_controls and its controls to the list. 90 * 91 * The controls will be either directly mapped, or copied into the shadow buffer to be mapped there. 92 * 93 * For controls with pointer data, the data is always directly mapped, not copied. 94 */ 95 int scatterlist_filler_add_ext_ctrls(struct scatterlist_filler *filler, 96 struct v4l2_ext_controls *ctrls, 97 bool add_userptrs); 98 99 /** 100 * scatterlist_filler_retrieve_data - Retrieve data written by the device on the shadow buffer, if needed. 101 * 102 * If the shadow buffer is pointed to by @sg, copy its content back into @data. 103 */ 104 int scatterlist_filler_retrieve_data(struct virtio_media_session *session, 105 struct scatterlist *sg, void *data, 106 size_t len); 107 108 /** 109 * scatterlist_filler_retrieve_buffer - Retrieve buffer data written by the device on the shadow buffer, if needed. 110 * 111 * If the shadow buffer is pointed to by @sg, copy its content back into @buffer. 112 */ 113 int scatterlist_filler_retrieve_buffer(struct virtio_media_session *session, 114 struct scatterlist **buffer_sgs, 115 struct v4l2_buffer *buffer, 116 size_t num_planes); 117 118 /** 119 * scatterlist_filler_retrieve_ext_ctrls - Retrieve controls data written by the device on the shadow buffer, if needed. 120 * 121 * If the shadow buffer is pointed to by @sg, copy its content back into @ctrls. 122 */ 123 int scatterlist_filler_retrieve_ext_ctrls(struct virtio_media_session *session, 124 struct scatterlist **sgs_idx, 125 int num_ctrls_sgs, 126 struct v4l2_ext_controls *ctrls); 127 128 #endif // __VIRTIO_MEDIA_SCATTERLIST_FILLER_H 129