[media] vb2: call buf_finish from __queue_cancel
authorHans Verkuil <hans.verkuil@cisco.com>
Tue, 4 Mar 2014 10:34:49 +0000 (07:34 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Tue, 11 Mar 2014 09:56:39 +0000 (06:56 -0300)
If a queue was canceled, then the buf_finish op was never called for the
pending buffers. So add this call to queue_cancel. Before calling buf_finish
set the buffer state to PREPARED, which is the correct state. That way the
states DONE and ERROR will only be seen in buf_finish if streaming is in
progress.

Since buf_finish can now be called from non-streaming state we need to
adapt the handful of drivers that actually need to know this.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/parport/bw-qcam.c
drivers/media/pci/sta2x11/sta2x11_vip.c
drivers/media/usb/uvc/uvc_queue.c
drivers/media/v4l2-core/videobuf2-core.c
include/media/videobuf2-core.h

index cf2db63da3b14ca7a654ffe5ccb228163765041e..8a0e84c7d495a158a01771dd693ce18db0428114 100644 (file)
@@ -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);
 
index e66556cae7ea90d3ff9f9c0216de91430a28f282..bb11443ed63e840b9bdd933e3aa4fdaaa1aa3330 100644 (file)
@@ -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)
index 26172cbcf096c74e4aadb569433c5e85e525c0cd..6e92d2080255f0353fa6006c210553bb0209ee8d 100644 (file)
@@ -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)
index 2be3cfec2ac82d6fad17e2da7c5ad2cf2add4ca7..16ae66f5584fb3e9529ec1ec97a5ca5a8358e34e 100644 (file)
@@ -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)
index 8d62a51cb7a0b6daced336066507fd486b0f7f3c..2ffcb81aee9c34fda9f1796596e9f9e7841a29cf 100644 (file)
@@ -276,7 +276,15 @@ struct vb2_buffer {
  *                     in driver; optional
  * @buf_finish:                called before every dequeue of the buffer back to
  *                     userspace; drivers may perform any operations required
- *                     before userspace accesses the buffer; optional
+ *                     before userspace accesses the buffer; optional. The
+ *                     buffer state can be one of the following: DONE and
+ *                     ERROR occur while streaming is in progress, and the
+ *                     PREPARED state occurs when the queue has been canceled
+ *                     and all pending buffers are being returned to their
+ *                     default DEQUEUED state. Typically you only have to do
+ *                     something if the state is VB2_BUF_STATE_DONE, since in
+ *                     all other cases the buffer contents will be ignored
+ *                     anyway.
  * @buf_cleanup:       called once before the buffer is freed; drivers may
  *                     perform any additional cleanup; optional
  * @start_streaming:   called once to enter 'streaming' state; the driver may