.. | .. |
---|
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"); |
---|