[media] em28xx: clean up resources should init fail

This patch ensures that the em28xx_init_dev() function cleans up after itself,
in the event that it fails. This isimportant because the struct em28xx will be
deallocated if em28xx_init_dev() returns an error.

[mchehab@redhat.com: Fix merge conflicts and simplify the goto labels]
Signed-off-by: Chris Rankin <rankincj@yahoo.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Chris Rankin 2011-08-20 08:28:17 -03:00 committed by Mauro Carvalho Chehab
parent 38b61eb2da
commit 6c03e38b34
2 changed files with 37 additions and 45 deletions

View File

@ -2806,7 +2806,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
{
struct em28xx *dev = *devhandle;
int retval;
int errCode;
dev->udev = udev;
mutex_init(&dev->ctrl_urb_lock);
@ -2883,8 +2882,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
if (dev->is_audio_only) {
errCode = em28xx_audio_setup(dev);
if (errCode)
retval = em28xx_audio_setup(dev);
if (retval)
return -ENODEV;
em28xx_add_into_devlist(dev);
em28xx_init_extension(dev);
@ -2903,7 +2902,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
/* Resets I2C speed */
em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
if (retval < 0) {
em28xx_errdev("%s: em28xx_write_regs_req failed!"
em28xx_errdev("%s: em28xx_write_reg failed!"
" retval [%d]\n",
__func__, retval);
return retval;
@ -2917,12 +2916,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
/* register i2c bus */
errCode = em28xx_i2c_register(dev);
if (errCode < 0) {
v4l2_device_unregister(&dev->v4l2_dev);
em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
__func__, errCode);
return errCode;
retval = em28xx_i2c_register(dev);
if (retval < 0) {
em28xx_errdev("%s: em28xx_i2c_register - error [%d]!\n",
__func__, retval);
goto unregister_dev;
}
/*
@ -2936,11 +2934,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
em28xx_card_setup(dev);
/* Configure audio */
errCode = em28xx_audio_setup(dev);
if (errCode < 0) {
v4l2_device_unregister(&dev->v4l2_dev);
em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
__func__, errCode);
retval = em28xx_audio_setup(dev);
if (retval < 0) {
em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
__func__, retval);
goto fail;
}
/* wake i2c devices */
@ -2954,31 +2952,28 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
if (dev->board.has_msp34xx) {
/* Send a reset to other chips via gpio */
errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
if (errCode < 0) {
em28xx_errdev("%s: em28xx_write_regs_req - "
"msp34xx(1) failed! errCode [%d]\n",
__func__, errCode);
return errCode;
retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
if (retval < 0) {
em28xx_errdev("%s: em28xx_write_reg - "
"msp34xx(1) failed! error [%d]\n",
__func__, retval);
goto fail;
}
msleep(3);
errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
if (errCode < 0) {
em28xx_errdev("%s: em28xx_write_regs_req - "
"msp34xx(2) failed! errCode [%d]\n",
__func__, errCode);
return errCode;
retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
if (retval < 0) {
em28xx_errdev("%s: em28xx_write_reg - "
"msp34xx(2) failed! error [%d]\n",
__func__, retval);
goto fail;
}
msleep(3);
}
em28xx_add_into_devlist(dev);
retval = em28xx_register_analog_devices(dev);
if (retval < 0) {
em28xx_release_resources(dev);
goto fail_reg_devices;
goto fail;
}
em28xx_init_extension(dev);
@ -2988,7 +2983,12 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
return 0;
fail_reg_devices:
fail:
em28xx_i2c_unregister(dev);
unregister_dev:
v4l2_device_unregister(&dev->v4l2_dev);
return retval;
}

View File

@ -1195,13 +1195,6 @@ void em28xx_remove_from_devlist(struct em28xx *dev)
mutex_unlock(&em28xx_devlist_mutex);
};
void em28xx_add_into_devlist(struct em28xx *dev)
{
mutex_lock(&em28xx_devlist_mutex);
list_add_tail(&dev->devlist, &em28xx_devlist);
mutex_unlock(&em28xx_devlist_mutex);
};
/*
* Extension interface
*/
@ -1239,14 +1232,13 @@ EXPORT_SYMBOL(em28xx_unregister_extension);
void em28xx_init_extension(struct em28xx *dev)
{
struct em28xx_ops *ops = NULL;
const struct em28xx_ops *ops = NULL;
mutex_lock(&em28xx_devlist_mutex);
if (!list_empty(&em28xx_extension_devlist)) {
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
if (ops->init)
ops->init(dev);
}
list_add_tail(&dev->devlist, &em28xx_devlist);
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
if (ops->init)
ops->init(dev);
}
mutex_unlock(&em28xx_devlist_mutex);
}