Commit 94f341db authored by Anton Vorontsov's avatar Anton Vorontsov Committed by Greg Kroah-Hartman

USB: fsl_qe_udc: Fix oops on QE UDC probe failure

In case of probing errors the driver kfrees the udc_controller, but it
doesn't set the pointer to NULL.

When usb_gadget_register_driver is called, it checks for udc_controller
!= NULL, the check passes and the driver accesses nonexistent memory.
Fix this by setting udc_controller to NULL in case of errors.

While at it, also implement irq_of_parse_and_map()'s failure and cleanup
cases.
Signed-off-by: default avatarAnton Vorontsov <avorontsov@ru.mvista.com>
Acked-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent f06da264
...@@ -2604,6 +2604,10 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, ...@@ -2604,6 +2604,10 @@ static int __devinit qe_udc_probe(struct of_device *ofdev,
(unsigned long)udc_controller); (unsigned long)udc_controller);
/* request irq and disable DR */ /* request irq and disable DR */
udc_controller->usb_irq = irq_of_parse_and_map(np, 0); udc_controller->usb_irq = irq_of_parse_and_map(np, 0);
if (!udc_controller->usb_irq) {
ret = -EINVAL;
goto err_noirq;
}
ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0, ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0,
driver_name, udc_controller); driver_name, udc_controller);
...@@ -2625,6 +2629,8 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, ...@@ -2625,6 +2629,8 @@ static int __devinit qe_udc_probe(struct of_device *ofdev,
err6: err6:
free_irq(udc_controller->usb_irq, udc_controller); free_irq(udc_controller->usb_irq, udc_controller);
err5: err5:
irq_dispose_mapping(udc_controller->usb_irq);
err_noirq:
if (udc_controller->nullmap) { if (udc_controller->nullmap) {
dma_unmap_single(udc_controller->gadget.dev.parent, dma_unmap_single(udc_controller->gadget.dev.parent,
udc_controller->nullp, 256, udc_controller->nullp, 256,
...@@ -2648,7 +2654,7 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, ...@@ -2648,7 +2654,7 @@ static int __devinit qe_udc_probe(struct of_device *ofdev,
iounmap(udc_controller->usb_regs); iounmap(udc_controller->usb_regs);
err1: err1:
kfree(udc_controller); kfree(udc_controller);
udc_controller = NULL;
return ret; return ret;
} }
...@@ -2710,6 +2716,7 @@ static int __devexit qe_udc_remove(struct of_device *ofdev) ...@@ -2710,6 +2716,7 @@ static int __devexit qe_udc_remove(struct of_device *ofdev)
kfree(ep->txframe); kfree(ep->txframe);
free_irq(udc_controller->usb_irq, udc_controller); free_irq(udc_controller->usb_irq, udc_controller);
irq_dispose_mapping(udc_controller->usb_irq);
tasklet_kill(&udc_controller->rx_tasklet); tasklet_kill(&udc_controller->rx_tasklet);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment