2008-06-30 15:04:50 -03:00
/*
* uvc_queue . c - - USB Video Class driver - Buffers management
*
2010-09-20 06:10:10 -03:00
* Copyright ( C ) 2005 - 2010
* Laurent Pinchart ( laurent . pinchart @ ideasonboard . com )
2008-06-30 15:04:50 -03:00
*
* 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 .
*
*/
# include <linux/kernel.h>
2008-07-23 21:28:13 -07:00
# include <linux/mm.h>
2008-06-30 15:04:50 -03:00
# include <linux/list.h>
# include <linux/module.h>
# include <linux/usb.h>
# include <linux/videodev2.h>
# include <linux/vmalloc.h>
# include <linux/wait.h>
# include <asm/atomic.h>
# include "uvcvideo.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 .
*
* Video buffer allocation and freeing are performed by uvc_alloc_buffers and
* uvc_free_buffers respectively . The former acquires the video queue lock ,
* while the later must be called with the lock held ( so that allocation can
* free previously allocated buffers ) . Trying to free buffers that are mapped
* to user space will return - EBUSY .
*
* Video buffers are managed using two queues . However , unlike most USB video
2009-01-03 19:12:40 -03:00
* drivers that use an in queue and an out queue , we use a main queue to hold
* all queued buffers ( both ' empty ' and ' done ' buffers ) , and an irq queue to
* hold empty buffers . This design ( copied from video - buf ) minimizes locking
* in interrupt , as only one queue is shared between interrupt and user
* contexts .
2008-06-30 15:04:50 -03:00
*
* Use cases
* - - - - - - - - -
*
2009-01-03 19:12:40 -03:00
* Unless stated otherwise , all operations that modify the irq buffers queue
2008-06-30 15:04:50 -03:00
* are protected by the irq spinlock .
*
* 1. The user queues the buffers , starts streaming and dequeues a buffer .
*
* The buffers are added to the main and irq queues . Both operations are
2009-01-03 19:12:40 -03:00
* protected by the queue lock , and the later is protected by the irq
2008-06-30 15:04:50 -03:00
* spinlock as well .
*
* The completion handler fetches a buffer from the irq queue and fills it
* with video data . If no buffer is available ( irq queue empty ) , the handler
* returns immediately .
*
* When the buffer is full , the completion handler removes it from the irq
2009-12-16 21:20:45 -03:00
* queue , marks it as done ( UVC_BUF_STATE_DONE ) and wakes its wait queue .
2008-06-30 15:04:50 -03:00
* At that point , any process waiting on the buffer will be woken up . If a
2009-12-16 21:20:45 -03:00
* process tries to dequeue a buffer after it has been marked done , the
2008-06-30 15:04:50 -03:00
* dequeing will succeed immediately .
*
* 2. Buffers are queued , user is waiting on a buffer and the device gets
* disconnected .
*
* When the device is disconnected , the kernel calls the completion handler
* with an appropriate status code . The handler marks all buffers in the
* irq queue as being erroneous ( UVC_BUF_STATE_ERROR ) and wakes them up so
* that any process waiting on a buffer gets woken up .
*
* Waking up up the first buffer on the irq list is not enough , as the
* process waiting on the buffer might restart the dequeue operation
* immediately .
*
*/
2010-06-17 06:52:37 -03:00
void uvc_queue_init ( struct uvc_video_queue * queue , enum v4l2_buf_type type ,
int drop_corrupted )
2008-06-30 15:04:50 -03:00
{
mutex_init ( & queue - > mutex ) ;
spin_lock_init ( & queue - > irqlock ) ;
INIT_LIST_HEAD ( & queue - > mainqueue ) ;
INIT_LIST_HEAD ( & queue - > irqqueue ) ;
2010-06-17 06:52:37 -03:00
queue - > flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0 ;
2008-12-28 22:32:29 -03:00
queue - > type = type ;
2008-06-30 15:04:50 -03:00
}
/*
* Allocate the video buffers .
*
2009-01-03 19:12:40 -03:00
* Pages are reserved to make sure they will not be swapped , as they will be
* filled in the URB completion handler .
2008-06-30 15:04:50 -03:00
*
* Buffers will be individually mapped , so they must all be page aligned .
*/
int uvc_alloc_buffers ( struct uvc_video_queue * queue , unsigned int nbuffers ,
unsigned int buflength )
{
unsigned int bufsize = PAGE_ALIGN ( buflength ) ;
unsigned int i ;
void * mem = NULL ;
int ret ;
if ( nbuffers > UVC_MAX_VIDEO_BUFFERS )
nbuffers = UVC_MAX_VIDEO_BUFFERS ;
mutex_lock ( & queue - > mutex ) ;
if ( ( ret = uvc_free_buffers ( queue ) ) < 0 )
goto done ;
/* Bail out if no buffers should be allocated. */
if ( nbuffers = = 0 )
goto done ;
/* Decrement the number of buffers until allocation succeeds. */
for ( ; nbuffers > 0 ; - - nbuffers ) {
mem = vmalloc_32 ( nbuffers * bufsize ) ;
if ( mem ! = NULL )
break ;
}
if ( mem = = NULL ) {
ret = - ENOMEM ;
goto done ;
}
for ( i = 0 ; i < nbuffers ; + + i ) {
memset ( & queue - > buffer [ i ] , 0 , sizeof queue - > buffer [ i ] ) ;
queue - > buffer [ i ] . buf . index = i ;
queue - > buffer [ i ] . buf . m . offset = i * bufsize ;
queue - > buffer [ i ] . buf . length = buflength ;
2008-12-28 22:32:29 -03:00
queue - > buffer [ i ] . buf . type = queue - > type ;
2008-06-30 15:04:50 -03:00
queue - > buffer [ i ] . buf . field = V4L2_FIELD_NONE ;
queue - > buffer [ i ] . buf . memory = V4L2_MEMORY_MMAP ;
queue - > buffer [ i ] . buf . flags = 0 ;
init_waitqueue_head ( & queue - > buffer [ i ] . wait ) ;
}
queue - > mem = mem ;
queue - > count = nbuffers ;
queue - > buf_size = bufsize ;
ret = nbuffers ;
done :
mutex_unlock ( & queue - > mutex ) ;
return ret ;
}
/*
* Free the video buffers .
*
* This function must be called with the queue lock held .
*/
int uvc_free_buffers ( struct uvc_video_queue * queue )
{
unsigned int i ;
for ( i = 0 ; i < queue - > count ; + + i ) {
if ( queue - > buffer [ i ] . vma_use_count ! = 0 )
return - EBUSY ;
}
if ( queue - > count ) {
vfree ( queue - > mem ) ;
queue - > count = 0 ;
}
return 0 ;
}
2009-06-04 09:26:39 -03:00
/*
* Check if buffers have been allocated .
*/
int uvc_queue_allocated ( struct uvc_video_queue * queue )
{
int allocated ;
mutex_lock ( & queue - > mutex ) ;
allocated = queue - > count ! = 0 ;
mutex_unlock ( & queue - > mutex ) ;
return allocated ;
}
2008-06-30 15:04:50 -03:00
static void __uvc_query_buffer ( struct uvc_buffer * buf ,
struct v4l2_buffer * v4l2_buf )
{
memcpy ( v4l2_buf , & buf - > buf , sizeof * v4l2_buf ) ;
if ( buf - > vma_use_count )
v4l2_buf - > flags | = V4L2_BUF_FLAG_MAPPED ;
switch ( buf - > state ) {
case UVC_BUF_STATE_ERROR :
case UVC_BUF_STATE_DONE :
v4l2_buf - > flags | = V4L2_BUF_FLAG_DONE ;
break ;
case UVC_BUF_STATE_QUEUED :
case UVC_BUF_STATE_ACTIVE :
2009-12-16 21:20:45 -03:00
case UVC_BUF_STATE_READY :
2008-06-30 15:04:50 -03:00
v4l2_buf - > flags | = V4L2_BUF_FLAG_QUEUED ;
break ;
case UVC_BUF_STATE_IDLE :
default :
break ;
}
}
int uvc_query_buffer ( struct uvc_video_queue * queue ,
struct v4l2_buffer * v4l2_buf )
{
int ret = 0 ;
mutex_lock ( & queue - > mutex ) ;
if ( v4l2_buf - > index > = queue - > count ) {
ret = - EINVAL ;
goto done ;
}
__uvc_query_buffer ( & queue - > buffer [ v4l2_buf - > index ] , v4l2_buf ) ;
done :
2009-01-03 19:12:40 -03:00
mutex_unlock ( & queue - > mutex ) ;
return ret ;
2008-06-30 15:04:50 -03:00
}
/*
* Queue a video buffer . Attempting to queue a buffer that has already been
* queued will return - EINVAL .
*/
int uvc_queue_buffer ( struct uvc_video_queue * queue ,
struct v4l2_buffer * v4l2_buf )
{
struct uvc_buffer * buf ;
unsigned long flags ;
int ret = 0 ;
uvc_trace ( UVC_TRACE_CAPTURE , " Queuing buffer %u. \n " , v4l2_buf - > index ) ;
2008-12-28 22:32:29 -03:00
if ( v4l2_buf - > type ! = queue - > type | |
2008-06-30 15:04:50 -03:00
v4l2_buf - > memory ! = V4L2_MEMORY_MMAP ) {
uvc_trace ( UVC_TRACE_CAPTURE , " [E] Invalid buffer type (%u) "
" and/or memory (%u). \n " , v4l2_buf - > type ,
v4l2_buf - > memory ) ;
return - EINVAL ;
}
mutex_lock ( & queue - > mutex ) ;
2009-01-03 19:12:40 -03:00
if ( v4l2_buf - > index > = queue - > count ) {
2008-06-30 15:04:50 -03:00
uvc_trace ( UVC_TRACE_CAPTURE , " [E] Out of range index. \n " ) ;
ret = - EINVAL ;
goto done ;
}
buf = & queue - > buffer [ v4l2_buf - > index ] ;
if ( buf - > state ! = UVC_BUF_STATE_IDLE ) {
uvc_trace ( UVC_TRACE_CAPTURE , " [E] Invalid buffer state "
" (%u). \n " , buf - > state ) ;
ret = - EINVAL ;
goto done ;
}
2008-12-28 22:32:29 -03:00
if ( v4l2_buf - > type = = V4L2_BUF_TYPE_VIDEO_OUTPUT & &
v4l2_buf - > bytesused > buf - > buf . length ) {
uvc_trace ( UVC_TRACE_CAPTURE , " [E] Bytes used out of bounds. \n " ) ;
ret = - EINVAL ;
goto done ;
}
2008-06-30 15:04:50 -03:00
spin_lock_irqsave ( & queue - > irqlock , flags ) ;
if ( queue - > flags & UVC_QUEUE_DISCONNECTED ) {
spin_unlock_irqrestore ( & queue - > irqlock , flags ) ;
ret = - ENODEV ;
goto done ;
}
buf - > state = UVC_BUF_STATE_QUEUED ;
2008-12-28 22:32:29 -03:00
if ( v4l2_buf - > type = = V4L2_BUF_TYPE_VIDEO_CAPTURE )
buf - > buf . bytesused = 0 ;
else
buf - > buf . bytesused = v4l2_buf - > bytesused ;
2008-06-30 15:04:50 -03:00
list_add_tail ( & buf - > stream , & queue - > mainqueue ) ;
list_add_tail ( & buf - > queue , & queue - > irqqueue ) ;
spin_unlock_irqrestore ( & queue - > irqlock , flags ) ;
done :
mutex_unlock ( & queue - > mutex ) ;
return ret ;
}
static int uvc_queue_waiton ( struct uvc_buffer * buf , int nonblocking )
{
if ( nonblocking ) {
return ( buf - > state ! = UVC_BUF_STATE_QUEUED & &
2009-12-16 21:20:45 -03:00
buf - > state ! = UVC_BUF_STATE_ACTIVE & &
buf - > state ! = UVC_BUF_STATE_READY )
2008-06-30 15:04:50 -03:00
? 0 : - EAGAIN ;
}
return wait_event_interruptible ( buf - > wait ,
buf - > state ! = UVC_BUF_STATE_QUEUED & &
2009-12-16 21:20:45 -03:00
buf - > state ! = UVC_BUF_STATE_ACTIVE & &
buf - > state ! = UVC_BUF_STATE_READY ) ;
2008-06-30 15:04:50 -03:00
}
/*
* Dequeue a video buffer . If nonblocking is false , block until a buffer is
* available .
*/
int uvc_dequeue_buffer ( struct uvc_video_queue * queue ,
struct v4l2_buffer * v4l2_buf , int nonblocking )
{
struct uvc_buffer * buf ;
int ret = 0 ;
2008-12-28 22:32:29 -03:00
if ( v4l2_buf - > type ! = queue - > type | |
2008-06-30 15:04:50 -03:00
v4l2_buf - > memory ! = V4L2_MEMORY_MMAP ) {
uvc_trace ( UVC_TRACE_CAPTURE , " [E] Invalid buffer type (%u) "
" and/or memory (%u). \n " , v4l2_buf - > type ,
v4l2_buf - > memory ) ;
return - EINVAL ;
}
mutex_lock ( & queue - > mutex ) ;
if ( list_empty ( & queue - > mainqueue ) ) {
uvc_trace ( UVC_TRACE_CAPTURE , " [E] Empty buffer queue. \n " ) ;
ret = - EINVAL ;
goto done ;
}
buf = list_first_entry ( & queue - > mainqueue , struct uvc_buffer , stream ) ;
if ( ( ret = uvc_queue_waiton ( buf , nonblocking ) ) < 0 )
goto done ;
uvc_trace ( UVC_TRACE_CAPTURE , " Dequeuing buffer %u (%u, %u bytes). \n " ,
buf - > buf . index , buf - > state , buf - > buf . bytesused ) ;
switch ( buf - > state ) {
case UVC_BUF_STATE_ERROR :
uvc_trace ( UVC_TRACE_CAPTURE , " [W] Corrupted data "
" (transmission error). \n " ) ;
ret = - EIO ;
case UVC_BUF_STATE_DONE :
buf - > state = UVC_BUF_STATE_IDLE ;
break ;
case UVC_BUF_STATE_IDLE :
case UVC_BUF_STATE_QUEUED :
case UVC_BUF_STATE_ACTIVE :
2009-12-16 21:20:45 -03:00
case UVC_BUF_STATE_READY :
2008-06-30 15:04:50 -03:00
default :
uvc_trace ( UVC_TRACE_CAPTURE , " [E] Invalid buffer state %u "
" (driver bug?). \n " , buf - > state ) ;
ret = - EINVAL ;
goto done ;
}
list_del ( & buf - > stream ) ;
__uvc_query_buffer ( buf , v4l2_buf ) ;
done :
mutex_unlock ( & queue - > mutex ) ;
return ret ;
}
/*
* Poll the video queue .
*
* This function implements video queue polling and is intended to be used by
* the device poll handler .
*/
unsigned int uvc_queue_poll ( struct uvc_video_queue * queue , struct file * file ,
poll_table * wait )
{
struct uvc_buffer * buf ;
unsigned int mask = 0 ;
mutex_lock ( & queue - > mutex ) ;
if ( list_empty ( & queue - > mainqueue ) ) {
mask | = POLLERR ;
goto done ;
}
buf = list_first_entry ( & queue - > mainqueue , struct uvc_buffer , stream ) ;
poll_wait ( file , & buf - > wait , wait ) ;
if ( buf - > state = = UVC_BUF_STATE_DONE | |
2010-03-31 12:29:26 -03:00
buf - > state = = UVC_BUF_STATE_ERROR ) {
if ( queue - > type = = V4L2_BUF_TYPE_VIDEO_CAPTURE )
mask | = POLLIN | POLLRDNORM ;
else
mask | = POLLOUT | POLLWRNORM ;
}
2008-06-30 15:04:50 -03:00
done :
mutex_unlock ( & queue - > mutex ) ;
return mask ;
}
/*
* 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 .
*
2010-10-02 11:06:05 -03:00
* Enabling the video queue returns - EBUSY if the queue is already enabled .
2008-06-30 15:04:50 -03:00
*
* 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 .
*/
int uvc_queue_enable ( struct uvc_video_queue * queue , int enable )
{
unsigned int i ;
int ret = 0 ;
mutex_lock ( & queue - > mutex ) ;
if ( enable ) {
if ( uvc_queue_streaming ( queue ) ) {
ret = - EBUSY ;
goto done ;
}
queue - > flags | = UVC_QUEUE_STREAMING ;
2008-12-28 22:32:29 -03:00
queue - > buf_used = 0 ;
2008-06-30 15:04:50 -03:00
} else {
uvc_queue_cancel ( queue , 0 ) ;
INIT_LIST_HEAD ( & queue - > mainqueue ) ;
2010-06-17 06:52:37 -03:00
for ( i = 0 ; i < queue - > count ; + + i ) {
queue - > buffer [ i ] . error = 0 ;
2008-06-30 15:04:50 -03:00
queue - > buffer [ i ] . state = UVC_BUF_STATE_IDLE ;
2010-06-17 06:52:37 -03:00
}
2008-06-30 15:04:50 -03:00
queue - > flags & = ~ UVC_QUEUE_STREAMING ;
}
done :
mutex_unlock ( & queue - > mutex ) ;
return ret ;
}
/*
* Cancel the video buffers queue .
*
* Cancelling the queue marks all buffers on the irq queue as erroneous ,
2009-01-03 19:12:40 -03:00
* wakes them up and removes them from the queue .
2008-06-30 15:04:50 -03:00
*
* 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 .
*/
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 ;
wake_up ( & buf - > wait ) ;
}
/* 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 ) ;
}
struct uvc_buffer * uvc_queue_next_buffer ( struct uvc_video_queue * queue ,
struct uvc_buffer * buf )
{
struct uvc_buffer * nextbuf ;
unsigned long flags ;
2010-06-17 06:52:37 -03:00
if ( ( queue - > flags & UVC_QUEUE_DROP_CORRUPTED ) & & buf - > error ) {
buf - > error = 0 ;
2008-06-30 15:04:50 -03:00
buf - > state = UVC_BUF_STATE_QUEUED ;
buf - > buf . bytesused = 0 ;
return buf ;
}
spin_lock_irqsave ( & queue - > irqlock , flags ) ;
list_del ( & buf - > queue ) ;
2010-06-17 06:52:37 -03:00
buf - > error = 0 ;
2009-12-16 21:20:45 -03:00
buf - > state = UVC_BUF_STATE_DONE ;
2008-06-30 15:04:50 -03:00
if ( ! list_empty ( & queue - > irqqueue ) )
nextbuf = list_first_entry ( & queue - > irqqueue , struct uvc_buffer ,
queue ) ;
else
nextbuf = NULL ;
spin_unlock_irqrestore ( & queue - > irqlock , flags ) ;
wake_up ( & buf - > wait ) ;
return nextbuf ;
}
2008-07-18 00:50:58 -03:00