aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c100
1 files changed, 67 insertions, 33 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 16ae66f5584f..6c33b788ecd7 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -377,8 +377,10 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
377 /* Call driver-provided cleanup function for each buffer, if provided */ 377 /* Call driver-provided cleanup function for each buffer, if provided */
378 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; 378 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
379 ++buffer) { 379 ++buffer) {
380 if (q->bufs[buffer]) 380 struct vb2_buffer *vb = q->bufs[buffer];
381 call_vb_qop(q->bufs[buffer], buf_cleanup, q->bufs[buffer]); 381
382 if (vb && vb->planes[0].mem_priv)
383 call_vb_qop(vb, buf_cleanup, vb);
382 } 384 }
383 385
384 /* Release video buffer memory */ 386 /* Release video buffer memory */
@@ -1196,6 +1198,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1196 unsigned int plane; 1198 unsigned int plane;
1197 int ret; 1199 int ret;
1198 int write = !V4L2_TYPE_IS_OUTPUT(q->type); 1200 int write = !V4L2_TYPE_IS_OUTPUT(q->type);
1201 bool reacquired = vb->planes[0].mem_priv == NULL;
1199 1202
1200 /* Copy relevant information provided by the userspace */ 1203 /* Copy relevant information provided by the userspace */
1201 __fill_vb2_buffer(vb, b, planes); 1204 __fill_vb2_buffer(vb, b, planes);
@@ -1221,12 +1224,16 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1221 } 1224 }
1222 1225
1223 /* Release previously acquired memory if present */ 1226 /* Release previously acquired memory if present */
1224 if (vb->planes[plane].mem_priv) 1227 if (vb->planes[plane].mem_priv) {
1228 if (!reacquired) {
1229 reacquired = true;
1230 call_vb_qop(vb, buf_cleanup, vb);
1231 }
1225 call_memop(vb, put_userptr, vb->planes[plane].mem_priv); 1232 call_memop(vb, put_userptr, vb->planes[plane].mem_priv);
1233 }
1226 1234
1227 vb->planes[plane].mem_priv = NULL; 1235 vb->planes[plane].mem_priv = NULL;
1228 vb->v4l2_planes[plane].m.userptr = 0; 1236 memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
1229 vb->v4l2_planes[plane].length = 0;
1230 1237
1231 /* Acquire each plane's memory */ 1238 /* Acquire each plane's memory */
1232 mem_priv = call_memop(vb, get_userptr, q->alloc_ctx[plane], 1239 mem_priv = call_memop(vb, get_userptr, q->alloc_ctx[plane],
@@ -1243,23 +1250,34 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1243 } 1250 }
1244 1251
1245 /* 1252 /*
1246 * Call driver-specific initialization on the newly acquired buffer,
1247 * if provided.
1248 */
1249 ret = call_vb_qop(vb, buf_init, vb);
1250 if (ret) {
1251 dprintk(1, "qbuf: buffer initialization failed\n");
1252 fail_vb_qop(vb, buf_init);
1253 goto err;
1254 }
1255
1256 /*
1257 * Now that everything is in order, copy relevant information 1253 * Now that everything is in order, copy relevant information
1258 * provided by userspace. 1254 * provided by userspace.
1259 */ 1255 */
1260 for (plane = 0; plane < vb->num_planes; ++plane) 1256 for (plane = 0; plane < vb->num_planes; ++plane)
1261 vb->v4l2_planes[plane] = planes[plane]; 1257 vb->v4l2_planes[plane] = planes[plane];
1262 1258
1259 if (reacquired) {
1260 /*
1261 * One or more planes changed, so we must call buf_init to do
1262 * the driver-specific initialization on the newly acquired
1263 * buffer, if provided.
1264 */
1265 ret = call_vb_qop(vb, buf_init, vb);
1266 if (ret) {
1267 dprintk(1, "qbuf: buffer initialization failed\n");
1268 fail_vb_qop(vb, buf_init);
1269 goto err;
1270 }
1271 }
1272
1273 ret = call_vb_qop(vb, buf_prepare, vb);
1274 if (ret) {
1275 dprintk(1, "qbuf: buffer preparation failed\n");
1276 fail_vb_qop(vb, buf_prepare);
1277 call_vb_qop(vb, buf_cleanup, vb);
1278 goto err;
1279 }
1280
1263 return 0; 1281 return 0;
1264err: 1282err:
1265 /* In case of errors, release planes that were already acquired */ 1283 /* In case of errors, release planes that were already acquired */
@@ -1279,8 +1297,13 @@ err:
1279 */ 1297 */
1280static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b) 1298static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1281{ 1299{
1300 int ret;
1301
1282 __fill_vb2_buffer(vb, b, vb->v4l2_planes); 1302 __fill_vb2_buffer(vb, b, vb->v4l2_planes);
1283 return 0; 1303 ret = call_vb_qop(vb, buf_prepare, vb);
1304 if (ret)
1305 fail_vb_qop(vb, buf_prepare);
1306 return ret;
1284} 1307}
1285 1308
1286/** 1309/**
@@ -1294,6 +1317,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1294 unsigned int plane; 1317 unsigned int plane;
1295 int ret; 1318 int ret;
1296 int write = !V4L2_TYPE_IS_OUTPUT(q->type); 1319 int write = !V4L2_TYPE_IS_OUTPUT(q->type);
1320 bool reacquired = vb->planes[0].mem_priv == NULL;
1297 1321
1298 /* Copy relevant information provided by the userspace */ 1322 /* Copy relevant information provided by the userspace */
1299 __fill_vb2_buffer(vb, b, planes); 1323 __fill_vb2_buffer(vb, b, planes);
@@ -1329,6 +1353,11 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1329 1353
1330 dprintk(1, "qbuf: buffer for plane %d changed\n", plane); 1354 dprintk(1, "qbuf: buffer for plane %d changed\n", plane);
1331 1355
1356 if (!reacquired) {
1357 reacquired = true;
1358 call_vb_qop(vb, buf_cleanup, vb);
1359 }
1360
1332 /* Release previously acquired memory if present */ 1361 /* Release previously acquired memory if present */
1333 __vb2_plane_dmabuf_put(vb, &vb->planes[plane]); 1362 __vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
1334 memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane)); 1363 memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
@@ -1364,23 +1393,33 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1364 } 1393 }
1365 1394
1366 /* 1395 /*
1367 * Call driver-specific initialization on the newly acquired buffer,
1368 * if provided.
1369 */
1370 ret = call_vb_qop(vb, buf_init, vb);
1371 if (ret) {
1372 dprintk(1, "qbuf: buffer initialization failed\n");
1373 fail_vb_qop(vb, buf_init);
1374 goto err;
1375 }
1376
1377 /*
1378 * Now that everything is in order, copy relevant information 1396 * Now that everything is in order, copy relevant information
1379 * provided by userspace. 1397 * provided by userspace.
1380 */ 1398 */
1381 for (plane = 0; plane < vb->num_planes; ++plane) 1399 for (plane = 0; plane < vb->num_planes; ++plane)
1382 vb->v4l2_planes[plane] = planes[plane]; 1400 vb->v4l2_planes[plane] = planes[plane];
1383 1401
1402 if (reacquired) {
1403 /*
1404 * Call driver-specific initialization on the newly acquired buffer,
1405 * if provided.
1406 */
1407 ret = call_vb_qop(vb, buf_init, vb);
1408 if (ret) {
1409 dprintk(1, "qbuf: buffer initialization failed\n");
1410 fail_vb_qop(vb, buf_init);
1411 goto err;
1412 }
1413 }
1414
1415 ret = call_vb_qop(vb, buf_prepare, vb);
1416 if (ret) {
1417 dprintk(1, "qbuf: buffer preparation failed\n");
1418 fail_vb_qop(vb, buf_prepare);
1419 call_vb_qop(vb, buf_cleanup, vb);
1420 goto err;
1421 }
1422
1384 return 0; 1423 return 0;
1385err: 1424err:
1386 /* In case of errors, release planes that were already acquired */ 1425 /* In case of errors, release planes that were already acquired */
@@ -1459,11 +1498,6 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1459 ret = -EINVAL; 1498 ret = -EINVAL;
1460 } 1499 }
1461 1500
1462 if (!ret) {
1463 ret = call_vb_qop(vb, buf_prepare, vb);
1464 if (ret)
1465 fail_vb_qop(vb, buf_prepare);
1466 }
1467 if (ret) 1501 if (ret)
1468 dprintk(1, "qbuf: buffer preparation failed: %d\n", ret); 1502 dprintk(1, "qbuf: buffer preparation failed: %d\n", ret);
1469 vb->state = ret ? VB2_BUF_STATE_DEQUEUED : VB2_BUF_STATE_PREPARED; 1503 vb->state = ret ? VB2_BUF_STATE_DEQUEUED : VB2_BUF_STATE_PREPARED;