summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2012-06-15 01:07:02 +0200
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-04 12:56:32 +0200
commitffe4ac92ee5a4a0a236b9583c3173902e158e14b (patch)
treed99f699360823a2a560951705f3e2905ace06abb /drivers/media/dvb
parent[media] dvb_usb_v2: return the download ret in dvb_usb_download_firmware (diff)
downloadlinux-ffe4ac92ee5a4a0a236b9583c3173902e158e14b.tar.xz
linux-ffe4ac92ee5a4a0a236b9583c3173902e158e14b.zip
[media] dvb_usb_v2: do not release USB interface when device reconnects
USB core will call disconnect and remove driver for us as device will disconnect itself. After that it is loaded again as a new device but it is warm and no firmware loading needed. Reported-by: Malcolm Priestley <tvboxspy@gmail.com> Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/dvb-usb/dvb_usb_init.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_init.c b/drivers/media/dvb/dvb-usb/dvb_usb_init.c
index 0ac1a72a7d81..e9bb006bb725 100644
--- a/drivers/media/dvb/dvb-usb/dvb_usb_init.c
+++ b/drivers/media/dvb/dvb-usb/dvb_usb_init.c
@@ -431,11 +431,24 @@ static void dvb_usbv2_init_work(struct work_struct *work)
KBUILD_MODNAME, d->name);
ret = dvb_usbv2_download_firmware(d);
if (ret == 0) {
+ /* device is warm, continue initialization */
;
} else if (ret == RECONNECTS_USB) {
- ret = 0;
- goto exit_usb_driver_release_interface;
+ /*
+ * USB core will call disconnect() and then probe()
+ * as device reconnects itself from the USB bus.
+ * disconnect() will release all driver resources
+ * and probe() is called for 'new' device. As 'new'
+ * device is warm we should never go here again.
+ */
+ return;
} else {
+ /* Unexpected fatal error. We must unregister driver
+ * manually from the device, because device is already
+ * register by returning from probe() with success.
+ * usb_driver_release_interface() finally calls
+ * disconnect() in order to free resources.
+ */
goto err_usb_driver_release_interface;
}
}
@@ -453,8 +466,7 @@ static void dvb_usbv2_init_work(struct work_struct *work)
err_usb_driver_release_interface:
pr_info("%s: '%s' error while loading driver (%d)\n", KBUILD_MODNAME,
d->name, ret);
-exit_usb_driver_release_interface:
- /* it finally calls .disconnect() which frees mem */
+ /* it finally calls disconnect() which frees mem */
usb_driver_release_interface(to_usb_driver(d->intf->dev.driver),
d->intf);
pr_debug("%s: failed=%d\n", __func__, ret);