1 #include <linux/init.h> 2 #include <linux/pci.h> 3 #include <linux/range.h> 4 5 #include "bus_numa.h" 6 7 int pci_root_num; 8 struct pci_root_info pci_root_info[PCI_ROOT_NR]; 9 10 void x86_pci_root_bus_resources(int bus, struct list_head *resources) 11 { 12 int i; 13 int j; 14 struct pci_root_info *info; 15 16 if (!pci_root_num) 17 goto default_resources; 18 19 for (i = 0; i < pci_root_num; i++) { 20 if (pci_root_info[i].bus_min == bus) 21 break; 22 } 23 24 if (i == pci_root_num) 25 goto default_resources; 26 27 printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", 28 bus); 29 30 info = &pci_root_info[i]; 31 for (j = 0; j < info->res_num; j++) { 32 struct resource *res; 33 struct resource *root; 34 35 res = &info->res[j]; 36 pci_add_resource(resources, res); 37 if (res->flags & IORESOURCE_IO) 38 root = &ioport_resource; 39 else 40 root = &iomem_resource; 41 insert_resource(root, res); 42 } 43 return; 44 45 default_resources: 46 /* 47 * We don't have any host bridge aperture information from the 48 * "native host bridge drivers," e.g., amd_bus or broadcom_bus, 49 * so fall back to the defaults historically used by pci_create_bus(). 50 */ 51 printk(KERN_DEBUG "PCI: root bus %02x: using default resources\n", bus); 52 pci_add_resource(resources, &ioport_resource); 53 pci_add_resource(resources, &iomem_resource); 54 } 55 56 void __devinit update_res(struct pci_root_info *info, resource_size_t start, 57 resource_size_t end, unsigned long flags, int merge) 58 { 59 int i; 60 struct resource *res; 61 62 if (start > end) 63 return; 64 65 if (start == MAX_RESOURCE) 66 return; 67 68 if (!merge) 69 goto addit; 70 71 /* try to merge it with old one */ 72 for (i = 0; i < info->res_num; i++) { 73 resource_size_t final_start, final_end; 74 resource_size_t common_start, common_end; 75 76 res = &info->res[i]; 77 if (res->flags != flags) 78 continue; 79 80 common_start = max(res->start, start); 81 common_end = min(res->end, end); 82 if (common_start > common_end + 1) 83 continue; 84 85 final_start = min(res->start, start); 86 final_end = max(res->end, end); 87 88 res->start = final_start; 89 res->end = final_end; 90 return; 91 } 92 93 addit: 94 95 /* need to add that */ 96 if (info->res_num >= RES_NUM) 97 return; 98 99 res = &info->res[info->res_num]; 100 res->name = info->name; 101 res->flags = flags; 102 res->start = start; 103 res->end = end; 104 res->child = NULL; 105 info->res_num++; 106 } 107