diff options
author | Vladislav Zolotarov <vladz@broadcom.com> | 2010-02-17 05:03:27 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-18 00:35:41 +0300 |
commit | 6cbe5065bb367d4c8db0a71d2e828995bcfae336 (patch) | |
tree | 8a2a715d587fb60acc66fa47f127e812fcc342a2 /drivers/net/bnx2x_main.c | |
parent | a475f603d23392f386e45cf377b17c30ed3bbb80 (diff) | |
download | linux-6cbe5065bb367d4c8db0a71d2e828995bcfae336.tar.xz |
bnx2x: Properly release allocated MSI-X/MSI vectors
Bug fix: Properly release allocated MSI-X/MSI vectors if ifup failed
due to lack of memory.
Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 6d8559052ee6..d7aef840a1d5 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6938,19 +6938,21 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) } } -static void bnx2x_free_irq(struct bnx2x *bp) +static void bnx2x_free_irq(struct bnx2x *bp, bool disable_only) { if (bp->flags & USING_MSIX_FLAG) { - bnx2x_free_msix_irqs(bp); + if (!disable_only) + bnx2x_free_msix_irqs(bp); pci_disable_msix(bp->pdev); bp->flags &= ~USING_MSIX_FLAG; } else if (bp->flags & USING_MSI_FLAG) { - free_irq(bp->pdev->irq, bp->dev); + if (!disable_only) + free_irq(bp->pdev->irq, bp->dev); pci_disable_msi(bp->pdev); bp->flags &= ~USING_MSI_FLAG; - } else + } else if (!disable_only) free_irq(bp->pdev->irq, bp->dev); } @@ -7443,8 +7445,10 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = bnx2x_set_num_queues(bp); - if (bnx2x_alloc_mem(bp)) + if (bnx2x_alloc_mem(bp)) { + bnx2x_free_irq(bp, true); return -ENOMEM; + } for_each_queue(bp, i) bnx2x_fp(bp, i, disable_tpa) = @@ -7459,7 +7463,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (bp->flags & USING_MSIX_FLAG) { rc = bnx2x_req_msix_irqs(bp); if (rc) { - pci_disable_msix(bp->pdev); + bnx2x_free_irq(bp, true); goto load_error1; } } else { @@ -7471,8 +7475,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = bnx2x_req_irq(bp); if (rc) { BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); - if (bp->flags & USING_MSI_FLAG) - pci_disable_msi(bp->pdev); + bnx2x_free_irq(bp, true); goto load_error1; } if (bp->flags & USING_MSI_FLAG) { @@ -7664,7 +7667,7 @@ load_error3: bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); load_error2: /* Release IRQs */ - bnx2x_free_irq(bp); + bnx2x_free_irq(bp, false); load_error1: bnx2x_napi_disable(bp); for_each_queue(bp, i) @@ -7855,7 +7858,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bnx2x_stats_handle(bp, STATS_EVENT_STOP); /* Release IRQs */ - bnx2x_free_irq(bp); + bnx2x_free_irq(bp, false); /* Wait until tx fastpath tasks complete */ for_each_queue(bp, i) { @@ -12299,7 +12302,7 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); /* Release IRQs */ - bnx2x_free_irq(bp); + bnx2x_free_irq(bp, false); if (CHIP_IS_E1(bp)) { struct mac_configuration_cmd *config = |