diff options
author | Gianluca Gennari | 2012-03-22 12:48:17 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab | 2012-04-10 20:46:35 +0200 |
commit | 5f5f147f638734c0739b663aa68a3ae03cdc682b (patch) | |
tree | 04951bcc15af31797c513db3b2c4913cdf6435c6 /drivers/media/video/em28xx/em28xx-core.c | |
parent | [media] usb: gadget/uvc: Remove non-required locking from 'uvc_queue_next_buf... (diff) | |
download | kernel-qcow2-linux-5f5f147f638734c0739b663aa68a3ae03cdc682b.tar.gz kernel-qcow2-linux-5f5f147f638734c0739b663aa68a3ae03cdc682b.tar.xz kernel-qcow2-linux-5f5f147f638734c0739b663aa68a3ae03cdc682b.zip |
[media] em28xx-dvb: stop URBs when stopping the streaming
Stop the URBs in em28xx_stop_streaming(), so that em28xx_irq_callback()
cannot be called after the streaming has stopped.
This should eliminate the crashes reported by Antti Palosaari and the warnings
reported by Andy Furniss.
Signed-off-by: Gianluca Gennari <gennarone@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-core.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 53a9fb91e97e..cbbe399bc77f 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -666,7 +666,6 @@ int em28xx_capture_start(struct em28xx *dev, int start) return rc; } -EXPORT_SYMBOL_GPL(em28xx_capture_start); int em28xx_vbi_supported(struct em28xx *dev) { @@ -1008,6 +1007,31 @@ void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode) EXPORT_SYMBOL_GPL(em28xx_uninit_isoc); /* + * Stop URBs + */ +void em28xx_stop_urbs(struct em28xx *dev) +{ + int i; + struct urb *urb; + struct em28xx_usb_isoc_bufs *isoc_bufs = &dev->isoc_ctl.digital_bufs; + + em28xx_isocdbg("em28xx: called em28xx_stop_urbs\n"); + + for (i = 0; i < isoc_bufs->num_bufs; i++) { + urb = isoc_bufs->urb[i]; + if (urb) { + if (!irqs_disabled()) + usb_kill_urb(urb); + else + usb_unlink_urb(urb); + } + } + + em28xx_capture_start(dev, 0); +} +EXPORT_SYMBOL_GPL(em28xx_stop_urbs); + +/* * Allocate URBs */ int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode, |