diff options
-rw-r--r-- | drivers/media/video/videobuf2-core.c | 294 | ||||
-rw-r--r-- | include/media/videobuf2-core.h | 35 |
2 files changed, 270 insertions, 59 deletions
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index f04f27d68cec..9005dc9991ab 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c | |||
@@ -38,7 +38,8 @@ module_param(debug, int, 0644); | |||
38 | (((q)->ops->op) ? ((q)->ops->op(args)) : 0) | 38 | (((q)->ops->op) ? ((q)->ops->op(args)) : 0) |
39 | 39 | ||
40 | #define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \ | 40 | #define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \ |
41 | V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR) | 41 | V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \ |
42 | V4L2_BUF_FLAG_PREPARED) | ||
42 | 43 | ||
43 | /** | 44 | /** |
44 | * __vb2_buf_mem_alloc() - allocate video memory for the given buffer | 45 | * __vb2_buf_mem_alloc() - allocate video memory for the given buffer |
@@ -109,13 +110,22 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb) | |||
109 | * __setup_offsets() - setup unique offsets ("cookies") for every plane in | 110 | * __setup_offsets() - setup unique offsets ("cookies") for every plane in |
110 | * every buffer on the queue | 111 | * every buffer on the queue |
111 | */ | 112 | */ |
112 | static void __setup_offsets(struct vb2_queue *q) | 113 | static void __setup_offsets(struct vb2_queue *q, unsigned int n) |
113 | { | 114 | { |
114 | unsigned int buffer, plane; | 115 | unsigned int buffer, plane; |
115 | struct vb2_buffer *vb; | 116 | struct vb2_buffer *vb; |
116 | unsigned long off = 0; | 117 | unsigned long off; |
117 | 118 | ||
118 | for (buffer = 0; buffer < q->num_buffers; ++buffer) { | 119 | if (q->num_buffers) { |
120 | struct v4l2_plane *p; | ||
121 | vb = q->bufs[q->num_buffers - 1]; | ||
122 | p = &vb->v4l2_planes[vb->num_planes - 1]; | ||
123 | off = PAGE_ALIGN(p->m.mem_offset + p->length); | ||
124 | } else { | ||
125 | off = 0; | ||
126 | } | ||
127 | |||
128 | for (buffer = q->num_buffers; buffer < q->num_buffers + n; ++buffer) { | ||
119 | vb = q->bufs[buffer]; | 129 | vb = q->bufs[buffer]; |
120 | if (!vb) | 130 | if (!vb) |
121 | continue; | 131 | continue; |
@@ -161,7 +171,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, | |||
161 | vb->state = VB2_BUF_STATE_DEQUEUED; | 171 | vb->state = VB2_BUF_STATE_DEQUEUED; |
162 | vb->vb2_queue = q; | 172 | vb->vb2_queue = q; |
163 | vb->num_planes = num_planes; | 173 | vb->num_planes = num_planes; |
164 | vb->v4l2_buf.index = buffer; | 174 | vb->v4l2_buf.index = q->num_buffers + buffer; |
165 | vb->v4l2_buf.type = q->type; | 175 | vb->v4l2_buf.type = q->type; |
166 | vb->v4l2_buf.memory = memory; | 176 | vb->v4l2_buf.memory = memory; |
167 | 177 | ||
@@ -189,15 +199,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, | |||
189 | } | 199 | } |
190 | } | 200 | } |
191 | 201 | ||
192 | q->bufs[buffer] = vb; | 202 | q->bufs[q->num_buffers + buffer] = vb; |
193 | } | 203 | } |
194 | 204 | ||
195 | q->num_buffers = buffer; | 205 | __setup_offsets(q, buffer); |
196 | |||
197 | __setup_offsets(q); | ||
198 | 206 | ||
199 | dprintk(1, "Allocated %d buffers, %d plane(s) each\n", | 207 | dprintk(1, "Allocated %d buffers, %d plane(s) each\n", |
200 | q->num_buffers, num_planes); | 208 | buffer, num_planes); |
201 | 209 | ||
202 | return buffer; | 210 | return buffer; |
203 | } | 211 | } |
@@ -205,12 +213,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, | |||
205 | /** | 213 | /** |
206 | * __vb2_free_mem() - release all video buffer memory for a given queue | 214 | * __vb2_free_mem() - release all video buffer memory for a given queue |
207 | */ | 215 | */ |
208 | static void __vb2_free_mem(struct vb2_queue *q) | 216 | static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers) |
209 | { | 217 | { |
210 | unsigned int buffer; | 218 | unsigned int buffer; |
211 | struct vb2_buffer *vb; | 219 | struct vb2_buffer *vb; |
212 | 220 | ||
213 | for (buffer = 0; buffer < q->num_buffers; ++buffer) { | 221 | for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; |
222 | ++buffer) { | ||
214 | vb = q->bufs[buffer]; | 223 | vb = q->bufs[buffer]; |
215 | if (!vb) | 224 | if (!vb) |
216 | continue; | 225 | continue; |
@@ -224,17 +233,18 @@ static void __vb2_free_mem(struct vb2_queue *q) | |||
224 | } | 233 | } |
225 | 234 | ||
226 | /** | 235 | /** |
227 | * __vb2_queue_free() - free the queue - video memory and related information | 236 | * __vb2_queue_free() - free buffers at the end of the queue - video memory and |
228 | * and return the queue to an uninitialized state. Might be called even if the | 237 | * related information, if no buffers are left return the queue to an |
229 | * queue has already been freed. | 238 | * uninitialized state. Might be called even if the queue has already been freed. |
230 | */ | 239 | */ |
231 | static void __vb2_queue_free(struct vb2_queue *q) | 240 | static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) |
232 | { | 241 | { |
233 | unsigned int buffer; | 242 | unsigned int buffer; |
234 | 243 | ||
235 | /* Call driver-provided cleanup function for each buffer, if provided */ | 244 | /* Call driver-provided cleanup function for each buffer, if provided */ |
236 | if (q->ops->buf_cleanup) { | 245 | if (q->ops->buf_cleanup) { |
237 | for (buffer = 0; buffer < q->num_buffers; ++buffer) { | 246 | for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; |
247 | ++buffer) { | ||
238 | if (NULL == q->bufs[buffer]) | 248 | if (NULL == q->bufs[buffer]) |
239 | continue; | 249 | continue; |
240 | q->ops->buf_cleanup(q->bufs[buffer]); | 250 | q->ops->buf_cleanup(q->bufs[buffer]); |
@@ -242,23 +252,25 @@ static void __vb2_queue_free(struct vb2_queue *q) | |||
242 | } | 252 | } |
243 | 253 | ||
244 | /* Release video buffer memory */ | 254 | /* Release video buffer memory */ |
245 | __vb2_free_mem(q); | 255 | __vb2_free_mem(q, buffers); |
246 | 256 | ||
247 | /* Free videobuf buffers */ | 257 | /* Free videobuf buffers */ |
248 | for (buffer = 0; buffer < q->num_buffers; ++buffer) { | 258 | for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; |
259 | ++buffer) { | ||
249 | kfree(q->bufs[buffer]); | 260 | kfree(q->bufs[buffer]); |
250 | q->bufs[buffer] = NULL; | 261 | q->bufs[buffer] = NULL; |
251 | } | 262 | } |
252 | 263 | ||
253 | q->num_buffers = 0; | 264 | q->num_buffers -= buffers; |
254 | q->memory = 0; | 265 | if (!q->num_buffers) |
266 | q->memory = 0; | ||
255 | } | 267 | } |
256 | 268 | ||
257 | /** | 269 | /** |
258 | * __verify_planes_array() - verify that the planes array passed in struct | 270 | * __verify_planes_array() - verify that the planes array passed in struct |
259 | * v4l2_buffer from userspace can be safely used | 271 | * v4l2_buffer from userspace can be safely used |
260 | */ | 272 | */ |
261 | static int __verify_planes_array(struct vb2_buffer *vb, struct v4l2_buffer *b) | 273 | static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b) |
262 | { | 274 | { |
263 | /* Is memory for copying plane information present? */ | 275 | /* Is memory for copying plane information present? */ |
264 | if (NULL == b->m.planes) { | 276 | if (NULL == b->m.planes) { |
@@ -318,7 +330,7 @@ static bool __buffers_in_use(struct vb2_queue *q) | |||
318 | static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) | 330 | static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) |
319 | { | 331 | { |
320 | struct vb2_queue *q = vb->vb2_queue; | 332 | struct vb2_queue *q = vb->vb2_queue; |
321 | int ret = 0; | 333 | int ret; |
322 | 334 | ||
323 | /* Copy back data such as timestamp, flags, input, etc. */ | 335 | /* Copy back data such as timestamp, flags, input, etc. */ |
324 | memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); | 336 | memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); |
@@ -365,8 +377,10 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) | |||
365 | case VB2_BUF_STATE_DONE: | 377 | case VB2_BUF_STATE_DONE: |
366 | b->flags |= V4L2_BUF_FLAG_DONE; | 378 | b->flags |= V4L2_BUF_FLAG_DONE; |
367 | break; | 379 | break; |
368 | case VB2_BUF_STATE_DEQUEUED: | ||
369 | case VB2_BUF_STATE_PREPARED: | 380 | case VB2_BUF_STATE_PREPARED: |
381 | b->flags |= V4L2_BUF_FLAG_PREPARED; | ||
382 | break; | ||
383 | case VB2_BUF_STATE_DEQUEUED: | ||
370 | /* nothing */ | 384 | /* nothing */ |
371 | break; | 385 | break; |
372 | } | 386 | } |
@@ -374,7 +388,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) | |||
374 | if (__buffer_in_use(q, vb)) | 388 | if (__buffer_in_use(q, vb)) |
375 | b->flags |= V4L2_BUF_FLAG_MAPPED; | 389 | b->flags |= V4L2_BUF_FLAG_MAPPED; |
376 | 390 | ||
377 | return ret; | 391 | return 0; |
378 | } | 392 | } |
379 | 393 | ||
380 | /** | 394 | /** |
@@ -460,7 +474,7 @@ static int __verify_mmap_ops(struct vb2_queue *q) | |||
460 | */ | 474 | */ |
461 | int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | 475 | int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) |
462 | { | 476 | { |
463 | unsigned int num_buffers, num_planes; | 477 | unsigned int num_buffers, allocated_buffers, num_planes = 0; |
464 | int ret = 0; | 478 | int ret = 0; |
465 | 479 | ||
466 | if (q->fileio) { | 480 | if (q->fileio) { |
@@ -508,7 +522,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
508 | return -EBUSY; | 522 | return -EBUSY; |
509 | } | 523 | } |
510 | 524 | ||
511 | __vb2_queue_free(q); | 525 | __vb2_queue_free(q, q->num_buffers); |
512 | 526 | ||
513 | /* | 527 | /* |
514 | * In case of REQBUFS(0) return immediately without calling | 528 | * In case of REQBUFS(0) return immediately without calling |
@@ -542,44 +556,168 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
542 | return -ENOMEM; | 556 | return -ENOMEM; |
543 | } | 557 | } |
544 | 558 | ||
559 | allocated_buffers = ret; | ||
560 | |||
545 | /* | 561 | /* |
546 | * Check if driver can handle the allocated number of buffers. | 562 | * Check if driver can handle the allocated number of buffers. |
547 | */ | 563 | */ |
548 | if (ret < num_buffers) { | 564 | if (allocated_buffers < num_buffers) { |
549 | unsigned int orig_num_buffers; | 565 | num_buffers = allocated_buffers; |
550 | 566 | ||
551 | orig_num_buffers = num_buffers = ret; | ||
552 | ret = call_qop(q, queue_setup, q, NULL, &num_buffers, | 567 | ret = call_qop(q, queue_setup, q, NULL, &num_buffers, |
553 | &num_planes, q->plane_sizes, q->alloc_ctx); | 568 | &num_planes, q->plane_sizes, q->alloc_ctx); |
554 | if (ret) | ||
555 | goto free_mem; | ||
556 | 569 | ||
557 | if (orig_num_buffers < num_buffers) { | 570 | if (!ret && allocated_buffers < num_buffers) |
558 | ret = -ENOMEM; | 571 | ret = -ENOMEM; |
559 | goto free_mem; | ||
560 | } | ||
561 | 572 | ||
562 | /* | 573 | /* |
563 | * Ok, driver accepted smaller number of buffers. | 574 | * Either the driver has accepted a smaller number of buffers, |
575 | * or .queue_setup() returned an error | ||
564 | */ | 576 | */ |
565 | ret = num_buffers; | 577 | } |
578 | |||
579 | q->num_buffers = allocated_buffers; | ||
580 | |||
581 | if (ret < 0) { | ||
582 | __vb2_queue_free(q, allocated_buffers); | ||
583 | return ret; | ||
566 | } | 584 | } |
567 | 585 | ||
568 | /* | 586 | /* |
569 | * Return the number of successfully allocated buffers | 587 | * Return the number of successfully allocated buffers |
570 | * to the userspace. | 588 | * to the userspace. |
571 | */ | 589 | */ |
572 | req->count = ret; | 590 | req->count = allocated_buffers; |
573 | 591 | ||
574 | return 0; | 592 | return 0; |
575 | |||
576 | free_mem: | ||
577 | __vb2_queue_free(q); | ||
578 | return ret; | ||
579 | } | 593 | } |
580 | EXPORT_SYMBOL_GPL(vb2_reqbufs); | 594 | EXPORT_SYMBOL_GPL(vb2_reqbufs); |
581 | 595 | ||
582 | /** | 596 | /** |
597 | * vb2_create_bufs() - Allocate buffers and any required auxiliary structs | ||
598 | * @q: videobuf2 queue | ||
599 | * @create: creation parameters, passed from userspace to vidioc_create_bufs | ||
600 | * handler in driver | ||
601 | * | ||
602 | * Should be called from vidioc_create_bufs ioctl handler of a driver. | ||
603 | * This function: | ||
604 | * 1) verifies parameter sanity | ||
605 | * 2) calls the .queue_setup() queue operation | ||
606 | * 3) performs any necessary memory allocations | ||
607 | * | ||
608 | * The return values from this function are intended to be directly returned | ||
609 | * from vidioc_create_bufs handler in driver. | ||
610 | */ | ||
611 | int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) | ||
612 | { | ||
613 | unsigned int num_planes = 0, num_buffers, allocated_buffers; | ||
614 | int ret = 0; | ||
615 | |||
616 | if (q->fileio) { | ||
617 | dprintk(1, "%s(): file io in progress\n", __func__); | ||
618 | return -EBUSY; | ||
619 | } | ||
620 | |||
621 | if (create->memory != V4L2_MEMORY_MMAP | ||
622 | && create->memory != V4L2_MEMORY_USERPTR) { | ||
623 | dprintk(1, "%s(): unsupported memory type\n", __func__); | ||
624 | return -EINVAL; | ||
625 | } | ||
626 | |||
627 | if (create->format.type != q->type) { | ||
628 | dprintk(1, "%s(): requested type is incorrect\n", __func__); | ||
629 | return -EINVAL; | ||
630 | } | ||
631 | |||
632 | /* | ||
633 | * Make sure all the required memory ops for given memory type | ||
634 | * are available. | ||
635 | */ | ||
636 | if (create->memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) { | ||
637 | dprintk(1, "%s(): MMAP for current setup unsupported\n", __func__); | ||
638 | return -EINVAL; | ||
639 | } | ||
640 | |||
641 | if (create->memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) { | ||
642 | dprintk(1, "%s(): USERPTR for current setup unsupported\n", __func__); | ||
643 | return -EINVAL; | ||
644 | } | ||
645 | |||
646 | if (q->num_buffers == VIDEO_MAX_FRAME) { | ||
647 | dprintk(1, "%s(): maximum number of buffers already allocated\n", | ||
648 | __func__); | ||
649 | return -ENOBUFS; | ||
650 | } | ||
651 | |||
652 | create->index = q->num_buffers; | ||
653 | |||
654 | if (!q->num_buffers) { | ||
655 | memset(q->plane_sizes, 0, sizeof(q->plane_sizes)); | ||
656 | memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); | ||
657 | q->memory = create->memory; | ||
658 | } | ||
659 | |||
660 | num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers); | ||
661 | |||
662 | /* | ||
663 | * Ask the driver, whether the requested number of buffers, planes per | ||
664 | * buffer and their sizes are acceptable | ||
665 | */ | ||
666 | ret = call_qop(q, queue_setup, q, &create->format, &num_buffers, | ||
667 | &num_planes, q->plane_sizes, q->alloc_ctx); | ||
668 | if (ret) | ||
669 | return ret; | ||
670 | |||
671 | /* Finally, allocate buffers and video memory */ | ||
672 | ret = __vb2_queue_alloc(q, create->memory, num_buffers, | ||
673 | num_planes); | ||
674 | if (ret < 0) { | ||
675 | dprintk(1, "Memory allocation failed with error: %d\n", ret); | ||
676 | return ret; | ||
677 | } | ||
678 | |||
679 | allocated_buffers = ret; | ||
680 | |||
681 | /* | ||
682 | * Check if driver can handle the so far allocated number of buffers. | ||
683 | */ | ||
684 | if (ret < num_buffers) { | ||
685 | num_buffers = ret; | ||
686 | |||
687 | /* | ||
688 | * q->num_buffers contains the total number of buffers, that the | ||
689 | * queue driver has set up | ||
690 | */ | ||
691 | ret = call_qop(q, queue_setup, q, &create->format, &num_buffers, | ||
692 | &num_planes, q->plane_sizes, q->alloc_ctx); | ||
693 | |||
694 | if (!ret && allocated_buffers < num_buffers) | ||
695 | ret = -ENOMEM; | ||
696 | |||
697 | /* | ||
698 | * Either the driver has accepted a smaller number of buffers, | ||
699 | * or .queue_setup() returned an error | ||
700 | */ | ||
701 | } | ||
702 | |||
703 | q->num_buffers += allocated_buffers; | ||
704 | |||
705 | if (ret < 0) { | ||
706 | __vb2_queue_free(q, allocated_buffers); | ||
707 | return ret; | ||
708 | } | ||
709 | |||
710 | /* | ||
711 | * Return the number of successfully allocated buffers | ||
712 | * to the userspace. | ||
713 | */ | ||
714 | create->count = allocated_buffers; | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | EXPORT_SYMBOL_GPL(vb2_create_bufs); | ||
719 | |||
720 | /** | ||
583 | * vb2_plane_vaddr() - Return a kernel virtual address of a given plane | 721 | * vb2_plane_vaddr() - Return a kernel virtual address of a given plane |
584 | * @vb: vb2_buffer to which the plane in question belongs to | 722 | * @vb: vb2_buffer to which the plane in question belongs to |
585 | * @plane_no: plane number for which the address is to be returned | 723 | * @plane_no: plane number for which the address is to be returned |
@@ -663,7 +801,7 @@ EXPORT_SYMBOL_GPL(vb2_buffer_done); | |||
663 | * __fill_vb2_buffer() - fill a vb2_buffer with information provided in | 801 | * __fill_vb2_buffer() - fill a vb2_buffer with information provided in |
664 | * a v4l2_buffer by the userspace | 802 | * a v4l2_buffer by the userspace |
665 | */ | 803 | */ |
666 | static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, | 804 | static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b, |
667 | struct v4l2_plane *v4l2_planes) | 805 | struct v4l2_plane *v4l2_planes) |
668 | { | 806 | { |
669 | unsigned int plane; | 807 | unsigned int plane; |
@@ -727,7 +865,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, | |||
727 | /** | 865 | /** |
728 | * __qbuf_userptr() - handle qbuf of a USERPTR buffer | 866 | * __qbuf_userptr() - handle qbuf of a USERPTR buffer |
729 | */ | 867 | */ |
730 | static int __qbuf_userptr(struct vb2_buffer *vb, struct v4l2_buffer *b) | 868 | static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) |
731 | { | 869 | { |
732 | struct v4l2_plane planes[VIDEO_MAX_PLANES]; | 870 | struct v4l2_plane planes[VIDEO_MAX_PLANES]; |
733 | struct vb2_queue *q = vb->vb2_queue; | 871 | struct vb2_queue *q = vb->vb2_queue; |
@@ -816,7 +954,7 @@ err: | |||
816 | /** | 954 | /** |
817 | * __qbuf_mmap() - handle qbuf of an MMAP buffer | 955 | * __qbuf_mmap() - handle qbuf of an MMAP buffer |
818 | */ | 956 | */ |
819 | static int __qbuf_mmap(struct vb2_buffer *vb, struct v4l2_buffer *b) | 957 | static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b) |
820 | { | 958 | { |
821 | return __fill_vb2_buffer(vb, b, vb->v4l2_planes); | 959 | return __fill_vb2_buffer(vb, b, vb->v4l2_planes); |
822 | } | 960 | } |
@@ -833,7 +971,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb) | |||
833 | q->ops->buf_queue(vb); | 971 | q->ops->buf_queue(vb); |
834 | } | 972 | } |
835 | 973 | ||
836 | static int __buf_prepare(struct vb2_buffer *vb, struct v4l2_buffer *b) | 974 | static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) |
837 | { | 975 | { |
838 | struct vb2_queue *q = vb->vb2_queue; | 976 | struct vb2_queue *q = vb->vb2_queue; |
839 | int ret; | 977 | int ret; |
@@ -861,6 +999,68 @@ static int __buf_prepare(struct vb2_buffer *vb, struct v4l2_buffer *b) | |||
861 | } | 999 | } |
862 | 1000 | ||
863 | /** | 1001 | /** |
1002 | * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel | ||
1003 | * @q: videobuf2 queue | ||
1004 | * @b: buffer structure passed from userspace to vidioc_prepare_buf | ||
1005 | * handler in driver | ||
1006 | * | ||
1007 | * Should be called from vidioc_prepare_buf ioctl handler of a driver. | ||
1008 | * This function: | ||
1009 | * 1) verifies the passed buffer, | ||
1010 | * 2) calls buf_prepare callback in the driver (if provided), in which | ||
1011 | * driver-specific buffer initialization can be performed, | ||
1012 | * | ||
1013 | * The return values from this function are intended to be directly returned | ||
1014 | * from vidioc_prepare_buf handler in driver. | ||
1015 | */ | ||
1016 | int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) | ||
1017 | { | ||
1018 | struct vb2_buffer *vb; | ||
1019 | int ret; | ||
1020 | |||
1021 | if (q->fileio) { | ||
1022 | dprintk(1, "%s(): file io in progress\n", __func__); | ||
1023 | return -EBUSY; | ||
1024 | } | ||
1025 | |||
1026 | if (b->type != q->type) { | ||
1027 | dprintk(1, "%s(): invalid buffer type\n", __func__); | ||
1028 | return -EINVAL; | ||
1029 | } | ||
1030 | |||
1031 | if (b->index >= q->num_buffers) { | ||
1032 | dprintk(1, "%s(): buffer index out of range\n", __func__); | ||
1033 | return -EINVAL; | ||
1034 | } | ||
1035 | |||
1036 | vb = q->bufs[b->index]; | ||
1037 | if (NULL == vb) { | ||
1038 | /* Should never happen */ | ||
1039 | dprintk(1, "%s(): buffer is NULL\n", __func__); | ||
1040 | return -EINVAL; | ||
1041 | } | ||
1042 | |||
1043 | if (b->memory != q->memory) { | ||
1044 | dprintk(1, "%s(): invalid memory type\n", __func__); | ||
1045 | return -EINVAL; | ||
1046 | } | ||
1047 | |||
1048 | if (vb->state != VB2_BUF_STATE_DEQUEUED) { | ||
1049 | dprintk(1, "%s(): invalid buffer state %d\n", __func__, vb->state); | ||
1050 | return -EINVAL; | ||
1051 | } | ||
1052 | |||
1053 | ret = __buf_prepare(vb, b); | ||
1054 | if (ret < 0) | ||
1055 | return ret; | ||
1056 | |||
1057 | __fill_v4l2_buffer(vb, b); | ||
1058 | |||
1059 | return 0; | ||
1060 | } | ||
1061 | EXPORT_SYMBOL_GPL(vb2_prepare_buf); | ||
1062 | |||
1063 | /** | ||
864 | * vb2_qbuf() - Queue a buffer from userspace | 1064 | * vb2_qbuf() - Queue a buffer from userspace |
865 | * @q: videobuf2 queue | 1065 | * @q: videobuf2 queue |
866 | * @b: buffer structure passed from userspace to vidioc_qbuf handler | 1066 | * @b: buffer structure passed from userspace to vidioc_qbuf handler |
@@ -1484,7 +1684,7 @@ void vb2_queue_release(struct vb2_queue *q) | |||
1484 | { | 1684 | { |
1485 | __vb2_cleanup_fileio(q); | 1685 | __vb2_cleanup_fileio(q); |
1486 | __vb2_queue_cancel(q); | 1686 | __vb2_queue_cancel(q); |
1487 | __vb2_queue_free(q); | 1687 | __vb2_queue_free(q, q->num_buffers); |
1488 | } | 1688 | } |
1489 | EXPORT_SYMBOL_GPL(vb2_queue_release); | 1689 | EXPORT_SYMBOL_GPL(vb2_queue_release); |
1490 | 1690 | ||
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 692e35c232a9..55c57d3d3e63 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h | |||
@@ -169,13 +169,21 @@ struct vb2_buffer { | |||
169 | /** | 169 | /** |
170 | * struct vb2_ops - driver-specific callbacks | 170 | * struct vb2_ops - driver-specific callbacks |
171 | * | 171 | * |
172 | * @queue_setup: called from a VIDIOC_REQBUFS handler, before | 172 | * @queue_setup: called from VIDIOC_REQBUFS and VIDIOC_CREATE_BUFS |
173 | * memory allocation; driver should return the required | 173 | * handlers before memory allocation, or, if |
174 | * number of buffers in num_buffers, the required number | 174 | * *num_planes != 0, after the allocation to verify a |
175 | * of planes per buffer in num_planes; the size of each | 175 | * smaller number of buffers. Driver should return |
176 | * plane should be set in the sizes[] array and optional | 176 | * the required number of buffers in *num_buffers, the |
177 | * per-plane allocator specific context in alloc_ctxs[] | 177 | * required number of planes per buffer in *num_planes; the |
178 | * array | 178 | * size of each plane should be set in the sizes[] array |
179 | * and optional per-plane allocator specific context in the | ||
180 | * alloc_ctxs[] array. When called from VIDIOC_REQBUFS, | ||
181 | * fmt == NULL, the driver has to use the currently | ||
182 | * configured format and *num_buffers is the total number | ||
183 | * of buffers, that are being allocated. When called from | ||
184 | * VIDIOC_CREATE_BUFS, fmt != NULL and it describes the | ||
185 | * target frame format. In this case *num_buffers are being | ||
186 | * allocated additionally to q->num_buffers. | ||
179 | * @wait_prepare: release any locks taken while calling vb2 functions; | 187 | * @wait_prepare: release any locks taken while calling vb2 functions; |
180 | * it is called before an ioctl needs to wait for a new | 188 | * it is called before an ioctl needs to wait for a new |
181 | * buffer to arrive; required to avoid a deadlock in | 189 | * buffer to arrive; required to avoid a deadlock in |
@@ -188,11 +196,11 @@ struct vb2_buffer { | |||
188 | * perform additional buffer-related initialization; | 196 | * perform additional buffer-related initialization; |
189 | * initialization failure (return != 0) will prevent | 197 | * initialization failure (return != 0) will prevent |
190 | * queue setup from completing successfully; optional | 198 | * queue setup from completing successfully; optional |
191 | * @buf_prepare: called every time the buffer is queued from userspace; | 199 | * @buf_prepare: called every time the buffer is queued from userspace |
192 | * drivers may perform any initialization required before | 200 | * and from the VIDIOC_PREPARE_BUF ioctl; drivers may |
193 | * each hardware operation in this callback; | 201 | * perform any initialization required before each hardware |
194 | * if an error is returned, the buffer will not be queued | 202 | * operation in this callback; if an error is returned, the |
195 | * in driver; optional | 203 | * buffer will not be queued in driver; optional |
196 | * @buf_finish: called before every dequeue of the buffer back to | 204 | * @buf_finish: called before every dequeue of the buffer back to |
197 | * userspace; drivers may perform any operations required | 205 | * userspace; drivers may perform any operations required |
198 | * before userspace accesses the buffer; optional | 206 | * before userspace accesses the buffer; optional |
@@ -300,6 +308,9 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q); | |||
300 | int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b); | 308 | int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b); |
301 | int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); | 309 | int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); |
302 | 310 | ||
311 | int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create); | ||
312 | int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b); | ||
313 | |||
303 | int vb2_queue_init(struct vb2_queue *q); | 314 | int vb2_queue_init(struct vb2_queue *q); |
304 | 315 | ||
305 | void vb2_queue_release(struct vb2_queue *q); | 316 | void vb2_queue_release(struct vb2_queue *q); |