diff options
author | Scott Feldman <scofeldm@cisco.com> | 2009-09-03 13:02:14 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-03 23:19:17 -0400 |
commit | 56ac88b38e5918d92bdfc97c528068e45ff4581c (patch) | |
tree | 9a087772b5f76379b812bd93feeda44374970ae2 /drivers/net/enic/enic_main.c | |
parent | d19e22dc2c1c43724c1d9ce4a5456ae74eeb6da8 (diff) |
enic: bug fix: protect fw call i/f with spinlock
Some driver -> nic firmware calls weren't guarded with a spinlock, exposing
the call i/f to a race between two threads
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/enic/enic_main.c')
-rw-r--r-- | drivers/net/enic/enic_main.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 73f01075287d..36cf0fcc66fe 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
@@ -1316,6 +1316,7 @@ static int enic_notify_set(struct enic *enic) | |||
1316 | { | 1316 | { |
1317 | int err; | 1317 | int err; |
1318 | 1318 | ||
1319 | spin_lock(&enic->devcmd_lock); | ||
1319 | switch (vnic_dev_get_intr_mode(enic->vdev)) { | 1320 | switch (vnic_dev_get_intr_mode(enic->vdev)) { |
1320 | case VNIC_DEV_INTR_MODE_INTX: | 1321 | case VNIC_DEV_INTR_MODE_INTX: |
1321 | err = vnic_dev_notify_set(enic->vdev, ENIC_INTX_NOTIFY); | 1322 | err = vnic_dev_notify_set(enic->vdev, ENIC_INTX_NOTIFY); |
@@ -1327,6 +1328,7 @@ static int enic_notify_set(struct enic *enic) | |||
1327 | err = vnic_dev_notify_set(enic->vdev, -1 /* no intr */); | 1328 | err = vnic_dev_notify_set(enic->vdev, -1 /* no intr */); |
1328 | break; | 1329 | break; |
1329 | } | 1330 | } |
1331 | spin_unlock(&enic->devcmd_lock); | ||
1330 | 1332 | ||
1331 | return err; | 1333 | return err; |
1332 | } | 1334 | } |
@@ -1380,12 +1382,16 @@ static int enic_open(struct net_device *netdev) | |||
1380 | for (i = 0; i < enic->rq_count; i++) | 1382 | for (i = 0; i < enic->rq_count; i++) |
1381 | vnic_rq_enable(&enic->rq[i]); | 1383 | vnic_rq_enable(&enic->rq[i]); |
1382 | 1384 | ||
1385 | spin_lock(&enic->devcmd_lock); | ||
1383 | enic_add_station_addr(enic); | 1386 | enic_add_station_addr(enic); |
1387 | spin_unlock(&enic->devcmd_lock); | ||
1384 | enic_set_multicast_list(netdev); | 1388 | enic_set_multicast_list(netdev); |
1385 | 1389 | ||
1386 | netif_wake_queue(netdev); | 1390 | netif_wake_queue(netdev); |
1387 | napi_enable(&enic->napi); | 1391 | napi_enable(&enic->napi); |
1392 | spin_lock(&enic->devcmd_lock); | ||
1388 | vnic_dev_enable(enic->vdev); | 1393 | vnic_dev_enable(enic->vdev); |
1394 | spin_unlock(&enic->devcmd_lock); | ||
1389 | 1395 | ||
1390 | for (i = 0; i < enic->intr_count; i++) | 1396 | for (i = 0; i < enic->intr_count; i++) |
1391 | vnic_intr_unmask(&enic->intr[i]); | 1397 | vnic_intr_unmask(&enic->intr[i]); |
@@ -1395,7 +1401,9 @@ static int enic_open(struct net_device *netdev) | |||
1395 | return 0; | 1401 | return 0; |
1396 | 1402 | ||
1397 | err_out_notify_unset: | 1403 | err_out_notify_unset: |
1404 | spin_lock(&enic->devcmd_lock); | ||
1398 | vnic_dev_notify_unset(enic->vdev); | 1405 | vnic_dev_notify_unset(enic->vdev); |
1406 | spin_unlock(&enic->devcmd_lock); | ||
1399 | err_out_free_intr: | 1407 | err_out_free_intr: |
1400 | enic_free_intr(enic); | 1408 | enic_free_intr(enic); |
1401 | 1409 | ||
@@ -1411,7 +1419,9 @@ static int enic_stop(struct net_device *netdev) | |||
1411 | 1419 | ||
1412 | del_timer_sync(&enic->notify_timer); | 1420 | del_timer_sync(&enic->notify_timer); |
1413 | 1421 | ||
1422 | spin_lock(&enic->devcmd_lock); | ||
1414 | vnic_dev_disable(enic->vdev); | 1423 | vnic_dev_disable(enic->vdev); |
1424 | spin_unlock(&enic->devcmd_lock); | ||
1415 | napi_disable(&enic->napi); | 1425 | napi_disable(&enic->napi); |
1416 | netif_stop_queue(netdev); | 1426 | netif_stop_queue(netdev); |
1417 | 1427 | ||
@@ -1429,7 +1439,9 @@ static int enic_stop(struct net_device *netdev) | |||
1429 | return err; | 1439 | return err; |
1430 | } | 1440 | } |
1431 | 1441 | ||
1442 | spin_lock(&enic->devcmd_lock); | ||
1432 | vnic_dev_notify_unset(enic->vdev); | 1443 | vnic_dev_notify_unset(enic->vdev); |
1444 | spin_unlock(&enic->devcmd_lock); | ||
1433 | enic_free_intr(enic); | 1445 | enic_free_intr(enic); |
1434 | 1446 | ||
1435 | (void)vnic_cq_service(&enic->cq[ENIC_CQ_RQ], | 1447 | (void)vnic_cq_service(&enic->cq[ENIC_CQ_RQ], |