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