Commit 58cf663f authored by Mark Rustad's avatar Mark Rustad Committed by Jeff Kirsher
Browse files

ixgbe: Add bit to mark service task initialization



There needs to be an indication when the service task has been
initialized. This is because register access prior to that time
can detect a removal and attempt to schedule the service task.
Adding the __IXGBE_SERVICE_INITED bit allows this to be checked
and if not set prevent the service task scheduling. By checking
for a removal right after initialization, the probe can be failed
at that point without getting the service task involved.
Signed-off-by: default avatarMark Rustad <mark.d.rustad@intel.com>
Tested-by: default avatarPhil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 6d39d589
...@@ -811,6 +811,7 @@ enum ixgbe_state_t { ...@@ -811,6 +811,7 @@ enum ixgbe_state_t {
__IXGBE_DISABLED, __IXGBE_DISABLED,
__IXGBE_REMOVING, __IXGBE_REMOVING,
__IXGBE_SERVICE_SCHED, __IXGBE_SERVICE_SCHED,
__IXGBE_SERVICE_INITED,
__IXGBE_IN_SFP_INIT, __IXGBE_IN_SFP_INIT,
__IXGBE_PTP_RUNNING, __IXGBE_PTP_RUNNING,
__IXGBE_PTP_TX_IN_PROGRESS, __IXGBE_PTP_TX_IN_PROGRESS,
......
...@@ -297,7 +297,8 @@ static void ixgbe_remove_adapter(struct ixgbe_hw *hw) ...@@ -297,7 +297,8 @@ static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
return; return;
hw->hw_addr = NULL; hw->hw_addr = NULL;
e_dev_err("Adapter removed\n"); e_dev_err("Adapter removed\n");
ixgbe_service_event_schedule(adapter); if (test_bit(__IXGBE_SERVICE_INITED, &adapter->state))
ixgbe_service_event_schedule(adapter);
} }
void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg) void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
...@@ -8023,6 +8024,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8023,6 +8024,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* EEPROM */ /* EEPROM */
memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops)); memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops));
eec = IXGBE_READ_REG(hw, IXGBE_EEC); eec = IXGBE_READ_REG(hw, IXGBE_EEC);
if (ixgbe_removed(hw->hw_addr)) {
err = -EIO;
goto err_ioremap;
}
/* If EEPROM is valid (bit 8 = 1), use default otherwise use bit bang */ /* If EEPROM is valid (bit 8 = 1), use default otherwise use bit bang */
if (!(eec & (1 << 8))) if (!(eec & (1 << 8)))
hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic; hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic;
...@@ -8185,7 +8190,12 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8185,7 +8190,12 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
setup_timer(&adapter->service_timer, &ixgbe_service_timer, setup_timer(&adapter->service_timer, &ixgbe_service_timer,
(unsigned long) adapter); (unsigned long) adapter);
if (ixgbe_removed(hw->hw_addr)) {
err = -EIO;
goto err_sw_init;
}
INIT_WORK(&adapter->service_task, ixgbe_service_task); INIT_WORK(&adapter->service_task, ixgbe_service_task);
set_bit(__IXGBE_SERVICE_INITED, &adapter->state);
clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state); clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
err = ixgbe_init_interrupt_scheme(adapter); err = ixgbe_init_interrupt_scheme(adapter);
...@@ -8494,6 +8504,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, ...@@ -8494,6 +8504,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
skip_bad_vf_detection: skip_bad_vf_detection:
#endif /* CONFIG_PCI_IOV */ #endif /* CONFIG_PCI_IOV */
if (!test_bit(__IXGBE_SERVICE_INITED, &adapter->state))
return PCI_ERS_RESULT_DISCONNECT;
rtnl_lock(); rtnl_lock();
netif_device_detach(netdev); netif_device_detach(netdev);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment