aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Rustad <mark.d.rustad@intel.com>2014-03-11 20:38:40 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-04-11 08:58:05 -0400
commit58cf663f0e962a51f051a84e38be281335bdf1fd (patch)
treea4a55234717f6135c645647f94afe01ca56c482d
parent6d39d589bb76ee8a1c6cde6822006ae0053decff (diff)
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>
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c15
2 files changed, 15 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 55c53a1cbb62..1a12c1dd7a27 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -811,6 +811,7 @@ enum ixgbe_state_t {
811 __IXGBE_DISABLED, 811 __IXGBE_DISABLED,
812 __IXGBE_REMOVING, 812 __IXGBE_REMOVING,
813 __IXGBE_SERVICE_SCHED, 813 __IXGBE_SERVICE_SCHED,
814 __IXGBE_SERVICE_INITED,
814 __IXGBE_IN_SFP_INIT, 815 __IXGBE_IN_SFP_INIT,
815 __IXGBE_PTP_RUNNING, 816 __IXGBE_PTP_RUNNING,
816 __IXGBE_PTP_TX_IN_PROGRESS, 817 __IXGBE_PTP_TX_IN_PROGRESS,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 8436c651b735..00c9308455b8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -297,7 +297,8 @@ static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
297 return; 297 return;
298 hw->hw_addr = NULL; 298 hw->hw_addr = NULL;
299 e_dev_err("Adapter removed\n"); 299 e_dev_err("Adapter removed\n");
300 ixgbe_service_event_schedule(adapter); 300 if (test_bit(__IXGBE_SERVICE_INITED, &adapter->state))
301 ixgbe_service_event_schedule(adapter);
301} 302}
302 303
303void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg) 304void 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 /* EEPROM */ 8024 /* EEPROM */
8024 memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops)); 8025 memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops));
8025 eec = IXGBE_READ_REG(hw, IXGBE_EEC); 8026 eec = IXGBE_READ_REG(hw, IXGBE_EEC);
8027 if (ixgbe_removed(hw->hw_addr)) {
8028 err = -EIO;
8029 goto err_ioremap;
8030 }
8026 /* If EEPROM is valid (bit 8 = 1), use default otherwise use bit bang */ 8031 /* If EEPROM is valid (bit 8 = 1), use default otherwise use bit bang */
8027 if (!(eec & (1 << 8))) 8032 if (!(eec & (1 << 8)))
8028 hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic; 8033 hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic;
@@ -8185,7 +8190,12 @@ skip_sriov:
8185 setup_timer(&adapter->service_timer, &ixgbe_service_timer, 8190 setup_timer(&adapter->service_timer, &ixgbe_service_timer,
8186 (unsigned long) adapter); 8191 (unsigned long) adapter);
8187 8192
8193 if (ixgbe_removed(hw->hw_addr)) {
8194 err = -EIO;
8195 goto err_sw_init;
8196 }
8188 INIT_WORK(&adapter->service_task, ixgbe_service_task); 8197 INIT_WORK(&adapter->service_task, ixgbe_service_task);
8198 set_bit(__IXGBE_SERVICE_INITED, &adapter->state);
8189 clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state); 8199 clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
8190 8200
8191 err = ixgbe_init_interrupt_scheme(adapter); 8201 err = ixgbe_init_interrupt_scheme(adapter);
@@ -8494,6 +8504,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
8494 8504
8495skip_bad_vf_detection: 8505skip_bad_vf_detection:
8496#endif /* CONFIG_PCI_IOV */ 8506#endif /* CONFIG_PCI_IOV */
8507 if (!test_bit(__IXGBE_SERVICE_INITED, &adapter->state))
8508 return PCI_ERS_RESULT_DISCONNECT;
8509
8497 rtnl_lock(); 8510 rtnl_lock();
8498 netif_device_detach(netdev); 8511 netif_device_detach(netdev);
8499 8512