Messages in this thread Patch in this message | ![/](/images/icornerl.gif) | | Date | Sat, 10 May 2003 00:02:22 +0200 | From | Francois Romieu <> | Subject | [ATM] [UPDATE] unbalanced exit path in Forerunner HE he_init_one() |
| |
Update:
- pci_enable_device() balanced on error path in he_init_one(); - return of atm_dev_register() isn't lost any more if he_dev allocation fails in he_init_one(); - pci_disable_device() added to he_disable_one();
drivers/atm/he.c | 43 ++++++++++++++++++++++++++++++------------- 1 files changed, 30 insertions(+), 13 deletions(-)
diff -puN drivers/atm/he.c~drivers-atm-he-chas drivers/atm/he.c --- linux-2.5.69-1.1042.101.10-to-1.1083/drivers/atm/he.c~drivers-atm-he-chas Fri May 9 23:43:22 2003 +++ linux-2.5.69-1.1042.101.10-to-1.1083-fr/drivers/atm/he.c Fri May 9 23:48:43 2003 @@ -364,23 +364,29 @@ he_init_one(struct pci_dev *pci_dev, con { struct atm_dev *atm_dev; struct he_dev *he_dev; + int ret = -EIO; printk(KERN_INFO "he: %s\n", version); - if (pci_enable_device(pci_dev)) return -EIO; - if (pci_set_dma_mask(pci_dev, HE_DMA_MASK) != 0) - { + if (pci_enable_device(pci_dev)) + goto out; + if (pci_set_dma_mask(pci_dev, HE_DMA_MASK) != 0) { printk(KERN_WARNING "he: no suitable dma available\n"); - return -EIO; + goto out_disable; } atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, 0); - if (!atm_dev) return -ENODEV; + if (!atm_dev) { + ret = -ENODEV; + goto out_disable; + } pci_set_drvdata(pci_dev, atm_dev); - he_dev = (struct he_dev *) kmalloc(sizeof(struct he_dev), - GFP_KERNEL); - if (!he_dev) return -ENOMEM; + he_dev = (struct he_dev *) kmalloc(sizeof(struct he_dev), GFP_KERNEL); + if (!he_dev) { + ret = -ENOMEM; + goto out_deregister; + } memset(he_dev, 0, sizeof(struct he_dev)); he_dev->pci_dev = pci_dev; @@ -389,16 +395,26 @@ he_init_one(struct pci_dev *pci_dev, con HE_DEV(atm_dev) = he_dev; he_dev->number = atm_dev->number; /* was devs */ if (he_start(atm_dev)) { - atm_dev_deregister(atm_dev); - he_stop(he_dev); - kfree(he_dev); - return -ENODEV; + ret = -ENODEV; + goto out_stop; } he_dev->next = NULL; if (he_devs) he_dev->next = he_devs; he_devs = he_dev; - return 0; + ret = 0; +out: + return ret; + +out_stop: + he_stop(he_dev); + kfree(he_dev); +out_deregister: + pci_set_drvdata(pci_dev, NULL); + atm_dev_deregister(atm_dev); +out_disable: + pci_disable_device(pci_dev); + goto out; } static void __devexit @@ -417,6 +433,7 @@ he_remove_one (struct pci_dev *pci_dev) kfree(he_dev); pci_set_drvdata(pci_dev, NULL); + pci_disable_device(pci_dev); } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| ![\](/images/icornerr.gif) |