mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Merge branch 'pci/err'
- For drivers using PCI legacy suspend, save config state at suspend so that state (not any earlier state from enumeration, probe, or error recovery) will be restored when resuming (Lukas Wunner) - For devices with no driver or a driver that lacks PM, save config state at hibernate so that state (not any earlier state from enumeration, probe, or error recovery) will be restored when resuming (Lukas Wunner) - Save device config space on device addition, before driver binding, so error recovery works more reliably (Lukas Wunner) - Drop pci_save_state() from several drivers that no longer need it since the PCI core always does it and pci_restore_state() no longer invalidates the saved state (Lukas Wunner) - Document use of pci_save_state() by drivers to capture the state they want restored during error recovery (Lukas Wunner) * pci/err: Documentation: PCI: Amend error recovery doc with pci_save_state() rules treewide: Drop pci_save_state() after pci_restore_state() PCI/ERR: Ensure error recoverability at all times PCI/PM: Stop needlessly clearing state_saved on enumeration and thaw PCI/PM: Reinstate clearing state_saved in legacy and !PM codepaths
This commit is contained in:
@@ -326,6 +326,21 @@ be recovered, there is nothing more that can be done; the platform
|
||||
will typically report a "permanent failure" in such a case. The
|
||||
device will be considered "dead" in this case.
|
||||
|
||||
Drivers typically need to call pci_restore_state() after reset to
|
||||
re-initialize the device's config space registers and thereby
|
||||
bring it from D0\ :sub:`uninitialized` into D0\ :sub:`active` state
|
||||
(PCIe r7.0 sec 5.3.1.1). The PCI core invokes pci_save_state()
|
||||
on enumeration after initializing config space to ensure that a
|
||||
saved state is available for subsequent error recovery.
|
||||
Drivers which modify config space on probe may need to invoke
|
||||
pci_save_state() afterwards to record those changes for later
|
||||
error recovery. When going into system suspend, pci_save_state()
|
||||
is called for every PCI device and that state will be restored
|
||||
not only on resume, but also on any subsequent error recovery.
|
||||
In the unlikely event that the saved state recorded on suspend
|
||||
is unsuitable for error recovery, drivers should call
|
||||
pci_save_state() on resume.
|
||||
|
||||
Drivers for multi-function cards will need to coordinate among
|
||||
themselves as to which driver instance will perform any "one-shot"
|
||||
or global device initialization. For example, the Symbios sym53cxx2
|
||||
|
||||
@@ -105,7 +105,6 @@ void adf_dev_restore(struct adf_accel_dev *accel_dev)
|
||||
accel_dev->accel_id);
|
||||
hw_device->reset_device(accel_dev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +203,6 @@ static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev)
|
||||
if (!pdev->is_busmaster)
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
res = adf_dev_up(accel_dev, false);
|
||||
if (res && res != -EALREADY)
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
|
||||
@@ -1286,7 +1286,6 @@ static pci_ers_result_t ioat_pcie_error_slot_reset(struct pci_dev *pdev)
|
||||
} else {
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
pci_wake_from_d3(pdev, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -6444,7 +6444,6 @@ bnx2_reset_task(struct work_struct *work)
|
||||
if (!(pcicmd & PCI_COMMAND_MEMORY)) {
|
||||
/* in case PCI block has reset */
|
||||
pci_restore_state(bp->pdev);
|
||||
pci_save_state(bp->pdev);
|
||||
}
|
||||
rc = bnx2_init_nic(bp, 1);
|
||||
if (rc) {
|
||||
@@ -8718,7 +8717,6 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev)
|
||||
} else {
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (netif_running(dev))
|
||||
err = bnx2_init_nic(bp, 1);
|
||||
|
||||
@@ -14216,7 +14216,6 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (netif_running(dev))
|
||||
bnx2x_set_power_state(bp, PCI_D0);
|
||||
|
||||
@@ -18352,7 +18352,6 @@ static pci_ers_result_t tg3_io_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (!netdev || !netif_running(netdev)) {
|
||||
rc = PCI_ERS_RESULT_RECOVERED;
|
||||
|
||||
@@ -2933,7 +2933,6 @@ static int t3_reenable_adapter(struct adapter *adapter)
|
||||
}
|
||||
pci_set_master(adapter->pdev);
|
||||
pci_restore_state(adapter->pdev);
|
||||
pci_save_state(adapter->pdev);
|
||||
|
||||
/* Free sge resources */
|
||||
t3_free_sge_resources(adapter);
|
||||
|
||||
@@ -5456,7 +5456,6 @@ static pci_ers_result_t eeh_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
if (!adap) {
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
return PCI_ERS_RESULT_RECOVERED;
|
||||
}
|
||||
|
||||
@@ -5471,7 +5470,6 @@ static pci_ers_result_t eeh_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (t4_wait_dev_ready(adap->regs) < 0)
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
|
||||
@@ -158,7 +158,6 @@ static pci_ers_result_t hbg_pci_err_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
hbg_err_reset(priv);
|
||||
return PCI_ERS_RESULT_RECOVERED;
|
||||
|
||||
@@ -7195,7 +7195,6 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
|
||||
"Cannot re-enable PCI device after reset.\n");
|
||||
result = PCI_ERS_RESULT_DISCONNECT;
|
||||
} else {
|
||||
pdev->state_saved = true;
|
||||
pci_restore_state(pdev);
|
||||
pci_set_master(pdev);
|
||||
|
||||
|
||||
@@ -2423,12 +2423,6 @@ static pci_ers_result_t fm10k_io_slot_reset(struct pci_dev *pdev)
|
||||
} else {
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
|
||||
/* After second error pci->state_saved is false, this
|
||||
* resets it so EEH doesn't break.
|
||||
*/
|
||||
pci_save_state(pdev);
|
||||
|
||||
pci_wake_from_d3(pdev, false);
|
||||
|
||||
result = PCI_ERS_RESULT_RECOVERED;
|
||||
|
||||
@@ -16455,7 +16455,6 @@ static pci_ers_result_t i40e_pci_error_slot_reset(struct pci_dev *pdev)
|
||||
} else {
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
pci_wake_from_d3(pdev, false);
|
||||
|
||||
reg = rd32(&pf->hw, I40E_GLGEN_RTRIG);
|
||||
|
||||
@@ -5663,7 +5663,6 @@ static int ice_resume(struct device *dev)
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (!pci_device_is_present(pdev))
|
||||
return -ENODEV;
|
||||
@@ -5763,7 +5762,6 @@ static pci_ers_result_t ice_pci_err_slot_reset(struct pci_dev *pdev)
|
||||
} else {
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
pci_wake_from_d3(pdev, false);
|
||||
|
||||
/* Check for life */
|
||||
|
||||
@@ -9599,7 +9599,6 @@ static int __igb_resume(struct device *dev, bool rpm)
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (!pci_device_is_present(pdev))
|
||||
return -ENODEV;
|
||||
@@ -9754,7 +9753,6 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
|
||||
} else {
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||
pci_enable_wake(pdev, PCI_D3cold, 0);
|
||||
|
||||
@@ -7530,7 +7530,6 @@ static int __igc_resume(struct device *dev, bool rpm)
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (!pci_device_is_present(pdev))
|
||||
return -ENODEV;
|
||||
@@ -7667,7 +7666,6 @@ static pci_ers_result_t igc_io_slot_reset(struct pci_dev *pdev)
|
||||
} else {
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||
pci_enable_wake(pdev, PCI_D3cold, 0);
|
||||
|
||||
@@ -12297,7 +12297,6 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
|
||||
adapter->hw.hw_addr = adapter->io_addr;
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
pci_wake_from_d3(pdev, false);
|
||||
|
||||
|
||||
@@ -4366,7 +4366,6 @@ static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
return PCI_ERS_RESULT_RECOVERED;
|
||||
}
|
||||
|
||||
|
||||
@@ -2095,7 +2095,6 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
err = wait_vital(pdev);
|
||||
if (err) {
|
||||
|
||||
@@ -574,7 +574,6 @@ static pci_ers_result_t fbnic_err_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (pci_enable_device_mem(pdev)) {
|
||||
dev_err(&pdev->dev,
|
||||
|
||||
@@ -3915,7 +3915,6 @@ static int lan743x_pm_resume(struct device *dev)
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
/* Restore HW_CFG that was saved during pm suspend */
|
||||
if (adapter->is_pci11x1x)
|
||||
|
||||
@@ -3416,10 +3416,6 @@ static void myri10ge_watchdog(struct work_struct *work)
|
||||
* nic was resumed from power saving mode.
|
||||
*/
|
||||
pci_restore_state(mgp->pdev);
|
||||
|
||||
/* save state again for accounting reasons */
|
||||
pci_save_state(mgp->pdev);
|
||||
|
||||
} else {
|
||||
/* if we get back -1's from our slot, perhaps somebody
|
||||
* powered off our card. Don't try to reset it in
|
||||
|
||||
@@ -3425,7 +3425,6 @@ static void s2io_reset(struct s2io_nic *sp)
|
||||
|
||||
/* Restore the PCI state saved during initialization. */
|
||||
pci_restore_state(sp->pdev);
|
||||
pci_save_state(sp->pdev);
|
||||
pci_read_config_word(sp->pdev, 0x2, &val16);
|
||||
if (check_pci_device_id(val16) != (u16)PCI_ANY_ID)
|
||||
break;
|
||||
|
||||
@@ -357,6 +357,9 @@ void pci_bus_add_device(struct pci_dev *dev)
|
||||
pci_proc_attach_device(dev);
|
||||
pci_bridge_d3_update(dev);
|
||||
|
||||
/* Save config space for error recoverability */
|
||||
pci_save_state(dev);
|
||||
|
||||
/*
|
||||
* If the PCI device is associated with a pwrctrl device with a
|
||||
* power supply, create a device link between the PCI device and
|
||||
|
||||
@@ -629,6 +629,8 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
struct pci_driver *drv = pci_dev->driver;
|
||||
|
||||
pci_dev->state_saved = false;
|
||||
|
||||
if (drv && drv->suspend) {
|
||||
pci_power_t prev = pci_dev->current_state;
|
||||
int error;
|
||||
@@ -1036,6 +1038,8 @@ static int pci_pm_freeze(struct device *dev)
|
||||
|
||||
if (!pm) {
|
||||
pci_pm_default_suspend(pci_dev);
|
||||
if (!pm_runtime_suspended(dev))
|
||||
pci_dev->state_saved = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1129,8 +1133,6 @@ static int pci_pm_thaw(struct device *dev)
|
||||
pci_pm_reenable_device(pci_dev);
|
||||
}
|
||||
|
||||
pci_dev->state_saved = false;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -1855,9 +1855,6 @@ static void pci_restore_rebar_state(struct pci_dev *pdev)
|
||||
*/
|
||||
void pci_restore_state(struct pci_dev *dev)
|
||||
{
|
||||
if (!dev->state_saved)
|
||||
return;
|
||||
|
||||
pci_restore_pcie_state(dev);
|
||||
pci_restore_pasid_state(dev);
|
||||
pci_restore_pri_state(dev);
|
||||
|
||||
@@ -760,7 +760,6 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)
|
||||
device_for_each_child(&dev->dev, &off, pcie_port_device_iter);
|
||||
|
||||
pci_restore_state(dev);
|
||||
pci_save_state(dev);
|
||||
return PCI_ERS_RESULT_RECOVERED;
|
||||
}
|
||||
|
||||
|
||||
@@ -2753,8 +2753,6 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
|
||||
|
||||
pci_reassigndev_resource_alignment(dev);
|
||||
|
||||
dev->state_saved = false;
|
||||
|
||||
pci_init_capabilities(dev);
|
||||
|
||||
/*
|
||||
|
||||
@@ -1528,7 +1528,6 @@ bfad_pci_slot_reset(struct pci_dev *pdev)
|
||||
goto out_disable_device;
|
||||
}
|
||||
|
||||
pci_save_state(pdev);
|
||||
pci_set_master(pdev);
|
||||
|
||||
rc = dma_set_mask_and_coherent(&bfad->pcidev->dev, DMA_BIT_MASK(64));
|
||||
|
||||
@@ -1093,7 +1093,6 @@ csio_pci_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
pci_set_master(pdev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
/* Bring HW s/m to ready state.
|
||||
* but don't resume IOs.
|
||||
|
||||
@@ -7859,7 +7859,6 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
|
||||
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
|
||||
|
||||
ENTER;
|
||||
ioa_cfg->pdev->state_saved = true;
|
||||
pci_restore_state(ioa_cfg->pdev);
|
||||
|
||||
if (ipr_set_pcix_cmd_reg(ioa_cfg)) {
|
||||
|
||||
@@ -14434,12 +14434,6 @@ lpfc_io_slot_reset_s3(struct pci_dev *pdev)
|
||||
|
||||
pci_restore_state(pdev);
|
||||
|
||||
/*
|
||||
* As the new kernel behavior of pci_restore_state() API call clears
|
||||
* device saved_state flag, need to save the restored state again.
|
||||
*/
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (pdev->is_busmaster)
|
||||
pci_set_master(pdev);
|
||||
|
||||
|
||||
@@ -7886,11 +7886,6 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev)
|
||||
|
||||
pci_restore_state(pdev);
|
||||
|
||||
/* pci_restore_state() clears the saved_state flag of the device
|
||||
* save restored state which resets saved_state flag
|
||||
*/
|
||||
pci_save_state(pdev);
|
||||
|
||||
if (ha->mem_only)
|
||||
rc = pci_enable_device_mem(pdev);
|
||||
else
|
||||
|
||||
@@ -9796,11 +9796,6 @@ qla4xxx_pci_slot_reset(struct pci_dev *pdev)
|
||||
*/
|
||||
pci_restore_state(pdev);
|
||||
|
||||
/* pci_restore_state() clears the saved_state flag of the device
|
||||
* save restored state which resets saved_state flag
|
||||
*/
|
||||
pci_save_state(pdev);
|
||||
|
||||
/* Initialize device or resume if in suspended state */
|
||||
rc = pci_enable_device(pdev);
|
||||
if (rc) {
|
||||
|
||||
@@ -6178,7 +6178,6 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
|
||||
pci_restore_state(dev);
|
||||
pci_save_state(dev);
|
||||
|
||||
return PCI_ERS_RESULT_RECOVERED;
|
||||
}
|
||||
|
||||
@@ -355,7 +355,6 @@ static void jsm_io_resume(struct pci_dev *pdev)
|
||||
struct jsm_board *brd = pci_get_drvdata(pdev);
|
||||
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
jsm_uart_port_init(brd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user