[media] dvb_usb_v2: do not release USB interface when device reconnects
authorAntti Palosaari <crope@iki.fi>
Thu, 14 Jun 2012 23:07:02 +0000 (20:07 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 4 Aug 2012 10:56:32 +0000 (07:56 -0300)
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>
drivers/media/dvb/dvb-usb/dvb_usb_init.c

index 0ac1a72..e9bb006 100644 (file)
@@ -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);