--- via-rhine.c.org 2004-08-05 00:31:19.796592888 +0200 +++ via-rhine.c 2004-08-05 00:39:26.241642000 +0200 @@ -485,6 +485,10 @@ dma_addr_t tx_bufs_dma; struct pci_dev *pdev; +#ifdef CONFIG_PM + long pioaddr; + u32 pci_state[16]; +#endif struct net_device_stats stats; spinlock_t lock; @@ -825,6 +829,9 @@ dev->base_addr = ioaddr; rp = netdev_priv(dev); rp->quirks = quirks; +#ifdef CONFIG_PM + rp->pioaddr = pioaddr; +#endif /* Get chip registers into a sane state */ rhine_power_init(dev); @@ -1951,11 +1958,64 @@ } +#ifdef CONFIG_PM +static int rhine_suspend (struct pci_dev *pdev, u32 state) +{ + struct net_device *dev = pci_get_drvdata (pdev); + struct rhine_private *rp = dev->priv; + + if (!netif_running (dev)) + return 0; + + netif_device_detach (dev); + + pci_save_state (pdev, rp->pci_state); + pci_set_power_state (pdev, 3); + + return 0; +} + +static int rhine_resume (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata (pdev); + struct rhine_private *rp = dev->priv; + unsigned long flags; + + if (!netif_running (dev)) + return 0; + + pci_set_power_state (pdev, 0); + pci_restore_state (pdev, rp->pci_state); + + spin_lock_irqsave (&rp->lock, flags); + + rhine_power_init(dev); + rhine_hw_init(dev, rp->pioaddr); + + free_tbufs(dev); + free_rbufs(dev); + alloc_tbufs(dev); + alloc_rbufs(dev); + + init_registers(dev); + + spin_unlock_irqrestore (&rp->lock, flags); + + netif_device_attach (dev); + + return 0; +} +#endif /* CONFIG_PM */ + static struct pci_driver rhine_driver = { .name = DRV_NAME, .id_table = rhine_pci_tbl, .probe = rhine_init_one, .remove = __devexit_p(rhine_remove_one), +#ifdef CONFIG_PM + .suspend = rhine_suspend, + .resume = rhine_resume, +#endif /* CONFIG_PM */ .driver = { .shutdown = rhine_shutdown, }