From patchwork Sun Sep 2 21:52:13 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 1397421 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 3073A3FC71 for ; Sun, 2 Sep 2012 21:54:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755871Ab2IBVwl (ORCPT ); Sun, 2 Sep 2012 17:52:41 -0400 Received: from acsinet15.oracle.com ([141.146.126.227]:19807 "EHLO acsinet15.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755822Ab2IBVwk (ORCPT ); Sun, 2 Sep 2012 17:52:40 -0400 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by acsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q82LqQUY004974 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 2 Sep 2012 21:52:27 GMT Received: from acsmt357.oracle.com (acsmt357.oracle.com [141.146.40.157]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q82LqPMM013661 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sun, 2 Sep 2012 21:52:26 GMT Received: from abhmt105.oracle.com (abhmt105.oracle.com [141.146.116.57]) by acsmt357.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q82LqPv5029406; Sun, 2 Sep 2012 16:52:25 -0500 Received: from linux-siqj.site (/75.55.221.75) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 02 Sep 2012 14:52:25 -0700 From: Yinghai Lu To: Bjorn Helgaas , Taku Izumi , Jiang Liu , x86 Cc: Andrew Morton , Linus Torvalds , Greg Kroah-Hartman , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, Yinghai Lu Subject: [PATCH part3 03/11] PCI: pci_bus_size_bridges() should not size own bridge Date: Sun, 2 Sep 2012 14:52:13 -0700 Message-Id: <1346622741-30799-4-git-send-email-yinghai@kernel.org> X-Mailer: git-send-email 1.7.7 In-Reply-To: <1346622741-30799-1-git-send-email-yinghai@kernel.org> References: <1346622741-30799-1-git-send-email-yinghai@kernel.org> X-Source-IP: acsinet22.oracle.com [141.146.126.238] Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org During checking acpiphp code, found following sequence: pci_bus_size_bridges(bus); pci_bus_assign_resources(bus); pci_enable_bridges(bus); The problem is that when bus is not root bus, pci_bus_size_bridges would also size own pci bridge bus->self if that bridge resource is not inserted before. but later pci_bus_assign_resources will not allocate those size bridge res. So try make it less confusing, let it does not include self sizing. and add with_self parameter info __pci_bus_size_bridge() Fixes caller in pci hotplug componets. Signed-off-by: Yinghai Lu --- drivers/pci/hotplug/acpiphp_glue.c | 3 ++- drivers/pci/setup-bus.c | 24 +++++++++++++++--------- include/linux/pci.h | 1 + 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 085eec7..6cb1923 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -842,7 +842,8 @@ static int __ref enable_device(struct acpiphp_slot *slot) max = pci_scan_bridge(bus, dev, max, pass); if (pass && dev->subordinate) { check_hotplug_bridge(slot, dev); - pci_bus_size_bridges(dev->subordinate); + pci_bus_size_bridges_with_self( + dev->subordinate); } } } diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1dc22b3..70d6292 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1005,8 +1005,8 @@ handle_done: ; } -void __ref __pci_bus_size_bridges(struct pci_bus *bus, - struct list_head *realloc_head) +static void __ref __pci_bus_size_bridges(struct pci_bus *bus, + struct list_head *realloc_head, bool with_self) { struct pci_dev *dev; unsigned long mask, prefmask; @@ -1024,13 +1024,13 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, case PCI_CLASS_BRIDGE_PCI: default: - __pci_bus_size_bridges(b, realloc_head); + __pci_bus_size_bridges(b, realloc_head, true); break; } } - /* The root bus? */ - if (!bus->self) + /* Is root bus or not wanted? */ + if (!bus->self || !with_self) return; switch (bus->self->class >> 8) { @@ -1070,9 +1070,15 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, } } +void __ref pci_bus_size_bridges_with_self(struct pci_bus *bus) +{ + __pci_bus_size_bridges(bus, NULL, true); +} +EXPORT_SYMBOL(pci_bus_size_bridges_with_self); + void __ref pci_bus_size_bridges(struct pci_bus *bus) { - __pci_bus_size_bridges(bus, NULL); + __pci_bus_size_bridges(bus, NULL, false); } EXPORT_SYMBOL(pci_bus_size_bridges); @@ -1385,7 +1391,7 @@ again: /* Depth first, calculate sizes and alignments of all subordinate buses. */ list_for_each_entry(bus, &pci_root_buses, node) - __pci_bus_size_bridges(bus, add_list); + __pci_bus_size_bridges(bus, add_list, false); /* Depth last, allocate resources and update the hardware. */ list_for_each_entry(bus, &pci_root_buses, node) @@ -1462,7 +1468,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) IORESOURCE_PREFETCH; again: - __pci_bus_size_bridges(parent, &add_list); + __pci_bus_size_bridges(parent, &add_list, true); __pci_bridge_assign_resources(bridge, &add_list, &fail_head); BUG_ON(!list_empty(&add_list)); tried_times++; @@ -1523,7 +1529,7 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus) dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) if (dev->subordinate) __pci_bus_size_bridges(dev->subordinate, - &add_list); + &add_list, true); up_read(&pci_bus_sem); __pci_bus_assign_resources(bus, &add_list, NULL); BUG_ON(!list_empty(&add_list)); diff --git a/include/linux/pci.h b/include/linux/pci.h index 1bd7559..f994e93 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -980,6 +980,7 @@ int pci_vpd_truncate(struct pci_dev *dev, size_t size); resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx); void pci_bus_assign_resources(const struct pci_bus *bus); void pci_bus_size_bridges(struct pci_bus *bus); +void pci_bus_size_bridges_with_self(struct pci_bus *bus); int pci_claim_resource(struct pci_dev *, int); void pci_assign_unassigned_resources(void); void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge);