aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/videobuf2-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/videobuf2-core.c')
-rw-r--r--drivers/media/video/videobuf2-core.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index 3015e6000946..c3606276607e 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -43,8 +43,7 @@ module_param(debug, int, 0644);
43/** 43/**
44 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer 44 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
45 */ 45 */
46static int __vb2_buf_mem_alloc(struct vb2_buffer *vb, 46static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
47 unsigned long *plane_sizes)
48{ 47{
49 struct vb2_queue *q = vb->vb2_queue; 48 struct vb2_queue *q = vb->vb2_queue;
50 void *mem_priv; 49 void *mem_priv;
@@ -53,13 +52,13 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb,
53 /* Allocate memory for all planes in this buffer */ 52 /* Allocate memory for all planes in this buffer */
54 for (plane = 0; plane < vb->num_planes; ++plane) { 53 for (plane = 0; plane < vb->num_planes; ++plane) {
55 mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane], 54 mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane],
56 plane_sizes[plane]); 55 q->plane_sizes[plane]);
57 if (IS_ERR_OR_NULL(mem_priv)) 56 if (IS_ERR_OR_NULL(mem_priv))
58 goto free; 57 goto free;
59 58
60 /* Associate allocator private data with this plane */ 59 /* Associate allocator private data with this plane */
61 vb->planes[plane].mem_priv = mem_priv; 60 vb->planes[plane].mem_priv = mem_priv;
62 vb->v4l2_planes[plane].length = plane_sizes[plane]; 61 vb->v4l2_planes[plane].length = q->plane_sizes[plane];
63 } 62 }
64 63
65 return 0; 64 return 0;
@@ -141,8 +140,7 @@ static void __setup_offsets(struct vb2_queue *q)
141 * Returns the number of buffers successfully allocated. 140 * Returns the number of buffers successfully allocated.
142 */ 141 */
143static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, 142static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
144 unsigned int num_buffers, unsigned int num_planes, 143 unsigned int num_buffers, unsigned int num_planes)
145 unsigned long plane_sizes[])
146{ 144{
147 unsigned int buffer; 145 unsigned int buffer;
148 struct vb2_buffer *vb; 146 struct vb2_buffer *vb;
@@ -169,7 +167,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
169 167
170 /* Allocate video buffer memory for the MMAP type */ 168 /* Allocate video buffer memory for the MMAP type */
171 if (memory == V4L2_MEMORY_MMAP) { 169 if (memory == V4L2_MEMORY_MMAP) {
172 ret = __vb2_buf_mem_alloc(vb, plane_sizes); 170 ret = __vb2_buf_mem_alloc(vb);
173 if (ret) { 171 if (ret) {
174 dprintk(1, "Failed allocating memory for " 172 dprintk(1, "Failed allocating memory for "
175 "buffer %d\n", buffer); 173 "buffer %d\n", buffer);
@@ -454,7 +452,6 @@ static bool __buffers_in_use(struct vb2_queue *q)
454int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) 452int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
455{ 453{
456 unsigned int num_buffers, num_planes; 454 unsigned int num_buffers, num_planes;
457 unsigned long plane_sizes[VIDEO_MAX_PLANES];
458 int ret = 0; 455 int ret = 0;
459 456
460 if (q->fileio) { 457 if (q->fileio) {
@@ -516,7 +513,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
516 * Make sure the requested values and current defaults are sane. 513 * Make sure the requested values and current defaults are sane.
517 */ 514 */
518 num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME); 515 num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
519 memset(plane_sizes, 0, sizeof(plane_sizes)); 516 memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
520 memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); 517 memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
521 q->memory = req->memory; 518 q->memory = req->memory;
522 519
@@ -525,13 +522,12 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
525 * Driver also sets the size and allocator context for each plane. 522 * Driver also sets the size and allocator context for each plane.
526 */ 523 */
527 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes, 524 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
528 plane_sizes, q->alloc_ctx); 525 q->plane_sizes, q->alloc_ctx);
529 if (ret) 526 if (ret)
530 return ret; 527 return ret;
531 528
532 /* Finally, allocate buffers and video memory */ 529 /* Finally, allocate buffers and video memory */
533 ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes, 530 ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes);
534 plane_sizes);
535 if (ret == 0) { 531 if (ret == 0) {
536 dprintk(1, "Memory allocation failed\n"); 532 dprintk(1, "Memory allocation failed\n");
537 return -ENOMEM; 533 return -ENOMEM;
@@ -545,7 +541,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
545 541
546 orig_num_buffers = num_buffers = ret; 542 orig_num_buffers = num_buffers = ret;
547 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes, 543 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
548 plane_sizes, q->alloc_ctx); 544 q->plane_sizes, q->alloc_ctx);
549 if (ret) 545 if (ret)
550 goto free_mem; 546 goto free_mem;
551 547
@@ -745,12 +741,20 @@ static int __qbuf_userptr(struct vb2_buffer *vb, struct v4l2_buffer *b)
745 dprintk(3, "qbuf: userspace address for plane %d changed, " 741 dprintk(3, "qbuf: userspace address for plane %d changed, "
746 "reacquiring memory\n", plane); 742 "reacquiring memory\n", plane);
747 743
744 /* Check if the provided plane buffer is large enough */
745 if (planes[plane].length < q->plane_sizes[plane]) {
746 ret = EINVAL;
747 goto err;
748 }
749
748 /* Release previously acquired memory if present */ 750 /* Release previously acquired memory if present */
749 if (vb->planes[plane].mem_priv) 751 if (vb->planes[plane].mem_priv)
750 call_memop(q, plane, put_userptr, 752 call_memop(q, plane, put_userptr,
751 vb->planes[plane].mem_priv); 753 vb->planes[plane].mem_priv);
752 754
753 vb->planes[plane].mem_priv = NULL; 755 vb->planes[plane].mem_priv = NULL;
756 vb->v4l2_planes[plane].m.userptr = 0;
757 vb->v4l2_planes[plane].length = 0;
754 758
755 /* Acquire each plane's memory */ 759 /* Acquire each plane's memory */
756 if (q->mem_ops->get_userptr) { 760 if (q->mem_ops->get_userptr) {
@@ -788,10 +792,13 @@ static int __qbuf_userptr(struct vb2_buffer *vb, struct v4l2_buffer *b)
788 return 0; 792 return 0;
789err: 793err:
790 /* In case of errors, release planes that were already acquired */ 794 /* In case of errors, release planes that were already acquired */
791 for (; plane > 0; --plane) { 795 for (plane = 0; plane < vb->num_planes; ++plane) {
792 call_memop(q, plane, put_userptr, 796 if (vb->planes[plane].mem_priv)
793 vb->planes[plane - 1].mem_priv); 797 call_memop(q, plane, put_userptr,
794 vb->planes[plane - 1].mem_priv = NULL; 798 vb->planes[plane].mem_priv);
799 vb->planes[plane].mem_priv = NULL;
800 vb->v4l2_planes[plane].m.userptr = 0;
801 vb->v4l2_planes[plane].length = 0;
795 } 802 }
796 803
797 return ret; 804 return ret;