On Sun, 3 Apr 2011, Pawel Osciak wrote:

> Drivers are now required to implement the stop_streaming() callback
> to ensure that all ongoing hardware operations are finished and their
> ownership of buffers is ceded.
> Drivers do not have to call vb2_buffer_done() for each buffer they own
> anymore.
> Also remove the return value from the callback.
> 
> Signed-off-by: Pawel Osciak <pa...@osciak.com>
> ---
>  drivers/media/video/videobuf2-core.c |   16 ++++++++++++++--
>  include/media/videobuf2-core.h       |   16 +++++++---------
>  2 files changed, 21 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/video/videobuf2-core.c 
> b/drivers/media/video/videobuf2-core.c
> index 6e69584..59d5e8b 100644
> --- a/drivers/media/video/videobuf2-core.c
> +++ b/drivers/media/video/videobuf2-core.c
> @@ -640,6 +640,9 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
> vb2_buffer_state state)
>       struct vb2_queue *q = vb->vb2_queue;
>       unsigned long flags;
>  
> +     if (atomic_read(&q->queued_count) == 0)
> +             return;
> +
>       if (vb->state != VB2_BUF_STATE_ACTIVE)
>               return;
>  
> @@ -1178,12 +1181,20 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
>       unsigned int i;
>  
>       /*
> -      * Tell driver to stop all transactions and release all queued
> +      * Tell the driver to stop all transactions and release all queued
>        * buffers.
>        */
>       if (q->streaming)
>               call_qop(q, stop_streaming, q);
> +
> +     /*
> +      * All buffers should now not be in use by the driver anymore, but we
> +      * have to manually set queued_count to 0, as the driver was not
> +      * required to call vb2_buffer_done() from stop_streaming() for all
> +      * buffers it had queued.
> +      */
>       q->streaming = 0;
> +     atomic_set(&q->queued_count, 0);
>  
>       /*
>        * Remove all buffers from videobuf's list...
> @@ -1197,7 +1208,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
>       wake_up_all(&q->done_wq);
>  
>       /*
> -      * Reinitialize all buffers for next use.
> +      * Reinitialize all buffers for future use.
>        */
>       for (i = 0; i < q->num_buffers; ++i)
>               q->bufs[i]->state = VB2_BUF_STATE_DEQUEUED;
> @@ -1440,6 +1451,7 @@ int vb2_queue_init(struct vb2_queue *q)
>  
>       BUG_ON(!q->ops->queue_setup);
>       BUG_ON(!q->ops->buf_queue);
> +     BUG_ON(!q->ops->stop_streaming);
>  
>       INIT_LIST_HEAD(&q->queued_list);
>       INIT_LIST_HEAD(&q->done_list);
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index f3bdbb2..8115fe9 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -184,7 +184,7 @@ struct vb2_buffer {
>  
>  /**
>   * struct vb2_ops - driver-specific callbacks to be implemented by the driver
> - * Required: queue_setup, buf_queue. The rest is optional.
> + * Required: queue_setup, buf_queue, stop_streaming. The rest is optional.
>   *
>   * @queue_setup:     used to negotiate queue parameters between the userspace
>   *                   and the driver; called before memory allocation;
> @@ -231,13 +231,11 @@ struct vb2_buffer {
>   *                   the driver before streaming begins (such as enabling
>   *                   the device);
>   * @stop_streaming:  called when the 'streaming' state must be disabled;
> - *                   drivers should stop any DMA transactions here (or wait
> - *                   until they are finished) and give back all the buffers
> - *                   received via buf_queue() by calling vb2_buffer_done()
> - *                   for each of them;
> - *                   drivers can use the vb2_wait_for_all_buffers() function
> - *                   here to wait for asynchronous completion events that
> - *                   call vb2_buffer_done(), such as ISRs;
> + *                   drivers should stop any DMA transactions here (or wait
> + *                   until they are finished) before returning;
> + *                   drivers can use the vb2_wait_for_all_buffers() function
> + *                   here to wait for asynchronous completion events, such
> + *                   as ISRs;
>   * @buf_queue:               passes a buffer to the driver; the driver may 
> start
>   *                   a hardware operation on that buffer; this callback
>   *                   MUST return immediately, i.e. it may NOT wait for
> @@ -259,7 +257,7 @@ struct vb2_ops {
>       void (*buf_cleanup)(struct vb2_buffer *vb);
>  
>       int (*start_streaming)(struct vb2_queue *q);
> -     int (*stop_streaming)(struct vb2_queue *q);
> +     void (*stop_streaming)(struct vb2_queue *q);

Won't compilation break after this patch with "assignment from 
incompatible pointer type?" I know, it's only until it is fixed by the 
follow-up patches, but normally we're trying to avoid such bisection 
breakages.

Thanks
Guennadi

>  
>       void (*buf_queue)(struct vb2_buffer *vb);
>  };
> -- 
> 1.7.4.2
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to