|
@@ -854,8 +854,6 @@ static int dvb_usbv2_exit(struct dvb_usb_device *d)
|
|
|
dvb_usbv2_remote_exit(d);
|
|
|
dvb_usbv2_adapter_exit(d);
|
|
|
dvb_usbv2_i2c_exit(d);
|
|
|
- kfree(d->priv);
|
|
|
- kfree(d);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -934,7 +932,7 @@ int dvb_usbv2_probe(struct usb_interface *intf,
|
|
|
if (intf->cur_altsetting->desc.bInterfaceNumber !=
|
|
|
d->props->bInterfaceNumber) {
|
|
|
ret = -ENODEV;
|
|
|
- goto err_free_all;
|
|
|
+ goto err_kfree_d;
|
|
|
}
|
|
|
|
|
|
mutex_init(&d->usb_mutex);
|
|
@@ -946,10 +944,16 @@ int dvb_usbv2_probe(struct usb_interface *intf,
|
|
|
dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
|
|
|
KBUILD_MODNAME);
|
|
|
ret = -ENOMEM;
|
|
|
- goto err_free_all;
|
|
|
+ goto err_kfree_d;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (d->props->probe) {
|
|
|
+ ret = d->props->probe(d);
|
|
|
+ if (ret)
|
|
|
+ goto err_kfree_priv;
|
|
|
+ }
|
|
|
+
|
|
|
if (d->props->identify_state) {
|
|
|
const char *name = NULL;
|
|
|
ret = d->props->identify_state(d, &name);
|
|
@@ -1001,6 +1005,12 @@ exit:
|
|
|
return 0;
|
|
|
err_free_all:
|
|
|
dvb_usbv2_exit(d);
|
|
|
+ if (d->props->disconnect)
|
|
|
+ d->props->disconnect(d);
|
|
|
+err_kfree_priv:
|
|
|
+ kfree(d->priv);
|
|
|
+err_kfree_d:
|
|
|
+ kfree(d);
|
|
|
err:
|
|
|
dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret);
|
|
|
return ret;
|
|
@@ -1021,6 +1031,12 @@ void dvb_usbv2_disconnect(struct usb_interface *intf)
|
|
|
|
|
|
dvb_usbv2_exit(d);
|
|
|
|
|
|
+ if (d->props->disconnect)
|
|
|
+ d->props->disconnect(d);
|
|
|
+
|
|
|
+ kfree(d->priv);
|
|
|
+ kfree(d);
|
|
|
+
|
|
|
pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n",
|
|
|
KBUILD_MODNAME, drvname, devname);
|
|
|
kfree(devname);
|