1 #include <linux/init.h> 2 #include <linux/pci.h> 3 4 #include "bus_numa.h" 5 6 int pci_root_num; 7 struct pci_root_info pci_root_info[PCI_ROOT_NR]; 8 int found_all_numa_early; 9 10 void x86_pci_root_bus_res_quirks(struct pci_bus *b) 11 { 12 int i; 13 int j; 14 struct pci_root_info *info; 15 16 /* don't go for it if _CRS is used already */ 17 if (b->resource[0] != &ioport_resource || 18 b->resource[1] != &iomem_resource) 19 return; 20 21 if (!pci_root_num) 22 return; 23 24 /* for amd, if only one root bus, don't need to do anything */ 25 if (pci_root_num < 2 && found_all_numa_early) 26 return; 27 28 for (i = 0; i < pci_root_num; i++) { 29 if (pci_root_info[i].bus_min == b->number) 30 break; 31 } 32 33 if (i == pci_root_num) 34 return; 35 36 printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n", 37 b->number); 38 39 info = &pci_root_info[i]; 40 for (j = 0; j < info->res_num; j++) { 41 struct resource *res; 42 struct resource *root; 43 44 res = &info->res[j]; 45 b->resource[j] = res; 46 if (res->flags & IORESOURCE_IO) 47 root = &ioport_resource; 48 else 49 root = &iomem_resource; 50 insert_resource(root, res); 51 } 52 } 53 54 void __devinit update_res(struct pci_root_info *info, size_t start, 55 size_t end, unsigned long flags, int merge) 56 { 57 int i; 58 struct resource *res; 59 60 if (start > end) 61 return; 62 63 if (!merge) 64 goto addit; 65 66 /* try to merge it with old one */ 67 for (i = 0; i < info->res_num; i++) { 68 size_t final_start, final_end; 69 size_t common_start, common_end; 70 71 res = &info->res[i]; 72 if (res->flags != flags) 73 continue; 74 75 common_start = max((size_t)res->start, start); 76 common_end = min((size_t)res->end, end); 77 if (common_start > common_end + 1) 78 continue; 79 80 final_start = min((size_t)res->start, start); 81 final_end = max((size_t)res->end, end); 82 83 res->start = final_start; 84 res->end = final_end; 85 return; 86 } 87 88 addit: 89 90 /* need to add that */ 91 if (info->res_num >= RES_NUM) 92 return; 93 94 res = &info->res[info->res_num]; 95 res->name = info->name; 96 res->flags = flags; 97 res->start = start; 98 res->end = end; 99 res->child = NULL; 100 info->res_num++; 101 } 102