aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-04-15 13:44:01 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-16 05:15:25 -0400
commit9d8d05ae66f40642987486f4b107565fc561a77c (patch)
tree72999fe5e731e785d5be685e0f9d51bf42df048d /drivers
parent4f9de721ab73a5271a79b126f7b5140b01a05c99 (diff)
NET/ixgbe: Fix powering off during shutdown
Prevent ixgbe from putting the adapter into D3 during shutdown except when we're going to power off the system, since doing that may generally cause problems with kexec to happen (such problems were observed for igb and forcedeth). For this purpose seperate ixgbe_shutdown() from ixgbe_suspend() and use the appropriate PCI PM callbacks in both of them. Signed-off-by: "Rafael J. Wysocki" <rjw@sisk.pl> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 11fd153da85f..febde45cf9fa 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -3612,9 +3612,9 @@ static int ixgbe_resume(struct pci_dev *pdev)
3612 3612
3613 return 0; 3613 return 0;
3614} 3614}
3615
3616#endif /* CONFIG_PM */ 3615#endif /* CONFIG_PM */
3617static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) 3616
3617static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
3618{ 3618{
3619 struct net_device *netdev = pci_get_drvdata(pdev); 3619 struct net_device *netdev = pci_get_drvdata(pdev);
3620 struct ixgbe_adapter *adapter = netdev_priv(netdev); 3620 struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -3673,18 +3673,46 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
3673 pci_enable_wake(pdev, PCI_D3cold, 0); 3673 pci_enable_wake(pdev, PCI_D3cold, 0);
3674 } 3674 }
3675 3675
3676 *enable_wake = !!wufc;
3677
3676 ixgbe_release_hw_control(adapter); 3678 ixgbe_release_hw_control(adapter);
3677 3679
3678 pci_disable_device(pdev); 3680 pci_disable_device(pdev);
3679 3681
3680 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 3682 return 0;
3683}
3684
3685#ifdef CONFIG_PM
3686static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
3687{
3688 int retval;
3689 bool wake;
3690
3691 retval = __ixgbe_shutdown(pdev, &wake);
3692 if (retval)
3693 return retval;
3694
3695 if (wake) {
3696 pci_prepare_to_sleep(pdev);
3697 } else {
3698 pci_wake_from_d3(pdev, false);
3699 pci_set_power_state(pdev, PCI_D3hot);
3700 }
3681 3701
3682 return 0; 3702 return 0;
3683} 3703}
3704#endif /* CONFIG_PM */
3684 3705
3685static void ixgbe_shutdown(struct pci_dev *pdev) 3706static void ixgbe_shutdown(struct pci_dev *pdev)
3686{ 3707{
3687 ixgbe_suspend(pdev, PMSG_SUSPEND); 3708 bool wake;
3709
3710 __ixgbe_shutdown(pdev, &wake);
3711
3712 if (system_state == SYSTEM_POWER_OFF) {
3713 pci_wake_from_d3(pdev, wake);
3714 pci_set_power_state(pdev, PCI_D3hot);
3715 }
3688} 3716}
3689 3717
3690/** 3718/**