Blob Blame History Raw
From e3c44b8ddc2349b48950b3b15c3b9d74655356c7 Mon Sep 17 00:00:00 2001
From: Bjorn Helgaas <bhelgaas@google.com>
Date: Thu, 25 Jan 2018 12:49:27 -0600
Subject: [PATCH] PCI/DPC: Read RP PIO Log Size once at probe
Git-commit: e3c44b8ddc2349b48950b3b15c3b9d74655356c7
Patch-mainline: v4.16-rc1
References: FATE#325195

The RP PIO Log Size is a read-only field in the DPC Capability, so it is
constant and known at probe-time, but previously we read it every time we
processed an RP PIO error.

Read it once in dpc_probe() (if the RP Extensions for DPC are supported)
and remember the size in struct dpc_dev.  No functional change intended.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Keith Busch <keith.busch@intel.com>
Reviewed-by: Sinan Kaya <okaya@codeaurora.org>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/pci/pcie/pcie-dpc.c |   29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -34,7 +34,6 @@ struct dpc_rp_pio_regs {
 	struct rp_pio_header_log_regs header_log;
 	u32 impspec_log;
 	u32 tlp_prefix_log[4];
-	u32 log_size;
 	u16 first_error;
 };
 
@@ -44,6 +43,7 @@ struct dpc_dev {
 	u16			cap_pos;
 	bool			rp_extensions;
 	u32			rp_pio_status;
+	u8			rp_log_size;
 };
 
 static const char * const rp_pio_error_string[] = {
@@ -173,11 +173,12 @@ static void dpc_rp_pio_print_error(struc
 	}
 
 	dpc_rp_pio_print_tlp_header(dev, &rp_pio->header_log);
-	if (rp_pio->log_size == 4)
+	if (dpc->rp_log_size == 4)
 		return;
+
 	dev_err(dev, "RP PIO ImpSpec Log %#010x\n", rp_pio->impspec_log);
 
-	for (i = 0; i < rp_pio->log_size - 5; i++)
+	for (i = 0; i < dpc->rp_log_size - 5; i++)
 		dev_err(dev, "TLP Prefix Header: dw%d, %#010x\n", i,
 			rp_pio->tlp_prefix_log[i]);
 }
@@ -186,7 +187,6 @@ static void dpc_rp_pio_get_info(struct d
 				struct dpc_rp_pio_regs *rp_pio)
 {
 	struct pci_dev *pdev = dpc->dev->port;
-	struct device *dev = &dpc->dev->device;
 	int i;
 	u16 cap = dpc->cap_pos, status;
 
@@ -206,13 +206,8 @@ static void dpc_rp_pio_get_info(struct d
 	pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
 	rp_pio->first_error = (status & 0x1f00) >> 8;
 
-	pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap);
-	rp_pio->log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
-	if (rp_pio->log_size < 4 || rp_pio->log_size > 9) {
-		dev_err(dev, "RP PIO log size %u is invalid\n",
-			rp_pio->log_size);
+	if (dpc->rp_log_size < 4)
 		return;
-	}
 
 	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
 			      &rp_pio->header_log.dw0);
@@ -222,12 +217,12 @@ static void dpc_rp_pio_get_info(struct d
 			      &rp_pio->header_log.dw2);
 	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 12,
 			      &rp_pio->header_log.dw3);
-	if (rp_pio->log_size == 4)
+	if (dpc->rp_log_size == 4)
 		return;
 
 	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG,
 			      &rp_pio->impspec_log);
-	for (i = 0; i < rp_pio->log_size - 5; i++)
+	for (i = 0; i < dpc->rp_log_size - 5; i++)
 		pci_read_config_dword(pdev,
 			cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
 			&rp_pio->tlp_prefix_log[i]);
@@ -327,6 +322,14 @@ static int dpc_probe(struct pcie_device
 	pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, &ctl);
 
 	dpc->rp_extensions = (cap & PCI_EXP_DPC_CAP_RP_EXT);
+	if (dpc->rp_extensions) {
+		dpc->rp_log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
+		if (dpc->rp_log_size < 4 || dpc->rp_log_size > 9) {
+			dev_err(device, "RP PIO log size %u is invalid\n",
+				dpc->rp_log_size);
+			dpc->rp_log_size = 0;
+		}
+	}
 
 	ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN;
 	pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl);
@@ -334,7 +337,7 @@ static int dpc_probe(struct pcie_device
 	dev_info(device, "DPC error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n",
 		cap & 0xf, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT),
 		FLAG(cap, PCI_EXP_DPC_CAP_POISONED_TLP),
-		FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), (cap >> 8) & 0xf,
+		FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), dpc->rp_log_size,
 		FLAG(cap, PCI_EXP_DPC_CAP_DL_ACTIVE));
 	return status;
 }