aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c71
1 files changed, 59 insertions, 12 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 0a3bb53f3eee..13f814485a36 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12721,17 +12721,11 @@ init_one_exit:
12721 return rc; 12721 return rc;
12722} 12722}
12723 12723
12724static void bnx2x_remove_one(struct pci_dev *pdev) 12724static void __bnx2x_remove(struct pci_dev *pdev,
12725 struct net_device *dev,
12726 struct bnx2x *bp,
12727 bool remove_netdev)
12725{ 12728{
12726 struct net_device *dev = pci_get_drvdata(pdev);
12727 struct bnx2x *bp;
12728
12729 if (!dev) {
12730 dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n");
12731 return;
12732 }
12733 bp = netdev_priv(dev);
12734
12735 /* Delete storage MAC address */ 12729 /* Delete storage MAC address */
12736 if (!NO_FCOE(bp)) { 12730 if (!NO_FCOE(bp)) {
12737 rtnl_lock(); 12731 rtnl_lock();
@@ -12744,7 +12738,15 @@ static void bnx2x_remove_one(struct pci_dev *pdev)
12744 bnx2x_dcbnl_update_applist(bp, true); 12738 bnx2x_dcbnl_update_applist(bp, true);
12745#endif 12739#endif
12746 12740
12747 unregister_netdev(dev); 12741 /* Close the interface - either directly or implicitly */
12742 if (remove_netdev) {
12743 unregister_netdev(dev);
12744 } else {
12745 rtnl_lock();
12746 if (netif_running(dev))
12747 bnx2x_close(dev);
12748 rtnl_unlock();
12749 }
12748 12750
12749 /* Power on: we can't let PCI layer write to us while we are in D3 */ 12751 /* Power on: we can't let PCI layer write to us while we are in D3 */
12750 if (IS_PF(bp)) 12752 if (IS_PF(bp))
@@ -12766,6 +12768,12 @@ static void bnx2x_remove_one(struct pci_dev *pdev)
12766 if (IS_VF(bp)) 12768 if (IS_VF(bp))
12767 bnx2x_vfpf_release(bp); 12769 bnx2x_vfpf_release(bp);
12768 12770
12771 /* Assumes no further PCIe PM changes will occur */
12772 if (system_state == SYSTEM_POWER_OFF) {
12773 pci_wake_from_d3(pdev, bp->wol);
12774 pci_set_power_state(pdev, PCI_D3hot);
12775 }
12776
12769 if (bp->regview) 12777 if (bp->regview)
12770 iounmap(bp->regview); 12778 iounmap(bp->regview);
12771 12779
@@ -12780,7 +12788,8 @@ static void bnx2x_remove_one(struct pci_dev *pdev)
12780 } 12788 }
12781 bnx2x_free_mem_bp(bp); 12789 bnx2x_free_mem_bp(bp);
12782 12790
12783 free_netdev(dev); 12791 if (remove_netdev)
12792 free_netdev(dev);
12784 12793
12785 if (atomic_read(&pdev->enable_cnt) == 1) 12794 if (atomic_read(&pdev->enable_cnt) == 1)
12786 pci_release_regions(pdev); 12795 pci_release_regions(pdev);
@@ -12789,6 +12798,20 @@ static void bnx2x_remove_one(struct pci_dev *pdev)
12789 pci_set_drvdata(pdev, NULL); 12798 pci_set_drvdata(pdev, NULL);
12790} 12799}
12791 12800
12801static void bnx2x_remove_one(struct pci_dev *pdev)
12802{
12803 struct net_device *dev = pci_get_drvdata(pdev);
12804 struct bnx2x *bp;
12805
12806 if (!dev) {
12807 dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n");
12808 return;
12809 }
12810 bp = netdev_priv(dev);
12811
12812 __bnx2x_remove(pdev, dev, bp, true);
12813}
12814
12792static int bnx2x_eeh_nic_unload(struct bnx2x *bp) 12815static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
12793{ 12816{
12794 bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; 12817 bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
@@ -12968,6 +12991,29 @@ static const struct pci_error_handlers bnx2x_err_handler = {
12968 .resume = bnx2x_io_resume, 12991 .resume = bnx2x_io_resume,
12969}; 12992};
12970 12993
12994static void bnx2x_shutdown(struct pci_dev *pdev)
12995{
12996 struct net_device *dev = pci_get_drvdata(pdev);
12997 struct bnx2x *bp;
12998
12999 if (!dev)
13000 return;
13001
13002 bp = netdev_priv(dev);
13003 if (!bp)
13004 return;
13005
13006 rtnl_lock();
13007 netif_device_detach(dev);
13008 rtnl_unlock();
13009
13010 /* Don't remove the netdevice, as there are scenarios which will cause
13011 * the kernel to hang, e.g., when trying to remove bnx2i while the
13012 * rootfs is mounted from SAN.
13013 */
13014 __bnx2x_remove(pdev, dev, bp, false);
13015}
13016
12971static struct pci_driver bnx2x_pci_driver = { 13017static struct pci_driver bnx2x_pci_driver = {
12972 .name = DRV_MODULE_NAME, 13018 .name = DRV_MODULE_NAME,
12973 .id_table = bnx2x_pci_tbl, 13019 .id_table = bnx2x_pci_tbl,
@@ -12979,6 +13025,7 @@ static struct pci_driver bnx2x_pci_driver = {
12979#ifdef CONFIG_BNX2X_SRIOV 13025#ifdef CONFIG_BNX2X_SRIOV
12980 .sriov_configure = bnx2x_sriov_configure, 13026 .sriov_configure = bnx2x_sriov_configure,
12981#endif 13027#endif
13028 .shutdown = bnx2x_shutdown,
12982}; 13029};
12983 13030
12984static int __init bnx2x_init(void) 13031static int __init bnx2x_init(void)