|
@@ -1109,6 +1109,8 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
|
|
|
|
|
|
assert (dev != NULL);
|
|
|
|
|
|
+ flush_scheduled_work();
|
|
|
+
|
|
|
unregister_netdev (dev);
|
|
|
|
|
|
__rtl8139_cleanup_dev (dev);
|
|
@@ -1603,18 +1605,21 @@ static void rtl8139_thread (struct work_struct *work)
|
|
|
struct net_device *dev = tp->mii.dev;
|
|
|
unsigned long thr_delay = next_tick;
|
|
|
|
|
|
+ rtnl_lock();
|
|
|
+
|
|
|
+ if (!netif_running(dev))
|
|
|
+ goto out_unlock;
|
|
|
+
|
|
|
if (tp->watchdog_fired) {
|
|
|
tp->watchdog_fired = 0;
|
|
|
rtl8139_tx_timeout_task(work);
|
|
|
- } else if (rtnl_trylock()) {
|
|
|
- rtl8139_thread_iter (dev, tp, tp->mmio_addr);
|
|
|
- rtnl_unlock ();
|
|
|
- } else {
|
|
|
- /* unlikely race. mitigate with fast poll. */
|
|
|
- thr_delay = HZ / 2;
|
|
|
- }
|
|
|
+ } else
|
|
|
+ rtl8139_thread_iter(dev, tp, tp->mmio_addr);
|
|
|
|
|
|
- schedule_delayed_work(&tp->thread, thr_delay);
|
|
|
+ if (tp->have_thread)
|
|
|
+ schedule_delayed_work(&tp->thread, thr_delay);
|
|
|
+out_unlock:
|
|
|
+ rtnl_unlock ();
|
|
|
}
|
|
|
|
|
|
static void rtl8139_start_thread(struct rtl8139_private *tp)
|
|
@@ -1626,19 +1631,11 @@ static void rtl8139_start_thread(struct rtl8139_private *tp)
|
|
|
return;
|
|
|
|
|
|
tp->have_thread = 1;
|
|
|
+ tp->watchdog_fired = 0;
|
|
|
|
|
|
schedule_delayed_work(&tp->thread, next_tick);
|
|
|
}
|
|
|
|
|
|
-static void rtl8139_stop_thread(struct rtl8139_private *tp)
|
|
|
-{
|
|
|
- if (tp->have_thread) {
|
|
|
- cancel_rearming_delayed_work(&tp->thread);
|
|
|
- tp->have_thread = 0;
|
|
|
- } else
|
|
|
- flush_scheduled_work();
|
|
|
-}
|
|
|
-
|
|
|
static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
|
|
|
{
|
|
|
tp->cur_tx = 0;
|
|
@@ -1696,12 +1693,11 @@ static void rtl8139_tx_timeout (struct net_device *dev)
|
|
|
{
|
|
|
struct rtl8139_private *tp = netdev_priv(dev);
|
|
|
|
|
|
+ tp->watchdog_fired = 1;
|
|
|
if (!tp->have_thread) {
|
|
|
- INIT_DELAYED_WORK(&tp->thread, rtl8139_tx_timeout_task);
|
|
|
+ INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
|
|
|
schedule_delayed_work(&tp->thread, next_tick);
|
|
|
- } else
|
|
|
- tp->watchdog_fired = 1;
|
|
|
-
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|
@@ -2233,8 +2229,6 @@ static int rtl8139_close (struct net_device *dev)
|
|
|
|
|
|
netif_stop_queue (dev);
|
|
|
|
|
|
- rtl8139_stop_thread(tp);
|
|
|
-
|
|
|
if (netif_msg_ifdown(tp))
|
|
|
printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
|
|
|
dev->name, RTL_R16 (IntrStatus));
|