diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/parport/bw-qcam.c | 3 | ||||
-rw-r--r-- | drivers/media/pci/sta2x11/sta2x11_vip.c | 3 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_queue.c | 3 | ||||
-rw-r--r-- | drivers/media/v4l2-core/videobuf2-core.c | 17 |
4 files changed, 22 insertions, 4 deletions
diff --git a/drivers/media/parport/bw-qcam.c b/drivers/media/parport/bw-qcam.c index cf2db63da3b..8a0e84c7d49 100644 --- a/drivers/media/parport/bw-qcam.c +++ b/drivers/media/parport/bw-qcam.c @@ -674,6 +674,9 @@ static void buffer_finish(struct vb2_buffer *vb) int size = vb->vb2_queue->plane_sizes[0]; int len; + if (!vb2_is_streaming(vb->vb2_queue)) + return; + mutex_lock(&qcam->lock); parport_claim_or_block(qcam->pdev); diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c index e66556cae7e..bb11443ed63 100644 --- a/drivers/media/pci/sta2x11/sta2x11_vip.c +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c @@ -337,7 +337,8 @@ static void buffer_finish(struct vb2_buffer *vb) list_del_init(&vip_buf->list); spin_unlock(&vip->lock); - vip_active_buf_next(vip); + if (vb2_is_streaming(vb->vb2_queue)) + vip_active_buf_next(vip); } static int start_streaming(struct vb2_queue *vq, unsigned int count) diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 26172cbcf09..6e92d208025 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -113,7 +113,8 @@ static void uvc_buffer_finish(struct vb2_buffer *vb) container_of(queue, struct uvc_streaming, queue); struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); - uvc_video_clock_update(stream, &vb->v4l2_buf, buf); + if (vb->state == VB2_BUF_STATE_DONE) + uvc_video_clock_update(stream, &vb->v4l2_buf, buf); } static void uvc_wait_prepare(struct vb2_queue *vq) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 2be3cfec2ac..16ae66f5584 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1929,9 +1929,22 @@ static void __vb2_queue_cancel(struct vb2_queue *q) /* * Reinitialize all buffers for next use. + * Make sure to call buf_finish for any queued buffers. Normally + * that's done in dqbuf, but that's not going to happen when we + * cancel the whole queue. Note: this code belongs here, not in + * __vb2_dqbuf() since in vb2_internal_dqbuf() there is a critical + * call to __fill_v4l2_buffer() after buf_finish(). That order can't + * be changed, so we can't move the buf_finish() to __vb2_dqbuf(). */ - for (i = 0; i < q->num_buffers; ++i) - __vb2_dqbuf(q->bufs[i]); + for (i = 0; i < q->num_buffers; ++i) { + struct vb2_buffer *vb = q->bufs[i]; + + if (vb->state != VB2_BUF_STATE_DEQUEUED) { + vb->state = VB2_BUF_STATE_PREPARED; + call_vb_qop(vb, buf_finish, vb); + } + __vb2_dqbuf(vb); + } } static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type) |