ENI155P error handling fix
Subsystems (3)
PATCH 2/3 ENI155P error handling fix
From: Panagiotis Issaris <[email protected]>
In the ENI155P device driver in six possible failure cases the requested irq is not being released.
In three of the above possible failure cases additionally there seems to be a memory leak.
Signed-off-by Andrew Morton <[email protected]>
---
25-akpm/drivers/atm/eni.c | 27 ++++++++++++++++++--------- 1 files changed, 18 insertions(+), 9 deletions(-)
drivers/atm/eni.c renamed from drivers/atm/eni.c~eni155p-error-handling-fix +18 -9
@@ -59,7 +59,6 @@* - doesn't support OAM cells * - eni_put_free may hang if not putting memory fragments that _complete_ * 2^n block (never happens in real life, though) -* - keeps IRQ even if initialization fails */
@@ -1802,22 +1801,22 @@ static int __devinit eni_start(struct atif (request_irq (eni_dev->irq,&eni_int,SA_SHIRQ ,DEV_LABEL ,dev)) { printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n", dev->number,eni_dev->irq); -return -EAGAIN ; + error = -EAGAIN ; + goto out; } -/* @@@ should release IRQ on error */ pci_set_master (eni_dev->pci_dev);if ((error =pci_write_config_word (eni_dev->pci_dev,PCI_COMMAND ,PCI_COMMAND_MEMORY |PCI_COMMAND_MASTER | (eni_dev->asic ?PCI_COMMAND_PARITY |PCI_COMMAND_SERR :0 )))) { printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+" "master (0x%02x)\n",dev->number,error); -return error; + goto free_irq; }if ((error =pci_write_config_byte (eni_dev->pci_dev,PCI_TONGA_CTRL ,END_SWAP_DMA ))) { printk(KERN_ERR DEV_LABEL "(itf %d): can't set endian swap " "(0x%02x)\n",dev->number,error); -return error; + goto free_irq; }/* determine addresses of internal tables */ eni_dev->vci = eni_dev->ram;
@@ -1839,7 +1838,8 @@ static int __devinit eni_start(struct atif (!eni_dev->free_list) { printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n", dev->number); -return -ENOMEM ; + error = -ENOMEM ; + goto free_irq; } eni_dev->free_len =0 ;eni_put_free (eni_dev,buf,buffer_mem);
@@ -1855,17 +1855,26 @@ static int __devinit eni_start(struct at*/ eni_out (0xffffffff ,MID_IE ); error =start_tx (dev); -if (error)return error; +if (error) goto free_list; error =start_rx (dev); -if (error)return error; +if (error) goto free_list; error = dev->phy->start (dev); -if (error)return error; +if (error) goto free_list;eni_out (eni_in (MID_MC_S ) | (1 <<MID_INT_SEL_SHIFT ) |MID_TX_LOCK_MODE |MID_DMA_ENABLE |MID_TX_ENABLE |MID_RX_ENABLE ,MID_MC_S );/* Tonga uses SBus INTReq1 */ (void )eni_in (MID_ISA );/* clear Midway interrupts */ return 0 ; + +free_list: +kfree (eni_dev->free_list); + +free_irq: +free_irq (eni_dev->irq, eni_dev); + +out: +return error; }
_