This change ensures the kernel will use DPC on a supporting device if the kernel will also control AER on the Root Ports & RCECs. The rules around controlling DPC/AER are somewhat clear in PCIe/ACPI specifications. It is recommended to always link control of both to the same entity, being the OS or system firmware. The kernel wants to be flexible by first having a default policy, but also by providing command line parameters to enable us all to do what we want even if it might violate the recommendations. The following mentioned patch brought the kernels default behavior more in line with the specification around AER, but changed its behavior around DPC on PCIe Downstream Switch Ports; preventing the kernel from controlling DPC on them unless using pcie_ports=dpc-native. * "PCI/portdrv: Allow AER service only for Root Ports & RCECs" After this change the behavior around using DPC on PCIe switch ports and Root Ports should be as it was before. Signed-off-by: Matthew W Carlis <mattc@xxxxxxxxxxxxxxx> --- drivers/pci/pcie/portdrv.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 14a4b89a3b83..8e023aa97672 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -257,12 +257,19 @@ static int get_port_device_capability(struct pci_dev *dev) } /* + * _OSC AER Control is required by the OS & requires OS to control AER, + * but _OSC DPC Control isn't required by the OS to control DPC; however + * it does require the OS to control DPC. _OSC DPC Control also requres + * _OSC EDR Control (Error Disconnect Recovery) (PCI Firmware - DPC ECN rev3.2) + * PCI_Express_Base 6.1, 6.2.11 Determination of DPC Control recommends + * platform fw or OS always link control of DPC to AER. + * * With dpc-native, allow Linux to use DPC even if it doesn't have * permission to use AER. */ if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC) && - pci_aer_available() && - (pcie_ports_dpc_native || (services & PCIE_PORT_SERVICE_AER))) + pci_aer_available() && (pcie_ports_dpc_native || + (dev->aer_cap && host->native_aer))) services |= PCIE_PORT_SERVICE_DPC; if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM || -- 2.17.1