e100: fix reboot -f with netconsole enabled
Subsystems (2)
e100: FIX: fix netconsole fast reboot attached to e100
When rebooting with netconsole over e100, the driver shutdown code would deadlock with netpoll. Reduce shutdown code to a bare minimum while retaining WoL and suspend functionality.
Signed-off-by Auke Kok <[email protected]>
Signed-off-by Andrew Morton <[email protected]>
---
drivers/net/e100.c | 50 ++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 19 deletions(-)
drivers/net/e100.c +31 -19
@@ -2039,7 +2039,6 @@ static int e100_change_mtu(struct net_dereturn 0 ; } -#ifdef CONFIG_PM static int e100_asf (struct nic *nic) {/* ASF can be enabled from eeprom */
@@ -2048,7 +2047,6 @@ static int e100_asf(struct nic *nic) !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE)); } -#endif static int e100_up (struct nic *nic) {
@@ -2715,34 +2713,32 @@ static void __devexit e100_remove(struct } } +#ifdef CONFIG_PM static int e100_suspend (struct pci_dev *pdev,pm_message_t state) {struct net_device *netdev =pci_get_drvdata (pdev);struct nic *nic =netdev_priv (netdev); -if (netif_running (netdev)) -e100_down (nic); -e100_hw_reset (nic); -netif_device_detach (netdev); +netif_poll_disable (nic->netdev); +del_timer_sync (&nic->watchdog); +netif_carrier_off (nic->netdev); -#ifdef CONFIG_PMpci_save_state (pdev); - if (nic->flags & (wol_magic | e100_asf(nic))) -#else - if (nic->flags & (wol_magic)) -#endif - pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); - else - /* disable PME */ - pci_enable_wake(pdev, 0, 0); + +if ((nic->flags & wol_magic) |e100_asf (nic)) { +pci_enable_wake (pdev, PCI_D3hot,1 ); +pci_enable_wake (pdev, PCI_D3cold,1 ); + }else { +pci_enable_wake (pdev, PCI_D3hot,0 ); +pci_enable_wake (pdev, PCI_D3cold,0 ); + }pci_disable_device (pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); +pci_set_power_state (pdev, PCI_D3hot);return 0 ; } -#ifdef CONFIG_PMstatic int e100_resume (struct pci_dev *pdev) {struct net_device *netdev =pci_get_drvdata (pdev);
@@ -2764,7 +2760,23 @@ #endif /* CONFIG_PM */static void e100_shutdown (struct pci_dev *pdev) { -e100_suspend (pdev,PMSG_SUSPEND ); +struct net_device *netdev =pci_get_drvdata (pdev); +struct nic *nic =netdev_priv (netdev); + +netif_poll_disable (nic->netdev); +del_timer_sync (&nic->watchdog); +netif_carrier_off (nic->netdev); + +if ((nic->flags & wol_magic) |e100_asf (nic)) { +pci_enable_wake (pdev, PCI_D3hot,1 ); +pci_enable_wake (pdev, PCI_D3cold,1 ); + }else { +pci_enable_wake (pdev, PCI_D3hot,0 ); +pci_enable_wake (pdev, PCI_D3cold,0 ); + } + +pci_disable_device (pdev); +pci_set_power_state (pdev, PCI_D3hot); }/* ------------------ PCI Error Recovery infrastructure -------------- */
@@ -2848,9 +2860,9 @@ static struct pci_driver e100_driver = { .id_table = e100_id_table, .probe = e100_probe, .remove =__devexit_p (e100_remove), +#ifdef CONFIG_PM/* Power Management hooks */ .suspend = e100_suspend, -#ifdef CONFIG_PM .resume = e100_resume, #endif .shutdown = e100_shutdown,