From d3694d4fa3f44f6a295f8ab064937c8a1549d174 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 27 Aug 2013 09:54:40 -0600 Subject: PCI: Allow PCIe Capability link-related register access for switches Every PCIe device has a link, except Root Complex Integrated Endpoints and Root Complex Event Collectors. Previously we didn't give access to PCIe capability link-related registers for Upstream Ports, Downstream Ports, and Bridges, so attempts to read PCI_EXP_LNKCTL incorrectly returned zero. See PCIe spec r3.0, sec 7.8 and 1.3.2.3. Reference: http://lkml.kernel.org/r/979A8436335E3744ADCD3A9F2A2B68A52AD136BE@SJEXCHMB10.corp.ad.broadcom.com Reported-by: Yuval Mintz Signed-off-by: Bjorn Helgaas Reviewed-By: Jiang Liu --- drivers/pci/access.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/pci/access.c') diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 1cc23661f79..e26c3bd9aca 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -485,9 +485,13 @@ static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev) int type = pci_pcie_type(dev); return pcie_cap_version(dev) > 1 || - type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_ENDPOINT || - type == PCI_EXP_TYPE_LEG_END; + type == PCI_EXP_TYPE_LEG_END || + type == PCI_EXP_TYPE_ROOT_PORT || + type == PCI_EXP_TYPE_UPSTREAM || + type == PCI_EXP_TYPE_DOWNSTREAM || + type == PCI_EXP_TYPE_PCI_BRIDGE || + type == PCI_EXP_TYPE_PCIE_BRIDGE; } static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev) -- cgit v1.2.3-70-g09d2 From c8b303d0206b28c4ff3aecada47108d1655ae00f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 28 Aug 2013 11:33:53 -0600 Subject: PCI: Remove PCIe Capability version checks Previously we relied on the PCIe r3.0, sec 7.8, spec language that says "For Functions that do not implement the [Link, Slot, Root] registers, these spaces must be hardwired to 0b," which means that for v2 PCIe capabilities, we don't need to check the device type at all. But it's simpler if we don't need to check the capability version at all, and I think the spec is explicit enough about which registers are required for which types that we can remove the version checks. Signed-off-by: Bjorn Helgaas Reviewed-By: Jiang Liu --- drivers/pci/access.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/pci/access.c') diff --git a/drivers/pci/access.c b/drivers/pci/access.c index e26c3bd9aca..9a46fa9135d 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -484,8 +484,7 @@ static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev) { int type = pci_pcie_type(dev); - return pcie_cap_version(dev) > 1 || - type == PCI_EXP_TYPE_ENDPOINT || + return type == PCI_EXP_TYPE_ENDPOINT || type == PCI_EXP_TYPE_LEG_END || type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_UPSTREAM || @@ -498,8 +497,7 @@ static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev) { int type = pci_pcie_type(dev); - return pcie_cap_version(dev) > 1 || - type == PCI_EXP_TYPE_ROOT_PORT || + return type == PCI_EXP_TYPE_ROOT_PORT || (type == PCI_EXP_TYPE_DOWNSTREAM && pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT); } @@ -508,8 +506,7 @@ static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev) { int type = pci_pcie_type(dev); - return pcie_cap_version(dev) > 1 || - type == PCI_EXP_TYPE_ROOT_PORT || + return type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_RC_EC; } -- cgit v1.2.3-70-g09d2 From 6d3a1741f1e648cfbd5a0cc94477a0d5004c6f5e Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 28 Aug 2013 12:01:03 -0600 Subject: PCI: Support PCIe Capability Slot registers only for ports with slots Previously we allowed callers to access Slot Capabilities, Status, and Control for Root Ports even if the Root Port did not implement a slot. This seems dubious because the spec only requires these registers if a slot is implemented. It's true that even Root Ports without slots must have *space* for these slot registers, because the Root Capabilities, Status, and Control registers are after the slot registers in the capability. However, for a v1 PCIe Capability, the *semantics* of the slot registers are undefined unless a slot is implemented. Signed-off-by: Bjorn Helgaas Reviewed-By: Jiang Liu --- drivers/pci/access.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/pci/access.c') diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 9a46fa9135d..061da8c3ab4 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -497,9 +497,9 @@ static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev) { int type = pci_pcie_type(dev); - return type == PCI_EXP_TYPE_ROOT_PORT || - (type == PCI_EXP_TYPE_DOWNSTREAM && - pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT); + return (type == PCI_EXP_TYPE_ROOT_PORT || + type == PCI_EXP_TYPE_DOWNSTREAM) && + pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT; } static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev) -- cgit v1.2.3-70-g09d2 From fed2451512495f0f0820ac9e53936bd208569bc8 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 28 Aug 2013 12:03:42 -0600 Subject: PCI: Remove pcie_cap_has_devctl() pcie_cap_has_devctl() does nothing, so remove it. Simplicity over consistency in this case. No functional change. Signed-off-by: Bjorn Helgaas Reviewed-By: Jiang Liu --- drivers/pci/access.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/pci/access.c') diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 061da8c3ab4..0857ca981fa 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -475,11 +475,6 @@ static inline int pcie_cap_version(const struct pci_dev *dev) return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS; } -static inline bool pcie_cap_has_devctl(const struct pci_dev *dev) -{ - return true; -} - static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev) { int type = pci_pcie_type(dev); @@ -521,7 +516,7 @@ static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos) case PCI_EXP_DEVCAP: case PCI_EXP_DEVCTL: case PCI_EXP_DEVSTA: - return pcie_cap_has_devctl(dev); + return true; case PCI_EXP_LNKCAP: case PCI_EXP_LNKCTL: case PCI_EXP_LNKSTA: -- cgit v1.2.3-70-g09d2