@ -260,6 +260,7 @@ struct s2255_dev {
atomic_t num_channels ;
int frames ;
struct mutex lock ; /* channels[].vdev.lock */
struct mutex cmdlock ; /* protects cmdbuf */
struct usb_device * udev ;
struct usb_interface * interface ;
u8 read_endpoint ;
@ -273,6 +274,8 @@ struct s2255_dev {
/* dsp firmware version (f2255usb.bin) */
int dsp_fw_ver ;
u16 pid ; /* product id */
# define S2255_CMDBUF_SIZE 512
__le32 * cmdbuf ;
} ;
static inline struct s2255_dev * to_s2255_dev ( struct v4l2_device * v4l2_dev )
@ -1121,11 +1124,12 @@ static int s2255_set_mode(struct s2255_vc *vc,
struct s2255_mode * mode )
{
int res ;
__le32 * buffer ;
unsigned long chn_rev ;
struct s2255_dev * dev = to_s2255_dev ( vc - > vdev . v4l2_dev ) ;
int i ;
__le32 * buffer = dev - > cmdbuf ;
mutex_lock ( & dev - > cmdlock ) ;
chn_rev = G_chnmap [ vc - > idx ] ;
dprintk ( dev , 3 , " %s channel: %d \n " , __func__ , vc - > idx ) ;
/* if JPEG, set the quality */
@ -1139,11 +1143,6 @@ static int s2255_set_mode(struct s2255_vc *vc,
vc - > mode = * mode ;
vc - > req_image_size = get_transfer_size ( mode ) ;
dprintk ( dev , 1 , " %s: reqsize %ld \n " , __func__ , vc - > req_image_size ) ;
buffer = kzalloc ( 512 , GFP_KERNEL ) ;
if ( buffer = = NULL ) {
dev_err ( & dev - > udev - > dev , " out of mem \n " ) ;
return - ENOMEM ;
}
/* set the mode */
buffer [ 0 ] = IN_DATA_TOKEN ;
buffer [ 1 ] = ( __le32 ) cpu_to_le32 ( chn_rev ) ;
@ -1154,7 +1153,6 @@ static int s2255_set_mode(struct s2255_vc *vc,
res = s2255_write_config ( dev - > udev , ( unsigned char * ) buffer , 512 ) ;
if ( debug )
s2255_print_cfg ( dev , mode ) ;
kfree ( buffer ) ;
/* wait at least 3 frames before continuing */
if ( mode - > restart ) {
wait_event_timeout ( vc - > wait_setmode ,
@ -1168,22 +1166,20 @@ static int s2255_set_mode(struct s2255_vc *vc,
/* clear the restart flag */
vc - > mode . restart = 0 ;
dprintk ( dev , 1 , " %s chn %d, result: %d \n " , __func__ , vc - > idx , res ) ;
mutex_unlock ( & dev - > cmdlock ) ;
return res ;
}
static int s2255_cmd_status ( struct s2255_vc * vc , u32 * pstatus )
{
int res ;
__le32 * buffer ;
u32 chn_rev ;
struct s2255_dev * dev = to_s2255_dev ( vc - > vdev . v4l2_dev ) ;
__le32 * buffer = dev - > cmdbuf ;
mutex_lock ( & dev - > cmdlock ) ;
chn_rev = G_chnmap [ vc - > idx ] ;
dprintk ( dev , 4 , " %s chan %d \n " , __func__ , vc - > idx ) ;
buffer = kzalloc ( 512 , GFP_KERNEL ) ;
if ( buffer = = NULL ) {
dev_err ( & dev - > udev - > dev , " out of mem \n " ) ;
return - ENOMEM ;
}
/* form the get vid status command */
buffer [ 0 ] = IN_DATA_TOKEN ;
buffer [ 1 ] = ( __le32 ) cpu_to_le32 ( chn_rev ) ;
@ -1191,7 +1187,6 @@ static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
* pstatus = 0 ;
vc - > vidstatus_ready = 0 ;
res = s2255_write_config ( dev - > udev , ( unsigned char * ) buffer , 512 ) ;
kfree ( buffer ) ;
wait_event_timeout ( vc - > wait_vidstatus ,
( vc - > vidstatus_ready ! = 0 ) ,
msecs_to_jiffies ( S2255_VIDSTATUS_TIMEOUT ) ) ;
@ -1201,6 +1196,7 @@ static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
}
* pstatus = vc - > vidstatus ;
dprintk ( dev , 4 , " %s, vid status %d \n " , __func__ , * pstatus ) ;
mutex_unlock ( & dev - > cmdlock ) ;
return res ;
}
@ -1724,6 +1720,7 @@ static void s2255_destroy(struct s2255_dev *dev)
mutex_destroy ( & dev - > lock ) ;
usb_put_dev ( dev - > udev ) ;
v4l2_device_unregister ( & dev - > v4l2_dev ) ;
kfree ( dev - > cmdbuf ) ;
kfree ( dev ) ;
}
@ -2350,18 +2347,14 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
/* starts acquisition process */
static int s2255_start_acquire ( struct s2255_vc * vc )
{
unsigned char * buffer ;
int res ;
unsigned long chn_rev ;
int j ;
struct s2255_dev * dev = to_s2255_dev ( vc - > vdev . v4l2_dev ) ;
chn_rev = G_chnmap [ vc - > idx ] ;
buffer = kzalloc ( 512 , GFP_KERNEL ) ;
if ( buffer = = NULL ) {
dev_err ( & dev - > udev - > dev , " out of mem \n " ) ;
return - ENOMEM ;
}
__le32 * buffer = dev - > cmdbuf ;
mutex_lock ( & dev - > cmdlock ) ;
chn_rev = G_chnmap [ vc - > idx ] ;
vc - > last_frame = - 1 ;
vc - > bad_payload = 0 ;
vc - > cur_frame = 0 ;
@ -2371,24 +2364,26 @@ static int s2255_start_acquire(struct s2255_vc *vc)
}
/* send the start command */
* ( __le32 * ) buffer = IN_DATA_TOKEN ;
* ( ( __le32 * ) buffer + 1 ) = ( __le32 ) cpu_to_le32 ( chn_rev ) ;
* ( ( __le32 * ) buffer + 2 ) = CMD_START ;
buffer [ 0 ] = IN_DATA_TOKEN ;
buffer [ 1 ] = ( __le32 ) cpu_to_le32 ( chn_rev ) ;
buffer [ 2 ] = CMD_START ;
res = s2255_write_config ( dev - > udev , ( unsigned char * ) buffer , 512 ) ;
if ( res ! = 0 )
dev_err ( & dev - > udev - > dev , " CMD_START error \n " ) ;
dprintk ( dev , 2 , " start acquire exit[%d] %d \n " , vc - > idx , res ) ;
kfree ( buffer ) ;
mutex_unlock ( & dev - > cmdlock ) ;
return 0 ;
}
static int s2255_stop_acquire ( struct s2255_vc * vc )
{
unsigned char * buffer ;
int res ;
unsigned long chn_rev ;
struct s2255_dev * dev = to_s2255_dev ( vc - > vdev . v4l2_dev ) ;
__le32 * buffer = dev - > cmdbuf ;
mutex_lock ( & dev - > cmdlock ) ;
chn_rev = G_chnmap [ vc - > idx ] ;
buffer = kzalloc ( 512 , GFP_KERNEL ) ;
if ( buffer = = NULL ) {
@ -2396,15 +2391,17 @@ static int s2255_stop_acquire(struct s2255_vc *vc)
return - ENOMEM ;
}
/* send the stop command */
* ( __le32 * ) buffer = IN_DATA_TOKEN ;
* ( ( __le32 * ) buffer + 1 ) = ( __le32 ) cpu_to_le32 ( chn_rev ) ;
* ( ( __le32 * ) buffer + 2 ) = CMD_STOP ;
buffer [ 0 ] = IN_DATA_TOKEN ;
buffer [ 1 ] = ( __le32 ) cpu_to_le32 ( chn_rev ) ;
buffer [ 2 ] = CMD_STOP ;
res = s2255_write_config ( dev - > udev , ( unsigned char * ) buffer , 512 ) ;
if ( res ! = 0 )
dev_err ( & dev - > udev - > dev , " CMD_STOP error \n " ) ;
kfree ( buffer ) ;
vc - > b_acquire = 0 ;
dprintk ( dev , 4 , " %s: chn %d, res %d \n " , __func__ , vc - > idx , res ) ;
mutex_unlock ( & dev - > cmdlock ) ;
return res ;
}
@ -2451,18 +2448,27 @@ static int s2255_probe(struct usb_interface *interface,
int retval = - ENOMEM ;
__le32 * pdata ;
int fw_size ;
/* allocate memory for our device state and initialize it to zero */
dev = kzalloc ( sizeof ( struct s2255_dev ) , GFP_KERNEL ) ;
if ( dev = = NULL ) {
s2255_dev_err ( & interface - > dev , " out of memory \n " ) ;
return - ENOMEM ;
}
dev - > cmdbuf = kzalloc ( S2255_CMDBUF_SIZE , GFP_KERNEL ) ;
if ( dev - > cmdbuf = = NULL ) {
s2255_dev_err ( & interface - > dev , " out of memory \n " ) ;
return - ENOMEM ;
}
atomic_set ( & dev - > num_channels , 0 ) ;
dev - > pid = le16_to_cpu ( id - > idProduct ) ;
dev - > fw_data = kzalloc ( sizeof ( struct s2255_fw ) , GFP_KERNEL ) ;
if ( ! dev - > fw_data )
goto errorFWDATA1 ;
mutex_init ( & dev - > lock ) ;
mutex_init ( & dev - > cmdlock ) ;
/* grab usb_device and save it */
dev - > udev = usb_get_dev ( interface_to_usbdev ( interface ) ) ;
if ( dev - > udev = = NULL ) {
@ -2568,6 +2574,7 @@ errorUDEV:
kfree ( dev - > fw_data ) ;
mutex_destroy ( & dev - > lock ) ;
errorFWDATA1 :
kfree ( dev - > cmdbuf ) ;
kfree ( dev ) ;
pr_warn ( " Sensoray 2255 driver load failed: 0x%x \n " , retval ) ;
return retval ;