aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/tg3.c30
-rw-r--r--drivers/net/tg3.h1
2 files changed, 27 insertions, 4 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index f2d1dafde087..e7dc653d5bd6 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -69,8 +69,8 @@
69 69
70#define DRV_MODULE_NAME "tg3" 70#define DRV_MODULE_NAME "tg3"
71#define PFX DRV_MODULE_NAME ": " 71#define PFX DRV_MODULE_NAME ": "
72#define DRV_MODULE_VERSION "3.48" 72#define DRV_MODULE_VERSION "3.49"
73#define DRV_MODULE_RELDATE "Jan 16, 2006" 73#define DRV_MODULE_RELDATE "Feb 2, 2006"
74 74
75#define TG3_DEF_MAC_MODE 0 75#define TG3_DEF_MAC_MODE 0
76#define TG3_DEF_RX_MODE 0 76#define TG3_DEF_RX_MODE 0
@@ -3482,6 +3482,17 @@ static void tg3_reset_task(void *_data)
3482 struct tg3 *tp = _data; 3482 struct tg3 *tp = _data;
3483 unsigned int restart_timer; 3483 unsigned int restart_timer;
3484 3484
3485 tg3_full_lock(tp, 0);
3486 tp->tg3_flags |= TG3_FLAG_IN_RESET_TASK;
3487
3488 if (!netif_running(tp->dev)) {
3489 tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK;
3490 tg3_full_unlock(tp);
3491 return;
3492 }
3493
3494 tg3_full_unlock(tp);
3495
3485 tg3_netif_stop(tp); 3496 tg3_netif_stop(tp);
3486 3497
3487 tg3_full_lock(tp, 1); 3498 tg3_full_lock(tp, 1);
@@ -3494,10 +3505,12 @@ static void tg3_reset_task(void *_data)
3494 3505
3495 tg3_netif_start(tp); 3506 tg3_netif_start(tp);
3496 3507
3497 tg3_full_unlock(tp);
3498
3499 if (restart_timer) 3508 if (restart_timer)
3500 mod_timer(&tp->timer, jiffies + 1); 3509 mod_timer(&tp->timer, jiffies + 1);
3510
3511 tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK;
3512
3513 tg3_full_unlock(tp);
3501} 3514}
3502 3515
3503static void tg3_tx_timeout(struct net_device *dev) 3516static void tg3_tx_timeout(struct net_device *dev)
@@ -6786,6 +6799,13 @@ static int tg3_close(struct net_device *dev)
6786{ 6799{
6787 struct tg3 *tp = netdev_priv(dev); 6800 struct tg3 *tp = netdev_priv(dev);
6788 6801
6802 /* Calling flush_scheduled_work() may deadlock because
6803 * linkwatch_event() may be on the workqueue and it will try to get
6804 * the rtnl_lock which we are holding.
6805 */
6806 while (tp->tg3_flags & TG3_FLAG_IN_RESET_TASK)
6807 msleep(1);
6808
6789 netif_stop_queue(dev); 6809 netif_stop_queue(dev);
6790 6810
6791 del_timer_sync(&tp->timer); 6811 del_timer_sync(&tp->timer);
@@ -10880,6 +10900,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
10880 if (dev) { 10900 if (dev) {
10881 struct tg3 *tp = netdev_priv(dev); 10901 struct tg3 *tp = netdev_priv(dev);
10882 10902
10903 flush_scheduled_work();
10883 unregister_netdev(dev); 10904 unregister_netdev(dev);
10884 if (tp->regs) { 10905 if (tp->regs) {
10885 iounmap(tp->regs); 10906 iounmap(tp->regs);
@@ -10901,6 +10922,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
10901 if (!netif_running(dev)) 10922 if (!netif_running(dev))
10902 return 0; 10923 return 0;
10903 10924
10925 flush_scheduled_work();
10904 tg3_netif_stop(tp); 10926 tg3_netif_stop(tp);
10905 10927
10906 del_timer_sync(&tp->timer); 10928 del_timer_sync(&tp->timer);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index e8243305f0e8..7f4b7f6ac40d 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2162,6 +2162,7 @@ struct tg3 {
2162#define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 2162#define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000
2163#define TG3_FLAG_10_100_ONLY 0x01000000 2163#define TG3_FLAG_10_100_ONLY 0x01000000
2164#define TG3_FLAG_PAUSE_AUTONEG 0x02000000 2164#define TG3_FLAG_PAUSE_AUTONEG 0x02000000
2165#define TG3_FLAG_IN_RESET_TASK 0x04000000
2165#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 2166#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
2166#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 2167#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
2167#define TG3_FLAG_SPLIT_MODE 0x40000000 2168#define TG3_FLAG_SPLIT_MODE 0x40000000