From patchwork Sat Jul 18 16:20:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bin Meng X-Patchwork-Id: 497382 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id BA328140D21 for ; Sun, 19 Jul 2015 02:21:07 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=In199vnv; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 041944B6BA; Sat, 18 Jul 2015 18:20:58 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dl7gL-3_-my0; Sat, 18 Jul 2015 18:20:57 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 107664B65F; Sat, 18 Jul 2015 18:20:47 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1F4884B65F for ; Sat, 18 Jul 2015 18:20:40 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SbNn--E46kBg for ; Sat, 18 Jul 2015 18:20:40 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-oi0-f46.google.com (mail-oi0-f46.google.com [209.85.218.46]) by theia.denx.de (Postfix) with ESMTPS id 388E54B691 for ; Sat, 18 Jul 2015 18:20:33 +0200 (CEST) Received: by oigd21 with SMTP id d21so44679468oig.1 for ; Sat, 18 Jul 2015 09:20:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:from:to:subject:date:in-reply-to:references:mime-version :content-type; bh=WXbfEKIgz0RkdVhq+2mZaG2fpkaR9GcBNkfHBz/3WYE=; b=In199vnvTuP66z+l4WA7ho8rOHLuSEHMItxa3U6cpK/kulNDaKYW2tXMrV3Jn9OP25 zud4v0gi0vEN6UVNqYRvdEDKqMAfmpCN1p3DLijkZn3taCYmdWUwFgX3sN8zdneX4Im0 wzGHxePjxMVT2YjFNrXxcTcDNPUe075B0PuMCqUTZUlZ/O6h0OZEeKx7S5R52kXeNel6 BxyYejmsLE9eiDKTYweCZ9aLW5HHqGoxN5fJ6buVAEsDJ4NZDR54NNmNTFiLP8ncSakf S9Ck639kP84NtGNC5TDKhY+DjCH4eX5t91X2k9Nf/OclKVROy6n5Ts97yl9Y/TTpFyIC cV0A== X-Received: by 10.202.182.65 with SMTP id g62mr5547152oif.85.1437236432842; Sat, 18 Jul 2015 09:20:32 -0700 (PDT) Received: from mail.hotmail.com (blu004-wss1s1.hotmail.com. [134.170.2.216]) by smtp.gmail.com with ESMTPSA id c3sm8281420obo.5.2015.07.18.09.20.32 (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jul 2015 09:20:32 -0700 (PDT) Received: from BLU436-SMTP119 ([134.170.2.215]) by BLU004-WSS1S1.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Sat, 18 Jul 2015 09:20:31 -0700 X-TMN: [bfsaXBaD6bZqgGRYVuwyC1TYRpe9WxVX] Message-ID: From: Bin Meng To: Simon Glass , U-Boot Mailing List Date: Sun, 19 Jul 2015 00:20:04 +0800 X-Mailer: git-send-email 2.3.2 (Apple Git-55) In-Reply-To: <1437236407-1916-1-git-send-email-bmeng.cn@gmail.com> References: <1437236407-1916-1-git-send-email-bmeng.cn@gmail.com> X-OriginalArrivalTime: 18 Jul 2015 16:20:30.0170 (UTC) FILETIME=[AA078BA0:01D0C175] MIME-Version: 1.0 Subject: [U-Boot] [PATCH 3/6] dm: pci: Use complete bdf in all pci config read/write routines X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Currently pci_bus_read_config() and pci_bus_write_config() are called with bus number masked off in the parameter bdf, and bus number is supposed to be added back in the bridge driver's pci config read/write ops if the device is behind a pci bridge. However this logic only works for a pci topology where there is only one bridge off the root controller. If there is addtional bridge in the system, the logic will create a non-existent bdf where its bus number gets accumulated across bridges. To correct this, we change all pci config read/write routines to use complete bdf all the way up to the root controller. Signed-off-by: Bin Meng Acked-by: Simon Glass Tested-by: Simon Glass --- drivers/pci/pci-uclass.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 5b91fe3..e92e4f3 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -199,8 +199,7 @@ int pci_write_config(pci_dev_t bdf, int offset, unsigned long value, if (ret) return ret; - return pci_bus_write_config(bus, PCI_MASK_BUS(bdf), offset, value, - size); + return pci_bus_write_config(bus, bdf, offset, value, size); } int pci_write_config32(pci_dev_t bdf, int offset, u32 value) @@ -239,8 +238,7 @@ int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep, if (ret) return ret; - return pci_bus_read_config(bus, PCI_MASK_BUS(bdf), offset, valuep, - size); + return pci_bus_read_config(bus, bdf, offset, valuep, size); } int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep) @@ -357,41 +355,43 @@ int pci_bind_bus_devices(struct udevice *bus) { ulong vendor, device; ulong header_type; - pci_dev_t devfn, end; + pci_dev_t bdf, end; bool found_multi; int ret; found_multi = false; - end = PCI_DEVFN(PCI_MAX_PCI_DEVICES - 1, PCI_MAX_PCI_FUNCTIONS - 1); - for (devfn = PCI_DEVFN(0, 0); devfn < end; devfn += PCI_DEVFN(0, 1)) { + end = PCI_BDF(bus->seq, PCI_MAX_PCI_DEVICES - 1, + PCI_MAX_PCI_FUNCTIONS - 1); + for (bdf = PCI_BDF(bus->seq, 0, 0); bdf < end; + bdf += PCI_BDF(0, 0, 1)) { struct pci_child_platdata *pplat; struct udevice *dev; ulong class; - if (PCI_FUNC(devfn) && !found_multi) + if (PCI_FUNC(bdf) && !found_multi) continue; /* Check only the first access, we don't expect problems */ - ret = pci_bus_read_config(bus, devfn, PCI_HEADER_TYPE, + ret = pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE, &header_type, PCI_SIZE_8); if (ret) goto error; - pci_bus_read_config(bus, devfn, PCI_VENDOR_ID, &vendor, + pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor, PCI_SIZE_16); if (vendor == 0xffff || vendor == 0x0000) continue; - if (!PCI_FUNC(devfn)) + if (!PCI_FUNC(bdf)) found_multi = header_type & 0x80; debug("%s: bus %d/%s: found device %x, function %d\n", __func__, - bus->seq, bus->name, PCI_DEV(devfn), PCI_FUNC(devfn)); - pci_bus_read_config(bus, devfn, PCI_DEVICE_ID, &device, + bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf)); + pci_bus_read_config(bus, bdf, PCI_DEVICE_ID, &device, PCI_SIZE_16); - pci_bus_read_config(bus, devfn, PCI_CLASS_DEVICE, &class, + pci_bus_read_config(bus, bdf, PCI_CLASS_DEVICE, &class, PCI_SIZE_16); /* Find this device in the device tree */ - ret = pci_bus_find_devfn(bus, devfn, &dev); + ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev); /* If nothing in the device tree, bind a generic device */ if (ret == -ENODEV) { @@ -399,7 +399,7 @@ int pci_bind_bus_devices(struct udevice *bus) const char *drv; sprintf(name, "pci_%x:%x.%x", bus->seq, - PCI_DEV(devfn), PCI_FUNC(devfn)); + PCI_DEV(bdf), PCI_FUNC(bdf)); str = strdup(name); if (!str) return -ENOMEM; @@ -412,7 +412,7 @@ int pci_bind_bus_devices(struct udevice *bus) /* Update the platform data */ pplat = dev_get_parent_platdata(dev); - pplat->devfn = devfn; + pplat->devfn = PCI_MASK_BUS(bdf); pplat->vendor = vendor; pplat->device = device; pplat->class = class; @@ -583,20 +583,20 @@ static int pci_uclass_child_post_bind(struct udevice *dev) return 0; } -int pci_bridge_read_config(struct udevice *bus, pci_dev_t devfn, uint offset, - ulong *valuep, enum pci_size_t size) +static int pci_bridge_read_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) { struct pci_controller *hose = bus->uclass_priv; - pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn); return pci_bus_read_config(hose->ctlr, bdf, offset, valuep, size); } -int pci_bridge_write_config(struct udevice *bus, pci_dev_t devfn, uint offset, - ulong value, enum pci_size_t size) +static int pci_bridge_write_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) { struct pci_controller *hose = bus->uclass_priv; - pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn); return pci_bus_write_config(hose->ctlr, bdf, offset, value, size); }