From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_PASS,UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 140B9C43144 for ; Wed, 27 Jun 2018 09:22:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C90CF26542 for ; Wed, 27 Jun 2018 09:22:49 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C90CF26542 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932326AbeF0JVu (ORCPT ); Wed, 27 Jun 2018 05:21:50 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:31688 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1750936AbeF0JVr (ORCPT ); Wed, 27 Jun 2018 05:21:47 -0400 X-UUID: a100d1d06d6845e184de6069d44f5393-20180627 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw01.mediatek.com (envelope-from ) (mhqrelay.mediatek.com ESMTP with TLS) with ESMTP id 944701599; Wed, 27 Jun 2018 17:21:45 +0800 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1210.3; Wed, 27 Jun 2018 17:21:43 +0800 Received: from localhost.localdomain (10.17.3.153) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1210.3 via Frontend Transport; Wed, 27 Jun 2018 17:21:42 +0800 From: To: , , , , , , , , , , , CC: , , , , , Subject: [PATCH 1/4] PCI: mediatek: fixup mtk_pcie_find_port logical Date: Wed, 27 Jun 2018 17:21:35 +0800 Message-ID: <1530091298-28120-2-git-send-email-honghui.zhang@mediatek.com> X-Mailer: git-send-email 2.6.4 In-Reply-To: <1530091298-28120-1-git-send-email-honghui.zhang@mediatek.com> References: <1530091298-28120-1-git-send-email-honghui.zhang@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Honghui Zhang Mediatek's host controller have two slots, each have it's own control registers. The host driver need to identify which slot was connected in order to access the device's configuration space. There's problem for current host driver to find out which slot was connected to for a given EP device. Assuming each slot have connect with one EP device as below: host bridge bus 0 --> __________|_______ | | | | slot 0 slot 1 bus 1 -->| bus 2 --> | | | EP 0 EP 1 While PCI emulation, system software will scan all the PCI device starting from devfn 0. So it will get the proper port for slot0 and slot1 device when using PCI_SLOT(devfn) for match. But it will get the wrong slot for EP1: The devfn will be start from 0 when scanning EP1 behind slot1, it will get port0 since the PCI_SLOT(EP1) is match for port0's slot value. So the host driver should not using EP's devfn but the slot's devfn(the slot which EP was connected to) for match. This patch fix the mtk_pcie_find_port's logical by using the slot's devfn for match. Signed-off-by: Honghui Zhang Reviewed-by: Ryder Lee --- drivers/pci/controller/pcie-mediatek.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c index 0baabe3..9cf7ecf 100644 --- a/drivers/pci/controller/pcie-mediatek.c +++ b/drivers/pci/controller/pcie-mediatek.c @@ -337,10 +337,23 @@ static struct mtk_pcie_port *mtk_pcie_find_port(struct pci_bus *bus, { struct mtk_pcie *pcie = bus->sysdata; struct mtk_pcie_port *port; + struct pci_dev *dev; + struct pci_bus *pbus; - list_for_each_entry(port, &pcie->ports, list) - if (port->slot == PCI_SLOT(devfn)) + list_for_each_entry(port, &pcie->ports, list) { + if (bus->number == 0 && port->slot == PCI_SLOT(devfn)) { return port; + } else if (bus->number != 0) { + pbus = bus; + do { + dev = pbus->self; + if (port->slot == PCI_SLOT(dev->devfn)) + return port; + + pbus = dev->bus; + } while (dev->bus->number != 0); + } + } return NULL; } -- 2.6.4