sky2: fix suspend/resume races
authorStephen Hemminger <shemminger@vyatta.com>
Wed, 2 Apr 2008 16:03:23 +0000 (09:03 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 2 Apr 2008 16:33:53 +0000 (09:33 -0700)
There are a couple of possible races on suspend/resume.
First the driver needs to block new packets from being queued for Tx.
The other less likely problem is the watchdog timer going off
during resume.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/net/sky2.c

index 54c662690f65482b613954918ce499121a84ea61..853bce0ac47827f5298d7d371fcf5d9bc8efd650 100644 (file)
@@ -4329,10 +4329,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
        if (!hw)
                return 0;
 
+       del_timer_sync(&hw->watchdog_timer);
+       cancel_work_sync(&hw->restart_work);
+
        for (i = 0; i < hw->ports; i++) {
                struct net_device *dev = hw->dev[i];
                struct sky2_port *sky2 = netdev_priv(dev);
 
+               netif_device_detach(dev);
                if (netif_running(dev))
                        sky2_down(dev);
 
@@ -4383,6 +4387,8 @@ static int sky2_resume(struct pci_dev *pdev)
 
        for (i = 0; i < hw->ports; i++) {
                struct net_device *dev = hw->dev[i];
+
+               netif_device_attach(dev);
                if (netif_running(dev)) {
                        err = sky2_up(dev);
                        if (err) {