Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bnx2: Add pci shutdown handler.

WoL and power state changes will now be done in the shutdown handler.
open/close/ethtool will no longer change the power state. NVRAM
operations can now be permitted whether the device is up or down.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Michael Chan and committed by
David S. Miller
25bfb1dd 28fb4eb4

+25 -22
+25 -22
drivers/net/ethernet/broadcom/bnx2.c
··· 6302 6302 6303 6303 netif_carrier_off(dev); 6304 6304 6305 - bnx2_set_power_state(bp, PCI_D0); 6306 6305 bnx2_disable_int(bp); 6307 6306 6308 6307 rc = bnx2_setup_int_mode(bp, disable_msi); ··· 6708 6709 bnx2_del_napi(bp); 6709 6710 bp->link_up = 0; 6710 6711 netif_carrier_off(bp->dev); 6711 - bnx2_set_power_state(bp, PCI_D3hot); 6712 6712 return 0; 6713 6713 } 6714 6714 ··· 7142 7144 struct bnx2 *bp = netdev_priv(dev); 7143 7145 int rc; 7144 7146 7145 - if (!netif_running(dev)) 7146 - return -EAGAIN; 7147 - 7148 7147 /* parameters already validated in ethtool_get_eeprom */ 7149 7148 7150 7149 rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len); ··· 7155 7160 { 7156 7161 struct bnx2 *bp = netdev_priv(dev); 7157 7162 int rc; 7158 - 7159 - if (!netif_running(dev)) 7160 - return -EAGAIN; 7161 7163 7162 7164 /* parameters already validated in ethtool_set_eeprom */ 7163 7165 ··· 7515 7523 { 7516 7524 struct bnx2 *bp = netdev_priv(dev); 7517 7525 7518 - bnx2_set_power_state(bp, PCI_D0); 7519 - 7520 7526 memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS); 7521 7527 if (etest->flags & ETH_TEST_FL_OFFLINE) { 7522 7528 int i; ··· 7563 7573 etest->flags |= ETH_TEST_FL_FAILED; 7564 7574 7565 7575 } 7566 - if (!netif_running(bp->dev)) 7567 - bnx2_set_power_state(bp, PCI_D3hot); 7568 7576 } 7569 7577 7570 7578 static void ··· 7634 7646 7635 7647 switch (state) { 7636 7648 case ETHTOOL_ID_ACTIVE: 7637 - bnx2_set_power_state(bp, PCI_D0); 7638 - 7639 7649 bp->leds_save = BNX2_RD(bp, BNX2_MISC_CFG); 7640 7650 BNX2_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); 7641 7651 return 1; /* cycle on/off once per second */ ··· 7654 7668 case ETHTOOL_ID_INACTIVE: 7655 7669 BNX2_WR(bp, BNX2_EMAC_LED, 0); 7656 7670 BNX2_WR(bp, BNX2_MISC_CFG, bp->leds_save); 7657 - 7658 - if (!netif_running(dev)) 7659 - bnx2_set_power_state(bp, PCI_D3hot); 7660 7671 break; 7661 7672 } 7662 7673 ··· 8100 8117 rc = -ENOMEM; 8101 8118 goto err_out_release; 8102 8119 } 8103 - 8104 - bnx2_set_power_state(bp, PCI_D0); 8105 8120 8106 8121 /* Configure byte swap and enable write to the reg_window registers. 8107 8122 * Rely on CPU to do target byte swapping on big endian systems ··· 8686 8705 pci_restore_state(pdev); 8687 8706 pci_save_state(pdev); 8688 8707 8689 - if (netif_running(dev)) { 8690 - bnx2_set_power_state(bp, PCI_D0); 8708 + if (netif_running(dev)) 8691 8709 err = bnx2_init_nic(bp, 1); 8692 - } 8710 + 8693 8711 if (!err) 8694 8712 result = PCI_ERS_RESULT_RECOVERED; 8695 8713 } ··· 8732 8752 rtnl_unlock(); 8733 8753 } 8734 8754 8755 + static void bnx2_shutdown(struct pci_dev *pdev) 8756 + { 8757 + struct net_device *dev = pci_get_drvdata(pdev); 8758 + struct bnx2 *bp; 8759 + 8760 + if (!dev) 8761 + return; 8762 + 8763 + bp = netdev_priv(dev); 8764 + if (!bp) 8765 + return; 8766 + 8767 + rtnl_lock(); 8768 + if (netif_running(dev)) 8769 + dev_close(bp->dev); 8770 + 8771 + if (system_state == SYSTEM_POWER_OFF) 8772 + bnx2_set_power_state(bp, PCI_D3hot); 8773 + 8774 + rtnl_unlock(); 8775 + } 8776 + 8735 8777 static const struct pci_error_handlers bnx2_err_handler = { 8736 8778 .error_detected = bnx2_io_error_detected, 8737 8779 .slot_reset = bnx2_io_slot_reset, ··· 8767 8765 .remove = bnx2_remove_one, 8768 8766 .driver.pm = BNX2_PM_OPS, 8769 8767 .err_handler = &bnx2_err_handler, 8768 + .shutdown = bnx2_shutdown, 8770 8769 }; 8771 8770 8772 8771 module_pci_driver(bnx2_pci_driver);