From patchwork Sun Apr 17 09:51:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 65991 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp759963qge; Sun, 17 Apr 2016 03:02:35 -0700 (PDT) X-Received: by 10.67.2.41 with SMTP id bl9mr41523786pad.39.1460886942785; Sun, 17 Apr 2016 02:55:42 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ew7si9449047pad.131.2016.04.17.02.55.42; Sun, 17 Apr 2016 02:55:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752367AbcDQJzQ (ORCPT + 3 others); Sun, 17 Apr 2016 05:55:16 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:41503 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752331AbcDQJzO (ORCPT ); Sun, 17 Apr 2016 05:55:14 -0400 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u3H9t7CP029074 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 17 Apr 2016 09:55:07 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id u3H9t7O6029896 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 17 Apr 2016 09:55:07 GMT Received: from abhmp0018.oracle.com (abhmp0018.oracle.com [141.146.116.24]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id u3H9t4a4012388; Sun, 17 Apr 2016 09:55:06 GMT Received: from lappy.us.oracle.com (/10.154.169.185) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 17 Apr 2016 02:55:04 -0700 From: Sasha Levin To: stable@vger.kernel.org, stable-commits@vger.kernel.org Cc: Yijing Wang , Bjorn Helgaas , Sasha Levin Subject: [added to the 4.1 stable tree] PCI: Add dev->has_secondary_link to track downstream PCIe links Date: Sun, 17 Apr 2016 05:51:36 -0400 Message-Id: <1460886804-19372-97-git-send-email-sasha.levin@oracle.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1460886804-19372-1-git-send-email-sasha.levin@oracle.com> References: <1460886804-19372-1-git-send-email-sasha.levin@oracle.com> X-Source-IP: aserv0022.oracle.com [141.146.126.234] Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Yijing Wang This patch has been added to the 4.1 stable tree. If you have any objections, please let us know. -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html =============== [ Upstream commit d0751b98dfa391f862e02dc36a233a54615e3f1d ] A PCIe Port is an interface to a Link. A Root Port is a PCI-PCI bridge in a Root Complex and has a Link on its secondary (downstream) side. For other Ports, the Link may be on either the upstream (closer to the Root Complex) or downstream side of the Port. The usual topology has a Root Port connected to an Upstream Port. We previously assumed this was the only possible topology, and that a Downstream Port's Link was always on its downstream side, like this: +---------------------+ +------+ | Downstream | | Root | | Upstream Port +--Link-- | Port +--Link--+ Port | +------+ | Downstream | | Port +--Link-- +---------------------+ But systems do exist (see URL below) where the Root Port is connected to a Downstream Port. In this case, a Downstream Port's Link may be on either the upstream or downstream side: +---------------------+ +------+ | Upstream | | Root | | Downstream Port +--Link-- | Port +--Link--+ Port | +------+ | Downstream | | Port +--Link-- +---------------------+ We can't use the Port type to determine which side the Link is on, so add a bit in struct pci_dev to keep track. A Root Port's Link is always on the Port's secondary side. A component (Endpoint or Port) on the other end of the Link obviously has the Link on its upstream side. If that component is a Port, it is part of a Switch or a Bridge. A Bridge has a PCI or PCI-X bus on its secondary side, not a Link. The internal bus of a Switch connects the Port to another Port whose Link is on the downstream side. [bhelgaas: changelog, comment, cache "type", use if/else] Link: http://lkml.kernel.org/r/54EB81B2.4050904@pobox.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=94361 Suggested-by: Bjorn Helgaas Signed-off-by: Yijing Wang Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/pci/probe.c | 18 ++++++++++++++++++ include/linux/pci.h | 1 + 2 files changed, 19 insertions(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c911857..bbfd01c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -973,6 +973,8 @@ void set_pcie_port_type(struct pci_dev *pdev) { int pos; u16 reg16; + int type; + struct pci_dev *parent; pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); if (!pos) @@ -982,6 +984,22 @@ void set_pcie_port_type(struct pci_dev *pdev) pdev->pcie_flags_reg = reg16; pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, ®16); pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; + + /* + * A Root Port is always the upstream end of a Link. No PCIe + * component has two Links. Two Links are connected by a Switch + * that has a Port on each Link and internal logic to connect the + * two Ports. + */ + type = pci_pcie_type(pdev); + if (type == PCI_EXP_TYPE_ROOT_PORT) + pdev->has_secondary_link = 1; + else if (type == PCI_EXP_TYPE_UPSTREAM || + type == PCI_EXP_TYPE_DOWNSTREAM) { + parent = pci_upstream_bridge(pdev); + if (!parent->has_secondary_link) + pdev->has_secondary_link = 1; + } } void set_pcie_hotplug_bridge(struct pci_dev *pdev) diff --git a/include/linux/pci.h b/include/linux/pci.h index 6e935e5..95d5f96 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -357,6 +357,7 @@ struct pci_dev { unsigned int broken_intx_masking:1; unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */ unsigned int irq_managed:1; + unsigned int has_secondary_link:1; pci_dev_flags_t dev_flags; atomic_t enable_cnt; /* pci_enable_device has been called */