From patchwork Sat Jan 16 11:07:08 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 73398 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0GBCi2d030853 for ; Sat, 16 Jan 2010 11:12:44 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752985Ab0APLLz (ORCPT ); Sat, 16 Jan 2010 06:11:55 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754711Ab0APLIu (ORCPT ); Sat, 16 Jan 2010 06:08:50 -0500 Received: from sca-es-mail-2.Sun.COM ([192.18.43.133]:38783 "EHLO sca-es-mail-2.sun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753738Ab0APLIt (ORCPT ); Sat, 16 Jan 2010 06:08:49 -0500 Received: from fe-sfbay-09.sun.com ([192.18.43.129]) by sca-es-mail-2.sun.com (8.13.7+Sun/8.12.9) with ESMTP id o0GB8nNm029440; Sat, 16 Jan 2010 03:08:49 -0800 (PST) MIME-version: 1.0 Content-transfer-encoding: 7BIT Content-type: TEXT/PLAIN Received: from conversion-daemon.fe-sfbay-09.sun.com by fe-sfbay-09.sun.com (Sun Java(tm) System Messaging Server 7u2-7.04 64bit (built Jul 2 2009)) id <0KWC00L006S6XR00@fe-sfbay-09.sun.com>; Sat, 16 Jan 2010 03:08:49 -0800 (PST) Received: from localhost.localdomain ([unknown] [75.36.243.89]) by fe-sfbay-09.sun.com (Sun Java(tm) System Messaging Server 7u2-7.04 64bit (built Jul 2 2009)) with ESMTPSA id <0KWC00FJR6YF4SC0@fe-sfbay-09.sun.com>; Sat, 16 Jan 2010 03:08:48 -0800 (PST) Date: Sat, 16 Jan 2010 03:07:08 -0800 From: Yinghai Lu Subject: [PATCH 02/11] pci: add failed_list to record failed one for pci_bus_assign_resources In-reply-to: <1263640037-24134-1-git-send-email-yinghai@kernel.org> To: Jesse Barnes , Ingo Molnar , Linus Torvalds , Ivan Kokshaysky , Kenji Kaneshige , Alex Chiang , Bjorn Helgaas Cc: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Yinghai Lu Message-id: <1263640037-24134-3-git-send-email-yinghai@kernel.org> X-Mailer: git-send-email 1.6.4.2 References: <1263640037-24134-1-git-send-email-yinghai@kernel.org> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 7a18428..fa9f4e2 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -27,7 +27,52 @@ #include #include "pci.h" -static void pbus_assign_resources_sorted(const struct pci_bus *bus) +struct resource_list_x { + struct resource_list_x *next; + struct resource *res; + struct pci_dev *dev; + resource_size_t start; + resource_size_t end; + unsigned long flags; +}; + +static void add_to_failed_list(struct resource_list_x *head, + struct pci_dev *dev, struct resource *res) +{ + struct resource_list_x *list = head; + struct resource_list_x *ln = list->next; + struct resource_list_x *tmp; + + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) { + pr_warning("add_to_failed_list: kmalloc() failed!\n"); + return; + } + + tmp->next = ln; + tmp->res = res; + tmp->dev = dev; + tmp->start = res->start; + tmp->end = res->end; + tmp->flags = res->flags; + list->next = tmp; +} + +static void free_failed_list(struct resource_list_x *head) +{ + struct resource_list_x *list, *tmp; + + for (list = head->next; list;) { + tmp = list; + list = list->next; + kfree(tmp); + } + + head->next = NULL; +} + +static void pbus_assign_resources_sorted(const struct pci_bus *bus, + struct resource_list_x *fail_head) { struct pci_dev *dev; struct resource *res; @@ -58,6 +103,13 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus) res = list->res; idx = res - &list->dev->resource[0]; if (pci_assign_resource(list->dev, idx)) { + if (fail_head && !pci_is_root_bus(list->dev->bus)) { + /* + * device need to keep flags and size + * for next try + */ + add_to_failed_list(fail_head, list->dev, res); + } res->start = 0; res->end = 0; res->flags = 0; @@ -572,19 +624,20 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) } EXPORT_SYMBOL(pci_bus_size_bridges); -void __ref pci_bus_assign_resources(const struct pci_bus *bus) +static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, + struct resource_list_x *fail_head) { struct pci_bus *b; struct pci_dev *dev; - pbus_assign_resources_sorted(bus); + pbus_assign_resources_sorted(bus, fail_head); list_for_each_entry(dev, &bus->devices, bus_list) { b = dev->subordinate; if (!b) continue; - pci_bus_assign_resources(b); + __pci_bus_assign_resources(b, fail_head); switch (dev->class >> 8) { case PCI_CLASS_BRIDGE_PCI: @@ -602,6 +655,11 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus) } } } + +void __ref pci_bus_assign_resources(const struct pci_bus *bus) +{ + __pci_bus_assign_resources(bus, NULL); +} EXPORT_SYMBOL(pci_bus_assign_resources); static void pci_bridge_release_resources(struct pci_bus *bus,