[PATCH] Prevent AER driver from being loaded on PCIE devices which are not root ports.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The PCI Express port driver is registering the AER service for any device
reporting AER capability. The AER driver uses registers which are only
available on PCI Express device root port devices which advertise AER
capabilities.

This patch adds a check that the PCI Express device is a root port before
enabling the AER service driver on that port.

Signed-off-by: Malcolm Crossley <malcolm.crossley2@xxxxxxxxxxx>
---
A bug was seen on boards using a PLX 8518 switch device which advertises AER
on each of it's transparent bridges. The AER driver was loaded for each bridge
and this driver tried to access the AER source ID register whenever an interrupt
occured on the shared PCI INTX lines. The source ID register does not exist
on non root port PCIE device's  which advertise AER and trying to access this 
register causes a unsupported request error on the bridge. Thus, when the next 
interrupt occurs, another error is found and the non existent source ID 
register is accessed again, and so it goes on. 

The result is a spammed dmesg with unsupported request PCI express errors on 
the bridge device that the AER driver is loaded against.


 drivers/pci/pcie/portdrv_core.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 52f84fc..2f0cfd5 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -225,7 +225,9 @@ static int get_port_device_capability(struct pci_dev *dev)
 	int services = 0, pos;
 	u16 reg16;
 	u32 reg32;
+	struct pcie_port_data *port_data;
 
+	port_data = pci_get_drvdata(dev);
 	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
 	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
 	/* Hot-Plug Capable */
@@ -236,7 +238,8 @@ static int get_port_device_capability(struct pci_dev *dev)
 			services |= PCIE_PORT_SERVICE_HP;
 	}
 	/* AER capable */
-	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
+	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR) &&
+		port_data->port_type == PCIE_RC_PORT)
 		services |= PCIE_PORT_SERVICE_AER;
 	/* VC support */
 	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))


--
Malcolm Crossley, Software Engineer, 
GE Fanuc Intelligent Platforms
GE Fanuc Intelligent Platforms Ltd, registered in England and Wales
(3828642) at 100 Barbirolli Square, Manchester, M2 3AB, VAT GB729849476

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux