diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-04 09:31:17 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-04 09:31:17 -0200 |
commit | 5e1b3cc0c50bf6b78f02a77a0ea8ce2a4ee40778 (patch) | |
tree | b2ffcd269e2fe1c81591fadb2a4bbda976d1af57 | |
parent | f3f744132ca77a71b257af56347c7c4747d3c63e (diff) | |
download | mediapointer-dvb-s2-5e1b3cc0c50bf6b78f02a77a0ea8ce2a4ee40778.tar.gz mediapointer-dvb-s2-5e1b3cc0c50bf6b78f02a77a0ea8ce2a4ee40778.tar.bz2 |
Usbvision_v4l2 robustness on disconnect
From: Thierry <thierry.merle@free.fr>
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
Signed-off-by: Thierry MERLE <thierry.merle@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | linux/drivers/media/video/usbvision/usbvision-core.c | 17 | ||||
-rw-r--r-- | linux/drivers/media/video/usbvision/usbvision.h | 7 |
2 files changed, 12 insertions, 12 deletions
diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c index c3f9e470a..df8c07b8d 100644 --- a/linux/drivers/media/video/usbvision/usbvision-core.c +++ b/linux/drivers/media/video/usbvision/usbvision-core.c @@ -2347,7 +2347,7 @@ static void usbvision_isocIrq(struct urb *urb, struct pt_regs *regs) /* 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(struct usb_usbvision *usbvision) 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 usb_usbvision *usbvision) } } - 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 usb_usbvision *usbvision) { 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(struct inode *inode, struct file *file, 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(struct usb_interface *intf, const struct us 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_disconnect(struct usb_interface *intf) #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 --git a/linux/drivers/media/video/usbvision/usbvision.h b/linux/drivers/media/video/usbvision/usbvision.h index e9bfe5c92..3ef18a4ed 100644 --- a/linux/drivers/media/video/usbvision/usbvision.h +++ b/linux/drivers/media/video/usbvision/usbvision.h @@ -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 { |