aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Kravkov <dmitry@broadcom.com>2011-06-13 21:33:08 -0400
committerDavid S. Miller <davem@conan.davemloft.net>2011-06-15 10:56:13 -0400
commitca92429f5f52a76eb6e161622d813b8224ce0565 (patch)
treee23dc97adf3885790d6ea24e5fd4fe2e8a23999c
parent93ef5c02a436000d6b90ff59c9d25563000eee7f (diff)
bnx2x: avoid release of unrequested irqs
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@conan.davemloft.net>
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 3a2a50c36b49..9fee7f0a2d99 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -1097,30 +1097,43 @@ void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value)
1097 } 1097 }
1098} 1098}
1099 1099
1100static void bnx2x_free_msix_irqs(struct bnx2x *bp) 1100/**
1101 * bnx2x_free_msix_irqs - free previously requested MSI-X IRQ vectors
1102 *
1103 * @bp: driver handle
1104 * @nvecs: number of vectors to be released
1105 */
1106static void bnx2x_free_msix_irqs(struct bnx2x *bp, int nvecs)
1101{ 1107{
1102 int i, offset = 1; 1108 int i, offset = 0;
1103 1109
1104 free_irq(bp->msix_table[0].vector, bp->dev); 1110 if (nvecs == offset)
1111 return;
1112 free_irq(bp->msix_table[offset].vector, bp->dev);
1105 DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n", 1113 DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n",
1106 bp->msix_table[0].vector); 1114 bp->msix_table[offset].vector);
1107 1115 offset++;
1108#ifdef BCM_CNIC 1116#ifdef BCM_CNIC
1117 if (nvecs == offset)
1118 return;
1109 offset++; 1119 offset++;
1110#endif 1120#endif
1121
1111 for_each_eth_queue(bp, i) { 1122 for_each_eth_queue(bp, i) {
1112 DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq " 1123 if (nvecs == offset)
1113 "state %x\n", i, bp->msix_table[i + offset].vector, 1124 return;
1114 bnx2x_fp(bp, i, state)); 1125 DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d "
1126 "irq\n", i, bp->msix_table[offset].vector);
1115 1127
1116 free_irq(bp->msix_table[i + offset].vector, &bp->fp[i]); 1128 free_irq(bp->msix_table[offset++].vector, &bp->fp[i]);
1117 } 1129 }
1118} 1130}
1119 1131
1120void bnx2x_free_irq(struct bnx2x *bp) 1132void bnx2x_free_irq(struct bnx2x *bp)
1121{ 1133{
1122 if (bp->flags & USING_MSIX_FLAG) 1134 if (bp->flags & USING_MSIX_FLAG)
1123 bnx2x_free_msix_irqs(bp); 1135 bnx2x_free_msix_irqs(bp, BNX2X_NUM_ETH_QUEUES(bp) +
1136 CNIC_CONTEXT_USE + 1);
1124 else if (bp->flags & USING_MSI_FLAG) 1137 else if (bp->flags & USING_MSI_FLAG)
1125 free_irq(bp->pdev->irq, bp->dev); 1138 free_irq(bp->pdev->irq, bp->dev);
1126 else 1139 else
@@ -1193,9 +1206,10 @@ int bnx2x_enable_msix(struct bnx2x *bp)
1193 1206
1194static int bnx2x_req_msix_irqs(struct bnx2x *bp) 1207static int bnx2x_req_msix_irqs(struct bnx2x *bp)
1195{ 1208{
1196 int i, rc, offset = 1; 1209 int i, rc, offset = 0;
1197 1210
1198 rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0, 1211 rc = request_irq(bp->msix_table[offset++].vector,
1212 bnx2x_msix_sp_int, 0,
1199 bp->dev->name, bp->dev); 1213 bp->dev->name, bp->dev);
1200 if (rc) { 1214 if (rc) {
1201 BNX2X_ERR("request sp irq failed\n"); 1215 BNX2X_ERR("request sp irq failed\n");
@@ -1213,8 +1227,9 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
1213 rc = request_irq(bp->msix_table[offset].vector, 1227 rc = request_irq(bp->msix_table[offset].vector,
1214 bnx2x_msix_fp_int, 0, fp->name, fp); 1228 bnx2x_msix_fp_int, 0, fp->name, fp);
1215 if (rc) { 1229 if (rc) {
1216 BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc); 1230 BNX2X_ERR("request fp #%d irq (%d) failed rc %d\n", i,
1217 bnx2x_free_msix_irqs(bp); 1231 bp->msix_table[offset].vector, rc);
1232 bnx2x_free_msix_irqs(bp, offset);
1218 return -EBUSY; 1233 return -EBUSY;
1219 } 1234 }
1220 1235