On 6/22/2023 2:04 AM, Lukas Wunner wrote:
On Wed, Jun 21, 2023 at 06:51:51PM +0000, Smita Koralahalli wrote:
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -292,10 +292,68 @@ void dpc_process_error(struct pci_dev *pdev)
}
}
+static void pci_clear_surpdn_errors(struct pci_dev *pdev)
+{
+ u16 reg16;
+ u32 reg32;
+
+ pci_read_config_dword(pdev, pdev->dpc_cap + PCI_EXP_DPC_RP_PIO_STATUS, ®32);
+ pci_write_config_dword(pdev, pdev->dpc_cap + PCI_EXP_DPC_RP_PIO_STATUS, reg32);
Make this read+write conditional on "if (pdev->dpc_rp_extensions)"
as the register otherwise doesn't exist.
I'm checking for pdev->dpc_rpc_extensions inside
dpc_handle_surprise_removal() before calling pci_clear_surpdn_errors().
Should I recheck it once again here?
Wrap to 80 chars per line.
Okay.
+ pci_read_config_word(pdev, PCI_STATUS, ®16);
+ pci_write_config_word(pdev, PCI_STATUS, reg16);
+
+ pcie_capability_write_word(pdev, PCI_EXP_DEVSTA, PCI_EXP_DEVSTA_FED);
+}
A code comment might be useful here saying that in practice,
Surprise Down errors have been observed to also set error bits
in the Status Register as well as the Fatal Error Detected bit
in the Device Status Register.
And probably move this code comment below to where this function is
called inside dpc_handle_surprise_removal()..?
+static void dpc_handle_surprise_removal(struct pci_dev *pdev)
+{
I'm wondering if we also need
if (!pcie_wait_for_link(pdev, false)) {
pci_info(pdev, "Data Link Layer Link Active not cleared in 1000 msec\n");
goto out;
}
here, similar to dpc_reset_link() and in accordance with PCIe r6.1
sec 6.2.11:
"To ensure that the LTSSM has time to reach the Disabled state
or at least to bring the Link down under a variety of error
conditions, software must leave the Downstream Port in DPC
until the Data Link Layer Link Active bit in the Link Status
Register reads 0b; otherwise, the result is undefined."
And include the above comment in code..
+ if (pdev->dpc_rp_extensions && dpc_wait_rp_inactive(pdev)) {
+ pci_err(pdev, "failed to retrieve DPC root port on async remove\n");
+ goto out;
+ }
I don't think pci_err() is needed here as dpc_wait_rp_inactive()
already emits a message. (I think I mistakenly gave the advice
to emit an error here in an earlier review comment -- sorry!)
:)
Will take care of other comments below as well.
Thanks,
Smita
/* We configure DPC so it only triggers on ERR_FATAL */
--
2.17.1