2010-05-02 22:57:41 +04:00
/*
* uvc_queue . c - - USB Video Class driver - Buffers management
*
* Copyright ( C ) 2005 - 2010
* Laurent Pinchart ( laurent . pinchart @ ideasonboard . com )
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*/
2013-03-28 13:41:52 +04:00
# include <linux/atomic.h>
2010-05-02 22:57:41 +04:00
# include <linux/kernel.h>
# include <linux/mm.h>
# include <linux/list.h>
# include <linux/module.h>
# include <linux/usb.h>
# include <linux/videodev2.h>
# include <linux/vmalloc.h>
# include <linux/wait.h>
2013-03-28 13:41:52 +04:00
# include <media/videobuf2-vmalloc.h>
2010-05-02 22:57:41 +04:00
# include "uvc.h"
/* ------------------------------------------------------------------------
* Video buffers queue management .
*
* Video queues is initialized by uvc_queue_init ( ) . The function performs
* basic initialization of the uvc_video_queue struct and never fails .
*
2013-03-28 13:41:52 +04:00
* Video buffers are managed by videobuf2 . The driver uses a mutex to protect
* the videobuf2 queue operations by serializing calls to videobuf2 and a
* spinlock to protect the IRQ queue that holds the buffers to be processed by
* the driver .
2010-05-02 22:57:41 +04:00
*/
2013-03-28 13:41:52 +04:00
/* -----------------------------------------------------------------------------
* videobuf2 queue operations
2010-07-10 23:13:05 +04:00
*/
2013-03-28 13:41:52 +04:00
static int uvc_queue_setup ( struct vb2_queue * vq , const struct v4l2_format * fmt ,
unsigned int * nbuffers , unsigned int * nplanes ,
unsigned int sizes [ ] , void * alloc_ctxs [ ] )
2010-07-10 23:13:05 +04:00
{
2013-03-28 13:41:52 +04:00
struct uvc_video_queue * queue = vb2_get_drv_priv ( vq ) ;
struct uvc_video * video = container_of ( queue , struct uvc_video , queue ) ;
2010-07-10 23:13:05 +04:00
2013-03-28 13:41:52 +04:00
if ( * nbuffers > UVC_MAX_VIDEO_BUFFERS )
* nbuffers = UVC_MAX_VIDEO_BUFFERS ;
2010-07-10 23:13:05 +04:00
2013-03-28 13:41:52 +04:00
* nplanes = 1 ;
sizes [ 0 ] = video - > imagesize ;
2010-07-10 23:13:05 +04:00
return 0 ;
}
2013-03-28 13:41:52 +04:00
static int uvc_buffer_prepare ( struct vb2_buffer * vb )
2010-05-02 22:57:41 +04:00
{
2013-03-28 13:41:52 +04:00
struct uvc_video_queue * queue = vb2_get_drv_priv ( vb - > vb2_queue ) ;
struct uvc_buffer * buf = container_of ( vb , struct uvc_buffer , buf ) ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
if ( vb - > v4l2_buf . type = = V4L2_BUF_TYPE_VIDEO_OUTPUT & &
vb2_get_plane_payload ( vb , 0 ) > vb2_plane_size ( vb , 0 ) ) {
uvc_trace ( UVC_TRACE_CAPTURE , " [E] Bytes used out of bounds. \n " ) ;
return - EINVAL ;
}
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
if ( unlikely ( queue - > flags & UVC_QUEUE_DISCONNECTED ) )
return - ENODEV ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
buf - > state = UVC_BUF_STATE_QUEUED ;
buf - > mem = vb2_plane_vaddr ( vb , 0 ) ;
buf - > length = vb2_plane_size ( vb , 0 ) ;
if ( vb - > v4l2_buf . type = = V4L2_BUF_TYPE_VIDEO_CAPTURE )
buf - > bytesused = 0 ;
else
buf - > bytesused = vb2_get_plane_payload ( vb , 0 ) ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
return 0 ;
}
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
static void uvc_buffer_queue ( struct vb2_buffer * vb )
{
struct uvc_video_queue * queue = vb2_get_drv_priv ( vb - > vb2_queue ) ;
struct uvc_buffer * buf = container_of ( vb , struct uvc_buffer , buf ) ;
unsigned long flags ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
spin_lock_irqsave ( & queue - > irqlock , flags ) ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
if ( likely ( ! ( queue - > flags & UVC_QUEUE_DISCONNECTED ) ) ) {
list_add_tail ( & buf - > queue , & queue - > irqqueue ) ;
} else {
/* If the device is disconnected return the buffer to userspace
* directly . The next QBUF call will fail with - ENODEV .
*/
buf - > state = UVC_BUF_STATE_ERROR ;
vb2_buffer_done ( & buf - > buf , VB2_BUF_STATE_ERROR ) ;
2010-05-02 22:57:41 +04:00
}
2013-03-28 13:41:52 +04:00
spin_unlock_irqrestore ( & queue - > irqlock , flags ) ;
2010-05-02 22:57:41 +04:00
}
2013-02-09 03:54:54 +04:00
static void uvc_wait_prepare ( struct vb2_queue * vq )
{
struct uvc_video_queue * queue = vb2_get_drv_priv ( vq ) ;
mutex_unlock ( & queue - > mutex ) ;
}
static void uvc_wait_finish ( struct vb2_queue * vq )
{
struct uvc_video_queue * queue = vb2_get_drv_priv ( vq ) ;
mutex_lock ( & queue - > mutex ) ;
}
2013-03-28 13:41:52 +04:00
static struct vb2_ops uvc_queue_qops = {
. queue_setup = uvc_queue_setup ,
. buf_prepare = uvc_buffer_prepare ,
. buf_queue = uvc_buffer_queue ,
2013-02-09 03:54:54 +04:00
. wait_prepare = uvc_wait_prepare ,
. wait_finish = uvc_wait_finish ,
2013-03-28 13:41:52 +04:00
} ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
static int uvc_queue_init ( struct uvc_video_queue * queue ,
enum v4l2_buf_type type )
2010-05-02 22:57:41 +04:00
{
2013-03-28 13:41:52 +04:00
int ret ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
queue - > queue . type = type ;
queue - > queue . io_modes = VB2_MMAP | VB2_USERPTR ;
queue - > queue . drv_priv = queue ;
queue - > queue . buf_struct_size = sizeof ( struct uvc_buffer ) ;
queue - > queue . ops = & uvc_queue_qops ;
queue - > queue . mem_ops = & vb2_vmalloc_memops ;
ret = vb2_queue_init ( & queue - > queue ) ;
if ( ret )
return ret ;
mutex_init ( & queue - > mutex ) ;
spin_lock_init ( & queue - > irqlock ) ;
INIT_LIST_HEAD ( & queue - > irqqueue ) ;
queue - > flags = 0 ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
return 0 ;
}
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
/*
* Free the video buffers .
*/
static void uvc_free_buffers ( struct uvc_video_queue * queue )
{
mutex_lock ( & queue - > mutex ) ;
vb2_queue_release ( & queue - > queue ) ;
2010-05-02 22:57:41 +04:00
mutex_unlock ( & queue - > mutex ) ;
}
/*
2013-03-28 13:41:52 +04:00
* Allocate the video buffers .
2010-05-02 22:57:41 +04:00
*/
2013-03-28 13:41:52 +04:00
static int uvc_alloc_buffers ( struct uvc_video_queue * queue ,
struct v4l2_requestbuffers * rb )
2010-05-02 22:57:41 +04:00
{
2013-03-28 13:41:52 +04:00
int ret ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
mutex_lock ( & queue - > mutex ) ;
ret = vb2_reqbufs ( & queue - > queue , rb ) ;
mutex_unlock ( & queue - > mutex ) ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
return ret ? ret : rb - > count ;
}
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
static int uvc_query_buffer ( struct uvc_video_queue * queue ,
struct v4l2_buffer * buf )
{
int ret ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
mutex_lock ( & queue - > mutex ) ;
ret = vb2_querybuf ( & queue - > queue , buf ) ;
mutex_unlock ( & queue - > mutex ) ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
return ret ;
}
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
static int uvc_queue_buffer ( struct uvc_video_queue * queue ,
struct v4l2_buffer * buf )
{
unsigned long flags ;
int ret ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
mutex_lock ( & queue - > mutex ) ;
ret = vb2_qbuf ( & queue - > queue , buf ) ;
2010-05-02 22:57:41 +04:00
spin_lock_irqsave ( & queue - > irqlock , flags ) ;
ret = ( queue - > flags & UVC_QUEUE_PAUSED ) ! = 0 ;
queue - > flags & = ~ UVC_QUEUE_PAUSED ;
spin_unlock_irqrestore ( & queue - > irqlock , flags ) ;
mutex_unlock ( & queue - > mutex ) ;
2013-03-28 13:41:52 +04:00
return ret ;
2010-05-02 22:57:41 +04:00
}
/*
* Dequeue a video buffer . If nonblocking is false , block until a buffer is
* available .
*/
2013-03-28 13:41:52 +04:00
static int uvc_dequeue_buffer ( struct uvc_video_queue * queue ,
struct v4l2_buffer * buf , int nonblocking )
2010-05-02 22:57:41 +04:00
{
2013-03-28 13:41:52 +04:00
int ret ;
2010-05-02 22:57:41 +04:00
mutex_lock ( & queue - > mutex ) ;
2013-03-28 13:41:52 +04:00
ret = vb2_dqbuf ( & queue - > queue , buf , nonblocking ) ;
2010-05-02 22:57:41 +04:00
mutex_unlock ( & queue - > mutex ) ;
2013-03-28 13:41:52 +04:00
2010-05-02 22:57:41 +04:00
return ret ;
}
/*
* Poll the video queue .
*
* This function implements video queue polling and is intended to be used by
* the device poll handler .
*/
2013-03-28 13:41:52 +04:00
static unsigned int uvc_queue_poll ( struct uvc_video_queue * queue ,
struct file * file , poll_table * wait )
2010-05-02 22:57:41 +04:00
{
2013-03-28 13:41:52 +04:00
unsigned int ret ;
2010-05-02 22:57:41 +04:00
mutex_lock ( & queue - > mutex ) ;
2013-03-28 13:41:52 +04:00
ret = vb2_poll ( & queue - > queue , file , wait ) ;
2010-05-02 22:57:41 +04:00
mutex_unlock ( & queue - > mutex ) ;
2013-03-28 13:41:52 +04:00
return ret ;
2010-05-02 22:57:41 +04:00
}
2013-03-28 13:41:52 +04:00
static int uvc_queue_mmap ( struct uvc_video_queue * queue ,
struct vm_area_struct * vma )
2010-05-02 22:57:41 +04:00
{
2013-03-28 13:41:52 +04:00
int ret ;
2010-05-02 22:57:41 +04:00
mutex_lock ( & queue - > mutex ) ;
2013-03-28 13:41:52 +04:00
ret = vb2_mmap ( & queue - > queue , vma ) ;
2010-05-02 22:57:41 +04:00
mutex_unlock ( & queue - > mutex ) ;
2013-03-28 13:41:52 +04:00
2010-05-02 22:57:41 +04:00
return ret ;
}
2013-03-28 13:41:53 +04:00
# ifndef CONFIG_MMU
/*
* Get unmapped area .
*
* NO - MMU arch need this function to make mmap ( ) work correctly .
*/
static unsigned long uvc_queue_get_unmapped_area ( struct uvc_video_queue * queue ,
unsigned long pgoff )
{
unsigned long ret ;
mutex_lock ( & queue - > mutex ) ;
ret = vb2_get_unmapped_area ( & queue - > queue , 0 , 0 , pgoff , 0 ) ;
mutex_unlock ( & queue - > mutex ) ;
return ret ;
}
# endif
2010-07-10 23:13:05 +04:00
/*
* Cancel the video buffers queue .
*
* Cancelling the queue marks all buffers on the irq queue as erroneous ,
* wakes them up and removes them from the queue .
*
* If the disconnect parameter is set , further calls to uvc_queue_buffer will
* fail with - ENODEV .
*
* This function acquires the irq spinlock and can be called from interrupt
* context .
*/
static void uvc_queue_cancel ( struct uvc_video_queue * queue , int disconnect )
{
struct uvc_buffer * buf ;
unsigned long flags ;
spin_lock_irqsave ( & queue - > irqlock , flags ) ;
while ( ! list_empty ( & queue - > irqqueue ) ) {
buf = list_first_entry ( & queue - > irqqueue , struct uvc_buffer ,
queue ) ;
list_del ( & buf - > queue ) ;
buf - > state = UVC_BUF_STATE_ERROR ;
2013-03-28 13:41:52 +04:00
vb2_buffer_done ( & buf - > buf , VB2_BUF_STATE_ERROR ) ;
2010-07-10 23:13:05 +04:00
}
/* This must be protected by the irqlock spinlock to avoid race
* conditions between uvc_queue_buffer and the disconnection event that
* could result in an interruptible wait in uvc_dequeue_buffer . Do not
* blindly replace this logic by checking for the UVC_DEV_DISCONNECTED
* state outside the queue code .
*/
if ( disconnect )
queue - > flags | = UVC_QUEUE_DISCONNECTED ;
spin_unlock_irqrestore ( & queue - > irqlock , flags ) ;
}
2010-05-02 22:57:41 +04:00
/*
* Enable or disable the video buffers queue .
*
* The queue must be enabled before starting video acquisition and must be
* disabled after stopping it . This ensures that the video buffers queue
* state can be properly initialized before buffers are accessed from the
* interrupt handler .
*
* Enabling the video queue initializes parameters ( such as sequence number ,
* sync pattern , . . . ) . If the queue is already enabled , return - EBUSY .
*
* Disabling the video queue cancels the queue and removes all buffers from
* the main queue .
*
* This function can ' t be called from interrupt context . Use
* uvc_queue_cancel ( ) instead .
*/
2010-07-10 23:13:05 +04:00
static int uvc_queue_enable ( struct uvc_video_queue * queue , int enable )
2010-05-02 22:57:41 +04:00
{
2013-03-28 13:41:52 +04:00
unsigned long flags ;
2010-05-02 22:57:41 +04:00
int ret = 0 ;
mutex_lock ( & queue - > mutex ) ;
if ( enable ) {
2013-03-28 13:41:52 +04:00
ret = vb2_streamon ( & queue - > queue , queue - > queue . type ) ;
if ( ret < 0 )
2010-05-02 22:57:41 +04:00
goto done ;
2013-03-28 13:41:52 +04:00
2010-05-02 22:57:41 +04:00
queue - > sequence = 0 ;
queue - > buf_used = 0 ;
} else {
2013-03-28 13:41:52 +04:00
ret = vb2_streamoff ( & queue - > queue , queue - > queue . type ) ;
if ( ret < 0 )
goto done ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
spin_lock_irqsave ( & queue - > irqlock , flags ) ;
INIT_LIST_HEAD ( & queue - > irqqueue ) ;
2010-05-02 22:57:41 +04:00
2013-03-28 13:41:52 +04:00
/*
* FIXME : We need to clear the DISCONNECTED flag to ensure that
* applications will be able to queue buffers for the next
* streaming run . However , clearing it here doesn ' t guarantee
* that the device will be reconnected in the meantime .
*/
queue - > flags & = ~ UVC_QUEUE_DISCONNECTED ;
spin_unlock_irqrestore ( & queue - > irqlock , flags ) ;
2010-05-02 22:57:41 +04:00
}
done :
mutex_unlock ( & queue - > mutex ) ;
return ret ;
}
2012-03-22 07:50:37 +04:00
/* called with &queue_irqlock held.. */
2013-03-28 13:41:52 +04:00
static struct uvc_buffer * uvc_queue_next_buffer ( struct uvc_video_queue * queue ,
struct uvc_buffer * buf )
2010-05-02 22:57:41 +04:00
{
struct uvc_buffer * nextbuf ;
if ( ( queue - > flags & UVC_QUEUE_DROP_INCOMPLETE ) & &
2013-03-28 13:41:52 +04:00
buf - > length ! = buf - > bytesused ) {
2010-05-02 22:57:41 +04:00
buf - > state = UVC_BUF_STATE_QUEUED ;
2013-03-28 13:41:52 +04:00
vb2_set_plane_payload ( & buf - > buf , 0 , 0 ) ;
2010-05-02 22:57:41 +04:00
return buf ;
}
list_del ( & buf - > queue ) ;
if ( ! list_empty ( & queue - > irqqueue ) )
nextbuf = list_first_entry ( & queue - > irqqueue , struct uvc_buffer ,
queue ) ;
else
nextbuf = NULL ;
2013-03-28 13:41:52 +04:00
/*
* FIXME : with videobuf2 , the sequence number or timestamp fields
* are valid only for video capture devices and the UVC gadget usually
* is a video output device . Keeping these until the specs are clear on
* this aspect .
*/
buf - > buf . v4l2_buf . sequence = queue - > sequence + + ;
do_gettimeofday ( & buf - > buf . v4l2_buf . timestamp ) ;
vb2_set_plane_payload ( & buf - > buf , 0 , buf - > bytesused ) ;
vb2_buffer_done ( & buf - > buf , VB2_BUF_STATE_DONE ) ;
2010-05-02 22:57:41 +04:00
return nextbuf ;
}
2010-07-10 23:13:05 +04:00
static struct uvc_buffer * uvc_queue_head ( struct uvc_video_queue * queue )
2010-05-02 22:57:41 +04:00
{
struct uvc_buffer * buf = NULL ;
if ( ! list_empty ( & queue - > irqqueue ) )
buf = list_first_entry ( & queue - > irqqueue , struct uvc_buffer ,
queue ) ;
else
queue - > flags | = UVC_QUEUE_PAUSED ;
return buf ;
}