Loading drivers/pci/setup-bus.c +57 −4 Original line number Diff line number Diff line Loading @@ -27,7 +27,52 @@ #include <linux/slab.h> #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; Loading Loading @@ -58,6 +103,8 @@ 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)) add_to_failed_list(fail_head, list->dev, res); res->start = 0; res->end = 0; res->flags = 0; Loading Loading @@ -572,19 +619,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: Loading @@ -602,6 +650,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, Loading Loading
drivers/pci/setup-bus.c +57 −4 Original line number Diff line number Diff line Loading @@ -27,7 +27,52 @@ #include <linux/slab.h> #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; Loading Loading @@ -58,6 +103,8 @@ 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)) add_to_failed_list(fail_head, list->dev, res); res->start = 0; res->end = 0; res->flags = 0; Loading Loading @@ -572,19 +619,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: Loading @@ -602,6 +650,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, Loading