From patchwork Thu Jun 30 23:47:38 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ram Pai X-Patchwork-Id: 933792 X-Patchwork-Delegate: bhelgaas@google.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5UNnKiL024645 for ; Thu, 30 Jun 2011 23:49:30 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752533Ab1F3XsL (ORCPT ); Thu, 30 Jun 2011 19:48:11 -0400 Received: from e8.ny.us.ibm.com ([32.97.182.138]:52388 "EHLO e8.ny.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753456Ab1F3XsJ (ORCPT ); Thu, 30 Jun 2011 19:48:09 -0400 Received: from d01relay04.pok.ibm.com (d01relay04.pok.ibm.com [9.56.227.236]) by e8.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p5UNaFx0031619; Thu, 30 Jun 2011 19:36:15 -0400 Received: from d01av03.pok.ibm.com (d01av03.pok.ibm.com [9.56.224.217]) by d01relay04.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p5UNm8Yj158082; Thu, 30 Jun 2011 19:48:08 -0400 Received: from d01av03.pok.ibm.com (loopback [127.0.0.1]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p5UJlswD021360; Thu, 30 Jun 2011 16:47:56 -0300 Received: from us.ibm.com (sig-9-65-220-236.mts.ibm.com [9.65.220.236]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id p5UJlqjB021299; Thu, 30 Jun 2011 16:47:52 -0300 Received: by us.ibm.com (sSMTP sendmail emulation); Thu, 30 Jun 2011 16:47:59 -0700 From: Ram Pai To: jbarnes@virtuousgeek.org, torvalds@linux-foundation.org Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, yinghai@kernel.org, bhutchings@solarflare.com, socketcan@hartkopp.net, bhelgaas@google.com, linux@dominikbrodowski.net, Ram Pai Subject: [PATCH 1/5 v2] PCI: honor child buses optional size in hot plug configuration Date: Thu, 30 Jun 2011 16:47:38 -0700 Message-Id: <1309477662-18680-2-git-send-email-linuxram@us.ibm.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1309477662-18680-1-git-send-email-linuxram@us.ibm.com> References: <1309477662-18680-1-git-send-email-linuxram@us.ibm.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 30 Jun 2011 23:49:30 +0000 (UTC) From: Yinghai Lu git commit c8adf9a3e873eddaaec11ac410a99ef6b9656938 "PCI: pre-allocate additional resources to devices only after successful allocation of essential resources." fails to take into consideration the optional-resources needed by children devices while calculating the optional-resource needed by the bridge. This can be a problem on some setup. For example, if a hotplug bridge has 8 children hotplug bridges, the bridge should have enough resources to accomodate the hotplug requirements for each of its children hotplug bridges. Currently this is not the case. This patch fixes the problem. Signed-off-by: Ram Pai Signed-off-by: Yinghai Lu --- drivers/pci/setup-bus.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1e9e5a5..e42b89a 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -536,6 +536,20 @@ static resource_size_t calculate_memsize(resource_size_t size, return size; } +static resource_size_t get_res_add_size(struct resource_list_x *add_head, + struct resource *res) +{ + struct resource_list_x *list; + + /* check if it is in add_head list */ + for (list = add_head->next; list && list->res != res; + list = list->next); + if (list) + return list->add_size; + + return 0; +} + /** * pbus_size_io() - size the io window of a given bus * @@ -555,6 +569,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, struct pci_dev *dev; struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); unsigned long size = 0, size0 = 0, size1 = 0; + resource_size_t children_add_size = 0; if (!b_res) return; @@ -575,10 +590,15 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, size += r_size; else size1 += r_size; + + if (add_head) + children_add_size += get_res_add_size(add_head, r); } } size0 = calculate_iosize(size, min_size, size1, resource_size(b_res), 4096); + if (children_add_size > add_size) + add_size = children_add_size; size1 = (!add_head || (add_head && !add_size)) ? size0 : calculate_iosize(size, min_size+add_size, size1, resource_size(b_res), 4096); @@ -620,6 +640,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, int order, max_order; struct resource *b_res = find_free_bus_resource(bus, type); unsigned int mem64_mask = 0; + resource_size_t children_add_size = 0; if (!b_res) return 0; @@ -661,6 +682,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, if (order > max_order) max_order = order; mem64_mask &= r->flags & IORESOURCE_MEM_64; + + if (add_head) + children_add_size += get_res_add_size(add_head, r); } } align = 0; @@ -677,6 +701,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, align += aligns[order]; } size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); + if (children_add_size > add_size) + add_size = children_add_size; size1 = (!add_head || (add_head && !add_size)) ? size0 : calculate_memsize(size, min_size+add_size, 0, resource_size(b_res), min_align);