----- Forwarded Message ----
From: Thierry <[EMAIL PROTECTED]>
To: Linux and Kernel Video <[email protected]>
Sent: Friday, November 10, 2006 2:18:12 AM
Subject: [PATCH] usbvision_v4l2 robustness on disconnect
From: Thierry <[EMAIL PROTECTED]>
To: Linux and Kernel Video <[email protected]>
Sent: Friday, November 10, 2006 2:18:12 AM
Subject: [PATCH] usbvision_v4l2 robustness on disconnect
Hello,
this patch corrects 2 bugs (causes kernel oops) that occur when
unplugging the peripheral whereas nobody has opened it yet :
- do not call usbvision_stop_isoc if usbvision_init_isoc has not been called
- do not call wakeup_interruptible on waitqueues that did not have been
initialized with init_waitqueue_head
Cheers,
Thierry
Signed-off-by: Thierry MERLE <[EMAIL PROTECTED]>
---
this patch corrects 2 bugs (causes kernel oops) that occur when
unplugging the peripheral whereas nobody has opened it yet :
- do not call usbvision_stop_isoc if usbvision_init_isoc has not been called
- do not call wakeup_interruptible on waitqueues that did not have been
initialized with init_waitqueue_head
Cheers,
Thierry
Signed-off-by: Thierry MERLE <[EMAIL PROTECTED]>
---
diff -r 2ed79285f83d linux/drivers/media/video/usbvision/usbvision-core.c
--- a/linux/drivers/media/video/usbvision/usbvision-core.c Wed Nov 08 22:48:37 2006 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c Fri Nov 10 07:01:57 2006 +0000
@@ -2347,7 +2347,7 @@ static void usbvision_isocIrq(struct urb
/* Manage streaming interruption */
if (usbvision->streaming == Stream_Interrupt) {
- usbvision->streaming = Stream_Off;
+ usbvision->streaming = Stream_Idle;
if ((*f)) {
(*f)->grabstate = FrameState_Ready;
(*f)->scanstate = ScanState_Scanning;
@@ -3244,7 +3244,7 @@ static int usbvision_stream_interrupt(st
usbvision->streaming = Stream_Interrupt;
ret = wait_event_timeout(usbvision->wait_stream,
- (usbvision->streaming == Stream_Off),
+ (usbvision->streaming == Stream_Idle),
msecs_to_jiffies(USBVISION_NUMSBUF*USBVISION_URB_FRAMES));
return ret;
}
@@ -3770,7 +3770,7 @@ static int usbvision_init_isoc(struct us
}
}
- usbvision->streaming = Stream_On;
+ usbvision->streaming = Stream_Idle;
PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp);
return 0;
}
@@ -3786,8 +3786,7 @@ static void usbvision_stop_isoc(struct u
{
int bufIdx, errCode, regValue;
- // FIXME : removed the streaming==Stream_Off. This field has not the same signification than before !
- if (usbvision->dev == NULL)
+ if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
return;
/* Unschedule all of the iso td's */
@@ -4547,7 +4546,7 @@ static int usbvision_v4l2_do_ioctl(struc
return -EINVAL;
if (list_empty(&(usbvision->outqueue))) {
- if (usbvision->streaming == Stream_Off)
+ if (usbvision->streaming == Stream_Idle)
return -EINVAL;
ret = wait_event_interruptible
(usbvision->wait_frame,
@@ -6101,6 +6100,7 @@ static int __devinit usbvision_probe(str
usbvision->isocPacketSize = 0;
usbvision->usb_bandwidth = 0;
usbvision->user = 0;
+ usbvision->streaming = Stream_Off;
usbvision_register_video(usbvision);
usbvision_configure_video(usbvision);
@@ -6168,13 +6168,12 @@ static void __devexit usbvision_disconne
#endif
usbvision->dev = NULL; // USB device is no more
- wake_up_interruptible(&usbvision->wait_frame);
- wake_up_interruptible(&usbvision->wait_stream);
-
up(&usbvision->lock);
if (usbvision->user) {
info("%s: In use, disconnect pending", __FUNCTION__);
+ wake_up_interruptible(&usbvision->wait_frame);
+ wake_up_interruptible(&usbvision->wait_stream);
}
else {
usbvision_release(usbvision);
diff -r 2ed79285f83d linux/drivers/media/video/usbvision/usbvision.h
--- a/linux/drivers/media/video/usbvision/usbvision.h Wed Nov 08 22:48:37 2006 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision.h Fri Nov 10 07:08:22 2006 +0000
@@ -265,9 +265,10 @@ enum FrameState {
/* stream states */
enum StreamState {
- Stream_Off,
- Stream_Interrupt,
- Stream_On,
+ Stream_Off, /* Driver streaming is completely OFF */
+ Stream_Idle, /* Driver streaming is ready to be put ON by the application */
+ Stream_Interrupt, /* Driver streaming must be interrupted */
+ Stream_On, /* Driver streaming is put ON by the application */
};
enum IsocState {
--- a/linux/drivers/media/video/usbvision/usbvision-core.c Wed Nov 08 22:48:37 2006 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c Fri Nov 10 07:01:57 2006 +0000
@@ -2347,7 +2347,7 @@ static void usbvision_isocIrq(struct urb
/* Manage streaming interruption */
if (usbvision->streaming == Stream_Interrupt) {
- usbvision->streaming = Stream_Off;
+ usbvision->streaming = Stream_Idle;
if ((*f)) {
(*f)->grabstate = FrameState_Ready;
(*f)->scanstate = ScanState_Scanning;
@@ -3244,7 +3244,7 @@ static int usbvision_stream_interrupt(st
usbvision->streaming = Stream_Interrupt;
ret = wait_event_timeout(usbvision->wait_stream,
- (usbvision->streaming == Stream_Off),
+ (usbvision->streaming == Stream_Idle),
msecs_to_jiffies(USBVISION_NUMSBUF*USBVISION_URB_FRAMES));
return ret;
}
@@ -3770,7 +3770,7 @@ static int usbvision_init_isoc(struct us
}
}
- usbvision->streaming = Stream_On;
+ usbvision->streaming = Stream_Idle;
PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp);
return 0;
}
@@ -3786,8 +3786,7 @@ static void usbvision_stop_isoc(struct u
{
int bufIdx, errCode, regValue;
- // FIXME : removed the streaming==Stream_Off. This field has not the same signification than before !
- if (usbvision->dev == NULL)
+ if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
return;
/* Unschedule all of the iso td's */
@@ -4547,7 +4546,7 @@ static int usbvision_v4l2_do_ioctl(struc
return -EINVAL;
if (list_empty(&(usbvision->outqueue))) {
- if (usbvision->streaming == Stream_Off)
+ if (usbvision->streaming == Stream_Idle)
return -EINVAL;
ret = wait_event_interruptible
(usbvision->wait_frame,
@@ -6101,6 +6100,7 @@ static int __devinit usbvision_probe(str
usbvision->isocPacketSize = 0;
usbvision->usb_bandwidth = 0;
usbvision->user = 0;
+ usbvision->streaming = Stream_Off;
usbvision_register_video(usbvision);
usbvision_configure_video(usbvision);
@@ -6168,13 +6168,12 @@ static void __devexit usbvision_disconne
#endif
usbvision->dev = NULL; // USB device is no more
- wake_up_interruptible(&usbvision->wait_frame);
- wake_up_interruptible(&usbvision->wait_stream);
-
up(&usbvision->lock);
if (usbvision->user) {
info("%s: In use, disconnect pending", __FUNCTION__);
+ wake_up_interruptible(&usbvision->wait_frame);
+ wake_up_interruptible(&usbvision->wait_stream);
}
else {
usbvision_release(usbvision);
diff -r 2ed79285f83d linux/drivers/media/video/usbvision/usbvision.h
--- a/linux/drivers/media/video/usbvision/usbvision.h Wed Nov 08 22:48:37 2006 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision.h Fri Nov 10 07:08:22 2006 +0000
@@ -265,9 +265,10 @@ enum FrameState {
/* stream states */
enum StreamState {
- Stream_Off,
- Stream_Interrupt,
- Stream_On,
+ Stream_Off, /* Driver streaming is completely OFF */
+ Stream_Idle, /* Driver streaming is ready to be put ON by the application */
+ Stream_Interrupt, /* Driver streaming must be interrupted */
+ Stream_On, /* Driver streaming is put ON by the application */
};
enum IsocState {
--
video4linux-list mailing list
Unsubscribe mailto:[EMAIL PROTECTED]
https://www.redhat.com/mailman/listinfo/video4linux-list
video4linux-list mailing list
Unsubscribe mailto:[EMAIL PROTECTED]
https://www.redhat.com/mailman/listinfo/video4linux-list
diff -r 2ed79285f83d linux/drivers/media/video/usbvision/usbvision-core.c
--- a/linux/drivers/media/video/usbvision/usbvision-core.c Wed Nov 08 22:48:37 2006 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c Fri Nov 10 07:01:57 2006 +0000
@@ -2347,7 +2347,7 @@ static void usbvision_isocIrq(struct urb
/* Manage streaming interruption */
if (usbvision->streaming == Stream_Interrupt) {
- usbvision->streaming = Stream_Off;
+ usbvision->streaming = Stream_Idle;
if ((*f)) {
(*f)->grabstate = FrameState_Ready;
(*f)->scanstate = ScanState_Scanning;
@@ -3244,7 +3244,7 @@ static int usbvision_stream_interrupt(st
usbvision->streaming = Stream_Interrupt;
ret = wait_event_timeout(usbvision->wait_stream,
- (usbvision->streaming == Stream_Off),
+ (usbvision->streaming == Stream_Idle),
msecs_to_jiffies(USBVISION_NUMSBUF*USBVISION_URB_FRAMES));
return ret;
}
@@ -3770,7 +3770,7 @@ static int usbvision_init_isoc(struct us
}
}
- usbvision->streaming = Stream_On;
+ usbvision->streaming = Stream_Idle;
PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp);
return 0;
}
@@ -3786,8 +3786,7 @@ static void usbvision_stop_isoc(struct u
{
int bufIdx, errCode, regValue;
- // FIXME : removed the streaming==Stream_Off. This field has not the same signification than before !
- if (usbvision->dev == NULL)
+ if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
return;
/* Unschedule all of the iso td's */
@@ -4547,7 +4546,7 @@ static int usbvision_v4l2_do_ioctl(struc
return -EINVAL;
if (list_empty(&(usbvision->outqueue))) {
- if (usbvision->streaming == Stream_Off)
+ if (usbvision->streaming == Stream_Idle)
return -EINVAL;
ret = wait_event_interruptible
(usbvision->wait_frame,
@@ -6101,6 +6100,7 @@ static int __devinit usbvision_probe(str
usbvision->isocPacketSize = 0;
usbvision->usb_bandwidth = 0;
usbvision->user = 0;
+ usbvision->streaming = Stream_Off;
usbvision_register_video(usbvision);
usbvision_configure_video(usbvision);
@@ -6168,13 +6168,12 @@ static void __devexit usbvision_disconne
#endif
usbvision->dev = NULL; // USB device is no more
- wake_up_interruptible(&usbvision->wait_frame);
- wake_up_interruptible(&usbvision->wait_stream);
-
up(&usbvision->lock);
if (usbvision->user) {
info("%s: In use, disconnect pending", __FUNCTION__);
+ wake_up_interruptible(&usbvision->wait_frame);
+ wake_up_interruptible(&usbvision->wait_stream);
}
else {
usbvision_release(usbvision);
diff -r 2ed79285f83d linux/drivers/media/video/usbvision/usbvision.h
--- a/linux/drivers/media/video/usbvision/usbvision.h Wed Nov 08 22:48:37 2006 -0200
+++ b/linux/drivers/media/video/usbvision/usbvision.h Fri Nov 10 07:08:22 2006 +0000
@@ -265,9 +265,10 @@ enum FrameState {
/* stream states */
enum StreamState {
- Stream_Off,
- Stream_Interrupt,
- Stream_On,
+ Stream_Off, /* Driver streaming is completely OFF */
+ Stream_Idle, /* Driver streaming is ready to be put ON by the application */
+ Stream_Interrupt, /* Driver streaming must be interrupted */
+ Stream_On, /* Driver streaming is put ON by the application */
};
enum IsocState {_______________________________________________ linux-dvb mailing list [email protected] http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb
