From patchwork Thu May 23 14:32:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Petazzoni X-Patchwork-Id: 2607271 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id BFD8FDFB78 for ; Thu, 23 May 2013 14:33:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758828Ab3EWOdO (ORCPT ); Thu, 23 May 2013 10:33:14 -0400 Received: from mail.free-electrons.com ([94.23.35.102]:45249 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758807Ab3EWOdM (ORCPT ); Thu, 23 May 2013 10:33:12 -0400 Received: by mail.free-electrons.com (Postfix, from userid 106) id 7D267C33; Thu, 23 May 2013 16:33:11 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.3.2 Received: from localhost (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id 2382A163B; Thu, 23 May 2013 16:32:58 +0200 (CEST) From: Thomas Petazzoni To: Bjorn Helgaas , linux-pci@vger.kernel.org, Jason Cooper , Andrew Lunn , Gregory Clement Cc: Ezequiel Garcia , Lior Amsalem , linux-arm-kernel@lists.infradead.org, Maen Suleiman Subject: [PATCH v2 2/3] pci: mvebu: allow the enumeration of devices beyond physical bridges Date: Thu, 23 May 2013 16:32:52 +0200 Message-Id: <1369319573-19927-3-git-send-email-thomas.petazzoni@free-electrons.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1369319573-19927-1-git-send-email-thomas.petazzoni@free-electrons.com> References: <1369319573-19927-1-git-send-email-thomas.petazzoni@free-electrons.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Until now, the Marvell PCIe driver was only allowing the enumeration of the devices in the secondary bus of the emulated PCI-to-PCI bridge. This works fine when a PCIe device is directly connected into a PCIe slot of the Marvell board. However, when the device connected in the PCIe slot is a physical PCIe bridge, beyond which a real PCIe device is connected, it no longer worked, as the driver was preventing the Linux PCI core from seeing such devices. This commit fixes that by ensuring that configuration transactions on subordinate busses are properly forwarded on the right PCIe interface. Thanks to this patch, a PCIe card beyond a PCIe bridge, itself beyond the emulated PCI-to-PCI bridge is properly detected, with the following layout: -[0000:00]-+-01.0-[01]----00.0 +-09.0-[02-07]----00.0-[03-07]--+-01.0-[04]-- | +-05.0-[05]-- | +-07.0-[06]-- | \-09.0-[07]----00.0 \-0a.0-[08]----00.0 Where the PCIe interface that sits beyond the emulated PCI-to-PCI bridge at 09.0 allows to access the secondary bus 02, on which there is a PCIe bridge that allows to access the 3 to 7 busses, that are subordinates to this bridge. And on one of this bus (bus 7), there is one real PCIe device connected. Signed-off-by: Thomas Petazzoni --- drivers/pci/host/pci-mvebu.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 0bc21b0..a3c4638 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -554,7 +554,8 @@ mvebu_pcie_find_port(struct mvebu_pcie *pcie, struct pci_bus *bus, if (bus->number == 0 && port->devfn == devfn) return port; if (bus->number != 0 && - port->bridge.secondary_bus == bus->number) + bus->number >= port->bridge.secondary_bus && + bus->number <= port->bridge.subordinate_bus) return port; } @@ -578,7 +579,18 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn, if (bus->number == 0) return mvebu_sw_pci_bridge_write(port, where, size, val); - if (!port->haslink || PCI_SLOT(devfn) != 0) + if (!port->haslink) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* + * On the secondary bus, we don't want to expose any other + * device than the device physically connected in the PCIe + * slot, visible in slot 0. In slot 1, there's a special + * Marvell device that only makes sense when the Armada is + * used as a PCIe endpoint. + */ + if (bus->number == port->bridge.secondary_bus && + PCI_SLOT(devfn) != 0) return PCIBIOS_DEVICE_NOT_FOUND; /* Access the real PCIe interface */ @@ -609,7 +621,20 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, if (bus->number == 0) return mvebu_sw_pci_bridge_read(port, where, size, val); - if (!port->haslink || PCI_SLOT(devfn) != 0) { + if (!port->haslink) { + *val = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + /* + * On the secondary bus, we don't want to expose any other + * device than the device physically connected in the PCIe + * slot, visible in slot 0. In slot 1, there's a special + * Marvell device that only makes sense when the Armada is + * used as a PCIe endpoint. + */ + if (bus->number == port->bridge.secondary_bus && + PCI_SLOT(devfn) != 0) { *val = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND; }