Loading arch/x86/pci/acpi.c +71 −45 Original line number Diff line number Diff line Loading @@ -9,11 +9,11 @@ struct pci_root_info { struct acpi_device *bridge; char *name; char name[16]; unsigned int res_num; struct resource *res; struct list_head *resources; int busnum; struct pci_sysdata sd; }; static bool pci_use_crs = true; Loading Loading @@ -287,7 +287,8 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type) } } static void add_resources(struct pci_root_info *info) static void add_resources(struct pci_root_info *info, struct list_head *resources) { int i; struct resource *res, *root, *conflict; Loading @@ -311,53 +312,74 @@ static void add_resources(struct pci_root_info *info) "ignoring host bridge window %pR (conflicts with %s %pR)\n", res, conflict->name, conflict); else pci_add_resource(info->resources, res); pci_add_resource(resources, res); } } static void free_pci_root_info_res(struct pci_root_info *info) { kfree(info->res); info->res = NULL; info->res_num = 0; } static void __release_pci_root_info(struct pci_root_info *info) { int i; struct resource *res; for (i = 0; i < info->res_num; i++) { res = &info->res[i]; if (!res->parent) continue; if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) continue; release_resource(res); } free_pci_root_info_res(info); kfree(info); } static void release_pci_root_info(struct pci_host_bridge *bridge) { struct pci_root_info *info = bridge->release_data; __release_pci_root_info(info); } static void get_current_resources(struct acpi_device *device, int busnum, int domain, struct list_head *resources) probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, int busnum, int domain) { struct pci_root_info info; size_t size; info.bridge = device; info.res_num = 0; info.resources = resources; info->bridge = device; info->res_num = 0; acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, &info); if (!info.res_num) info); if (!info->res_num) return; size = sizeof(*info.res) * info.res_num; info.res = kmalloc(size, GFP_KERNEL); if (!info.res) size = sizeof(*info->res) * info->res_num; info->res_num = 0; info->res = kmalloc(size, GFP_KERNEL); if (!info->res) return; info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum); if (!info.name) goto name_alloc_fail; sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); info.res_num = 0; acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, &info); if (pci_use_crs) { add_resources(&info); return; } kfree(info.name); name_alloc_fail: kfree(info.res); info); } struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) { struct acpi_device *device = root->device; struct pci_root_info *info = NULL; int domain = root->segment; int busnum = root->secondary.start; LIST_HEAD(resources); Loading Loading @@ -389,17 +411,14 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) if (node != -1 && !node_online(node)) node = -1; /* Allocate per-root-bus (not per bus) arch-specific data. * TODO: leak; this memory is never freed. * It's arguable whether it's worth the trouble to care. */ sd = kzalloc(sizeof(*sd), GFP_KERNEL); if (!sd) { info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { printk(KERN_WARNING "pci_bus %04x:%02x: " "ignored (out of memory)\n", domain, busnum); return NULL; } sd = &info->sd; sd->domain = domain; sd->node = node; /* Loading @@ -413,22 +432,32 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) * be replaced by sd. */ memcpy(bus->sysdata, sd, sizeof(*sd)); kfree(sd); kfree(info); } else { get_current_resources(device, busnum, domain, &resources); probe_pci_root_info(info, device, busnum, domain); /* * _CRS with no apertures is normal, so only fall back to * defaults or native bridge info if we're ignoring _CRS. */ if (!pci_use_crs) if (pci_use_crs) add_resources(info, &resources); else { free_pci_root_info_res(info); x86_pci_root_bus_resources(busnum, &resources); } bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); if (bus) if (bus) { bus->subordinate = pci_scan_child_bus(bus); else pci_set_host_bridge_release( to_pci_host_bridge(bus->bridge), release_pci_root_info, info); } else { pci_free_resource_list(&resources); __release_pci_root_info(info); } } /* After the PCI-E bus has been walked and all devices discovered, Loading @@ -445,9 +474,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) } } if (!bus) kfree(sd); if (bus && node != -1) { #ifdef CONFIG_ACPI_NUMA if (pxm >= 0) Loading arch/x86/pci/amd_bus.c +27 −49 Original line number Diff line number Diff line Loading @@ -32,6 +32,18 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = { #define RANGE_NUM 16 static struct pci_root_info __init *find_pci_root_info(int node, int link) { struct pci_root_info *info; /* find the position */ list_for_each_entry(info, &pci_root_infos, list) if (info->node == node && info->link == link) return info; return NULL; } /** * early_fill_mp_bus_to_node() * called before pcibios_scan_root and pci_scan_bus Loading @@ -50,7 +62,6 @@ static int __init early_fill_mp_bus_info(void) int def_link; struct pci_root_info *info; u32 reg; struct resource *res; u64 start; u64 end; struct range range[RANGE_NUM]; Loading Loading @@ -86,7 +97,6 @@ static int __init early_fill_mp_bus_info(void) if (!found) return 0; pci_root_num = 0; for (i = 0; i < 4; i++) { int min_bus; int max_bus; Loading @@ -105,13 +115,8 @@ static int __init early_fill_mp_bus_info(void) #endif link = (reg >> 8) & 0x03; info = &pci_root_info[pci_root_num]; info->bus_min = min_bus; info->bus_max = max_bus; info->node = node; info->link = link; info = alloc_pci_root_info(min_bus, max_bus, node, link); sprintf(info->name, "PCI Bus #%02x", min_bus); pci_root_num++; } /* get the default node and link for left over res */ Loading @@ -134,16 +139,10 @@ static int __init early_fill_mp_bus_info(void) link = (reg >> 4) & 0x03; end = (reg & 0xfff000) | 0xfff; /* find the position */ for (j = 0; j < pci_root_num; j++) { info = &pci_root_info[j]; if (info->node == node && info->link == link) break; } if (j == pci_root_num) info = find_pci_root_info(node, link); if (!info) continue; /* not found */ info = &pci_root_info[j]; printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n", node, link, start, end); Loading @@ -155,13 +154,8 @@ static int __init early_fill_mp_bus_info(void) } /* add left over io port range to def node/link, [0, 0xffff] */ /* find the position */ for (j = 0; j < pci_root_num; j++) { info = &pci_root_info[j]; if (info->node == def_node && info->link == def_link) break; } if (j < pci_root_num) { info = &pci_root_info[j]; info = find_pci_root_info(def_node, def_link); if (info) { for (i = 0; i < RANGE_NUM; i++) { if (!range[i].end) continue; Loading Loading @@ -214,16 +208,10 @@ static int __init early_fill_mp_bus_info(void) end <<= 8; end |= 0xffff; /* find the position */ for (j = 0; j < pci_root_num; j++) { info = &pci_root_info[j]; if (info->node == node && info->link == link) break; } if (j == pci_root_num) continue; /* not found */ info = find_pci_root_info(node, link); info = &pci_root_info[j]; if (!info) continue; printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]", node, link, start, end); Loading Loading @@ -291,14 +279,8 @@ static int __init early_fill_mp_bus_info(void) * add left over mmio range to def node/link ? * that is tricky, just record range in from start_min to 4G */ for (j = 0; j < pci_root_num; j++) { info = &pci_root_info[j]; if (info->node == def_node && info->link == def_link) break; } if (j < pci_root_num) { info = &pci_root_info[j]; info = find_pci_root_info(def_node, def_link); if (info) { for (i = 0; i < RANGE_NUM; i++) { if (!range[i].end) continue; Loading @@ -309,20 +291,16 @@ static int __init early_fill_mp_bus_info(void) } } for (i = 0; i < pci_root_num; i++) { int res_num; list_for_each_entry(info, &pci_root_infos, list) { int busnum; struct pci_root_res *root_res; info = &pci_root_info[i]; res_num = info->res_num; busnum = info->bus_min; printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", info->bus_min, info->bus_max, info->node, info->link); for (j = 0; j < res_num; j++) { res = &info->res[j]; printk(KERN_DEBUG "bus: %02x index %x %pR\n", busnum, j, res); } list_for_each_entry(root_res, &info->resources, list) printk(KERN_DEBUG "bus: %02x %pR\n", busnum, &root_res->res); } return 0; Loading arch/x86/pci/broadcom_bus.c +4 −8 Original line number Diff line number Diff line Loading @@ -22,19 +22,15 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func) { struct pci_root_info *info; struct pci_root_res *root_res; struct resource res; u16 word1, word2; u8 fbus, lbus; int i; info = &pci_root_info[pci_root_num]; pci_root_num++; /* read the PCI bus numbers */ fbus = read_pci_config_byte(bus, slot, func, 0x44); lbus = read_pci_config_byte(bus, slot, func, 0x45); info->bus_min = fbus; info->bus_max = lbus; info = alloc_pci_root_info(fbus, lbus, 0, 0); /* * Add the legacy IDE ports on bus 0 Loading Loading @@ -86,8 +82,8 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func) res.flags = IORESOURCE_BUS; printk(KERN_INFO "CNB20LE PCI Host Bridge (domain 0000 %pR)\n", &res); for (i = 0; i < info->res_num; i++) printk(KERN_INFO "host bridge window %pR\n", &info->res[i]); list_for_each_entry(root_res, &info->resources, list) printk(KERN_INFO "host bridge window %pR\n", &root_res->res); } static int __init broadcom_postcore_init(void) Loading arch/x86/pci/bus_numa.c +47 −22 Original line number Diff line number Diff line Loading @@ -4,35 +4,38 @@ #include "bus_numa.h" int pci_root_num; struct pci_root_info pci_root_info[PCI_ROOT_NR]; LIST_HEAD(pci_root_infos); void x86_pci_root_bus_resources(int bus, struct list_head *resources) static struct pci_root_info *x86_find_pci_root_info(int bus) { int i; int j; struct pci_root_info *info; if (!pci_root_num) goto default_resources; if (list_empty(&pci_root_infos)) return NULL; for (i = 0; i < pci_root_num; i++) { if (pci_root_info[i].bus_min == bus) break; list_for_each_entry(info, &pci_root_infos, list) if (info->bus_min == bus) return info; return NULL; } if (i == pci_root_num) void x86_pci_root_bus_resources(int bus, struct list_head *resources) { struct pci_root_info *info = x86_find_pci_root_info(bus); struct pci_root_res *root_res; if (!info) goto default_resources; printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", bus); info = &pci_root_info[i]; for (j = 0; j < info->res_num; j++) { list_for_each_entry(root_res, &info->resources, list) { struct resource *res; struct resource *root; res = &info->res[j]; res = &root_res->res; pci_add_resource(resources, res); if (res->flags & IORESOURCE_IO) root = &ioport_resource; Loading @@ -53,11 +56,32 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) pci_add_resource(resources, &iomem_resource); } struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max, int node, int link) { struct pci_root_info *info; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return info; INIT_LIST_HEAD(&info->resources); info->bus_min = bus_min; info->bus_max = bus_max; info->node = node; info->link = link; list_add_tail(&info->list, &pci_root_infos); return info; } void __devinit update_res(struct pci_root_info *info, resource_size_t start, resource_size_t end, unsigned long flags, int merge) { int i; struct resource *res; struct pci_root_res *root_res; if (start > end) return; Loading @@ -69,11 +93,11 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start, goto addit; /* try to merge it with old one */ for (i = 0; i < info->res_num; i++) { list_for_each_entry(root_res, &info->resources, list) { resource_size_t final_start, final_end; resource_size_t common_start, common_end; res = &info->res[i]; res = &root_res->res; if (res->flags != flags) continue; Loading @@ -93,14 +117,15 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start, addit: /* need to add that */ if (info->res_num >= RES_NUM) root_res = kzalloc(sizeof(*root_res), GFP_KERNEL); if (!root_res) return; res = &info->res[info->res_num]; res = &root_res->res; res->name = info->name; res->flags = flags; res->start = start; res->end = end; res->child = NULL; info->res_num++; list_add_tail(&root_res->list, &info->resources); } arch/x86/pci/bus_numa.h +10 −8 Original line number Diff line number Diff line Loading @@ -4,22 +4,24 @@ * sub bus (transparent) will use entres from 3 to store extra from * root, so need to make sure we have enough slot there. */ #define RES_NUM 16 struct pci_root_res { struct list_head list; struct resource res; }; struct pci_root_info { struct list_head list; char name[12]; unsigned int res_num; struct resource res[RES_NUM]; struct list_head resources; int bus_min; int bus_max; int node; int link; }; /* 4 at this time, it may become to 32 */ #define PCI_ROOT_NR 4 extern int pci_root_num; extern struct pci_root_info pci_root_info[PCI_ROOT_NR]; extern struct list_head pci_root_infos; struct pci_root_info *alloc_pci_root_info(int bus_min, int bus_max, int node, int link); extern void update_res(struct pci_root_info *info, resource_size_t start, resource_size_t end, unsigned long flags, int merge); #endif Loading
arch/x86/pci/acpi.c +71 −45 Original line number Diff line number Diff line Loading @@ -9,11 +9,11 @@ struct pci_root_info { struct acpi_device *bridge; char *name; char name[16]; unsigned int res_num; struct resource *res; struct list_head *resources; int busnum; struct pci_sysdata sd; }; static bool pci_use_crs = true; Loading Loading @@ -287,7 +287,8 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type) } } static void add_resources(struct pci_root_info *info) static void add_resources(struct pci_root_info *info, struct list_head *resources) { int i; struct resource *res, *root, *conflict; Loading @@ -311,53 +312,74 @@ static void add_resources(struct pci_root_info *info) "ignoring host bridge window %pR (conflicts with %s %pR)\n", res, conflict->name, conflict); else pci_add_resource(info->resources, res); pci_add_resource(resources, res); } } static void free_pci_root_info_res(struct pci_root_info *info) { kfree(info->res); info->res = NULL; info->res_num = 0; } static void __release_pci_root_info(struct pci_root_info *info) { int i; struct resource *res; for (i = 0; i < info->res_num; i++) { res = &info->res[i]; if (!res->parent) continue; if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) continue; release_resource(res); } free_pci_root_info_res(info); kfree(info); } static void release_pci_root_info(struct pci_host_bridge *bridge) { struct pci_root_info *info = bridge->release_data; __release_pci_root_info(info); } static void get_current_resources(struct acpi_device *device, int busnum, int domain, struct list_head *resources) probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, int busnum, int domain) { struct pci_root_info info; size_t size; info.bridge = device; info.res_num = 0; info.resources = resources; info->bridge = device; info->res_num = 0; acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, &info); if (!info.res_num) info); if (!info->res_num) return; size = sizeof(*info.res) * info.res_num; info.res = kmalloc(size, GFP_KERNEL); if (!info.res) size = sizeof(*info->res) * info->res_num; info->res_num = 0; info->res = kmalloc(size, GFP_KERNEL); if (!info->res) return; info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum); if (!info.name) goto name_alloc_fail; sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); info.res_num = 0; acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, &info); if (pci_use_crs) { add_resources(&info); return; } kfree(info.name); name_alloc_fail: kfree(info.res); info); } struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) { struct acpi_device *device = root->device; struct pci_root_info *info = NULL; int domain = root->segment; int busnum = root->secondary.start; LIST_HEAD(resources); Loading Loading @@ -389,17 +411,14 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) if (node != -1 && !node_online(node)) node = -1; /* Allocate per-root-bus (not per bus) arch-specific data. * TODO: leak; this memory is never freed. * It's arguable whether it's worth the trouble to care. */ sd = kzalloc(sizeof(*sd), GFP_KERNEL); if (!sd) { info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { printk(KERN_WARNING "pci_bus %04x:%02x: " "ignored (out of memory)\n", domain, busnum); return NULL; } sd = &info->sd; sd->domain = domain; sd->node = node; /* Loading @@ -413,22 +432,32 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) * be replaced by sd. */ memcpy(bus->sysdata, sd, sizeof(*sd)); kfree(sd); kfree(info); } else { get_current_resources(device, busnum, domain, &resources); probe_pci_root_info(info, device, busnum, domain); /* * _CRS with no apertures is normal, so only fall back to * defaults or native bridge info if we're ignoring _CRS. */ if (!pci_use_crs) if (pci_use_crs) add_resources(info, &resources); else { free_pci_root_info_res(info); x86_pci_root_bus_resources(busnum, &resources); } bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); if (bus) if (bus) { bus->subordinate = pci_scan_child_bus(bus); else pci_set_host_bridge_release( to_pci_host_bridge(bus->bridge), release_pci_root_info, info); } else { pci_free_resource_list(&resources); __release_pci_root_info(info); } } /* After the PCI-E bus has been walked and all devices discovered, Loading @@ -445,9 +474,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) } } if (!bus) kfree(sd); if (bus && node != -1) { #ifdef CONFIG_ACPI_NUMA if (pxm >= 0) Loading
arch/x86/pci/amd_bus.c +27 −49 Original line number Diff line number Diff line Loading @@ -32,6 +32,18 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = { #define RANGE_NUM 16 static struct pci_root_info __init *find_pci_root_info(int node, int link) { struct pci_root_info *info; /* find the position */ list_for_each_entry(info, &pci_root_infos, list) if (info->node == node && info->link == link) return info; return NULL; } /** * early_fill_mp_bus_to_node() * called before pcibios_scan_root and pci_scan_bus Loading @@ -50,7 +62,6 @@ static int __init early_fill_mp_bus_info(void) int def_link; struct pci_root_info *info; u32 reg; struct resource *res; u64 start; u64 end; struct range range[RANGE_NUM]; Loading Loading @@ -86,7 +97,6 @@ static int __init early_fill_mp_bus_info(void) if (!found) return 0; pci_root_num = 0; for (i = 0; i < 4; i++) { int min_bus; int max_bus; Loading @@ -105,13 +115,8 @@ static int __init early_fill_mp_bus_info(void) #endif link = (reg >> 8) & 0x03; info = &pci_root_info[pci_root_num]; info->bus_min = min_bus; info->bus_max = max_bus; info->node = node; info->link = link; info = alloc_pci_root_info(min_bus, max_bus, node, link); sprintf(info->name, "PCI Bus #%02x", min_bus); pci_root_num++; } /* get the default node and link for left over res */ Loading @@ -134,16 +139,10 @@ static int __init early_fill_mp_bus_info(void) link = (reg >> 4) & 0x03; end = (reg & 0xfff000) | 0xfff; /* find the position */ for (j = 0; j < pci_root_num; j++) { info = &pci_root_info[j]; if (info->node == node && info->link == link) break; } if (j == pci_root_num) info = find_pci_root_info(node, link); if (!info) continue; /* not found */ info = &pci_root_info[j]; printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n", node, link, start, end); Loading @@ -155,13 +154,8 @@ static int __init early_fill_mp_bus_info(void) } /* add left over io port range to def node/link, [0, 0xffff] */ /* find the position */ for (j = 0; j < pci_root_num; j++) { info = &pci_root_info[j]; if (info->node == def_node && info->link == def_link) break; } if (j < pci_root_num) { info = &pci_root_info[j]; info = find_pci_root_info(def_node, def_link); if (info) { for (i = 0; i < RANGE_NUM; i++) { if (!range[i].end) continue; Loading Loading @@ -214,16 +208,10 @@ static int __init early_fill_mp_bus_info(void) end <<= 8; end |= 0xffff; /* find the position */ for (j = 0; j < pci_root_num; j++) { info = &pci_root_info[j]; if (info->node == node && info->link == link) break; } if (j == pci_root_num) continue; /* not found */ info = find_pci_root_info(node, link); info = &pci_root_info[j]; if (!info) continue; printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]", node, link, start, end); Loading Loading @@ -291,14 +279,8 @@ static int __init early_fill_mp_bus_info(void) * add left over mmio range to def node/link ? * that is tricky, just record range in from start_min to 4G */ for (j = 0; j < pci_root_num; j++) { info = &pci_root_info[j]; if (info->node == def_node && info->link == def_link) break; } if (j < pci_root_num) { info = &pci_root_info[j]; info = find_pci_root_info(def_node, def_link); if (info) { for (i = 0; i < RANGE_NUM; i++) { if (!range[i].end) continue; Loading @@ -309,20 +291,16 @@ static int __init early_fill_mp_bus_info(void) } } for (i = 0; i < pci_root_num; i++) { int res_num; list_for_each_entry(info, &pci_root_infos, list) { int busnum; struct pci_root_res *root_res; info = &pci_root_info[i]; res_num = info->res_num; busnum = info->bus_min; printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", info->bus_min, info->bus_max, info->node, info->link); for (j = 0; j < res_num; j++) { res = &info->res[j]; printk(KERN_DEBUG "bus: %02x index %x %pR\n", busnum, j, res); } list_for_each_entry(root_res, &info->resources, list) printk(KERN_DEBUG "bus: %02x %pR\n", busnum, &root_res->res); } return 0; Loading
arch/x86/pci/broadcom_bus.c +4 −8 Original line number Diff line number Diff line Loading @@ -22,19 +22,15 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func) { struct pci_root_info *info; struct pci_root_res *root_res; struct resource res; u16 word1, word2; u8 fbus, lbus; int i; info = &pci_root_info[pci_root_num]; pci_root_num++; /* read the PCI bus numbers */ fbus = read_pci_config_byte(bus, slot, func, 0x44); lbus = read_pci_config_byte(bus, slot, func, 0x45); info->bus_min = fbus; info->bus_max = lbus; info = alloc_pci_root_info(fbus, lbus, 0, 0); /* * Add the legacy IDE ports on bus 0 Loading Loading @@ -86,8 +82,8 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func) res.flags = IORESOURCE_BUS; printk(KERN_INFO "CNB20LE PCI Host Bridge (domain 0000 %pR)\n", &res); for (i = 0; i < info->res_num; i++) printk(KERN_INFO "host bridge window %pR\n", &info->res[i]); list_for_each_entry(root_res, &info->resources, list) printk(KERN_INFO "host bridge window %pR\n", &root_res->res); } static int __init broadcom_postcore_init(void) Loading
arch/x86/pci/bus_numa.c +47 −22 Original line number Diff line number Diff line Loading @@ -4,35 +4,38 @@ #include "bus_numa.h" int pci_root_num; struct pci_root_info pci_root_info[PCI_ROOT_NR]; LIST_HEAD(pci_root_infos); void x86_pci_root_bus_resources(int bus, struct list_head *resources) static struct pci_root_info *x86_find_pci_root_info(int bus) { int i; int j; struct pci_root_info *info; if (!pci_root_num) goto default_resources; if (list_empty(&pci_root_infos)) return NULL; for (i = 0; i < pci_root_num; i++) { if (pci_root_info[i].bus_min == bus) break; list_for_each_entry(info, &pci_root_infos, list) if (info->bus_min == bus) return info; return NULL; } if (i == pci_root_num) void x86_pci_root_bus_resources(int bus, struct list_head *resources) { struct pci_root_info *info = x86_find_pci_root_info(bus); struct pci_root_res *root_res; if (!info) goto default_resources; printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", bus); info = &pci_root_info[i]; for (j = 0; j < info->res_num; j++) { list_for_each_entry(root_res, &info->resources, list) { struct resource *res; struct resource *root; res = &info->res[j]; res = &root_res->res; pci_add_resource(resources, res); if (res->flags & IORESOURCE_IO) root = &ioport_resource; Loading @@ -53,11 +56,32 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) pci_add_resource(resources, &iomem_resource); } struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max, int node, int link) { struct pci_root_info *info; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return info; INIT_LIST_HEAD(&info->resources); info->bus_min = bus_min; info->bus_max = bus_max; info->node = node; info->link = link; list_add_tail(&info->list, &pci_root_infos); return info; } void __devinit update_res(struct pci_root_info *info, resource_size_t start, resource_size_t end, unsigned long flags, int merge) { int i; struct resource *res; struct pci_root_res *root_res; if (start > end) return; Loading @@ -69,11 +93,11 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start, goto addit; /* try to merge it with old one */ for (i = 0; i < info->res_num; i++) { list_for_each_entry(root_res, &info->resources, list) { resource_size_t final_start, final_end; resource_size_t common_start, common_end; res = &info->res[i]; res = &root_res->res; if (res->flags != flags) continue; Loading @@ -93,14 +117,15 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start, addit: /* need to add that */ if (info->res_num >= RES_NUM) root_res = kzalloc(sizeof(*root_res), GFP_KERNEL); if (!root_res) return; res = &info->res[info->res_num]; res = &root_res->res; res->name = info->name; res->flags = flags; res->start = start; res->end = end; res->child = NULL; info->res_num++; list_add_tail(&root_res->list, &info->resources); }
arch/x86/pci/bus_numa.h +10 −8 Original line number Diff line number Diff line Loading @@ -4,22 +4,24 @@ * sub bus (transparent) will use entres from 3 to store extra from * root, so need to make sure we have enough slot there. */ #define RES_NUM 16 struct pci_root_res { struct list_head list; struct resource res; }; struct pci_root_info { struct list_head list; char name[12]; unsigned int res_num; struct resource res[RES_NUM]; struct list_head resources; int bus_min; int bus_max; int node; int link; }; /* 4 at this time, it may become to 32 */ #define PCI_ROOT_NR 4 extern int pci_root_num; extern struct pci_root_info pci_root_info[PCI_ROOT_NR]; extern struct list_head pci_root_infos; struct pci_root_info *alloc_pci_root_info(int bus_min, int bus_max, int node, int link); extern void update_res(struct pci_root_info *info, resource_size_t start, resource_size_t end, unsigned long flags, int merge); #endif