Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c03e38b authored by Chris Rankin's avatar Chris Rankin Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarChris Rankin <rankincj@yahoo.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 38b61eb2
Loading
Loading
Loading
Loading
+32 −32
Original line number Diff line number Diff line
@@ -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;
}

+5 −13
Original line number Diff line number Diff line
@@ -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,15 +1232,14 @@ 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_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);
}