diff options
author | Mark Rustad <mark.d.rustad@intel.com> | 2014-03-11 20:38:51 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-04-11 08:58:06 -0400 |
commit | ea699569b150daa5d5f6c23040da997b83e4cfa3 (patch) | |
tree | 90b1bedd5325581712071cad614a48aa7ab976e0 | |
parent | 2049e1f6f5e6720b182c42695dbdef071804226e (diff) |
ixgbevf: Add bit to mark work queue initialization
An indication of work queue initialization is needed. This is
because register accesses prior to that time can detect a removal
and attempt to schedule the watchdog task. Adding the
__IXGBEVF_WORK_INIT bit allows this to be checked and if not
set prevent the watchdog task scheduling. By checking for a
removal right after initialization, the probe can be failed
at that point without getting the watchdog task involved.
Signed-off-by: Mark Rustad <mark.d.rustad@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 11 |
2 files changed, 11 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index e7e7d695816b..a0a1de9ce238 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | |||
@@ -421,6 +421,7 @@ enum ixbgevf_state_t { | |||
421 | __IXGBEVF_DOWN, | 421 | __IXGBEVF_DOWN, |
422 | __IXGBEVF_DISABLED, | 422 | __IXGBEVF_DISABLED, |
423 | __IXGBEVF_REMOVING, | 423 | __IXGBEVF_REMOVING, |
424 | __IXGBEVF_WORK_INIT, | ||
424 | }; | 425 | }; |
425 | 426 | ||
426 | struct ixgbevf_cb { | 427 | struct ixgbevf_cb { |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 4ba139b2d25a..905c26cfa600 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -107,7 +107,8 @@ static void ixgbevf_remove_adapter(struct ixgbe_hw *hw) | |||
107 | return; | 107 | return; |
108 | hw->hw_addr = NULL; | 108 | hw->hw_addr = NULL; |
109 | dev_err(&adapter->pdev->dev, "Adapter removed\n"); | 109 | dev_err(&adapter->pdev->dev, "Adapter removed\n"); |
110 | schedule_work(&adapter->watchdog_task); | 110 | if (test_bit(__IXGBEVF_WORK_INIT, &adapter->state)) |
111 | schedule_work(&adapter->watchdog_task); | ||
111 | } | 112 | } |
112 | 113 | ||
113 | static void ixgbevf_check_remove(struct ixgbe_hw *hw, u32 reg) | 114 | static void ixgbevf_check_remove(struct ixgbe_hw *hw, u32 reg) |
@@ -3573,8 +3574,13 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3573 | adapter->watchdog_timer.function = ixgbevf_watchdog; | 3574 | adapter->watchdog_timer.function = ixgbevf_watchdog; |
3574 | adapter->watchdog_timer.data = (unsigned long)adapter; | 3575 | adapter->watchdog_timer.data = (unsigned long)adapter; |
3575 | 3576 | ||
3577 | if (IXGBE_REMOVED(hw->hw_addr)) { | ||
3578 | err = -EIO; | ||
3579 | goto err_sw_init; | ||
3580 | } | ||
3576 | INIT_WORK(&adapter->reset_task, ixgbevf_reset_task); | 3581 | INIT_WORK(&adapter->reset_task, ixgbevf_reset_task); |
3577 | INIT_WORK(&adapter->watchdog_task, ixgbevf_watchdog_task); | 3582 | INIT_WORK(&adapter->watchdog_task, ixgbevf_watchdog_task); |
3583 | set_bit(__IXGBEVF_WORK_INIT, &adapter->state); | ||
3578 | 3584 | ||
3579 | err = ixgbevf_init_interrupt_scheme(adapter); | 3585 | err = ixgbevf_init_interrupt_scheme(adapter); |
3580 | if (err) | 3586 | if (err) |
@@ -3667,6 +3673,9 @@ static pci_ers_result_t ixgbevf_io_error_detected(struct pci_dev *pdev, | |||
3667 | struct net_device *netdev = pci_get_drvdata(pdev); | 3673 | struct net_device *netdev = pci_get_drvdata(pdev); |
3668 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 3674 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
3669 | 3675 | ||
3676 | if (!test_bit(__IXGBEVF_WORK_INIT, &adapter->state)) | ||
3677 | return PCI_ERS_RESULT_DISCONNECT; | ||
3678 | |||
3670 | rtnl_lock(); | 3679 | rtnl_lock(); |
3671 | netif_device_detach(netdev); | 3680 | netif_device_detach(netdev); |
3672 | 3681 | ||