diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/tg3.c | 30 | ||||
| -rw-r--r-- | drivers/net/tg3.h | 1 | 
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 | ||
| 3503 | static void tg3_tx_timeout(struct net_device *dev) | 3516 | static 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 | 
