A rewrite of udc_pci_probe() with proper error handling. We use here
free_dma_pools() in error handling.

Signed-off-by: Sudip Mukherjee <su...@vectorindia.org>
---
 drivers/usb/gadget/udc/amd5536udc.c | 52 +++++++++++++++++++------------------
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/gadget/udc/amd5536udc.c 
b/drivers/usb/gadget/udc/amd5536udc.c
index 8b700de..8646f6c 100644
--- a/drivers/usb/gadget/udc/amd5536udc.c
+++ b/drivers/usb/gadget/udc/amd5536udc.c
@@ -3244,17 +3244,13 @@ static int udc_pci_probe(
 
        /* init */
        dev = kzalloc(sizeof(struct udc), GFP_KERNEL);
-       if (!dev) {
-               retval = -ENOMEM;
-               goto finished;
-       }
+       if (!dev)
+               return -ENOMEM;
 
        /* pci setup */
        if (pci_enable_device(pdev) < 0) {
-               kfree(dev);
-               dev = NULL;
                retval = -ENODEV;
-               goto finished;
+               goto err_enabledev;
        }
        dev->active = 1;
 
@@ -3264,28 +3260,22 @@ static int udc_pci_probe(
 
        if (!request_mem_region(resource, len, name)) {
                dev_dbg(&pdev->dev, "pci device used already\n");
-               kfree(dev);
-               dev = NULL;
                retval = -EBUSY;
-               goto finished;
+               goto err_requestmem;
        }
        dev->mem_region = 1;
 
        dev->virt_addr = ioremap_nocache(resource, len);
        if (dev->virt_addr == NULL) {
                dev_dbg(&pdev->dev, "start address cannot be mapped\n");
-               kfree(dev);
-               dev = NULL;
                retval = -EFAULT;
-               goto finished;
+               goto err_ioremap;
        }
 
        if (!pdev->irq) {
                dev_err(&pdev->dev, "irq not set\n");
-               kfree(dev);
-               dev = NULL;
                retval = -ENODEV;
-               goto finished;
+               goto err_irqreq;
        }
 
        spin_lock_init(&dev->lock);
@@ -3301,10 +3291,8 @@ static int udc_pci_probe(
 
        if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
                dev_dbg(&pdev->dev, "request_irq(%d) fail\n", pdev->irq);
-               kfree(dev);
-               dev = NULL;
                retval = -EBUSY;
-               goto finished;
+               goto err_irqreq;
        }
        dev->irq_registered = 1;
 
@@ -3320,7 +3308,7 @@ static int udc_pci_probe(
        if (use_dma) {
                retval = init_dma_pools(dev);
                if (retval != 0)
-                       goto finished;
+                       goto err_dma;
        }
 
        dev->phys_addr = resource;
@@ -3328,12 +3316,26 @@ static int udc_pci_probe(
        dev->pdev = pdev;
 
        /* general probing */
-       if (udc_probe(dev) == 0)
-               return 0;
+       if (udc_probe(dev) != 0) {
+               retval = -ENODEV;
+               goto err_probe;
+       }
+       return 0;
 
-finished:
-       if (dev)
-               udc_pci_remove(pdev);
+err_probe:
+       if (use_dma)
+               free_dma_pools(dev);
+err_dma:
+       free_irq(pdev->irq, dev);
+err_irqreq:
+       iounmap(dev->virt_addr);
+err_ioremap:
+       release_mem_region(resource, len);
+err_requestmem:
+       pci_disable_device(pdev);
+err_enabledev:
+       kfree(dev);
+       dev = NULL;
        return retval;
 }
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to