aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-09-28 05:12:53 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-10-05 21:21:40 -0400
commit32a772603173f9e1bf675c01e4649e3fe3b794bc (patch)
tree090dec95f087913c5e74c52ee76a65d9e7b5efb0 /drivers/media/v4l2-core
parent626d533f8cb63b6c0cd6b83e1ce7e7656ccaba84 (diff)
[media] videobuf2-core: move plane verification out of __fill_v4l2/vb_buffer
The plane verification should be done before actually queuing or dequeuing buffers, so move it out of __fill_v4l2_buffer and __fill_vb_buffer and call it as a separate step. This also makes it possible to change the return type of __fill_v4l2/vb_buffer to void. The dqbuf case took some special care: before removing a buffer from the done_list you have to verify that the receiving v4l2_buffer has enough room for all the planes. The number of planes can differ between buffers due to the fact that buffers for other formats can be prepared using VIDIOC_PREPARE_BUF. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c78
1 files changed, 38 insertions, 40 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index e6a26b433e87..5a132b286894 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -276,6 +276,9 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
276 */ 276 */
277static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b) 277static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b)
278{ 278{
279 if (!V4L2_TYPE_IS_MULTIPLANAR(b->type))
280 return 0;
281
279 /* Is memory for copying plane information present? */ 282 /* Is memory for copying plane information present? */
280 if (NULL == b->m.planes) { 283 if (NULL == b->m.planes) {
281 dprintk(1, "Multi-planar buffer passed but " 284 dprintk(1, "Multi-planar buffer passed but "
@@ -331,10 +334,9 @@ static bool __buffers_in_use(struct vb2_queue *q)
331 * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be 334 * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
332 * returned to userspace 335 * returned to userspace
333 */ 336 */
334static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) 337static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
335{ 338{
336 struct vb2_queue *q = vb->vb2_queue; 339 struct vb2_queue *q = vb->vb2_queue;
337 int ret;
338 340
339 /* Copy back data such as timestamp, flags, etc. */ 341 /* Copy back data such as timestamp, flags, etc. */
340 memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); 342 memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
@@ -342,13 +344,9 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
342 b->reserved = vb->v4l2_buf.reserved; 344 b->reserved = vb->v4l2_buf.reserved;
343 345
344 if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) { 346 if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) {
345 ret = __verify_planes_array(vb, b);
346 if (ret)
347 return ret;
348
349 /* 347 /*
350 * Fill in plane-related data if userspace provided an array 348 * Fill in plane-related data if userspace provided an array
351 * for it. The memory and size is verified above. 349 * for it. The caller has already verified memory and size.
352 */ 350 */
353 memcpy(b->m.planes, vb->v4l2_planes, 351 memcpy(b->m.planes, vb->v4l2_planes,
354 b->length * sizeof(struct v4l2_plane)); 352 b->length * sizeof(struct v4l2_plane));
@@ -391,8 +389,6 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
391 389
392 if (__buffer_in_use(q, vb)) 390 if (__buffer_in_use(q, vb))
393 b->flags |= V4L2_BUF_FLAG_MAPPED; 391 b->flags |= V4L2_BUF_FLAG_MAPPED;
394
395 return 0;
396} 392}
397 393
398/** 394/**
@@ -411,6 +407,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
411int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b) 407int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
412{ 408{
413 struct vb2_buffer *vb; 409 struct vb2_buffer *vb;
410 int ret;
414 411
415 if (b->type != q->type) { 412 if (b->type != q->type) {
416 dprintk(1, "querybuf: wrong buffer type\n"); 413 dprintk(1, "querybuf: wrong buffer type\n");
@@ -422,8 +419,10 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
422 return -EINVAL; 419 return -EINVAL;
423 } 420 }
424 vb = q->bufs[b->index]; 421 vb = q->bufs[b->index];
425 422 ret = __verify_planes_array(vb, b);
426 return __fill_v4l2_buffer(vb, b); 423 if (!ret)
424 __fill_v4l2_buffer(vb, b);
425 return ret;
427} 426}
428EXPORT_SYMBOL(vb2_querybuf); 427EXPORT_SYMBOL(vb2_querybuf);
429 428
@@ -813,24 +812,16 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
813EXPORT_SYMBOL_GPL(vb2_buffer_done); 812EXPORT_SYMBOL_GPL(vb2_buffer_done);
814 813
815/** 814/**
816 * __fill_vb2_buffer() - fill a vb2_buffer with information provided in 815 * __fill_vb2_buffer() - fill a vb2_buffer with information provided in a
817 * a v4l2_buffer by the userspace 816 * v4l2_buffer by the userspace. The caller has already verified that struct
817 * v4l2_buffer has a valid number of planes.
818 */ 818 */
819static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b, 819static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
820 struct v4l2_plane *v4l2_planes) 820 struct v4l2_plane *v4l2_planes)
821{ 821{
822 unsigned int plane; 822 unsigned int plane;
823 int ret;
824 823
825 if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { 824 if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
826 /*
827 * Verify that the userspace gave us a valid array for
828 * plane information.
829 */
830 ret = __verify_planes_array(vb, b);
831 if (ret)
832 return ret;
833
834 /* Fill in driver-provided information for OUTPUT types */ 825 /* Fill in driver-provided information for OUTPUT types */
835 if (V4L2_TYPE_IS_OUTPUT(b->type)) { 826 if (V4L2_TYPE_IS_OUTPUT(b->type)) {
836 /* 827 /*
@@ -872,8 +863,6 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
872 vb->v4l2_buf.field = b->field; 863 vb->v4l2_buf.field = b->field;
873 vb->v4l2_buf.timestamp = b->timestamp; 864 vb->v4l2_buf.timestamp = b->timestamp;
874 vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS; 865 vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS;
875
876 return 0;
877} 866}
878 867
879/** 868/**
@@ -888,10 +877,8 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
888 int ret; 877 int ret;
889 int write = !V4L2_TYPE_IS_OUTPUT(q->type); 878 int write = !V4L2_TYPE_IS_OUTPUT(q->type);
890 879
891 /* Verify and copy relevant information provided by the userspace */ 880 /* Copy relevant information provided by the userspace */
892 ret = __fill_vb2_buffer(vb, b, planes); 881 __fill_vb2_buffer(vb, b, planes);
893 if (ret)
894 return ret;
895 882
896 for (plane = 0; plane < vb->num_planes; ++plane) { 883 for (plane = 0; plane < vb->num_planes; ++plane) {
897 /* Skip the plane if already verified */ 884 /* Skip the plane if already verified */
@@ -966,7 +953,8 @@ err:
966 */ 953 */
967static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b) 954static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
968{ 955{
969 return __fill_vb2_buffer(vb, b, vb->v4l2_planes); 956 __fill_vb2_buffer(vb, b, vb->v4l2_planes);
957 return 0;
970} 958}
971 959
972/** 960/**
@@ -1059,7 +1047,9 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
1059 dprintk(1, "%s(): invalid buffer state %d\n", __func__, vb->state); 1047 dprintk(1, "%s(): invalid buffer state %d\n", __func__, vb->state);
1060 return -EINVAL; 1048 return -EINVAL;
1061 } 1049 }
1062 1050 ret = __verify_planes_array(vb, b);
1051 if (ret < 0)
1052 return ret;
1063 ret = __buf_prepare(vb, b); 1053 ret = __buf_prepare(vb, b);
1064 if (ret < 0) 1054 if (ret < 0)
1065 return ret; 1055 return ret;
@@ -1147,6 +1137,9 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
1147 ret = -EINVAL; 1137 ret = -EINVAL;
1148 goto unlock; 1138 goto unlock;
1149 } 1139 }
1140 ret = __verify_planes_array(vb, b);
1141 if (ret)
1142 goto unlock;
1150 1143
1151 switch (vb->state) { 1144 switch (vb->state) {
1152 case VB2_BUF_STATE_DEQUEUED: 1145 case VB2_BUF_STATE_DEQUEUED:
@@ -1243,8 +1236,10 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
1243 * the locks or return an error if one occurred. 1236 * the locks or return an error if one occurred.
1244 */ 1237 */
1245 call_qop(q, wait_finish, q); 1238 call_qop(q, wait_finish, q);
1246 if (ret) 1239 if (ret) {
1240 dprintk(1, "Sleep was interrupted\n");
1247 return ret; 1241 return ret;
1242 }
1248 } 1243 }
1249 return 0; 1244 return 0;
1250} 1245}
@@ -1255,7 +1250,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
1255 * Will sleep if required for nonblocking == false. 1250 * Will sleep if required for nonblocking == false.
1256 */ 1251 */
1257static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, 1252static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
1258 int nonblocking) 1253 struct v4l2_buffer *b, int nonblocking)
1259{ 1254{
1260 unsigned long flags; 1255 unsigned long flags;
1261 int ret; 1256 int ret;
@@ -1273,10 +1268,16 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
1273 */ 1268 */
1274 spin_lock_irqsave(&q->done_lock, flags); 1269 spin_lock_irqsave(&q->done_lock, flags);
1275 *vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry); 1270 *vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry);
1276 list_del(&(*vb)->done_entry); 1271 /*
1272 * Only remove the buffer from done_list if v4l2_buffer can handle all
1273 * the planes.
1274 */
1275 ret = __verify_planes_array(*vb, b);
1276 if (!ret)
1277 list_del(&(*vb)->done_entry);
1277 spin_unlock_irqrestore(&q->done_lock, flags); 1278 spin_unlock_irqrestore(&q->done_lock, flags);
1278 1279
1279 return 0; 1280 return ret;
1280} 1281}
1281 1282
1282/** 1283/**
@@ -1335,12 +1336,9 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
1335 dprintk(1, "dqbuf: invalid buffer type\n"); 1336 dprintk(1, "dqbuf: invalid buffer type\n");
1336 return -EINVAL; 1337 return -EINVAL;
1337 } 1338 }
1338 1339 ret = __vb2_get_done_vb(q, &vb, b, nonblocking);
1339 ret = __vb2_get_done_vb(q, &vb, nonblocking); 1340 if (ret < 0)
1340 if (ret < 0) {
1341 dprintk(1, "dqbuf: error getting next done buffer\n");
1342 return ret; 1341 return ret;
1343 }
1344 1342
1345 ret = call_qop(q, buf_finish, vb); 1343 ret = call_qop(q, buf_finish, vb);
1346 if (ret) { 1344 if (ret) {