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

Commit af8a819a authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

[media] lirc_imon: simplify error handling code



Instead of using a state machine and a switch with lots of
fall-trough, use gotos and cleanup the error handling loop.

That removes those two smatch warnings:
	drivers/staging/media/lirc/lirc_imon.c:933 imon_probe() warn: possible memory leak of 'context'
	drivers/staging/media/lirc/lirc_imon.c:933 imon_probe() warn: possible memory leak of 'driver'

And make the error handling code more standard.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent b295e5c7
Loading
Loading
Loading
Loading
+39 −58
Original line number Diff line number Diff line
@@ -693,10 +693,9 @@ static int imon_probe(struct usb_interface *interface,
	int ifnum;
	int lirc_minor = 0;
	int num_endpts;
	int retval = 0;
	int retval = -ENOMEM;
	int display_ep_found = 0;
	int ir_ep_found = 0;
	int alloc_status = 0;
	int vfd_proto_6p = 0;
	struct imon_context *context = NULL;
	int i;
@@ -706,10 +705,8 @@ static int imon_probe(struct usb_interface *interface,
	mutex_lock(&driver_lock);

	context = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
	if (!context) {
		alloc_status = 1;
		goto alloc_status_switch;
	}
	if (!context)
		goto driver_unlock;

	/*
	 * Try to auto-detect the type of display if the user hasn't set
@@ -775,8 +772,7 @@ static int imon_probe(struct usb_interface *interface,
		dev_err(dev, "%s: no valid input (IR) endpoint found.\n",
			__func__);
		retval = -ENODEV;
		alloc_status = 2;
		goto alloc_status_switch;
		goto free_context;
	}

	/* Determine if display requires 6 packets */
@@ -790,31 +786,26 @@ static int imon_probe(struct usb_interface *interface,

	driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
	if (!driver) {
		alloc_status = 2;
		goto alloc_status_switch;
		goto free_context;
	}
	rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
	if (!rbuf) {
		alloc_status = 3;
		goto alloc_status_switch;
		goto free_driver;
	}
	if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) {
		dev_err(dev, "%s: lirc_buffer_init failed\n", __func__);
		alloc_status = 4;
		goto alloc_status_switch;
		goto free_rbuf;
	}
	rx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!rx_urb) {
		dev_err(dev, "%s: usb_alloc_urb failed for IR urb\n", __func__);
		alloc_status = 5;
		goto alloc_status_switch;
		goto free_lirc_buf;
	}
	tx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!tx_urb) {
		dev_err(dev, "%s: usb_alloc_urb failed for display urb\n",
		    __func__);
		alloc_status = 6;
		goto alloc_status_switch;
		goto free_rx_urb;
	}

	mutex_init(&context->ctx_lock);
@@ -840,9 +831,9 @@ static int imon_probe(struct usb_interface *interface,
	lirc_minor = lirc_register_driver(driver);
	if (lirc_minor < 0) {
		dev_err(dev, "%s: lirc_register_driver failed\n", __func__);
		alloc_status = 7;
		goto unlock;
	} else
		goto free_tx_urb;
	}

	dev_info(dev, "Registered iMON driver (lirc minor: %d)\n",
			lirc_minor);

@@ -872,11 +863,9 @@ static int imon_probe(struct usb_interface *interface,
		context->rx_endpoint->bInterval);

	retval = usb_submit_urb(context->rx_urb, GFP_KERNEL);

	if (retval) {
		dev_err(dev, "usb_submit_urb failed for intf0 (%d)\n", retval);
		alloc_status = 8;
		goto unlock;
		goto unregister_lirc;
	}

	usb_set_intfdata(interface, context);
@@ -895,39 +884,31 @@ static int imon_probe(struct usb_interface *interface,
	dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n",
		vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);

unlock:
	mutex_unlock(&context->ctx_lock);
alloc_status_switch:
	/* Everything went fine. Just unlock and return retval (with is 0) */
	goto driver_unlock;

	switch (alloc_status) {
	case 8:
unregister_lirc:
	lirc_unregister_driver(driver->minor);
	case 7:

free_tx_urb:
	usb_free_urb(tx_urb);
	case 6:

free_rx_urb:
	usb_free_urb(rx_urb);
		/* fall-through */
	case 5:
		if (rbuf)

free_lirc_buf:
	lirc_buffer_free(rbuf);
		/* fall-through */
	case 4:

free_rbuf:
	kfree(rbuf);
		/* fall-through */
	case 3:

free_driver:
	kfree(driver);
		/* fall-through */
	case 2:
free_context:
	kfree(context);
	context = NULL;
	case 1:
		if (retval != -ENODEV)
			retval = -ENOMEM;
		break;
	case 0:
		retval = 0;
	}

driver_unlock:
	mutex_unlock(&driver_lock);

	return retval;