Commit 36b6ca01 authored by Jeroen Vreeken's avatar Jeroen Vreeken Committed by Greg Kroah-Hartman

[PATCH] USB: se401 driver update

parent d2ce5064
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* - Jeroen Vreeken * - Jeroen Vreeken
*/ */
static const char version[] = "0.23"; static const char version[] = "0.24";
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -980,6 +980,34 @@ static int se401_newframe(struct usb_se401 *se401, int framenr) ...@@ -980,6 +980,34 @@ static int se401_newframe(struct usb_se401 *se401, int framenr)
return 0; return 0;
} }
static void usb_se401_remove_disconnected (struct usb_se401 *se401)
{
int i;
se401->dev = NULL;
for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
usb_unlink_urb(se401->urb[i]);
usb_free_urb(se401->urb[i]);
se401->urb[i] = NULL;
kfree(se401->sbuf[i].data);
}
for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
kfree(se401->scratch[i].data);
}
if (se401->inturb) {
usb_unlink_urb(se401->inturb);
usb_free_urb(se401->inturb);
}
info("%s disconnected", se401->camera_name);
/* Free the memory */
kfree(se401->width);
kfree(se401->height);
kfree(se401);
}
/**************************************************************************** /****************************************************************************
* *
...@@ -1015,20 +1043,16 @@ static int se401_close(struct inode *inode, struct file *file) ...@@ -1015,20 +1043,16 @@ static int se401_close(struct inode *inode, struct file *file)
struct usb_se401 *se401 = (struct usb_se401 *)dev; struct usb_se401 *se401 = (struct usb_se401 *)dev;
int i; int i;
for (i=0; i<SE401_NUMFRAMES; i++)
se401->frame[i].grabstate=FRAME_UNUSED;
if (se401->streaming)
se401_stop_stream(se401);
rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES); rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
se401->user=0;
if (se401->removed) { if (se401->removed) {
kfree(se401->width); usb_se401_remove_disconnected(se401);
kfree(se401->height);
kfree(se401);
se401 = NULL;
info("device unregistered"); info("device unregistered");
} else {
for (i=0; i<SE401_NUMFRAMES; i++)
se401->frame[i].grabstate=FRAME_UNUSED;
if (se401->streaming)
se401_stop_stream(se401);
se401->user=0;
} }
file->private_data = NULL; file->private_data = NULL;
return 0; return 0;
...@@ -1302,7 +1326,7 @@ static struct video_device se401_template = { ...@@ -1302,7 +1326,7 @@ static struct video_device se401_template = {
/***************************/ /***************************/
static int se401_init(struct usb_se401 *se401) static int se401_init(struct usb_se401 *se401, int button)
{ {
int i=0, rc; int i=0, rc;
unsigned char cp[0x40]; unsigned char cp[0x40];
...@@ -1367,22 +1391,25 @@ static int se401_init(struct usb_se401 *se401) ...@@ -1367,22 +1391,25 @@ static int se401_init(struct usb_se401 *se401)
se401->readcount=0; se401->readcount=0;
/* Start interrupt transfers for snapshot button */ /* Start interrupt transfers for snapshot button */
se401->inturb=usb_alloc_urb(0, GFP_KERNEL); if (button) {
if (!se401->inturb) { se401->inturb=usb_alloc_urb(0, GFP_KERNEL);
info("Allocation of inturb failed"); if (!se401->inturb) {
return 1; info("Allocation of inturb failed");
} return 1;
FILL_INT_URB(se401->inturb, se401->dev, }
usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT), FILL_INT_URB(se401->inturb, se401->dev,
&se401->button, sizeof(se401->button), usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
se401_button_irq, &se401->button, sizeof(se401->button),
se401, se401_button_irq,
HZ/10 se401,
); HZ/10
if (usb_submit_urb(se401->inturb, GFP_KERNEL)) { );
info("int urb burned down"); if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
return 1; info("int urb burned down");
} return 1;
}
} else
se401->inturb=NULL;
/* Flash the led */ /* Flash the led */
se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
...@@ -1399,6 +1426,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1399,6 +1426,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum,
struct usb_interface_descriptor *interface; struct usb_interface_descriptor *interface;
struct usb_se401 *se401; struct usb_se401 *se401;
char *camera_name=NULL; char *camera_name=NULL;
int button=1;
/* We don't handle multi-config cameras */ /* We don't handle multi-config cameras */
if (dev->descriptor.bNumConfigurations != 1) if (dev->descriptor.bNumConfigurations != 1)
...@@ -1422,6 +1450,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1422,6 +1450,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum,
} else if (dev->descriptor.idVendor == 0x047d && } else if (dev->descriptor.idVendor == 0x047d &&
dev->descriptor.idProduct == 0x5003) { dev->descriptor.idProduct == 0x5003) {
camera_name="Kensington VideoCAM 67016"; camera_name="Kensington VideoCAM 67016";
button=0;
} else } else
return NULL; return NULL;
...@@ -1447,7 +1476,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1447,7 +1476,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum,
info("firmware version: %02x", dev->descriptor.bcdDevice & 255); info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
if (se401_init(se401)) { if (se401_init(se401, button)) {
kfree(se401); kfree(se401);
return NULL; return NULL;
} }
...@@ -1479,45 +1508,18 @@ static void se401_disconnect(struct usb_device *dev, void *ptr) ...@@ -1479,45 +1508,18 @@ static void se401_disconnect(struct usb_device *dev, void *ptr)
if (!se401->user){ if (!se401->user){
usb_se401_remove_disconnected(se401); usb_se401_remove_disconnected(se401);
} else { } else {
se401->removed = 1; se401->frame[0].grabstate = FRAME_ERROR;
} se401->frame[0].grabstate = FRAME_ERROR;
}
static inline void usb_se401_remove_disconnected (struct usb_se401 *se401) se401->streaming = 0;
{
int i; wake_up_interruptible(&se401->wq);
se401->removed = 1;
se401->dev = NULL;
se401->frame[0].grabstate = FRAME_ERROR;
se401->frame[1].grabstate = FRAME_ERROR;
se401->streaming = 0;
wake_up_interruptible(&se401->wq);
for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
usb_unlink_urb(se401->urb[i]);
usb_free_urb(se401->urb[i]);
se401->urb[i] = NULL;
kfree(se401->sbuf[i].data);
}
for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
kfree(se401->scratch[i].data);
}
if (se401->inturb) {
usb_unlink_urb(se401->inturb);
usb_free_urb(se401->inturb);
} }
info("%s disconnected", se401->camera_name);
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
destroy_proc_se401_cam(se401); destroy_proc_se401_cam(se401);
#endif #endif
/* Free the memory */
kfree(se401->width);
kfree(se401->height);
kfree(se401);
} }
static struct usb_driver se401_driver = { static struct usb_driver se401_driver = {
......
...@@ -230,7 +230,6 @@ struct usb_se401 { ...@@ -230,7 +230,6 @@ struct usb_se401 {
int nullpackets; int nullpackets;
}; };
static inline void usb_se401_remove_disconnected (struct usb_se401 *se401);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment