Commit e8e82b76 authored by Auke Kok's avatar Auke Kok Committed by Linus Torvalds
Browse files

[PATCH] e100: fix reboot -f with netconsole enabled



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: default avatarAuke Kok <auke-jan.h.kok@intel.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ce9e3d99
Loading
Loading
Loading
Loading
+31 −19
Original line number Diff line number Diff line
@@ -2039,7 +2039,6 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu)
	return 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 pci_dev *pdev)
	}
}

#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_PM
	pci_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_PM
static int e100_resume(struct pci_dev *pdev)
{
	struct net_device *netdev = pci_get_drvdata(pdev);
@@ -2764,7 +2760,23 @@ static int e100_resume(struct pci_dev *pdev)

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,