assert(dev != NULL);
assert(tp != NULL);
+ flush_scheduled_work();
+
unregister_netdev(dev);
rtl8169_release_board(pdev, dev, tp->mmio_addr);
pci_set_drvdata(pdev, NULL);
struct net_device *dev = tp->dev;
int ret;
- if (netif_running(dev)) {
- rtl8169_wait_for_quiescence(dev);
- rtl8169_close(dev);
- }
+ rtnl_lock();
+
+ if (!netif_running(dev))
+ goto out_unlock;
+
+ rtl8169_wait_for_quiescence(dev);
+ rtl8169_close(dev);
ret = rtl8169_open(dev);
if (unlikely(ret < 0)) {
}
rtl8169_schedule_work(dev, rtl8169_reinit_task);
}
+
+out_unlock:
+ rtnl_unlock();
}
static void rtl8169_reset_task(struct work_struct *work)
container_of(work, struct rtl8169_private, task.work);
struct net_device *dev = tp->dev;
+ rtnl_lock();
+
if (!netif_running(dev))
- return;
+ goto out_unlock;
rtl8169_wait_for_quiescence(dev);
}
rtl8169_schedule_work(dev, rtl8169_reset_task);
}
+
+out_unlock:
+ rtnl_unlock();
}
static void rtl8169_tx_timeout(struct net_device *dev)
netif_stop_queue(dev);
- flush_scheduled_work();
-
core_down:
spin_lock_irq(&tp->lock);