summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2009-09-25 16:17:23 +0400
committerDavid S. Miller <davem@davemloft.net>2009-09-27 07:15:34 +0400
commitbaa34745fe6263c733f43feddb0b8100d6538f37 (patch)
treec77d8e304a958f01f9665a51e1703e1f20c499dd
parent51851073093f36a626de5f5eb1b87db9cae7e0d2 (diff)
downloadlinux-baa34745fe6263c733f43feddb0b8100d6538f37.tar.xz
e1000: stop timers at appropriate times
there were some hotplug cases that made timers still run after the driver had been removed, make sure to stop all the timers and not allow racy reschedules. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/e1000/e1000_main.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 4d6677e4f9f2..7af3255a8e9c 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1098,6 +1098,11 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ set_bit(__E1000_DOWN, &adapter->flags);
+ del_timer_sync(&adapter->tx_fifo_stall_timer);
+ del_timer_sync(&adapter->watchdog_timer);
+ del_timer_sync(&adapter->phy_info_timer);
+
cancel_work_sync(&adapter->reset_task);
e1000_release_manageability(adapter);
@@ -2240,7 +2245,7 @@ static void e1000_82547_tx_fifo_stall(unsigned long data)
adapter->tx_fifo_head = 0;
atomic_set(&adapter->tx_fifo_stall, 0);
netif_wake_queue(netdev);
- } else {
+ } else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
}
}
@@ -2309,8 +2314,9 @@ static void e1000_watchdog(unsigned long data)
ew32(TCTL, tctl);
netif_carrier_on(netdev);
- mod_timer(&adapter->phy_info_timer,
- round_jiffies(jiffies + 2 * HZ));
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ mod_timer(&adapter->phy_info_timer,
+ round_jiffies(jiffies + 2 * HZ));
adapter->smartspeed = 0;
}
} else {
@@ -2320,8 +2326,10 @@ static void e1000_watchdog(unsigned long data)
printk(KERN_INFO "e1000: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
- mod_timer(&adapter->phy_info_timer,
- round_jiffies(jiffies + 2 * HZ));
+
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ mod_timer(&adapter->phy_info_timer,
+ round_jiffies(jiffies + 2 * HZ));
}
e1000_smartspeed(adapter);
@@ -2361,7 +2369,9 @@ static void e1000_watchdog(unsigned long data)
adapter->detect_tx_hung = true;
/* Reset the timer */
- mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ mod_timer(&adapter->watchdog_timer,
+ round_jiffies(jiffies + 2 * HZ));
}
enum latency_range {
@@ -2977,7 +2987,9 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
if (unlikely(hw->mac_type == e1000_82547)) {
if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
netif_stop_queue(netdev);
- mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ mod_timer(&adapter->tx_fifo_stall_timer,
+ jiffies + 1);
return NETDEV_TX_BUSY;
}
}