[media] dvb_usb_v2: get rid of deferred probe
authorAntti Palosaari <crope@iki.fi>
Tue, 30 Jul 2013 20:22:25 +0000 (17:22 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Sun, 18 Aug 2013 10:55:06 +0000 (07:55 -0300)
Deferred probe was added in order to avoid udev vs. Kernel firmware
download problems. It is not needed anymore.
https://bugzilla.redhat.com/show_bug.cgi?id=827538

Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/usb/dvb-usb-v2/dvb_usb.h
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c

index 399916bd588f709269fffc6f6611b3f87f8c05ad..124b4baa7e975d9ec63ac8c243d3e2741fd8d4c7 100644 (file)
@@ -352,9 +352,7 @@ struct dvb_usb_adapter {
  * @rc_map: name of rc codes table
  * @rc_polling_active: set when RC polling is active
  * @udev: pointer to the device's struct usb_device
- * @intf: pointer to the device's usb interface
  * @rc: remote controller configuration
- * @probe_work: work to defer .probe()
  * @powered: indicated whether the device is power or not
  * @usb_mutex: mutex for usb control messages
  * @i2c_mutex: mutex for i2c-transfers
@@ -370,10 +368,7 @@ struct dvb_usb_device {
        const char *rc_map;
        bool rc_polling_active;
        struct usb_device *udev;
-       struct usb_interface *intf;
        struct dvb_usb_rc rc;
-       struct work_struct probe_work;
-       pid_t work_pid;
        int powered;
 
        /* locking */
index 19f6737d98173e006b47706d2a71bcec2287f365..8a054d66e708449ce6417135eaf4e20e675ac3aa 100644 (file)
@@ -833,20 +833,44 @@ err:
        return ret;
 }
 
-/*
- * udev, which is used for the firmware downloading, requires we cannot
- * block during module_init(). module_init() calls USB probe() which
- * is this routine. Due to that we delay actual operation using workqueue
- * and return always success here.
- */
-static void dvb_usbv2_init_work(struct work_struct *work)
+int dvb_usbv2_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
 {
        int ret;
-       struct dvb_usb_device *d =
-                       container_of(work, struct dvb_usb_device, probe_work);
+       struct dvb_usb_device *d;
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct dvb_usb_driver_info *driver_info =
+                       (struct dvb_usb_driver_info *) id->driver_info;
+
+       dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
+                       intf->cur_altsetting->desc.bInterfaceNumber);
+
+       if (!id->driver_info) {
+               dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME);
+               ret = -ENODEV;
+               goto err;
+       }
+
+       d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
+       if (!d) {
+               dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+               ret = -ENOMEM;
+               goto err;
+       }
 
-       d->work_pid = current->pid;
-       dev_dbg(&d->udev->dev, "%s: work_pid=%d\n", __func__, d->work_pid);
+       d->name = driver_info->name;
+       d->rc_map = driver_info->rc_map;
+       d->udev = udev;
+       d->props = driver_info->props;
+
+       if (intf->cur_altsetting->desc.bInterfaceNumber !=
+                       d->props->bInterfaceNumber) {
+               ret = -ENODEV;
+               goto err_free_all;
+       }
+
+       mutex_init(&d->usb_mutex);
+       mutex_init(&d->i2c_mutex);
 
        if (d->props->size_of_priv) {
                d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL);
@@ -854,7 +878,7 @@ static void dvb_usbv2_init_work(struct work_struct *work)
                        dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
                                        KBUILD_MODNAME);
                        ret = -ENOMEM;
-                       goto err_usb_driver_release_interface;
+                       goto err_free_all;
                }
        }
 
@@ -884,20 +908,12 @@ static void dvb_usbv2_init_work(struct work_struct *work)
                                 * device. As 'new' device is warm we should
                                 * never go here again.
                                 */
-                               return;
+                               goto exit;
                        } else {
-                               /*
-                                * Unexpected 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;
+                               goto err_free_all;
                        }
                } else {
-                       goto err_usb_driver_release_interface;
+                       goto err_free_all;
                }
        }
 
@@ -906,73 +922,17 @@ static void dvb_usbv2_init_work(struct work_struct *work)
 
        ret = dvb_usbv2_init(d);
        if (ret < 0)
-               goto err_usb_driver_release_interface;
+               goto err_free_all;
 
        dev_info(&d->udev->dev,
                        "%s: '%s' successfully initialized and connected\n",
                        KBUILD_MODNAME, d->name);
-
-       return;
-err_usb_driver_release_interface:
-       dev_info(&d->udev->dev, "%s: '%s' error while loading driver (%d)\n",
-                       KBUILD_MODNAME, d->name, ret);
-       usb_driver_release_interface(to_usb_driver(d->intf->dev.driver),
-                       d->intf);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return;
-}
-
-int dvb_usbv2_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       int ret;
-       struct dvb_usb_device *d;
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct dvb_usb_driver_info *driver_info =
-                       (struct dvb_usb_driver_info *) id->driver_info;
-
-       dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
-                       intf->cur_altsetting->desc.bInterfaceNumber);
-
-       if (!id->driver_info) {
-               dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME);
-               ret = -ENODEV;
-               goto err;
-       }
-
-       d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
-       if (!d) {
-               dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       d->name = driver_info->name;
-       d->rc_map = driver_info->rc_map;
-       d->udev = udev;
-       d->intf = intf;
-       d->props = driver_info->props;
-
-       if (d->intf->cur_altsetting->desc.bInterfaceNumber !=
-                       d->props->bInterfaceNumber) {
-               ret = -ENODEV;
-               goto err_kfree;
-       }
-
-       mutex_init(&d->usb_mutex);
-       mutex_init(&d->i2c_mutex);
-       INIT_WORK(&d->probe_work, dvb_usbv2_init_work);
+exit:
        usb_set_intfdata(intf, d);
-       ret = schedule_work(&d->probe_work);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: schedule_work() failed\n",
-                               KBUILD_MODNAME);
-               goto err_kfree;
-       }
 
        return 0;
-err_kfree:
-       kfree(d);
+err_free_all:
+       dvb_usbv2_exit(d);
 err:
        dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret);
        return ret;
@@ -984,12 +944,8 @@ void dvb_usbv2_disconnect(struct usb_interface *intf)
        struct dvb_usb_device *d = usb_get_intfdata(intf);
        const char *name = d->name;
        struct device dev = d->udev->dev;
-       dev_dbg(&d->udev->dev, "%s: pid=%d work_pid=%d\n", __func__,
-                       current->pid, d->work_pid);
-
-       /* ensure initialization work is finished until release resources */
-       if (d->work_pid != current->pid)
-               cancel_work_sync(&d->probe_work);
+       dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
+                       intf->cur_altsetting->desc.bInterfaceNumber);
 
        if (d->props->exit)
                d->props->exit(d);