2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-28 07:04:00 +08:00

[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: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
Mauro Carvalho Chehab 2015-06-05 11:06:46 -03:00
parent b295e5c7d8
commit af8a819a25

View File

@ -693,10 +693,9 @@ static int imon_probe(struct usb_interface *interface,
int ifnum; int ifnum;
int lirc_minor = 0; int lirc_minor = 0;
int num_endpts; int num_endpts;
int retval = 0; int retval = -ENOMEM;
int display_ep_found = 0; int display_ep_found = 0;
int ir_ep_found = 0; int ir_ep_found = 0;
int alloc_status = 0;
int vfd_proto_6p = 0; int vfd_proto_6p = 0;
struct imon_context *context = NULL; struct imon_context *context = NULL;
int i; int i;
@ -706,10 +705,8 @@ static int imon_probe(struct usb_interface *interface,
mutex_lock(&driver_lock); mutex_lock(&driver_lock);
context = kzalloc(sizeof(struct imon_context), GFP_KERNEL); context = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
if (!context) { if (!context)
alloc_status = 1; goto driver_unlock;
goto alloc_status_switch;
}
/* /*
* Try to auto-detect the type of display if the user hasn't set * 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", dev_err(dev, "%s: no valid input (IR) endpoint found.\n",
__func__); __func__);
retval = -ENODEV; retval = -ENODEV;
alloc_status = 2; goto free_context;
goto alloc_status_switch;
} }
/* Determine if display requires 6 packets */ /* 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); driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
if (!driver) { if (!driver) {
alloc_status = 2; goto free_context;
goto alloc_status_switch;
} }
rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
if (!rbuf) { if (!rbuf) {
alloc_status = 3; goto free_driver;
goto alloc_status_switch;
} }
if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) {
dev_err(dev, "%s: lirc_buffer_init failed\n", __func__); dev_err(dev, "%s: lirc_buffer_init failed\n", __func__);
alloc_status = 4; goto free_rbuf;
goto alloc_status_switch;
} }
rx_urb = usb_alloc_urb(0, GFP_KERNEL); rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!rx_urb) { if (!rx_urb) {
dev_err(dev, "%s: usb_alloc_urb failed for IR urb\n", __func__); dev_err(dev, "%s: usb_alloc_urb failed for IR urb\n", __func__);
alloc_status = 5; goto free_lirc_buf;
goto alloc_status_switch;
} }
tx_urb = usb_alloc_urb(0, GFP_KERNEL); tx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!tx_urb) { if (!tx_urb) {
dev_err(dev, "%s: usb_alloc_urb failed for display urb\n", dev_err(dev, "%s: usb_alloc_urb failed for display urb\n",
__func__); __func__);
alloc_status = 6; goto free_rx_urb;
goto alloc_status_switch;
} }
mutex_init(&context->ctx_lock); mutex_init(&context->ctx_lock);
@ -840,11 +831,11 @@ static int imon_probe(struct usb_interface *interface,
lirc_minor = lirc_register_driver(driver); lirc_minor = lirc_register_driver(driver);
if (lirc_minor < 0) { if (lirc_minor < 0) {
dev_err(dev, "%s: lirc_register_driver failed\n", __func__); dev_err(dev, "%s: lirc_register_driver failed\n", __func__);
alloc_status = 7; goto free_tx_urb;
goto unlock; }
} else
dev_info(dev, "Registered iMON driver (lirc minor: %d)\n", dev_info(dev, "Registered iMON driver (lirc minor: %d)\n",
lirc_minor); lirc_minor);
/* Needed while unregistering! */ /* Needed while unregistering! */
driver->minor = lirc_minor; driver->minor = lirc_minor;
@ -872,11 +863,9 @@ static int imon_probe(struct usb_interface *interface,
context->rx_endpoint->bInterval); context->rx_endpoint->bInterval);
retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); retval = usb_submit_urb(context->rx_urb, GFP_KERNEL);
if (retval) { if (retval) {
dev_err(dev, "usb_submit_urb failed for intf0 (%d)\n", retval); dev_err(dev, "usb_submit_urb failed for intf0 (%d)\n", retval);
alloc_status = 8; goto unregister_lirc;
goto unlock;
} }
usb_set_intfdata(interface, context); 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", dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n",
vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum); vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);
unlock: /* Everything went fine. Just unlock and return retval (with is 0) */
mutex_unlock(&context->ctx_lock); goto driver_unlock;
alloc_status_switch:
switch (alloc_status) { unregister_lirc:
case 8: lirc_unregister_driver(driver->minor);
lirc_unregister_driver(driver->minor);
case 7:
usb_free_urb(tx_urb);
case 6:
usb_free_urb(rx_urb);
/* fall-through */
case 5:
if (rbuf)
lirc_buffer_free(rbuf);
/* fall-through */
case 4:
kfree(rbuf);
/* fall-through */
case 3:
kfree(driver);
/* fall-through */
case 2:
kfree(context);
context = NULL;
case 1:
if (retval != -ENODEV)
retval = -ENOMEM;
break;
case 0:
retval = 0;
}
free_tx_urb:
usb_free_urb(tx_urb);
free_rx_urb:
usb_free_urb(rx_urb);
free_lirc_buf:
lirc_buffer_free(rbuf);
free_rbuf:
kfree(rbuf);
free_driver:
kfree(driver);
free_context:
kfree(context);
context = NULL;
driver_unlock:
mutex_unlock(&driver_lock); mutex_unlock(&driver_lock);
return retval; return retval;