| .. | .. |
|---|
| 14 | 14 | * the Free Software Foundation. |
|---|
| 15 | 15 | */ |
|---|
| 16 | 16 | |
|---|
| 17 | +#include <linux/device.h> |
|---|
| 17 | 18 | #include <linux/err.h> |
|---|
| 18 | | -#include <linux/kernel.h> |
|---|
| 19 | | -#include <linux/module.h> |
|---|
| 20 | | -#include <linux/mm.h> |
|---|
| 21 | | -#include <linux/poll.h> |
|---|
| 22 | | -#include <linux/slab.h> |
|---|
| 23 | | -#include <linux/sched.h> |
|---|
| 24 | 19 | #include <linux/freezer.h> |
|---|
| 20 | +#include <linux/kernel.h> |
|---|
| 25 | 21 | #include <linux/kthread.h> |
|---|
| 22 | +#include <linux/mm.h> |
|---|
| 23 | +#include <linux/module.h> |
|---|
| 24 | +#include <linux/poll.h> |
|---|
| 25 | +#include <linux/sched.h> |
|---|
| 26 | +#include <linux/slab.h> |
|---|
| 26 | 27 | |
|---|
| 27 | | -#include <media/v4l2-dev.h> |
|---|
| 28 | | -#include <media/v4l2-fh.h> |
|---|
| 29 | | -#include <media/v4l2-event.h> |
|---|
| 30 | 28 | #include <media/v4l2-common.h> |
|---|
| 29 | +#include <media/v4l2-dev.h> |
|---|
| 30 | +#include <media/v4l2-device.h> |
|---|
| 31 | +#include <media/v4l2-event.h> |
|---|
| 32 | +#include <media/v4l2-fh.h> |
|---|
| 31 | 33 | |
|---|
| 32 | 34 | #include <media/videobuf2-v4l2.h> |
|---|
| 33 | 35 | |
|---|
| 34 | 36 | static int debug; |
|---|
| 35 | 37 | module_param(debug, int, 0644); |
|---|
| 36 | 38 | |
|---|
| 37 | | -#define dprintk(level, fmt, arg...) \ |
|---|
| 39 | +#define dprintk(q, level, fmt, arg...) \ |
|---|
| 38 | 40 | do { \ |
|---|
| 39 | 41 | if (debug >= level) \ |
|---|
| 40 | | - pr_info("vb2-v4l2: %s: " fmt, __func__, ## arg); \ |
|---|
| 42 | + pr_info("vb2-v4l2: [%p] %s: " fmt, \ |
|---|
| 43 | + (q)->name, __func__, ## arg); \ |
|---|
| 41 | 44 | } while (0) |
|---|
| 42 | 45 | |
|---|
| 43 | | -/* Flags that are set by the vb2 core */ |
|---|
| 46 | +/* Flags that are set by us */ |
|---|
| 44 | 47 | #define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \ |
|---|
| 45 | 48 | V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \ |
|---|
| 46 | 49 | V4L2_BUF_FLAG_PREPARED | \ |
|---|
| 50 | + V4L2_BUF_FLAG_IN_REQUEST | \ |
|---|
| 51 | + V4L2_BUF_FLAG_REQUEST_FD | \ |
|---|
| 47 | 52 | V4L2_BUF_FLAG_TIMESTAMP_MASK) |
|---|
| 48 | 53 | /* Output buffer flags that should be passed on to the driver */ |
|---|
| 49 | | -#define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \ |
|---|
| 50 | | - V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE) |
|---|
| 54 | +#define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | \ |
|---|
| 55 | + V4L2_BUF_FLAG_BFRAME | \ |
|---|
| 56 | + V4L2_BUF_FLAG_KEYFRAME | \ |
|---|
| 57 | + V4L2_BUF_FLAG_TIMECODE | \ |
|---|
| 58 | + V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF) |
|---|
| 51 | 59 | |
|---|
| 52 | 60 | /* |
|---|
| 53 | 61 | * __verify_planes_array() - verify that the planes array passed in struct |
|---|
| .. | .. |
|---|
| 60 | 68 | |
|---|
| 61 | 69 | /* Is memory for copying plane information present? */ |
|---|
| 62 | 70 | if (b->m.planes == NULL) { |
|---|
| 63 | | - dprintk(1, "multi-planar buffer passed but planes array not provided\n"); |
|---|
| 71 | + dprintk(vb->vb2_queue, 1, |
|---|
| 72 | + "multi-planar buffer passed but planes array not provided\n"); |
|---|
| 64 | 73 | return -EINVAL; |
|---|
| 65 | 74 | } |
|---|
| 66 | 75 | |
|---|
| 67 | 76 | if (b->length < vb->num_planes || b->length > VB2_MAX_PLANES) { |
|---|
| 68 | | - dprintk(1, "incorrect planes array length, expected %d, got %d\n", |
|---|
| 77 | + dprintk(vb->vb2_queue, 1, |
|---|
| 78 | + "incorrect planes array length, expected %d, got %d\n", |
|---|
| 69 | 79 | vb->num_planes, b->length); |
|---|
| 70 | 80 | return -EINVAL; |
|---|
| 71 | 81 | } |
|---|
| .. | .. |
|---|
| 88 | 98 | unsigned int bytesused; |
|---|
| 89 | 99 | unsigned int plane; |
|---|
| 90 | 100 | |
|---|
| 91 | | - if (!V4L2_TYPE_IS_OUTPUT(b->type)) |
|---|
| 101 | + if (V4L2_TYPE_IS_CAPTURE(b->type)) |
|---|
| 92 | 102 | return 0; |
|---|
| 93 | 103 | |
|---|
| 94 | 104 | if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { |
|---|
| .. | .. |
|---|
| 118 | 128 | return 0; |
|---|
| 119 | 129 | } |
|---|
| 120 | 130 | |
|---|
| 131 | +/* |
|---|
| 132 | + * __init_vb2_v4l2_buffer() - initialize the vb2_v4l2_buffer struct |
|---|
| 133 | + */ |
|---|
| 134 | +static void __init_vb2_v4l2_buffer(struct vb2_buffer *vb) |
|---|
| 135 | +{ |
|---|
| 136 | + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
|---|
| 137 | + |
|---|
| 138 | + vbuf->request_fd = -1; |
|---|
| 139 | +} |
|---|
| 140 | + |
|---|
| 121 | 141 | static void __copy_timestamp(struct vb2_buffer *vb, const void *pb) |
|---|
| 122 | 142 | { |
|---|
| 123 | 143 | const struct v4l2_buffer *b = pb; |
|---|
| .. | .. |
|---|
| 130 | 150 | * and the timecode field and flag if needed. |
|---|
| 131 | 151 | */ |
|---|
| 132 | 152 | if (q->copy_timestamp) |
|---|
| 133 | | - vb->timestamp = timeval_to_ns(&b->timestamp); |
|---|
| 153 | + vb->timestamp = v4l2_buffer_get_timestamp(b); |
|---|
| 134 | 154 | vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE; |
|---|
| 135 | 155 | if (b->flags & V4L2_BUF_FLAG_TIMECODE) |
|---|
| 136 | 156 | vbuf->timecode = b->timecode; |
|---|
| .. | .. |
|---|
| 151 | 171 | pr_warn("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n"); |
|---|
| 152 | 172 | else |
|---|
| 153 | 173 | pr_warn("use the actual size instead.\n"); |
|---|
| 174 | +} |
|---|
| 175 | + |
|---|
| 176 | +static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) |
|---|
| 177 | +{ |
|---|
| 178 | + struct vb2_queue *q = vb->vb2_queue; |
|---|
| 179 | + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
|---|
| 180 | + struct vb2_plane *planes = vbuf->planes; |
|---|
| 181 | + unsigned int plane; |
|---|
| 182 | + int ret; |
|---|
| 183 | + |
|---|
| 184 | + ret = __verify_length(vb, b); |
|---|
| 185 | + if (ret < 0) { |
|---|
| 186 | + dprintk(q, 1, "plane parameters verification failed: %d\n", ret); |
|---|
| 187 | + return ret; |
|---|
| 188 | + } |
|---|
| 189 | + if (b->field == V4L2_FIELD_ALTERNATE && q->is_output) { |
|---|
| 190 | + /* |
|---|
| 191 | + * If the format's field is ALTERNATE, then the buffer's field |
|---|
| 192 | + * should be either TOP or BOTTOM, not ALTERNATE since that |
|---|
| 193 | + * makes no sense. The driver has to know whether the |
|---|
| 194 | + * buffer represents a top or a bottom field in order to |
|---|
| 195 | + * program any DMA correctly. Using ALTERNATE is wrong, since |
|---|
| 196 | + * that just says that it is either a top or a bottom field, |
|---|
| 197 | + * but not which of the two it is. |
|---|
| 198 | + */ |
|---|
| 199 | + dprintk(q, 1, "the field is incorrectly set to ALTERNATE for an output buffer\n"); |
|---|
| 200 | + return -EINVAL; |
|---|
| 201 | + } |
|---|
| 202 | + vbuf->sequence = 0; |
|---|
| 203 | + vbuf->request_fd = -1; |
|---|
| 204 | + vbuf->is_held = false; |
|---|
| 205 | + |
|---|
| 206 | + if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { |
|---|
| 207 | + switch (b->memory) { |
|---|
| 208 | + case VB2_MEMORY_USERPTR: |
|---|
| 209 | + for (plane = 0; plane < vb->num_planes; ++plane) { |
|---|
| 210 | + planes[plane].m.userptr = |
|---|
| 211 | + b->m.planes[plane].m.userptr; |
|---|
| 212 | + planes[plane].length = |
|---|
| 213 | + b->m.planes[plane].length; |
|---|
| 214 | + } |
|---|
| 215 | + break; |
|---|
| 216 | + case VB2_MEMORY_DMABUF: |
|---|
| 217 | + for (plane = 0; plane < vb->num_planes; ++plane) { |
|---|
| 218 | + planes[plane].m.fd = |
|---|
| 219 | + b->m.planes[plane].m.fd; |
|---|
| 220 | + planes[plane].length = |
|---|
| 221 | + b->m.planes[plane].length; |
|---|
| 222 | + } |
|---|
| 223 | + break; |
|---|
| 224 | + default: |
|---|
| 225 | + for (plane = 0; plane < vb->num_planes; ++plane) { |
|---|
| 226 | + planes[plane].m.offset = |
|---|
| 227 | + vb->planes[plane].m.offset; |
|---|
| 228 | + planes[plane].length = |
|---|
| 229 | + vb->planes[plane].length; |
|---|
| 230 | + } |
|---|
| 231 | + break; |
|---|
| 232 | + } |
|---|
| 233 | + |
|---|
| 234 | + /* Fill in driver-provided information for OUTPUT types */ |
|---|
| 235 | + if (V4L2_TYPE_IS_OUTPUT(b->type)) { |
|---|
| 236 | + /* |
|---|
| 237 | + * Will have to go up to b->length when API starts |
|---|
| 238 | + * accepting variable number of planes. |
|---|
| 239 | + * |
|---|
| 240 | + * If bytesused == 0 for the output buffer, then fall |
|---|
| 241 | + * back to the full buffer size. In that case |
|---|
| 242 | + * userspace clearly never bothered to set it and |
|---|
| 243 | + * it's a safe assumption that they really meant to |
|---|
| 244 | + * use the full plane sizes. |
|---|
| 245 | + * |
|---|
| 246 | + * Some drivers, e.g. old codec drivers, use bytesused == 0 |
|---|
| 247 | + * as a way to indicate that streaming is finished. |
|---|
| 248 | + * In that case, the driver should use the |
|---|
| 249 | + * allow_zero_bytesused flag to keep old userspace |
|---|
| 250 | + * applications working. |
|---|
| 251 | + */ |
|---|
| 252 | + for (plane = 0; plane < vb->num_planes; ++plane) { |
|---|
| 253 | + struct vb2_plane *pdst = &planes[plane]; |
|---|
| 254 | + struct v4l2_plane *psrc = &b->m.planes[plane]; |
|---|
| 255 | + |
|---|
| 256 | + if (psrc->bytesused == 0) |
|---|
| 257 | + vb2_warn_zero_bytesused(vb); |
|---|
| 258 | + |
|---|
| 259 | + if (vb->vb2_queue->allow_zero_bytesused) |
|---|
| 260 | + pdst->bytesused = psrc->bytesused; |
|---|
| 261 | + else |
|---|
| 262 | + pdst->bytesused = psrc->bytesused ? |
|---|
| 263 | + psrc->bytesused : pdst->length; |
|---|
| 264 | + pdst->data_offset = psrc->data_offset; |
|---|
| 265 | + } |
|---|
| 266 | + } |
|---|
| 267 | + } else { |
|---|
| 268 | + /* |
|---|
| 269 | + * Single-planar buffers do not use planes array, |
|---|
| 270 | + * so fill in relevant v4l2_buffer struct fields instead. |
|---|
| 271 | + * In videobuf we use our internal V4l2_planes struct for |
|---|
| 272 | + * single-planar buffers as well, for simplicity. |
|---|
| 273 | + * |
|---|
| 274 | + * If bytesused == 0 for the output buffer, then fall back |
|---|
| 275 | + * to the full buffer size as that's a sensible default. |
|---|
| 276 | + * |
|---|
| 277 | + * Some drivers, e.g. old codec drivers, use bytesused == 0 as |
|---|
| 278 | + * a way to indicate that streaming is finished. In that case, |
|---|
| 279 | + * the driver should use the allow_zero_bytesused flag to keep |
|---|
| 280 | + * old userspace applications working. |
|---|
| 281 | + */ |
|---|
| 282 | + switch (b->memory) { |
|---|
| 283 | + case VB2_MEMORY_USERPTR: |
|---|
| 284 | + planes[0].m.userptr = b->m.userptr; |
|---|
| 285 | + planes[0].length = b->length; |
|---|
| 286 | + break; |
|---|
| 287 | + case VB2_MEMORY_DMABUF: |
|---|
| 288 | + planes[0].m.fd = b->m.fd; |
|---|
| 289 | + planes[0].length = b->length; |
|---|
| 290 | + break; |
|---|
| 291 | + default: |
|---|
| 292 | + planes[0].m.offset = vb->planes[0].m.offset; |
|---|
| 293 | + planes[0].length = vb->planes[0].length; |
|---|
| 294 | + break; |
|---|
| 295 | + } |
|---|
| 296 | + |
|---|
| 297 | + planes[0].data_offset = 0; |
|---|
| 298 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_COMPAT_32BIT_TIME) && \ |
|---|
| 299 | + IS_ENABLED(CONFIG_USB_F_UVC) |
|---|
| 300 | + if (b->memory == VB2_MEMORY_DMABUF) |
|---|
| 301 | + planes[0].data_offset = b->reserved2; |
|---|
| 302 | +#endif |
|---|
| 303 | + |
|---|
| 304 | + if (V4L2_TYPE_IS_OUTPUT(b->type)) { |
|---|
| 305 | + if (b->bytesused == 0) |
|---|
| 306 | + vb2_warn_zero_bytesused(vb); |
|---|
| 307 | + |
|---|
| 308 | + if (vb->vb2_queue->allow_zero_bytesused) |
|---|
| 309 | + planes[0].bytesused = b->bytesused; |
|---|
| 310 | + else |
|---|
| 311 | + planes[0].bytesused = b->bytesused ? |
|---|
| 312 | + b->bytesused : planes[0].length; |
|---|
| 313 | + } else |
|---|
| 314 | + planes[0].bytesused = 0; |
|---|
| 315 | + |
|---|
| 316 | + } |
|---|
| 317 | + |
|---|
| 318 | + /* Zero flags that we handle */ |
|---|
| 319 | + vbuf->flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS; |
|---|
| 320 | + if (!vb->vb2_queue->copy_timestamp || V4L2_TYPE_IS_CAPTURE(b->type)) { |
|---|
| 321 | + /* |
|---|
| 322 | + * Non-COPY timestamps and non-OUTPUT queues will get |
|---|
| 323 | + * their timestamp and timestamp source flags from the |
|---|
| 324 | + * queue. |
|---|
| 325 | + */ |
|---|
| 326 | + vbuf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; |
|---|
| 327 | + } |
|---|
| 328 | + |
|---|
| 329 | + if (V4L2_TYPE_IS_OUTPUT(b->type)) { |
|---|
| 330 | + /* |
|---|
| 331 | + * For output buffers mask out the timecode flag: |
|---|
| 332 | + * this will be handled later in vb2_qbuf(). |
|---|
| 333 | + * The 'field' is valid metadata for this output buffer |
|---|
| 334 | + * and so that needs to be copied here. |
|---|
| 335 | + */ |
|---|
| 336 | + vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE; |
|---|
| 337 | + vbuf->field = b->field; |
|---|
| 338 | + if (!(q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF)) |
|---|
| 339 | + vbuf->flags &= ~V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; |
|---|
| 340 | + } else { |
|---|
| 341 | + /* Zero any output buffer flags as this is a capture buffer */ |
|---|
| 342 | + vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS; |
|---|
| 343 | + /* Zero last flag, this is a signal from driver to userspace */ |
|---|
| 344 | + vbuf->flags &= ~V4L2_BUF_FLAG_LAST; |
|---|
| 345 | + } |
|---|
| 346 | + |
|---|
| 347 | + return 0; |
|---|
| 154 | 348 | } |
|---|
| 155 | 349 | |
|---|
| 156 | 350 | static void set_buffer_cache_hints(struct vb2_queue *q, |
|---|
| .. | .. |
|---|
| 200 | 394 | vb->need_cache_sync_on_prepare = 0; |
|---|
| 201 | 395 | } |
|---|
| 202 | 396 | |
|---|
| 203 | | -static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b, |
|---|
| 204 | | - const char *opname) |
|---|
| 397 | +static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *mdev, |
|---|
| 398 | + struct v4l2_buffer *b, bool is_prepare, |
|---|
| 399 | + struct media_request **p_req) |
|---|
| 205 | 400 | { |
|---|
| 401 | + const char *opname = is_prepare ? "prepare_buf" : "qbuf"; |
|---|
| 402 | + struct media_request *req; |
|---|
| 403 | + struct vb2_v4l2_buffer *vbuf; |
|---|
| 404 | + struct vb2_buffer *vb; |
|---|
| 405 | + int ret; |
|---|
| 406 | + |
|---|
| 206 | 407 | if (b->type != q->type) { |
|---|
| 207 | | - dprintk(1, "%s: invalid buffer type\n", opname); |
|---|
| 408 | + dprintk(q, 1, "%s: invalid buffer type\n", opname); |
|---|
| 208 | 409 | return -EINVAL; |
|---|
| 209 | 410 | } |
|---|
| 210 | 411 | |
|---|
| 211 | 412 | if (b->index >= q->num_buffers) { |
|---|
| 212 | | - dprintk(1, "%s: buffer index out of range\n", opname); |
|---|
| 413 | + dprintk(q, 1, "%s: buffer index out of range\n", opname); |
|---|
| 213 | 414 | return -EINVAL; |
|---|
| 214 | 415 | } |
|---|
| 215 | 416 | |
|---|
| 216 | 417 | if (q->bufs[b->index] == NULL) { |
|---|
| 217 | 418 | /* Should never happen */ |
|---|
| 218 | | - dprintk(1, "%s: buffer is NULL\n", opname); |
|---|
| 419 | + dprintk(q, 1, "%s: buffer is NULL\n", opname); |
|---|
| 219 | 420 | return -EINVAL; |
|---|
| 220 | 421 | } |
|---|
| 221 | 422 | |
|---|
| 222 | 423 | if (b->memory != q->memory) { |
|---|
| 223 | | - dprintk(1, "%s: invalid memory type\n", opname); |
|---|
| 424 | + dprintk(q, 1, "%s: invalid memory type\n", opname); |
|---|
| 224 | 425 | return -EINVAL; |
|---|
| 225 | 426 | } |
|---|
| 226 | 427 | |
|---|
| 227 | | - set_buffer_cache_hints(q, q->bufs[b->index], b); |
|---|
| 428 | + vb = q->bufs[b->index]; |
|---|
| 429 | + vbuf = to_vb2_v4l2_buffer(vb); |
|---|
| 430 | + ret = __verify_planes_array(vb, b); |
|---|
| 431 | + if (ret) |
|---|
| 432 | + return ret; |
|---|
| 228 | 433 | |
|---|
| 229 | | - return __verify_planes_array(q->bufs[b->index], b); |
|---|
| 434 | + if (!is_prepare && (b->flags & V4L2_BUF_FLAG_REQUEST_FD) && |
|---|
| 435 | + vb->state != VB2_BUF_STATE_DEQUEUED) { |
|---|
| 436 | + dprintk(q, 1, "%s: buffer is not in dequeued state\n", opname); |
|---|
| 437 | + return -EINVAL; |
|---|
| 438 | + } |
|---|
| 439 | + |
|---|
| 440 | + if (!vb->prepared) { |
|---|
| 441 | + set_buffer_cache_hints(q, vb, b); |
|---|
| 442 | + /* Copy relevant information provided by the userspace */ |
|---|
| 443 | + memset(vbuf->planes, 0, |
|---|
| 444 | + sizeof(vbuf->planes[0]) * vb->num_planes); |
|---|
| 445 | + ret = vb2_fill_vb2_v4l2_buffer(vb, b); |
|---|
| 446 | + if (ret) |
|---|
| 447 | + return ret; |
|---|
| 448 | + } |
|---|
| 449 | + |
|---|
| 450 | + if (is_prepare) |
|---|
| 451 | + return 0; |
|---|
| 452 | + |
|---|
| 453 | + if (!(b->flags & V4L2_BUF_FLAG_REQUEST_FD)) { |
|---|
| 454 | + if (q->requires_requests) { |
|---|
| 455 | + dprintk(q, 1, "%s: queue requires requests\n", opname); |
|---|
| 456 | + return -EBADR; |
|---|
| 457 | + } |
|---|
| 458 | + if (q->uses_requests) { |
|---|
| 459 | + dprintk(q, 1, "%s: queue uses requests\n", opname); |
|---|
| 460 | + return -EBUSY; |
|---|
| 461 | + } |
|---|
| 462 | + return 0; |
|---|
| 463 | + } else if (!q->supports_requests) { |
|---|
| 464 | + dprintk(q, 1, "%s: queue does not support requests\n", opname); |
|---|
| 465 | + return -EBADR; |
|---|
| 466 | + } else if (q->uses_qbuf) { |
|---|
| 467 | + dprintk(q, 1, "%s: queue does not use requests\n", opname); |
|---|
| 468 | + return -EBUSY; |
|---|
| 469 | + } |
|---|
| 470 | + |
|---|
| 471 | + /* |
|---|
| 472 | + * For proper locking when queueing a request you need to be able |
|---|
| 473 | + * to lock access to the vb2 queue, so check that there is a lock |
|---|
| 474 | + * that we can use. In addition p_req must be non-NULL. |
|---|
| 475 | + */ |
|---|
| 476 | + if (WARN_ON(!q->lock || !p_req)) |
|---|
| 477 | + return -EINVAL; |
|---|
| 478 | + |
|---|
| 479 | + /* |
|---|
| 480 | + * Make sure this op is implemented by the driver. It's easy to forget |
|---|
| 481 | + * this callback, but is it important when canceling a buffer in a |
|---|
| 482 | + * queued request. |
|---|
| 483 | + */ |
|---|
| 484 | + if (WARN_ON(!q->ops->buf_request_complete)) |
|---|
| 485 | + return -EINVAL; |
|---|
| 486 | + /* |
|---|
| 487 | + * Make sure this op is implemented by the driver for the output queue. |
|---|
| 488 | + * It's easy to forget this callback, but is it important to correctly |
|---|
| 489 | + * validate the 'field' value at QBUF time. |
|---|
| 490 | + */ |
|---|
| 491 | + if (WARN_ON((q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || |
|---|
| 492 | + q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && |
|---|
| 493 | + !q->ops->buf_out_validate)) |
|---|
| 494 | + return -EINVAL; |
|---|
| 495 | + |
|---|
| 496 | + if (b->request_fd < 0) { |
|---|
| 497 | + dprintk(q, 1, "%s: request_fd < 0\n", opname); |
|---|
| 498 | + return -EINVAL; |
|---|
| 499 | + } |
|---|
| 500 | + |
|---|
| 501 | + req = media_request_get_by_fd(mdev, b->request_fd); |
|---|
| 502 | + if (IS_ERR(req)) { |
|---|
| 503 | + dprintk(q, 1, "%s: invalid request_fd\n", opname); |
|---|
| 504 | + return PTR_ERR(req); |
|---|
| 505 | + } |
|---|
| 506 | + |
|---|
| 507 | + /* |
|---|
| 508 | + * Early sanity check. This is checked again when the buffer |
|---|
| 509 | + * is bound to the request in vb2_core_qbuf(). |
|---|
| 510 | + */ |
|---|
| 511 | + if (req->state != MEDIA_REQUEST_STATE_IDLE && |
|---|
| 512 | + req->state != MEDIA_REQUEST_STATE_UPDATING) { |
|---|
| 513 | + dprintk(q, 1, "%s: request is not idle\n", opname); |
|---|
| 514 | + media_request_put(req); |
|---|
| 515 | + return -EBUSY; |
|---|
| 516 | + } |
|---|
| 517 | + |
|---|
| 518 | + *p_req = req; |
|---|
| 519 | + vbuf->request_fd = b->request_fd; |
|---|
| 520 | + |
|---|
| 521 | + return 0; |
|---|
| 230 | 522 | } |
|---|
| 231 | 523 | |
|---|
| 232 | 524 | /* |
|---|
| .. | .. |
|---|
| 248 | 540 | |
|---|
| 249 | 541 | b->flags = vbuf->flags; |
|---|
| 250 | 542 | b->field = vbuf->field; |
|---|
| 251 | | - b->timestamp = ns_to_timeval(vb->timestamp); |
|---|
| 543 | + v4l2_buffer_set_timestamp(b, vb->timestamp); |
|---|
| 252 | 544 | b->timecode = vbuf->timecode; |
|---|
| 253 | 545 | b->sequence = vbuf->sequence; |
|---|
| 254 | 546 | b->reserved2 = 0; |
|---|
| 255 | | - b->reserved = 0; |
|---|
| 547 | + b->request_fd = 0; |
|---|
| 256 | 548 | |
|---|
| 257 | 549 | if (q->is_multiplanar) { |
|---|
| 258 | 550 | /* |
|---|
| .. | .. |
|---|
| 309 | 601 | case VB2_BUF_STATE_ACTIVE: |
|---|
| 310 | 602 | b->flags |= V4L2_BUF_FLAG_QUEUED; |
|---|
| 311 | 603 | break; |
|---|
| 604 | + case VB2_BUF_STATE_IN_REQUEST: |
|---|
| 605 | + b->flags |= V4L2_BUF_FLAG_IN_REQUEST; |
|---|
| 606 | + break; |
|---|
| 312 | 607 | case VB2_BUF_STATE_ERROR: |
|---|
| 313 | 608 | b->flags |= V4L2_BUF_FLAG_ERROR; |
|---|
| 314 | | - /* fall through */ |
|---|
| 609 | + fallthrough; |
|---|
| 315 | 610 | case VB2_BUF_STATE_DONE: |
|---|
| 316 | 611 | b->flags |= V4L2_BUF_FLAG_DONE; |
|---|
| 317 | 612 | break; |
|---|
| 318 | | - case VB2_BUF_STATE_PREPARED: |
|---|
| 319 | | - b->flags |= V4L2_BUF_FLAG_PREPARED; |
|---|
| 320 | | - break; |
|---|
| 321 | 613 | case VB2_BUF_STATE_PREPARING: |
|---|
| 322 | 614 | case VB2_BUF_STATE_DEQUEUED: |
|---|
| 323 | | - case VB2_BUF_STATE_REQUEUEING: |
|---|
| 324 | 615 | /* nothing */ |
|---|
| 325 | 616 | break; |
|---|
| 326 | 617 | } |
|---|
| 327 | 618 | |
|---|
| 619 | + if ((vb->state == VB2_BUF_STATE_DEQUEUED || |
|---|
| 620 | + vb->state == VB2_BUF_STATE_IN_REQUEST) && |
|---|
| 621 | + vb->synced && vb->prepared) |
|---|
| 622 | + b->flags |= V4L2_BUF_FLAG_PREPARED; |
|---|
| 623 | + |
|---|
| 328 | 624 | if (vb2_buffer_in_use(q, vb)) |
|---|
| 329 | 625 | b->flags |= V4L2_BUF_FLAG_MAPPED; |
|---|
| 330 | | - |
|---|
| 331 | | - if (!q->is_output && |
|---|
| 332 | | - b->flags & V4L2_BUF_FLAG_DONE && |
|---|
| 333 | | - b->flags & V4L2_BUF_FLAG_LAST) |
|---|
| 334 | | - q->last_buffer_dequeued = true; |
|---|
| 626 | + if (vbuf->request_fd >= 0) { |
|---|
| 627 | + b->flags |= V4L2_BUF_FLAG_REQUEST_FD; |
|---|
| 628 | + b->request_fd = vbuf->request_fd; |
|---|
| 629 | + } |
|---|
| 335 | 630 | } |
|---|
| 336 | 631 | |
|---|
| 337 | 632 | /* |
|---|
| .. | .. |
|---|
| 339 | 634 | * v4l2_buffer by the userspace. It also verifies that struct |
|---|
| 340 | 635 | * v4l2_buffer has a valid number of planes. |
|---|
| 341 | 636 | */ |
|---|
| 342 | | -static int __fill_vb2_buffer(struct vb2_buffer *vb, |
|---|
| 343 | | - const void *pb, struct vb2_plane *planes) |
|---|
| 637 | +static int __fill_vb2_buffer(struct vb2_buffer *vb, struct vb2_plane *planes) |
|---|
| 344 | 638 | { |
|---|
| 345 | | - struct vb2_queue *q = vb->vb2_queue; |
|---|
| 346 | | - const struct v4l2_buffer *b = pb; |
|---|
| 347 | 639 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
|---|
| 348 | 640 | unsigned int plane; |
|---|
| 349 | | - int ret; |
|---|
| 350 | 641 | |
|---|
| 351 | | - ret = __verify_length(vb, b); |
|---|
| 352 | | - if (ret < 0) { |
|---|
| 353 | | - dprintk(1, "plane parameters verification failed: %d\n", ret); |
|---|
| 354 | | - return ret; |
|---|
| 355 | | - } |
|---|
| 356 | | - if (b->field == V4L2_FIELD_ALTERNATE && q->is_output) { |
|---|
| 357 | | - /* |
|---|
| 358 | | - * If the format's field is ALTERNATE, then the buffer's field |
|---|
| 359 | | - * should be either TOP or BOTTOM, not ALTERNATE since that |
|---|
| 360 | | - * makes no sense. The driver has to know whether the |
|---|
| 361 | | - * buffer represents a top or a bottom field in order to |
|---|
| 362 | | - * program any DMA correctly. Using ALTERNATE is wrong, since |
|---|
| 363 | | - * that just says that it is either a top or a bottom field, |
|---|
| 364 | | - * but not which of the two it is. |
|---|
| 365 | | - */ |
|---|
| 366 | | - dprintk(1, "the field is incorrectly set to ALTERNATE for an output buffer\n"); |
|---|
| 367 | | - return -EINVAL; |
|---|
| 368 | | - } |
|---|
| 369 | | - vb->timestamp = 0; |
|---|
| 370 | | - vbuf->sequence = 0; |
|---|
| 642 | + if (!vb->vb2_queue->copy_timestamp) |
|---|
| 643 | + vb->timestamp = 0; |
|---|
| 371 | 644 | |
|---|
| 372 | | - if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { |
|---|
| 373 | | - if (b->memory == VB2_MEMORY_USERPTR) { |
|---|
| 374 | | - for (plane = 0; plane < vb->num_planes; ++plane) { |
|---|
| 375 | | - planes[plane].m.userptr = |
|---|
| 376 | | - b->m.planes[plane].m.userptr; |
|---|
| 377 | | - planes[plane].length = |
|---|
| 378 | | - b->m.planes[plane].length; |
|---|
| 379 | | - } |
|---|
| 645 | + for (plane = 0; plane < vb->num_planes; ++plane) { |
|---|
| 646 | + if (vb->vb2_queue->memory != VB2_MEMORY_MMAP) { |
|---|
| 647 | + planes[plane].m = vbuf->planes[plane].m; |
|---|
| 648 | + planes[plane].length = vbuf->planes[plane].length; |
|---|
| 380 | 649 | } |
|---|
| 381 | | - if (b->memory == VB2_MEMORY_DMABUF) { |
|---|
| 382 | | - for (plane = 0; plane < vb->num_planes; ++plane) { |
|---|
| 383 | | - planes[plane].m.fd = |
|---|
| 384 | | - b->m.planes[plane].m.fd; |
|---|
| 385 | | - planes[plane].length = |
|---|
| 386 | | - b->m.planes[plane].length; |
|---|
| 387 | | - } |
|---|
| 388 | | - } |
|---|
| 389 | | - |
|---|
| 390 | | - /* Fill in driver-provided information for OUTPUT types */ |
|---|
| 391 | | - if (V4L2_TYPE_IS_OUTPUT(b->type)) { |
|---|
| 392 | | - /* |
|---|
| 393 | | - * Will have to go up to b->length when API starts |
|---|
| 394 | | - * accepting variable number of planes. |
|---|
| 395 | | - * |
|---|
| 396 | | - * If bytesused == 0 for the output buffer, then fall |
|---|
| 397 | | - * back to the full buffer size. In that case |
|---|
| 398 | | - * userspace clearly never bothered to set it and |
|---|
| 399 | | - * it's a safe assumption that they really meant to |
|---|
| 400 | | - * use the full plane sizes. |
|---|
| 401 | | - * |
|---|
| 402 | | - * Some drivers, e.g. old codec drivers, use bytesused == 0 |
|---|
| 403 | | - * as a way to indicate that streaming is finished. |
|---|
| 404 | | - * In that case, the driver should use the |
|---|
| 405 | | - * allow_zero_bytesused flag to keep old userspace |
|---|
| 406 | | - * applications working. |
|---|
| 407 | | - */ |
|---|
| 408 | | - for (plane = 0; plane < vb->num_planes; ++plane) { |
|---|
| 409 | | - struct vb2_plane *pdst = &planes[plane]; |
|---|
| 410 | | - struct v4l2_plane *psrc = &b->m.planes[plane]; |
|---|
| 411 | | - |
|---|
| 412 | | - if (psrc->bytesused == 0) |
|---|
| 413 | | - vb2_warn_zero_bytesused(vb); |
|---|
| 414 | | - |
|---|
| 415 | | - if (vb->vb2_queue->allow_zero_bytesused) |
|---|
| 416 | | - pdst->bytesused = psrc->bytesused; |
|---|
| 417 | | - else |
|---|
| 418 | | - pdst->bytesused = psrc->bytesused ? |
|---|
| 419 | | - psrc->bytesused : pdst->length; |
|---|
| 420 | | - pdst->data_offset = psrc->data_offset; |
|---|
| 421 | | - } |
|---|
| 422 | | - } |
|---|
| 423 | | - } else { |
|---|
| 424 | | - /* |
|---|
| 425 | | - * Single-planar buffers do not use planes array, |
|---|
| 426 | | - * so fill in relevant v4l2_buffer struct fields instead. |
|---|
| 427 | | - * In videobuf we use our internal V4l2_planes struct for |
|---|
| 428 | | - * single-planar buffers as well, for simplicity. |
|---|
| 429 | | - * |
|---|
| 430 | | - * If bytesused == 0 for the output buffer, then fall back |
|---|
| 431 | | - * to the full buffer size as that's a sensible default. |
|---|
| 432 | | - * |
|---|
| 433 | | - * Some drivers, e.g. old codec drivers, use bytesused == 0 as |
|---|
| 434 | | - * a way to indicate that streaming is finished. In that case, |
|---|
| 435 | | - * the driver should use the allow_zero_bytesused flag to keep |
|---|
| 436 | | - * old userspace applications working. |
|---|
| 437 | | - */ |
|---|
| 438 | | - if (b->memory == VB2_MEMORY_USERPTR) { |
|---|
| 439 | | - planes[0].m.userptr = b->m.userptr; |
|---|
| 440 | | - planes[0].length = b->length; |
|---|
| 441 | | - } |
|---|
| 442 | | - |
|---|
| 443 | | - if (b->memory == VB2_MEMORY_DMABUF) { |
|---|
| 444 | | - planes[0].m.fd = b->m.fd; |
|---|
| 445 | | - planes[0].length = b->length; |
|---|
| 446 | | - } |
|---|
| 447 | | - |
|---|
| 448 | | - if (V4L2_TYPE_IS_OUTPUT(b->type)) { |
|---|
| 449 | | - if (b->bytesused == 0) |
|---|
| 450 | | - vb2_warn_zero_bytesused(vb); |
|---|
| 451 | | - |
|---|
| 452 | | - if (vb->vb2_queue->allow_zero_bytesused) |
|---|
| 453 | | - planes[0].bytesused = b->bytesused; |
|---|
| 454 | | - else |
|---|
| 455 | | - planes[0].bytesused = b->bytesused ? |
|---|
| 456 | | - b->bytesused : planes[0].length; |
|---|
| 457 | | - } else |
|---|
| 458 | | - planes[0].bytesused = 0; |
|---|
| 459 | | - |
|---|
| 650 | + planes[plane].bytesused = vbuf->planes[plane].bytesused; |
|---|
| 651 | + planes[plane].data_offset = vbuf->planes[plane].data_offset; |
|---|
| 460 | 652 | } |
|---|
| 461 | | - |
|---|
| 462 | | - /* Zero flags that the vb2 core handles */ |
|---|
| 463 | | - vbuf->flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS; |
|---|
| 464 | | - if (!vb->vb2_queue->copy_timestamp || !V4L2_TYPE_IS_OUTPUT(b->type)) { |
|---|
| 465 | | - /* |
|---|
| 466 | | - * Non-COPY timestamps and non-OUTPUT queues will get |
|---|
| 467 | | - * their timestamp and timestamp source flags from the |
|---|
| 468 | | - * queue. |
|---|
| 469 | | - */ |
|---|
| 470 | | - vbuf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; |
|---|
| 471 | | - } |
|---|
| 472 | | - |
|---|
| 473 | | - if (V4L2_TYPE_IS_OUTPUT(b->type)) { |
|---|
| 474 | | - /* |
|---|
| 475 | | - * For output buffers mask out the timecode flag: |
|---|
| 476 | | - * this will be handled later in vb2_qbuf(). |
|---|
| 477 | | - * The 'field' is valid metadata for this output buffer |
|---|
| 478 | | - * and so that needs to be copied here. |
|---|
| 479 | | - */ |
|---|
| 480 | | - vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE; |
|---|
| 481 | | - vbuf->field = b->field; |
|---|
| 482 | | - /* get image sequence from user space */ |
|---|
| 483 | | - vbuf->sequence = b->sequence; |
|---|
| 484 | | - } else { |
|---|
| 485 | | - /* Zero any output buffer flags as this is a capture buffer */ |
|---|
| 486 | | - vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS; |
|---|
| 487 | | - /* Zero last flag, this is a signal from driver to userspace */ |
|---|
| 488 | | - vbuf->flags &= ~V4L2_BUF_FLAG_LAST; |
|---|
| 489 | | - } |
|---|
| 490 | | - |
|---|
| 491 | 653 | return 0; |
|---|
| 492 | 654 | } |
|---|
| 493 | 655 | |
|---|
| 494 | 656 | static const struct vb2_buf_ops v4l2_buf_ops = { |
|---|
| 495 | 657 | .verify_planes_array = __verify_planes_array_core, |
|---|
| 658 | + .init_buffer = __init_vb2_v4l2_buffer, |
|---|
| 496 | 659 | .fill_user_buffer = __fill_v4l2_buffer, |
|---|
| 497 | 660 | .fill_vb2_buffer = __fill_vb2_buffer, |
|---|
| 498 | 661 | .copy_timestamp = __copy_timestamp, |
|---|
| 499 | 662 | }; |
|---|
| 663 | + |
|---|
| 664 | +int vb2_find_timestamp(const struct vb2_queue *q, u64 timestamp, |
|---|
| 665 | + unsigned int start_idx) |
|---|
| 666 | +{ |
|---|
| 667 | + unsigned int i; |
|---|
| 668 | + |
|---|
| 669 | + for (i = start_idx; i < q->num_buffers; i++) |
|---|
| 670 | + if (q->bufs[i]->copied_timestamp && |
|---|
| 671 | + q->bufs[i]->timestamp == timestamp) |
|---|
| 672 | + return i; |
|---|
| 673 | + return -1; |
|---|
| 674 | +} |
|---|
| 675 | +EXPORT_SYMBOL_GPL(vb2_find_timestamp); |
|---|
| 500 | 676 | |
|---|
| 501 | 677 | /* |
|---|
| 502 | 678 | * vb2_querybuf() - query video buffer information |
|---|
| .. | .. |
|---|
| 517 | 693 | int ret; |
|---|
| 518 | 694 | |
|---|
| 519 | 695 | if (b->type != q->type) { |
|---|
| 520 | | - dprintk(1, "wrong buffer type\n"); |
|---|
| 696 | + dprintk(q, 1, "wrong buffer type\n"); |
|---|
| 521 | 697 | return -EINVAL; |
|---|
| 522 | 698 | } |
|---|
| 523 | 699 | |
|---|
| 524 | 700 | if (b->index >= q->num_buffers) { |
|---|
| 525 | | - dprintk(1, "buffer index out of range\n"); |
|---|
| 701 | + dprintk(q, 1, "buffer index out of range\n"); |
|---|
| 526 | 702 | return -EINVAL; |
|---|
| 527 | 703 | } |
|---|
| 528 | 704 | vb = q->bufs[b->index]; |
|---|
| .. | .. |
|---|
| 533 | 709 | } |
|---|
| 534 | 710 | EXPORT_SYMBOL(vb2_querybuf); |
|---|
| 535 | 711 | |
|---|
| 712 | +static void fill_buf_caps(struct vb2_queue *q, u32 *caps) |
|---|
| 713 | +{ |
|---|
| 714 | + *caps = V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS; |
|---|
| 715 | + if (q->io_modes & VB2_MMAP) |
|---|
| 716 | + *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP; |
|---|
| 717 | + if (q->io_modes & VB2_USERPTR) |
|---|
| 718 | + *caps |= V4L2_BUF_CAP_SUPPORTS_USERPTR; |
|---|
| 719 | + if (q->io_modes & VB2_DMABUF) |
|---|
| 720 | + *caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF; |
|---|
| 721 | + if (q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF) |
|---|
| 722 | + *caps |= V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF; |
|---|
| 723 | + if (q->allow_cache_hints && q->io_modes & VB2_MMAP) |
|---|
| 724 | + *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS; |
|---|
| 725 | +#ifdef CONFIG_MEDIA_CONTROLLER_REQUEST_API |
|---|
| 726 | + if (q->supports_requests) |
|---|
| 727 | + *caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS; |
|---|
| 728 | +#endif |
|---|
| 729 | +} |
|---|
| 730 | + |
|---|
| 536 | 731 | int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) |
|---|
| 537 | 732 | { |
|---|
| 538 | 733 | int ret = vb2_verify_memory_type(q, req->memory, req->type); |
|---|
| 539 | 734 | |
|---|
| 735 | + fill_buf_caps(q, &req->capabilities); |
|---|
| 540 | 736 | return ret ? ret : vb2_core_reqbufs(q, req->memory, &req->count); |
|---|
| 541 | 737 | } |
|---|
| 542 | 738 | EXPORT_SYMBOL_GPL(vb2_reqbufs); |
|---|
| 543 | 739 | |
|---|
| 544 | | -int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) |
|---|
| 740 | +int vb2_prepare_buf(struct vb2_queue *q, struct media_device *mdev, |
|---|
| 741 | + struct v4l2_buffer *b) |
|---|
| 545 | 742 | { |
|---|
| 546 | 743 | int ret; |
|---|
| 547 | 744 | |
|---|
| 548 | 745 | if (vb2_fileio_is_active(q)) { |
|---|
| 549 | | - dprintk(1, "file io in progress\n"); |
|---|
| 746 | + dprintk(q, 1, "file io in progress\n"); |
|---|
| 550 | 747 | return -EBUSY; |
|---|
| 551 | 748 | } |
|---|
| 552 | 749 | |
|---|
| 553 | | - ret = vb2_queue_or_prepare_buf(q, b, "prepare_buf"); |
|---|
| 750 | + if (b->flags & V4L2_BUF_FLAG_REQUEST_FD) |
|---|
| 751 | + return -EINVAL; |
|---|
| 752 | + |
|---|
| 753 | + ret = vb2_queue_or_prepare_buf(q, mdev, b, true, NULL); |
|---|
| 554 | 754 | |
|---|
| 555 | 755 | return ret ? ret : vb2_core_prepare_buf(q, b->index, b); |
|---|
| 556 | 756 | } |
|---|
| .. | .. |
|---|
| 564 | 764 | int ret = vb2_verify_memory_type(q, create->memory, f->type); |
|---|
| 565 | 765 | unsigned i; |
|---|
| 566 | 766 | |
|---|
| 767 | + fill_buf_caps(q, &create->capabilities); |
|---|
| 567 | 768 | create->index = q->num_buffers; |
|---|
| 568 | 769 | if (create->count == 0) |
|---|
| 569 | 770 | return ret != -EBUSY ? ret : 0; |
|---|
| .. | .. |
|---|
| 607 | 808 | if (requested_sizes[i] == 0) |
|---|
| 608 | 809 | return -EINVAL; |
|---|
| 609 | 810 | return ret ? ret : vb2_core_create_bufs(q, create->memory, |
|---|
| 610 | | - &create->count, requested_planes, requested_sizes); |
|---|
| 811 | + &create->count, |
|---|
| 812 | + requested_planes, |
|---|
| 813 | + requested_sizes); |
|---|
| 611 | 814 | } |
|---|
| 612 | 815 | EXPORT_SYMBOL_GPL(vb2_create_bufs); |
|---|
| 613 | 816 | |
|---|
| 614 | | -int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) |
|---|
| 817 | +int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev, |
|---|
| 818 | + struct v4l2_buffer *b) |
|---|
| 615 | 819 | { |
|---|
| 820 | + struct media_request *req = NULL; |
|---|
| 616 | 821 | int ret; |
|---|
| 617 | 822 | |
|---|
| 618 | 823 | if (vb2_fileio_is_active(q)) { |
|---|
| 619 | | - dprintk(1, "file io in progress\n"); |
|---|
| 824 | + dprintk(q, 1, "file io in progress\n"); |
|---|
| 620 | 825 | return -EBUSY; |
|---|
| 621 | 826 | } |
|---|
| 622 | 827 | |
|---|
| 623 | | - ret = vb2_queue_or_prepare_buf(q, b, "qbuf"); |
|---|
| 624 | | - return ret ? ret : vb2_core_qbuf(q, b->index, b); |
|---|
| 828 | + ret = vb2_queue_or_prepare_buf(q, mdev, b, false, &req); |
|---|
| 829 | + if (ret) |
|---|
| 830 | + return ret; |
|---|
| 831 | + ret = vb2_core_qbuf(q, b->index, b, req); |
|---|
| 832 | + if (req) |
|---|
| 833 | + media_request_put(req); |
|---|
| 834 | + return ret; |
|---|
| 625 | 835 | } |
|---|
| 626 | 836 | EXPORT_SYMBOL_GPL(vb2_qbuf); |
|---|
| 627 | 837 | |
|---|
| .. | .. |
|---|
| 630 | 840 | int ret; |
|---|
| 631 | 841 | |
|---|
| 632 | 842 | if (vb2_fileio_is_active(q)) { |
|---|
| 633 | | - dprintk(1, "file io in progress\n"); |
|---|
| 843 | + dprintk(q, 1, "file io in progress\n"); |
|---|
| 634 | 844 | return -EBUSY; |
|---|
| 635 | 845 | } |
|---|
| 636 | 846 | |
|---|
| 637 | 847 | if (b->type != q->type) { |
|---|
| 638 | | - dprintk(1, "invalid buffer type\n"); |
|---|
| 848 | + dprintk(q, 1, "invalid buffer type\n"); |
|---|
| 639 | 849 | return -EINVAL; |
|---|
| 640 | 850 | } |
|---|
| 641 | 851 | |
|---|
| 642 | 852 | ret = vb2_core_dqbuf(q, NULL, b, nonblocking); |
|---|
| 853 | + |
|---|
| 854 | + if (!q->is_output && |
|---|
| 855 | + b->flags & V4L2_BUF_FLAG_DONE && |
|---|
| 856 | + b->flags & V4L2_BUF_FLAG_LAST) |
|---|
| 857 | + q->last_buffer_dequeued = true; |
|---|
| 643 | 858 | |
|---|
| 644 | 859 | /* |
|---|
| 645 | 860 | * After calling the VIDIOC_DQBUF V4L2_BUF_FLAG_DONE must be |
|---|
| .. | .. |
|---|
| 654 | 869 | int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type) |
|---|
| 655 | 870 | { |
|---|
| 656 | 871 | if (vb2_fileio_is_active(q)) { |
|---|
| 657 | | - dprintk(1, "file io in progress\n"); |
|---|
| 872 | + dprintk(q, 1, "file io in progress\n"); |
|---|
| 658 | 873 | return -EBUSY; |
|---|
| 659 | 874 | } |
|---|
| 660 | 875 | return vb2_core_streamon(q, type); |
|---|
| .. | .. |
|---|
| 664 | 879 | int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) |
|---|
| 665 | 880 | { |
|---|
| 666 | 881 | if (vb2_fileio_is_active(q)) { |
|---|
| 667 | | - dprintk(1, "file io in progress\n"); |
|---|
| 882 | + dprintk(q, 1, "file io in progress\n"); |
|---|
| 668 | 883 | return -EBUSY; |
|---|
| 669 | 884 | } |
|---|
| 670 | 885 | return vb2_core_streamoff(q, type); |
|---|
| .. | .. |
|---|
| 678 | 893 | } |
|---|
| 679 | 894 | EXPORT_SYMBOL_GPL(vb2_expbuf); |
|---|
| 680 | 895 | |
|---|
| 681 | | -int vb2_queue_init(struct vb2_queue *q) |
|---|
| 896 | +int vb2_queue_init_name(struct vb2_queue *q, const char *name) |
|---|
| 682 | 897 | { |
|---|
| 683 | 898 | /* |
|---|
| 684 | 899 | * Sanity check |
|---|
| .. | .. |
|---|
| 714 | 929 | */ |
|---|
| 715 | 930 | q->quirk_poll_must_check_waiting_for_buffers = true; |
|---|
| 716 | 931 | |
|---|
| 932 | + if (name) |
|---|
| 933 | + strscpy(q->name, name, sizeof(q->name)); |
|---|
| 934 | + else |
|---|
| 935 | + q->name[0] = '\0'; |
|---|
| 936 | + |
|---|
| 717 | 937 | return vb2_core_queue_init(q); |
|---|
| 938 | +} |
|---|
| 939 | +EXPORT_SYMBOL_GPL(vb2_queue_init_name); |
|---|
| 940 | + |
|---|
| 941 | +int vb2_queue_init(struct vb2_queue *q) |
|---|
| 942 | +{ |
|---|
| 943 | + return vb2_queue_init_name(q, NULL); |
|---|
| 718 | 944 | } |
|---|
| 719 | 945 | EXPORT_SYMBOL_GPL(vb2_queue_init); |
|---|
| 720 | 946 | |
|---|
| .. | .. |
|---|
| 727 | 953 | __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) |
|---|
| 728 | 954 | { |
|---|
| 729 | 955 | struct video_device *vfd = video_devdata(file); |
|---|
| 730 | | - __poll_t req_events = poll_requested_events(wait); |
|---|
| 731 | | - __poll_t res = 0; |
|---|
| 956 | + __poll_t res; |
|---|
| 957 | + |
|---|
| 958 | + res = vb2_core_poll(q, file, wait); |
|---|
| 732 | 959 | |
|---|
| 733 | 960 | if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { |
|---|
| 734 | 961 | struct v4l2_fh *fh = file->private_data; |
|---|
| 735 | 962 | |
|---|
| 963 | + poll_wait(file, &fh->wait, wait); |
|---|
| 736 | 964 | if (v4l2_event_pending(fh)) |
|---|
| 737 | | - res = EPOLLPRI; |
|---|
| 738 | | - else if (req_events & EPOLLPRI) |
|---|
| 739 | | - poll_wait(file, &fh->wait, wait); |
|---|
| 965 | + res |= EPOLLPRI; |
|---|
| 740 | 966 | } |
|---|
| 741 | 967 | |
|---|
| 742 | | - return res | vb2_core_poll(q, file, wait); |
|---|
| 968 | + return res; |
|---|
| 743 | 969 | } |
|---|
| 744 | 970 | EXPORT_SYMBOL_GPL(vb2_poll); |
|---|
| 745 | 971 | |
|---|
| .. | .. |
|---|
| 765 | 991 | struct video_device *vdev = video_devdata(file); |
|---|
| 766 | 992 | int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type); |
|---|
| 767 | 993 | |
|---|
| 994 | + fill_buf_caps(vdev->queue, &p->capabilities); |
|---|
| 768 | 995 | if (res) |
|---|
| 769 | 996 | return res; |
|---|
| 770 | 997 | if (vb2_queue_is_busy(vdev, file)) |
|---|
| .. | .. |
|---|
| 786 | 1013 | p->format.type); |
|---|
| 787 | 1014 | |
|---|
| 788 | 1015 | p->index = vdev->queue->num_buffers; |
|---|
| 1016 | + fill_buf_caps(vdev->queue, &p->capabilities); |
|---|
| 789 | 1017 | /* |
|---|
| 790 | 1018 | * If count == 0, then just check if memory and type are valid. |
|---|
| 791 | 1019 | * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0. |
|---|
| .. | .. |
|---|
| 811 | 1039 | |
|---|
| 812 | 1040 | if (vb2_queue_is_busy(vdev, file)) |
|---|
| 813 | 1041 | return -EBUSY; |
|---|
| 814 | | - return vb2_prepare_buf(vdev->queue, p); |
|---|
| 1042 | + return vb2_prepare_buf(vdev->queue, vdev->v4l2_dev->mdev, p); |
|---|
| 815 | 1043 | } |
|---|
| 816 | 1044 | EXPORT_SYMBOL_GPL(vb2_ioctl_prepare_buf); |
|---|
| 817 | 1045 | |
|---|
| .. | .. |
|---|
| 830 | 1058 | |
|---|
| 831 | 1059 | if (vb2_queue_is_busy(vdev, file)) |
|---|
| 832 | 1060 | return -EBUSY; |
|---|
| 833 | | - return vb2_qbuf(vdev->queue, p); |
|---|
| 1061 | + return vb2_qbuf(vdev->queue, vdev->v4l2_dev->mdev, p); |
|---|
| 834 | 1062 | } |
|---|
| 835 | 1063 | EXPORT_SYMBOL_GPL(vb2_ioctl_qbuf); |
|---|
| 836 | 1064 | |
|---|
| .. | .. |
|---|
| 998 | 1226 | EXPORT_SYMBOL_GPL(vb2_fop_get_unmapped_area); |
|---|
| 999 | 1227 | #endif |
|---|
| 1000 | 1228 | |
|---|
| 1229 | +void vb2_video_unregister_device(struct video_device *vdev) |
|---|
| 1230 | +{ |
|---|
| 1231 | + /* Check if vdev was ever registered at all */ |
|---|
| 1232 | + if (!vdev || !video_is_registered(vdev)) |
|---|
| 1233 | + return; |
|---|
| 1234 | + |
|---|
| 1235 | + /* |
|---|
| 1236 | + * Calling this function only makes sense if vdev->queue is set. |
|---|
| 1237 | + * If it is NULL, then just call video_unregister_device() instead. |
|---|
| 1238 | + */ |
|---|
| 1239 | + WARN_ON(!vdev->queue); |
|---|
| 1240 | + |
|---|
| 1241 | + /* |
|---|
| 1242 | + * Take a reference to the device since video_unregister_device() |
|---|
| 1243 | + * calls device_unregister(), but we don't want that to release |
|---|
| 1244 | + * the device since we want to clean up the queue first. |
|---|
| 1245 | + */ |
|---|
| 1246 | + get_device(&vdev->dev); |
|---|
| 1247 | + video_unregister_device(vdev); |
|---|
| 1248 | + if (vdev->queue && vdev->queue->owner) { |
|---|
| 1249 | + struct mutex *lock = vdev->queue->lock ? |
|---|
| 1250 | + vdev->queue->lock : vdev->lock; |
|---|
| 1251 | + |
|---|
| 1252 | + if (lock) |
|---|
| 1253 | + mutex_lock(lock); |
|---|
| 1254 | + vb2_queue_release(vdev->queue); |
|---|
| 1255 | + vdev->queue->owner = NULL; |
|---|
| 1256 | + if (lock) |
|---|
| 1257 | + mutex_unlock(lock); |
|---|
| 1258 | + } |
|---|
| 1259 | + /* |
|---|
| 1260 | + * Now we put the device, and in most cases this will release |
|---|
| 1261 | + * everything. |
|---|
| 1262 | + */ |
|---|
| 1263 | + put_device(&vdev->dev); |
|---|
| 1264 | +} |
|---|
| 1265 | +EXPORT_SYMBOL_GPL(vb2_video_unregister_device); |
|---|
| 1266 | + |
|---|
| 1001 | 1267 | /* vb2_ops helpers. Only use if vq->lock is non-NULL. */ |
|---|
| 1002 | 1268 | |
|---|
| 1003 | 1269 | void vb2_ops_wait_prepare(struct vb2_queue *vq) |
|---|
| .. | .. |
|---|
| 1012 | 1278 | } |
|---|
| 1013 | 1279 | EXPORT_SYMBOL_GPL(vb2_ops_wait_finish); |
|---|
| 1014 | 1280 | |
|---|
| 1281 | +/* |
|---|
| 1282 | + * Note that this function is called during validation time and |
|---|
| 1283 | + * thus the req_queue_mutex is held to ensure no request objects |
|---|
| 1284 | + * can be added or deleted while validating. So there is no need |
|---|
| 1285 | + * to protect the objects list. |
|---|
| 1286 | + */ |
|---|
| 1287 | +int vb2_request_validate(struct media_request *req) |
|---|
| 1288 | +{ |
|---|
| 1289 | + struct media_request_object *obj; |
|---|
| 1290 | + int ret = 0; |
|---|
| 1291 | + |
|---|
| 1292 | + if (!vb2_request_buffer_cnt(req)) |
|---|
| 1293 | + return -ENOENT; |
|---|
| 1294 | + |
|---|
| 1295 | + list_for_each_entry(obj, &req->objects, list) { |
|---|
| 1296 | + if (!obj->ops->prepare) |
|---|
| 1297 | + continue; |
|---|
| 1298 | + |
|---|
| 1299 | + ret = obj->ops->prepare(obj); |
|---|
| 1300 | + if (ret) |
|---|
| 1301 | + break; |
|---|
| 1302 | + } |
|---|
| 1303 | + |
|---|
| 1304 | + if (ret) { |
|---|
| 1305 | + list_for_each_entry_continue_reverse(obj, &req->objects, list) |
|---|
| 1306 | + if (obj->ops->unprepare) |
|---|
| 1307 | + obj->ops->unprepare(obj); |
|---|
| 1308 | + return ret; |
|---|
| 1309 | + } |
|---|
| 1310 | + return 0; |
|---|
| 1311 | +} |
|---|
| 1312 | +EXPORT_SYMBOL_GPL(vb2_request_validate); |
|---|
| 1313 | + |
|---|
| 1314 | +void vb2_request_queue(struct media_request *req) |
|---|
| 1315 | +{ |
|---|
| 1316 | + struct media_request_object *obj, *obj_safe; |
|---|
| 1317 | + |
|---|
| 1318 | + /* |
|---|
| 1319 | + * Queue all objects. Note that buffer objects are at the end of the |
|---|
| 1320 | + * objects list, after all other object types. Once buffer objects |
|---|
| 1321 | + * are queued, the driver might delete them immediately (if the driver |
|---|
| 1322 | + * processes the buffer at once), so we have to use |
|---|
| 1323 | + * list_for_each_entry_safe() to handle the case where the object we |
|---|
| 1324 | + * queue is deleted. |
|---|
| 1325 | + */ |
|---|
| 1326 | + list_for_each_entry_safe(obj, obj_safe, &req->objects, list) |
|---|
| 1327 | + if (obj->ops->queue) |
|---|
| 1328 | + obj->ops->queue(obj); |
|---|
| 1329 | +} |
|---|
| 1330 | +EXPORT_SYMBOL_GPL(vb2_request_queue); |
|---|
| 1331 | + |
|---|
| 1015 | 1332 | MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2"); |
|---|
| 1016 | 1333 | MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>, Marek Szyprowski"); |
|---|
| 1017 | 1334 | MODULE_LICENSE("GPL"); |
|---|