aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWill Newton <will.newton@gmail.com>2008-08-12 10:39:17 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-17 17:41:07 -0400
commit23d7cd040e1f43113da3e8763becf576ab86b39a (patch)
treed4f98257a6a379dfcf53d814aef79cdebe1cd340 /drivers
parent59097fb73cf60276053551308524f6c772f305a9 (diff)
fsl_usb2_udc: Fix oops on probe failure.
In some circumstances when fsl_udc_probe fails udc_controller is freed but the pointer remains non-NULL. fsl_udc_remove will then try and teardown the partly initialized and freed controller structure resulting in an oops. This patch ensures udc_controller is either NULL or fully initialized after fsl_udc_probe. Signed-off-by: Will Newton <will.newton@gmail.com> Acked-by: Li Yang <leoli@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c
index 0492441bc0ba..091bb55c9aa7 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.c
+++ b/drivers/usb/gadget/fsl_usb2_udc.c
@@ -2244,21 +2244,21 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
2244 2244
2245 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2245 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2246 if (!res) { 2246 if (!res) {
2247 kfree(udc_controller); 2247 ret = -ENXIO;
2248 return -ENXIO; 2248 goto err_kfree;
2249 } 2249 }
2250 2250
2251 if (!request_mem_region(res->start, res->end - res->start + 1, 2251 if (!request_mem_region(res->start, res->end - res->start + 1,
2252 driver_name)) { 2252 driver_name)) {
2253 ERR("request mem region for %s failed\n", pdev->name); 2253 ERR("request mem region for %s failed\n", pdev->name);
2254 kfree(udc_controller); 2254 ret = -EBUSY;
2255 return -EBUSY; 2255 goto err_kfree;
2256 } 2256 }
2257 2257
2258 dr_regs = ioremap(res->start, res->end - res->start + 1); 2258 dr_regs = ioremap(res->start, res->end - res->start + 1);
2259 if (!dr_regs) { 2259 if (!dr_regs) {
2260 ret = -ENOMEM; 2260 ret = -ENOMEM;
2261 goto err1; 2261 goto err_release_mem_region;
2262 } 2262 }
2263 2263
2264 usb_sys_regs = (struct usb_sys_interface *) 2264 usb_sys_regs = (struct usb_sys_interface *)
@@ -2269,7 +2269,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
2269 if (!(dccparams & DCCPARAMS_DC)) { 2269 if (!(dccparams & DCCPARAMS_DC)) {
2270 ERR("This SOC doesn't support device role\n"); 2270 ERR("This SOC doesn't support device role\n");
2271 ret = -ENODEV; 2271 ret = -ENODEV;
2272 goto err2; 2272 goto err_iounmap;
2273 } 2273 }
2274 /* Get max device endpoints */ 2274 /* Get max device endpoints */
2275 /* DEN is bidirectional ep number, max_ep doubles the number */ 2275 /* DEN is bidirectional ep number, max_ep doubles the number */
@@ -2278,7 +2278,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
2278 udc_controller->irq = platform_get_irq(pdev, 0); 2278 udc_controller->irq = platform_get_irq(pdev, 0);
2279 if (!udc_controller->irq) { 2279 if (!udc_controller->irq) {
2280 ret = -ENODEV; 2280 ret = -ENODEV;
2281 goto err2; 2281 goto err_iounmap;
2282 } 2282 }
2283 2283
2284 ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED, 2284 ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED,
@@ -2286,14 +2286,14 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
2286 if (ret != 0) { 2286 if (ret != 0) {
2287 ERR("cannot request irq %d err %d\n", 2287 ERR("cannot request irq %d err %d\n",
2288 udc_controller->irq, ret); 2288 udc_controller->irq, ret);
2289 goto err2; 2289 goto err_iounmap;
2290 } 2290 }
2291 2291
2292 /* Initialize the udc structure including QH member and other member */ 2292 /* Initialize the udc structure including QH member and other member */
2293 if (struct_udc_setup(udc_controller, pdev)) { 2293 if (struct_udc_setup(udc_controller, pdev)) {
2294 ERR("Can't initialize udc data structure\n"); 2294 ERR("Can't initialize udc data structure\n");
2295 ret = -ENOMEM; 2295 ret = -ENOMEM;
2296 goto err3; 2296 goto err_free_irq;
2297 } 2297 }
2298 2298
2299 /* initialize usb hw reg except for regs for EP, 2299 /* initialize usb hw reg except for regs for EP,
@@ -2314,7 +2314,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
2314 udc_controller->gadget.dev.parent = &pdev->dev; 2314 udc_controller->gadget.dev.parent = &pdev->dev;
2315 ret = device_register(&udc_controller->gadget.dev); 2315 ret = device_register(&udc_controller->gadget.dev);
2316 if (ret < 0) 2316 if (ret < 0)
2317 goto err3; 2317 goto err_free_irq;
2318 2318
2319 /* setup QH and epctrl for ep0 */ 2319 /* setup QH and epctrl for ep0 */
2320 ep0_setup(udc_controller); 2320 ep0_setup(udc_controller);
@@ -2344,20 +2344,22 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
2344 DTD_ALIGNMENT, UDC_DMA_BOUNDARY); 2344 DTD_ALIGNMENT, UDC_DMA_BOUNDARY);
2345 if (udc_controller->td_pool == NULL) { 2345 if (udc_controller->td_pool == NULL) {
2346 ret = -ENOMEM; 2346 ret = -ENOMEM;
2347 goto err4; 2347 goto err_unregister;
2348 } 2348 }
2349 create_proc_file(); 2349 create_proc_file();
2350 return 0; 2350 return 0;
2351 2351
2352err4: 2352err_unregister:
2353 device_unregister(&udc_controller->gadget.dev); 2353 device_unregister(&udc_controller->gadget.dev);
2354err3: 2354err_free_irq:
2355 free_irq(udc_controller->irq, udc_controller); 2355 free_irq(udc_controller->irq, udc_controller);
2356err2: 2356err_iounmap:
2357 iounmap(dr_regs); 2357 iounmap(dr_regs);
2358err1: 2358err_release_mem_region:
2359 release_mem_region(res->start, res->end - res->start + 1); 2359 release_mem_region(res->start, res->end - res->start + 1);
2360err_kfree:
2360 kfree(udc_controller); 2361 kfree(udc_controller);
2362 udc_controller = NULL;
2361 return ret; 2363 return ret;
2362} 2364}
2363 2365