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: 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>
This commit is contained in:
Mark Rustad 2014-03-12 00:38:40 +00:00 committed by Jeff Kirsher
parent 6d39d589bb
commit 58cf663f0e
2 changed files with 15 additions and 1 deletions

View File

@ -811,6 +811,7 @@ enum ixgbe_state_t {
__IXGBE_DISABLED,
__IXGBE_REMOVING,
__IXGBE_SERVICE_SCHED,
__IXGBE_SERVICE_INITED,
__IXGBE_IN_SFP_INIT,
__IXGBE_PTP_RUNNING,
__IXGBE_PTP_TX_IN_PROGRESS,

View File

@ -297,7 +297,8 @@ static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
return;
hw->hw_addr = NULL;
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)
@ -8023,6 +8024,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* EEPROM */
memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops));
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 (!(eec & (1 << 8)))
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)
setup_timer(&adapter->service_timer, &ixgbe_service_timer,
(unsigned long) adapter);
if (ixgbe_removed(hw->hw_addr)) {
err = -EIO;
goto err_sw_init;
}
INIT_WORK(&adapter->service_task, ixgbe_service_task);
set_bit(__IXGBE_SERVICE_INITED, &adapter->state);
clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
err = ixgbe_init_interrupt_scheme(adapter);
@ -8494,6 +8504,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
skip_bad_vf_detection:
#endif /* CONFIG_PCI_IOV */
if (!test_bit(__IXGBE_SERVICE_INITED, &adapter->state))
return PCI_ERS_RESULT_DISCONNECT;
rtnl_lock();
netif_device_detach(netdev);