Blob Blame History Raw
From: Keith Busch <keith.busch@intel.com>
Date: Wed, 24 Jan 2018 17:03:18 -0600
Subject: PCI/DPC: Enable DPC only if AER is available
Git-commit: eed85ff4c0da72640dcf7c0737c5a08bca2958e7
Patch-mainline: v4.16-rc1
References: bsc#1082368

The "Determination of DPC Control" implementation note in PCIe r4.0, sec
6.1.10, recommends the operating system always link DPC control to the
control of AER, as the two functionalities are strongly connected.

To avoid conflicts over whether platform firmware or the OS controls DPC,
enable DPC only if AER is enabled in the OS, and the device's error
handling does not have firmware-first AER handling.

Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <helgaas@kernel.org>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/pci/pcie/Kconfig        |    2 +-
 drivers/pci/pcie/pcie-dpc.c     |    4 ++++
 drivers/pci/pcie/portdrv_core.c |    4 ++--
 3 files changed, 7 insertions(+), 3 deletions(-)

--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -92,7 +92,7 @@ config PCIE_PME
 
 config PCIE_DPC
 	bool "PCIe Downstream Port Containment support"
-	depends on PCIEPORTBUS
+	depends on PCIEPORTBUS && PCIEAER
 	default n
 	help
 	  This enables PCI Express Downstream Port Containment (DPC)
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -15,6 +15,7 @@
 #include <linux/pci.h>
 #include <linux/pcieport_if.h>
 #include "../pci.h"
+#include "aer/aerdrv.h"
 
 struct rp_pio_header_log_regs {
 	u32 dw0;
@@ -289,6 +290,9 @@ static int dpc_probe(struct pcie_device
 	int status;
 	u16 ctl, cap;
 
+	if (pcie_aer_get_firmware_first(pdev))
+		return -ENOTSUPP;
+
 	dpc = devm_kzalloc(device, sizeof(*dpc), GFP_KERNEL);
 	if (!dpc)
 		return -ENOMEM;
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -207,9 +207,9 @@ static int get_port_device_capability(st
 		return 0;
 
 	cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
-			| PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_DPC;
+			| PCIE_PORT_SERVICE_VC;
 	if (pci_aer_available())
-		cap_mask |= PCIE_PORT_SERVICE_AER;
+		cap_mask |= PCIE_PORT_SERVICE_AER | PCIE_PORT_SERVICE_DPC;
 
 	if (pcie_ports_auto)
 		pcie_port_platform_notify(dev, &cap_mask);