setup-bus.c (2934a0de095f277a7bbc15a72ecf61af31a45163) | setup-bus.c (bdc4abecaeff30b3cc230b418a925999dda594c2) |
---|---|
1/* 2 * drivers/pci/setup-bus.c 3 * 4 * Extruded from code written by 5 * Dave Rusling (david.rusling@reo.mts.dec.com) 6 * David Mosberger (davidm@cs.arizona.edu) 7 * David Miller (davem@redhat.com) 8 * --- 13 unchanged lines hidden (view full) --- 22#include <linux/module.h> 23#include <linux/pci.h> 24#include <linux/errno.h> 25#include <linux/ioport.h> 26#include <linux/cache.h> 27#include <linux/slab.h> 28#include "pci.h" 29 | 1/* 2 * drivers/pci/setup-bus.c 3 * 4 * Extruded from code written by 5 * Dave Rusling (david.rusling@reo.mts.dec.com) 6 * David Mosberger (davidm@cs.arizona.edu) 7 * David Miller (davem@redhat.com) 8 * --- 13 unchanged lines hidden (view full) --- 22#include <linux/module.h> 23#include <linux/pci.h> 24#include <linux/errno.h> 25#include <linux/ioport.h> 26#include <linux/cache.h> 27#include <linux/slab.h> 28#include "pci.h" 29 |
30struct resource_list { 31 struct resource_list *next; | 30struct pci_dev_resource { 31 struct list_head list; |
32 struct resource *res; 33 struct pci_dev *dev; 34}; 35 | 32 struct resource *res; 33 struct pci_dev *dev; 34}; 35 |
36struct resource_list_x { 37 struct resource_list_x *next; | 36struct pci_dev_resource_x { 37 struct list_head list; |
38 struct resource *res; 39 struct pci_dev *dev; 40 resource_size_t start; 41 resource_size_t end; 42 resource_size_t add_size; 43 resource_size_t min_align; 44 unsigned long flags; 45}; 46 | 38 struct resource *res; 39 struct pci_dev *dev; 40 resource_size_t start; 41 resource_size_t end; 42 resource_size_t add_size; 43 resource_size_t min_align; 44 unsigned long flags; 45}; 46 |
47#define free_list(type, head) do { \ 48 struct type *list, *tmp; \ 49 for (list = (head)->next; list;) { \ 50 tmp = list; \ 51 list = list->next; \ 52 kfree(tmp); \ 53 } \ 54 (head)->next = NULL; \ | 47#define free_list(type, head) do { \ 48 struct type *dev_res, *tmp; \ 49 list_for_each_entry_safe(dev_res, tmp, head, list) { \ 50 list_del(&dev_res->list); \ 51 kfree(dev_res); \ 52 } \ |
55} while (0) 56 57int pci_realloc_enable = 0; 58#define pci_realloc_enabled() pci_realloc_enable 59void pci_realloc(void) 60{ 61 pci_realloc_enable = 1; 62} 63 64/** 65 * add_to_list() - add a new resource tracker to the list 66 * @head: Head of the list 67 * @dev: device corresponding to which the resource 68 * belongs 69 * @res: The resource to be tracked 70 * @add_size: additional size to be optionally added 71 * to the resource 72 */ | 53} while (0) 54 55int pci_realloc_enable = 0; 56#define pci_realloc_enabled() pci_realloc_enable 57void pci_realloc(void) 58{ 59 pci_realloc_enable = 1; 60} 61 62/** 63 * add_to_list() - add a new resource tracker to the list 64 * @head: Head of the list 65 * @dev: device corresponding to which the resource 66 * belongs 67 * @res: The resource to be tracked 68 * @add_size: additional size to be optionally added 69 * to the resource 70 */ |
73static int add_to_list(struct resource_list_x *head, | 71static int add_to_list(struct list_head *head, |
74 struct pci_dev *dev, struct resource *res, 75 resource_size_t add_size, resource_size_t min_align) 76{ | 72 struct pci_dev *dev, struct resource *res, 73 resource_size_t add_size, resource_size_t min_align) 74{ |
77 struct resource_list_x *list = head; 78 struct resource_list_x *ln = list->next; 79 struct resource_list_x *tmp; | 75 struct pci_dev_resource_x *tmp; |
80 | 76 |
81 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | 77 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); |
82 if (!tmp) { 83 pr_warning("add_to_list: kmalloc() failed!\n"); 84 return -ENOMEM; 85 } 86 | 78 if (!tmp) { 79 pr_warning("add_to_list: kmalloc() failed!\n"); 80 return -ENOMEM; 81 } 82 |
87 tmp->next = ln; | |
88 tmp->res = res; 89 tmp->dev = dev; 90 tmp->start = res->start; 91 tmp->end = res->end; 92 tmp->flags = res->flags; 93 tmp->add_size = add_size; 94 tmp->min_align = min_align; | 83 tmp->res = res; 84 tmp->dev = dev; 85 tmp->start = res->start; 86 tmp->end = res->end; 87 tmp->flags = res->flags; 88 tmp->add_size = add_size; 89 tmp->min_align = min_align; |
95 list->next = tmp; | |
96 | 90 |
91 list_add(&tmp->list, head); 92 |
|
97 return 0; 98} 99 | 93 return 0; 94} 95 |
100static void add_to_failed_list(struct resource_list_x *head, | 96static void add_to_failed_list(struct list_head *head, |
101 struct pci_dev *dev, struct resource *res) 102{ 103 add_to_list(head, dev, res, 104 0 /* dont care */, 105 0 /* dont care */); 106} 107 | 97 struct pci_dev *dev, struct resource *res) 98{ 99 add_to_list(head, dev, res, 100 0 /* dont care */, 101 0 /* dont care */); 102} 103 |
108static void remove_from_list(struct resource_list_x *realloc_head, | 104static void remove_from_list(struct list_head *realloc_head, |
109 struct resource *res) 110{ | 105 struct resource *res) 106{ |
111 struct resource_list_x *prev, *tmp, *list; | 107 struct pci_dev_resource_x *dev_res_x, *tmp; |
112 | 108 |
113 prev = realloc_head; 114 for (list = realloc_head->next; list;) { 115 if (list->res != res) { 116 prev = list; 117 list = list->next; 118 continue; | 109 list_for_each_entry_safe(dev_res_x, tmp, realloc_head, list) { 110 if (dev_res_x->res == res) { 111 list_del(&dev_res_x->list); 112 kfree(dev_res_x); 113 break; |
119 } | 114 } |
120 tmp = list; 121 prev->next = list = list->next; 122 kfree(tmp); | |
123 } 124} 125 | 115 } 116} 117 |
126static resource_size_t get_res_add_size(struct resource_list_x *realloc_head, | 118static resource_size_t get_res_add_size(struct list_head *realloc_head, |
127 struct resource *res) 128{ | 119 struct resource *res) 120{ |
129 struct resource_list_x *list; | 121 struct pci_dev_resource_x *dev_res_x; |
130 | 122 |
131 /* check if it is in realloc_head list */ 132 for (list = realloc_head->next; list && list->res != res; 133 list = list->next) 134 ; 135 136 if (list) { 137 dev_printk(KERN_DEBUG, &list->dev->dev, 138 "%pR get_res_add_size add_size %llx\n", 139 list->res, (unsigned long long)list->add_size); 140 return list->add_size; | 123 list_for_each_entry(dev_res_x, realloc_head, list) { 124 if (dev_res_x->res == res) { 125 dev_printk(KERN_DEBUG, &dev_res_x->dev->dev, 126 "%pR get_res_add_size add_size %llx\n", 127 dev_res_x->res, 128 (unsigned long long)dev_res_x->add_size); 129 return dev_res_x->add_size; 130 } |
141 } 142 143 return 0; 144} 145 146/* Sort resources by alignment */ | 131 } 132 133 return 0; 134} 135 136/* Sort resources by alignment */ |
147static void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | 137static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) |
148{ 149 int i; 150 151 for (i = 0; i < PCI_NUM_RESOURCES; i++) { 152 struct resource *r; | 138{ 139 int i; 140 141 for (i = 0; i < PCI_NUM_RESOURCES; i++) { 142 struct resource *r; |
153 struct resource_list *list, *tmp; | 143 struct pci_dev_resource *dev_res, *tmp; |
154 resource_size_t r_align; | 144 resource_size_t r_align; |
145 struct list_head *n; |
|
155 156 r = &dev->resource[i]; 157 158 if (r->flags & IORESOURCE_PCI_FIXED) 159 continue; 160 161 if (!(r->flags) || r->parent) 162 continue; 163 164 r_align = pci_resource_alignment(dev, r); 165 if (!r_align) { 166 dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", 167 i, r); 168 continue; 169 } | 146 147 r = &dev->resource[i]; 148 149 if (r->flags & IORESOURCE_PCI_FIXED) 150 continue; 151 152 if (!(r->flags) || r->parent) 153 continue; 154 155 r_align = pci_resource_alignment(dev, r); 156 if (!r_align) { 157 dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", 158 i, r); 159 continue; 160 } |
170 for (list = head; ; list = list->next) { 171 resource_size_t align = 0; 172 struct resource_list *ln = list->next; | |
173 | 161 |
174 if (ln) 175 align = pci_resource_alignment(ln->dev, ln->res); | 162 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 163 if (!tmp) 164 panic("pdev_sort_resources(): " 165 "kmalloc() failed!\n"); 166 tmp->res = r; 167 tmp->dev = dev; |
176 | 168 |
169 /* fallback is smallest one or list is empty*/ 170 n = head; 171 list_for_each_entry(dev_res, head, list) { 172 resource_size_t align; 173 174 align = pci_resource_alignment(dev_res->dev, 175 dev_res->res); 176 |
|
177 if (r_align > align) { | 177 if (r_align > align) { |
178 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); 179 if (!tmp) 180 panic("pdev_sort_resources(): " 181 "kmalloc() failed!\n"); 182 tmp->next = ln; 183 tmp->res = r; 184 tmp->dev = dev; 185 list->next = tmp; | 178 n = &dev_res->list; |
186 break; 187 } 188 } | 179 break; 180 } 181 } |
182 /* Insert it just before n*/ 183 list_add_tail(&tmp->list, n); |
|
189 } 190} 191 192static void __dev_sort_resources(struct pci_dev *dev, | 184 } 185} 186 187static void __dev_sort_resources(struct pci_dev *dev, |
193 struct resource_list *head) | 188 struct list_head *head) |
194{ 195 u16 class = dev->class >> 8; 196 197 /* Don't touch classless devices or host bridges or ioapics. */ 198 if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST) 199 return; 200 201 /* Don't touch ioapic devices already enabled by firmware */ --- 21 unchanged lines hidden (view full) --- 223 * resources 224 * @head : head of the list tracking requests with allocated 225 * resources 226 * 227 * Walk through each element of the realloc_head and try to procure 228 * additional resources for the element, provided the element 229 * is in the head list. 230 */ | 189{ 190 u16 class = dev->class >> 8; 191 192 /* Don't touch classless devices or host bridges or ioapics. */ 193 if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST) 194 return; 195 196 /* Don't touch ioapic devices already enabled by firmware */ --- 21 unchanged lines hidden (view full) --- 218 * resources 219 * @head : head of the list tracking requests with allocated 220 * resources 221 * 222 * Walk through each element of the realloc_head and try to procure 223 * additional resources for the element, provided the element 224 * is in the head list. 225 */ |
231static void reassign_resources_sorted(struct resource_list_x *realloc_head, 232 struct resource_list *head) | 226static void reassign_resources_sorted(struct list_head *realloc_head, 227 struct list_head *head) |
233{ 234 struct resource *res; | 228{ 229 struct resource *res; |
235 struct resource_list_x *list, *tmp, *prev; 236 struct resource_list *hlist; | 230 struct pci_dev_resource_x *dev_res_x, *tmp; 231 struct pci_dev_resource *dev_res; |
237 resource_size_t add_size; 238 int idx; 239 | 232 resource_size_t add_size; 233 int idx; 234 |
240 prev = realloc_head; 241 for (list = realloc_head->next; list;) { 242 res = list->res; | 235 list_for_each_entry_safe(dev_res_x, tmp, realloc_head, list) { 236 bool found_match = false; 237 238 res = dev_res_x->res; |
243 /* skip resource that has been reset */ 244 if (!res->flags) 245 goto out; 246 247 /* skip this resource if not found in head list */ | 239 /* skip resource that has been reset */ 240 if (!res->flags) 241 goto out; 242 243 /* skip this resource if not found in head list */ |
248 for (hlist = head->next; hlist && hlist->res != res; 249 hlist = hlist->next); 250 if (!hlist) { /* just skip */ 251 prev = list; 252 list = list->next; 253 continue; | 244 list_for_each_entry(dev_res, head, list) { 245 if (dev_res->res == res) { 246 found_match = true; 247 break; 248 } |
254 } | 249 } |
250 if (!found_match)/* just skip */ 251 continue; |
|
255 | 252 |
256 idx = res - &list->dev->resource[0]; 257 add_size=list->add_size; | 253 idx = res - &dev_res_x->dev->resource[0]; 254 add_size = dev_res_x->add_size; |
258 if (!resource_size(res)) { | 255 if (!resource_size(res)) { |
259 res->start = list->start; | 256 res->start = dev_res_x->start; |
260 res->end = res->start + add_size - 1; | 257 res->end = res->start + add_size - 1; |
261 if(pci_assign_resource(list->dev, idx)) | 258 if (pci_assign_resource(dev_res_x->dev, idx)) |
262 reset_resource(res); 263 } else { | 259 reset_resource(res); 260 } else { |
264 resource_size_t align = list->min_align; 265 res->flags |= list->flags & (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN); 266 if (pci_reassign_resource(list->dev, idx, add_size, align)) 267 dev_printk(KERN_DEBUG, &list->dev->dev, "failed to add optional resources res=%pR\n", | 261 resource_size_t align = dev_res_x->min_align; 262 res->flags |= dev_res_x->flags & 263 (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN); 264 if (pci_reassign_resource(dev_res_x->dev, idx, 265 add_size, align)) 266 dev_printk(KERN_DEBUG, &dev_res_x->dev->dev, 267 "failed to add optional resources res=%pR\n", |
268 res); 269 } 270out: | 268 res); 269 } 270out: |
271 tmp = list; 272 prev->next = list = list->next; 273 kfree(tmp); | 271 list_del(&dev_res_x->list); 272 kfree(dev_res_x); |
274 } 275} 276 277/** 278 * assign_requested_resources_sorted() - satisfy resource requests 279 * 280 * @head : head of the list tracking requests for resources 281 * @failed_list : head of the list tracking requests that could 282 * not be allocated 283 * 284 * Satisfy resource requests of each element in the list. Add 285 * requests that could not satisfied to the failed_list. 286 */ | 273 } 274} 275 276/** 277 * assign_requested_resources_sorted() - satisfy resource requests 278 * 279 * @head : head of the list tracking requests for resources 280 * @failed_list : head of the list tracking requests that could 281 * not be allocated 282 * 283 * Satisfy resource requests of each element in the list. Add 284 * requests that could not satisfied to the failed_list. 285 */ |
287static void assign_requested_resources_sorted(struct resource_list *head, 288 struct resource_list_x *fail_head) | 286static void assign_requested_resources_sorted(struct list_head *head, 287 struct list_head *fail_head) |
289{ 290 struct resource *res; | 288{ 289 struct resource *res; |
291 struct resource_list *list; | 290 struct pci_dev_resource *dev_res; |
292 int idx; 293 | 291 int idx; 292 |
294 for (list = head->next; list; list = list->next) { 295 res = list->res; 296 idx = res - &list->dev->resource[0]; 297 if (resource_size(res) && pci_assign_resource(list->dev, idx)) { 298 if (fail_head && !pci_is_root_bus(list->dev->bus)) { | 293 list_for_each_entry(dev_res, head, list) { 294 res = dev_res->res; 295 idx = res - &dev_res->dev->resource[0]; 296 if (resource_size(res) && 297 pci_assign_resource(dev_res->dev, idx)) { 298 if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) { |
299 /* 300 * if the failed res is for ROM BAR, and it will 301 * be enabled later, don't add it to the list 302 */ 303 if (!((idx == PCI_ROM_RESOURCE) && 304 (!(res->flags & IORESOURCE_ROM_ENABLE)))) | 299 /* 300 * if the failed res is for ROM BAR, and it will 301 * be enabled later, don't add it to the list 302 */ 303 if (!((idx == PCI_ROM_RESOURCE) && 304 (!(res->flags & IORESOURCE_ROM_ENABLE)))) |
305 add_to_failed_list(fail_head, list->dev, res); | 305 add_to_failed_list(fail_head, 306 dev_res->dev, res); |
306 } 307 reset_resource(res); 308 } 309 } 310} 311 | 307 } 308 reset_resource(res); 309 } 310 } 311} 312 |
312static void __assign_resources_sorted(struct resource_list *head, 313 struct resource_list_x *realloc_head, 314 struct resource_list_x *fail_head) | 313static void __assign_resources_sorted(struct list_head *head, 314 struct list_head *realloc_head, 315 struct list_head *fail_head) |
315{ 316 /* 317 * Should not assign requested resources at first. 318 * they could be adjacent, so later reassign can not reallocate 319 * them one by one in parent resource window. 320 * Try to assign requested + add_size at begining 321 * if could do that, could get out early. 322 * if could not do that, we still try to assign requested at first, 323 * then try to reassign add_size for some resources. 324 */ | 316{ 317 /* 318 * Should not assign requested resources at first. 319 * they could be adjacent, so later reassign can not reallocate 320 * them one by one in parent resource window. 321 * Try to assign requested + add_size at begining 322 * if could do that, could get out early. 323 * if could not do that, we still try to assign requested at first, 324 * then try to reassign add_size for some resources. 325 */ |
325 struct resource_list_x save_head, local_fail_head, *list; 326 struct resource_list *l; | 326 LIST_HEAD(save_head); 327 LIST_HEAD(local_fail_head); 328 struct pci_dev_resource_x *dev_res_x; 329 struct pci_dev_resource *dev_res; |
327 328 /* Check if optional add_size is there */ | 330 331 /* Check if optional add_size is there */ |
329 if (!realloc_head || !realloc_head->next) | 332 if (!realloc_head || list_empty(realloc_head)) |
330 goto requested_and_reassign; 331 332 /* Save original start, end, flags etc at first */ | 333 goto requested_and_reassign; 334 335 /* Save original start, end, flags etc at first */ |
333 save_head.next = NULL; 334 for (l = head->next; l; l = l->next) 335 if (add_to_list(&save_head, l->dev, l->res, 0, 0)) { 336 free_list(resource_list_x, &save_head); | 336 list_for_each_entry(dev_res, head, list) { 337 if (add_to_list(&save_head, dev_res->dev, dev_res->res, 0, 0)) { 338 free_list(pci_dev_resource_x, &save_head); |
337 goto requested_and_reassign; 338 } | 339 goto requested_and_reassign; 340 } |
341 } |
|
339 340 /* Update res in head list with add_size in realloc_head list */ | 342 343 /* Update res in head list with add_size in realloc_head list */ |
341 for (l = head->next; l; l = l->next) 342 l->res->end += get_res_add_size(realloc_head, l->res); | 344 list_for_each_entry(dev_res, head, list) 345 dev_res->res->end += get_res_add_size(realloc_head, 346 dev_res->res); |
343 344 /* Try updated head list with add_size added */ | 347 348 /* Try updated head list with add_size added */ |
345 local_fail_head.next = NULL; | |
346 assign_requested_resources_sorted(head, &local_fail_head); 347 348 /* all assigned with add_size ? */ | 349 assign_requested_resources_sorted(head, &local_fail_head); 350 351 /* all assigned with add_size ? */ |
349 if (!local_fail_head.next) { | 352 if (list_empty(&local_fail_head)) { |
350 /* Remove head list from realloc_head list */ | 353 /* Remove head list from realloc_head list */ |
351 for (l = head->next; l; l = l->next) 352 remove_from_list(realloc_head, l->res); 353 free_list(resource_list_x, &save_head); 354 free_list(resource_list, head); | 354 list_for_each_entry(dev_res, head, list) 355 remove_from_list(realloc_head, dev_res->res); 356 free_list(pci_dev_resource_x, &save_head); 357 free_list(pci_dev_resource, head); |
355 return; 356 } 357 | 358 return; 359 } 360 |
358 free_list(resource_list_x, &local_fail_head); | 361 free_list(pci_dev_resource_x, &local_fail_head); |
359 /* Release assigned resource */ | 362 /* Release assigned resource */ |
360 for (l = head->next; l; l = l->next) 361 if (l->res->parent) 362 release_resource(l->res); | 363 list_for_each_entry(dev_res, head, list) 364 if (dev_res->res->parent) 365 release_resource(dev_res->res); |
363 /* Restore start/end/flags from saved list */ | 366 /* Restore start/end/flags from saved list */ |
364 for (list = save_head.next; list; list = list->next) { 365 struct resource *res = list->res; | 367 list_for_each_entry(dev_res_x, &save_head, list) { 368 struct resource *res = dev_res_x->res; |
366 | 369 |
367 res->start = list->start; 368 res->end = list->end; 369 res->flags = list->flags; | 370 res->start = dev_res_x->start; 371 res->end = dev_res_x->end; 372 res->flags = dev_res_x->flags; |
370 } | 373 } |
371 free_list(resource_list_x, &save_head); | 374 free_list(pci_dev_resource_x, &save_head); |
372 373requested_and_reassign: 374 /* Satisfy the must-have resource requests */ 375 assign_requested_resources_sorted(head, fail_head); 376 377 /* Try to satisfy any additional optional resource 378 requests */ 379 if (realloc_head) 380 reassign_resources_sorted(realloc_head, head); | 375 376requested_and_reassign: 377 /* Satisfy the must-have resource requests */ 378 assign_requested_resources_sorted(head, fail_head); 379 380 /* Try to satisfy any additional optional resource 381 requests */ 382 if (realloc_head) 383 reassign_resources_sorted(realloc_head, head); |
381 free_list(resource_list, head); | 384 free_list(pci_dev_resource, head); |
382} 383 384static void pdev_assign_resources_sorted(struct pci_dev *dev, | 385} 386 387static void pdev_assign_resources_sorted(struct pci_dev *dev, |
385 struct resource_list_x *add_head, 386 struct resource_list_x *fail_head) | 388 struct list_head *add_head, 389 struct list_head *fail_head) |
387{ | 390{ |
388 struct resource_list head; | 391 LIST_HEAD(head); |
389 | 392 |
390 head.next = NULL; | |
391 __dev_sort_resources(dev, &head); 392 __assign_resources_sorted(&head, add_head, fail_head); 393 394} 395 396static void pbus_assign_resources_sorted(const struct pci_bus *bus, | 393 __dev_sort_resources(dev, &head); 394 __assign_resources_sorted(&head, add_head, fail_head); 395 396} 397 398static void pbus_assign_resources_sorted(const struct pci_bus *bus, |
397 struct resource_list_x *realloc_head, 398 struct resource_list_x *fail_head) | 399 struct list_head *realloc_head, 400 struct list_head *fail_head) |
399{ 400 struct pci_dev *dev; | 401{ 402 struct pci_dev *dev; |
401 struct resource_list head; | 403 LIST_HEAD(head); |
402 | 404 |
403 head.next = NULL; | |
404 list_for_each_entry(dev, &bus->devices, bus_list) 405 __dev_sort_resources(dev, &head); 406 407 __assign_resources_sorted(&head, realloc_head, fail_head); 408} 409 410void pci_setup_cardbus(struct pci_bus *bus) 411{ --- 296 unchanged lines hidden (view full) --- 708 * @realloc_head : track the additional io window on this list 709 * 710 * Sizing the IO windows of the PCI-PCI bridge is trivial, 711 * since these windows have 4K granularity and the IO ranges 712 * of non-bridge PCI devices are limited to 256 bytes. 713 * We must be careful with the ISA aliasing though. 714 */ 715static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | 405 list_for_each_entry(dev, &bus->devices, bus_list) 406 __dev_sort_resources(dev, &head); 407 408 __assign_resources_sorted(&head, realloc_head, fail_head); 409} 410 411void pci_setup_cardbus(struct pci_bus *bus) 412{ --- 296 unchanged lines hidden (view full) --- 709 * @realloc_head : track the additional io window on this list 710 * 711 * Sizing the IO windows of the PCI-PCI bridge is trivial, 712 * since these windows have 4K granularity and the IO ranges 713 * of non-bridge PCI devices are limited to 256 bytes. 714 * We must be careful with the ISA aliasing though. 715 */ 716static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, |
716 resource_size_t add_size, struct resource_list_x *realloc_head) | 717 resource_size_t add_size, struct list_head *realloc_head) |
717{ 718 struct pci_dev *dev; 719 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); 720 unsigned long size = 0, size0 = 0, size1 = 0; 721 resource_size_t children_add_size = 0; 722 723 if (!b_res) 724 return; --- 51 unchanged lines hidden (view full) --- 776 * @realloc_head : track the additional memory window on this list 777 * 778 * Calculate the size of the bus and minimal alignment which 779 * guarantees that all child resources fit in this size. 780 */ 781static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, 782 unsigned long type, resource_size_t min_size, 783 resource_size_t add_size, | 718{ 719 struct pci_dev *dev; 720 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); 721 unsigned long size = 0, size0 = 0, size1 = 0; 722 resource_size_t children_add_size = 0; 723 724 if (!b_res) 725 return; --- 51 unchanged lines hidden (view full) --- 777 * @realloc_head : track the additional memory window on this list 778 * 779 * Calculate the size of the bus and minimal alignment which 780 * guarantees that all child resources fit in this size. 781 */ 782static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, 783 unsigned long type, resource_size_t min_size, 784 resource_size_t add_size, |
784 struct resource_list_x *realloc_head) | 785 struct list_head *realloc_head) |
785{ 786 struct pci_dev *dev; 787 resource_size_t min_align, align, size, size0, size1; 788 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ 789 int order, max_order; 790 struct resource *b_res = find_free_bus_resource(bus, type); 791 unsigned int mem64_mask = 0; 792 resource_size_t children_add_size = 0; --- 93 unchanged lines hidden (view full) --- 886 if (res->flags & IORESOURCE_IO) 887 return pci_cardbus_io_size; 888 if (res->flags & IORESOURCE_MEM) 889 return pci_cardbus_mem_size; 890 return 0; 891} 892 893static void pci_bus_size_cardbus(struct pci_bus *bus, | 786{ 787 struct pci_dev *dev; 788 resource_size_t min_align, align, size, size0, size1; 789 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ 790 int order, max_order; 791 struct resource *b_res = find_free_bus_resource(bus, type); 792 unsigned int mem64_mask = 0; 793 resource_size_t children_add_size = 0; --- 93 unchanged lines hidden (view full) --- 887 if (res->flags & IORESOURCE_IO) 888 return pci_cardbus_io_size; 889 if (res->flags & IORESOURCE_MEM) 890 return pci_cardbus_mem_size; 891 return 0; 892} 893 894static void pci_bus_size_cardbus(struct pci_bus *bus, |
894 struct resource_list_x *realloc_head) | 895 struct list_head *realloc_head) |
895{ 896 struct pci_dev *bridge = bus->self; 897 struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; 898 u16 ctrl; 899 900 /* 901 * Reserve some resources for CardBus. We reserve 902 * a fixed amount of bus space for CardBus bridges. --- 45 unchanged lines hidden (view full) --- 948 * get assigned during required-resource allocation cycle but gets assigned 949 * during the optional-resource allocation cycle. 950 */ 951 b_res[0].start = b_res[1].start = b_res[2].start = b_res[3].start = 1; 952 b_res[0].end = b_res[1].end = b_res[2].end = b_res[3].end = 0; 953} 954 955void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 896{ 897 struct pci_dev *bridge = bus->self; 898 struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; 899 u16 ctrl; 900 901 /* 902 * Reserve some resources for CardBus. We reserve 903 * a fixed amount of bus space for CardBus bridges. --- 45 unchanged lines hidden (view full) --- 949 * get assigned during required-resource allocation cycle but gets assigned 950 * during the optional-resource allocation cycle. 951 */ 952 b_res[0].start = b_res[1].start = b_res[2].start = b_res[3].start = 1; 953 b_res[0].end = b_res[1].end = b_res[2].end = b_res[3].end = 0; 954} 955 956void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
956 struct resource_list_x *realloc_head) | 957 struct list_head *realloc_head) |
957{ 958 struct pci_dev *dev; 959 unsigned long mask, prefmask; 960 resource_size_t additional_mem_size = 0, additional_io_size = 0; 961 962 list_for_each_entry(dev, &bus->devices, bus_list) { 963 struct pci_bus *b = dev->subordinate; 964 if (!b) --- 54 unchanged lines hidden (view full) --- 1019 1020void __ref pci_bus_size_bridges(struct pci_bus *bus) 1021{ 1022 __pci_bus_size_bridges(bus, NULL); 1023} 1024EXPORT_SYMBOL(pci_bus_size_bridges); 1025 1026static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, | 958{ 959 struct pci_dev *dev; 960 unsigned long mask, prefmask; 961 resource_size_t additional_mem_size = 0, additional_io_size = 0; 962 963 list_for_each_entry(dev, &bus->devices, bus_list) { 964 struct pci_bus *b = dev->subordinate; 965 if (!b) --- 54 unchanged lines hidden (view full) --- 1020 1021void __ref pci_bus_size_bridges(struct pci_bus *bus) 1022{ 1023 __pci_bus_size_bridges(bus, NULL); 1024} 1025EXPORT_SYMBOL(pci_bus_size_bridges); 1026 1027static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, |
1027 struct resource_list_x *realloc_head, 1028 struct resource_list_x *fail_head) | 1028 struct list_head *realloc_head, 1029 struct list_head *fail_head) |
1029{ 1030 struct pci_bus *b; 1031 struct pci_dev *dev; 1032 1033 pbus_assign_resources_sorted(bus, realloc_head, fail_head); 1034 1035 list_for_each_entry(dev, &bus->devices, bus_list) { 1036 b = dev->subordinate; --- 22 unchanged lines hidden (view full) --- 1059 1060void __ref pci_bus_assign_resources(const struct pci_bus *bus) 1061{ 1062 __pci_bus_assign_resources(bus, NULL, NULL); 1063} 1064EXPORT_SYMBOL(pci_bus_assign_resources); 1065 1066static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge, | 1030{ 1031 struct pci_bus *b; 1032 struct pci_dev *dev; 1033 1034 pbus_assign_resources_sorted(bus, realloc_head, fail_head); 1035 1036 list_for_each_entry(dev, &bus->devices, bus_list) { 1037 b = dev->subordinate; --- 22 unchanged lines hidden (view full) --- 1060 1061void __ref pci_bus_assign_resources(const struct pci_bus *bus) 1062{ 1063 __pci_bus_assign_resources(bus, NULL, NULL); 1064} 1065EXPORT_SYMBOL(pci_bus_assign_resources); 1066 1067static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge, |
1067 struct resource_list_x *add_head, 1068 struct resource_list_x *fail_head) | 1068 struct list_head *add_head, 1069 struct list_head *fail_head) |
1069{ 1070 struct pci_bus *b; 1071 1072 pdev_assign_resources_sorted((struct pci_dev *)bridge, 1073 add_head, fail_head); 1074 1075 b = bridge->subordinate; 1076 if (!b) --- 167 unchanged lines hidden (view full) --- 1244 * first try will not touch pci bridge res 1245 * second and later try will clear small leaf bridge res 1246 * will stop till to the max deepth if can not find good one 1247 */ 1248void __init 1249pci_assign_unassigned_resources(void) 1250{ 1251 struct pci_bus *bus; | 1070{ 1071 struct pci_bus *b; 1072 1073 pdev_assign_resources_sorted((struct pci_dev *)bridge, 1074 add_head, fail_head); 1075 1076 b = bridge->subordinate; 1077 if (!b) --- 167 unchanged lines hidden (view full) --- 1245 * first try will not touch pci bridge res 1246 * second and later try will clear small leaf bridge res 1247 * will stop till to the max deepth if can not find good one 1248 */ 1249void __init 1250pci_assign_unassigned_resources(void) 1251{ 1252 struct pci_bus *bus; |
1252 struct resource_list_x realloc_list; /* list of resources that | 1253 LIST_HEAD(realloc_head); /* list of resources that |
1253 want additional resources */ | 1254 want additional resources */ |
1254 struct resource_list_x *add_list = NULL; | 1255 struct list_head *add_list = NULL; |
1255 int tried_times = 0; 1256 enum release_type rel_type = leaf_only; | 1256 int tried_times = 0; 1257 enum release_type rel_type = leaf_only; |
1257 struct resource_list_x head, *list; | 1258 LIST_HEAD(fail_head); 1259 struct pci_dev_resource_x *dev_res_x; |
1258 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | 1259 IORESOURCE_PREFETCH; 1260 unsigned long failed_type; 1261 int pci_try_num = 1; 1262 | 1260 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | 1261 IORESOURCE_PREFETCH; 1262 unsigned long failed_type; 1263 int pci_try_num = 1; 1264 |
1263 head.next = NULL; 1264 realloc_list.next = NULL; 1265 | |
1266 /* don't realloc if asked to do so */ 1267 if (pci_realloc_enabled()) { 1268 int max_depth = pci_get_max_depth(); 1269 1270 pci_try_num = max_depth + 1; 1271 printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", 1272 max_depth, pci_try_num); 1273 } 1274 1275again: 1276 /* 1277 * last try will use add_list, otherwise will try good to have as 1278 * must have, so can realloc parent bridge resource 1279 */ 1280 if (tried_times + 1 == pci_try_num) | 1265 /* don't realloc if asked to do so */ 1266 if (pci_realloc_enabled()) { 1267 int max_depth = pci_get_max_depth(); 1268 1269 pci_try_num = max_depth + 1; 1270 printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", 1271 max_depth, pci_try_num); 1272 } 1273 1274again: 1275 /* 1276 * last try will use add_list, otherwise will try good to have as 1277 * must have, so can realloc parent bridge resource 1278 */ 1279 if (tried_times + 1 == pci_try_num) |
1281 add_list = &realloc_list; | 1280 add_list = &realloc_head; |
1282 /* Depth first, calculate sizes and alignments of all 1283 subordinate buses. */ 1284 list_for_each_entry(bus, &pci_root_buses, node) 1285 __pci_bus_size_bridges(bus, add_list); 1286 1287 /* Depth last, allocate resources and update the hardware. */ 1288 list_for_each_entry(bus, &pci_root_buses, node) | 1281 /* Depth first, calculate sizes and alignments of all 1282 subordinate buses. */ 1283 list_for_each_entry(bus, &pci_root_buses, node) 1284 __pci_bus_size_bridges(bus, add_list); 1285 1286 /* Depth last, allocate resources and update the hardware. */ 1287 list_for_each_entry(bus, &pci_root_buses, node) |
1289 __pci_bus_assign_resources(bus, add_list, &head); | 1288 __pci_bus_assign_resources(bus, add_list, &fail_head); |
1290 if (add_list) | 1289 if (add_list) |
1291 BUG_ON(add_list->next); | 1290 BUG_ON(!list_empty(add_list)); |
1292 tried_times++; 1293 1294 /* any device complain? */ | 1291 tried_times++; 1292 1293 /* any device complain? */ |
1295 if (!head.next) | 1294 if (list_empty(&fail_head)) |
1296 goto enable_and_dump; 1297 1298 failed_type = 0; | 1295 goto enable_and_dump; 1296 1297 failed_type = 0; |
1299 for (list = head.next; list;) { 1300 failed_type |= list->flags; 1301 list = list->next; 1302 } | 1298 list_for_each_entry(dev_res_x, &fail_head, list) 1299 failed_type |= dev_res_x->flags; 1300 |
1303 /* 1304 * io port are tight, don't try extra 1305 * or if reach the limit, don't want to try more 1306 */ 1307 failed_type &= type_mask; 1308 if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) { | 1301 /* 1302 * io port are tight, don't try extra 1303 * or if reach the limit, don't want to try more 1304 */ 1305 failed_type &= type_mask; 1306 if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) { |
1309 free_list(resource_list_x, &head); | 1307 free_list(pci_dev_resource_x, &fail_head); |
1310 goto enable_and_dump; 1311 } 1312 1313 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", 1314 tried_times + 1); 1315 1316 /* third times and later will not check if it is leaf */ 1317 if ((tried_times + 1) > 2) 1318 rel_type = whole_subtree; 1319 1320 /* 1321 * Try to release leaf bridge's resources that doesn't fit resource of 1322 * child device under that bridge 1323 */ | 1308 goto enable_and_dump; 1309 } 1310 1311 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", 1312 tried_times + 1); 1313 1314 /* third times and later will not check if it is leaf */ 1315 if ((tried_times + 1) > 2) 1316 rel_type = whole_subtree; 1317 1318 /* 1319 * Try to release leaf bridge's resources that doesn't fit resource of 1320 * child device under that bridge 1321 */ |
1324 for (list = head.next; list;) { 1325 bus = list->dev->bus; 1326 pci_bus_release_bridge_resources(bus, list->flags & type_mask, 1327 rel_type); 1328 list = list->next; | 1322 list_for_each_entry(dev_res_x, &fail_head, list) { 1323 bus = dev_res_x->dev->bus; 1324 pci_bus_release_bridge_resources(bus, 1325 dev_res_x->flags & type_mask, 1326 rel_type); |
1329 } 1330 /* restore size and flags */ | 1327 } 1328 /* restore size and flags */ |
1331 for (list = head.next; list;) { 1332 struct resource *res = list->res; | 1329 list_for_each_entry(dev_res_x, &fail_head, list) { 1330 struct resource *res = dev_res_x->res; |
1333 | 1331 |
1334 res->start = list->start; 1335 res->end = list->end; 1336 res->flags = list->flags; 1337 if (list->dev->subordinate) | 1332 res->start = dev_res_x->start; 1333 res->end = dev_res_x->end; 1334 res->flags = dev_res_x->flags; 1335 if (dev_res_x->dev->subordinate) |
1338 res->flags = 0; | 1336 res->flags = 0; |
1339 1340 list = list->next; | |
1341 } | 1337 } |
1342 free_list(resource_list_x, &head); | 1338 free_list(pci_dev_resource_x, &fail_head); |
1343 1344 goto again; 1345 1346enable_and_dump: 1347 /* Depth last, update the hardware. */ 1348 list_for_each_entry(bus, &pci_root_buses, node) 1349 pci_enable_bridges(bus); 1350 1351 /* dump the resource on buses */ 1352 list_for_each_entry(bus, &pci_root_buses, node) 1353 pci_bus_dump_resources(bus); 1354} 1355 1356void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) 1357{ 1358 struct pci_bus *parent = bridge->subordinate; | 1339 1340 goto again; 1341 1342enable_and_dump: 1343 /* Depth last, update the hardware. */ 1344 list_for_each_entry(bus, &pci_root_buses, node) 1345 pci_enable_bridges(bus); 1346 1347 /* dump the resource on buses */ 1348 list_for_each_entry(bus, &pci_root_buses, node) 1349 pci_bus_dump_resources(bus); 1350} 1351 1352void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) 1353{ 1354 struct pci_bus *parent = bridge->subordinate; |
1359 struct resource_list_x add_list; /* list of resources that | 1355 LIST_HEAD(add_list); /* list of resources that |
1360 want additional resources */ 1361 int tried_times = 0; | 1356 want additional resources */ 1357 int tried_times = 0; |
1362 struct resource_list_x head, *list; | 1358 LIST_HEAD(fail_head); 1359 struct pci_dev_resource_x *dev_res_x; |
1363 int retval; 1364 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | 1365 IORESOURCE_PREFETCH; 1366 | 1360 int retval; 1361 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | 1362 IORESOURCE_PREFETCH; 1363 |
1367 head.next = NULL; 1368 add_list.next = NULL; 1369 | |
1370again: 1371 __pci_bus_size_bridges(parent, &add_list); | 1364again: 1365 __pci_bus_size_bridges(parent, &add_list); |
1372 __pci_bridge_assign_resources(bridge, &add_list, &head); 1373 BUG_ON(add_list.next); | 1366 __pci_bridge_assign_resources(bridge, &add_list, &fail_head); 1367 BUG_ON(!list_empty(&add_list)); |
1374 tried_times++; 1375 | 1368 tried_times++; 1369 |
1376 if (!head.next) | 1370 if (list_empty(&fail_head)) |
1377 goto enable_all; 1378 1379 if (tried_times >= 2) { 1380 /* still fail, don't need to try more */ | 1371 goto enable_all; 1372 1373 if (tried_times >= 2) { 1374 /* still fail, don't need to try more */ |
1381 free_list(resource_list_x, &head); | 1375 free_list(pci_dev_resource_x, &fail_head); |
1382 goto enable_all; 1383 } 1384 1385 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", 1386 tried_times + 1); 1387 1388 /* 1389 * Try to release leaf bridge's resources that doesn't fit resource of 1390 * child device under that bridge 1391 */ | 1376 goto enable_all; 1377 } 1378 1379 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", 1380 tried_times + 1); 1381 1382 /* 1383 * Try to release leaf bridge's resources that doesn't fit resource of 1384 * child device under that bridge 1385 */ |
1392 for (list = head.next; list;) { 1393 struct pci_bus *bus = list->dev->bus; 1394 unsigned long flags = list->flags; | 1386 list_for_each_entry(dev_res_x, &fail_head, list) { 1387 struct pci_bus *bus = dev_res_x->dev->bus; 1388 unsigned long flags = dev_res_x->flags; |
1395 1396 pci_bus_release_bridge_resources(bus, flags & type_mask, 1397 whole_subtree); | 1389 1390 pci_bus_release_bridge_resources(bus, flags & type_mask, 1391 whole_subtree); |
1398 list = list->next; | |
1399 } 1400 /* restore size and flags */ | 1392 } 1393 /* restore size and flags */ |
1401 for (list = head.next; list;) { 1402 struct resource *res = list->res; | 1394 list_for_each_entry(dev_res_x, &fail_head, list) { 1395 struct resource *res = dev_res_x->res; |
1403 | 1396 |
1404 res->start = list->start; 1405 res->end = list->end; 1406 res->flags = list->flags; 1407 if (list->dev->subordinate) | 1397 res->start = dev_res_x->start; 1398 res->end = dev_res_x->end; 1399 res->flags = dev_res_x->flags; 1400 if (dev_res_x->dev->subordinate) |
1408 res->flags = 0; | 1401 res->flags = 0; |
1409 1410 list = list->next; | |
1411 } | 1402 } |
1412 free_list(resource_list_x, &head); | 1403 free_list(pci_dev_resource_x, &fail_head); |
1413 1414 goto again; 1415 1416enable_all: 1417 retval = pci_reenable_device(bridge); 1418 pci_set_master(bridge); 1419 pci_enable_bridges(parent); 1420} --- 8 unchanged lines hidden (view full) --- 1429 * and enables them. 1430 * 1431 * Returns the max number of subordinate bus discovered. 1432 */ 1433unsigned int __ref pci_rescan_bus(struct pci_bus *bus) 1434{ 1435 unsigned int max; 1436 struct pci_dev *dev; | 1404 1405 goto again; 1406 1407enable_all: 1408 retval = pci_reenable_device(bridge); 1409 pci_set_master(bridge); 1410 pci_enable_bridges(parent); 1411} --- 8 unchanged lines hidden (view full) --- 1420 * and enables them. 1421 * 1422 * Returns the max number of subordinate bus discovered. 1423 */ 1424unsigned int __ref pci_rescan_bus(struct pci_bus *bus) 1425{ 1426 unsigned int max; 1427 struct pci_dev *dev; |
1437 struct resource_list_x add_list; /* list of resources that | 1428 LIST_HEAD(add_list); /* list of resources that |
1438 want additional resources */ 1439 1440 max = pci_scan_child_bus(bus); 1441 | 1429 want additional resources */ 1430 1431 max = pci_scan_child_bus(bus); 1432 |
1442 add_list.next = NULL; | |
1443 down_read(&pci_bus_sem); 1444 list_for_each_entry(dev, &bus->devices, bus_list) 1445 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 1446 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 1447 if (dev->subordinate) 1448 __pci_bus_size_bridges(dev->subordinate, 1449 &add_list); 1450 up_read(&pci_bus_sem); 1451 __pci_bus_assign_resources(bus, &add_list, NULL); | 1433 down_read(&pci_bus_sem); 1434 list_for_each_entry(dev, &bus->devices, bus_list) 1435 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 1436 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 1437 if (dev->subordinate) 1438 __pci_bus_size_bridges(dev->subordinate, 1439 &add_list); 1440 up_read(&pci_bus_sem); 1441 __pci_bus_assign_resources(bus, &add_list, NULL); |
1452 BUG_ON(add_list.next); | 1442 BUG_ON(!list_empty(&add_list)); |
1453 1454 pci_enable_bridges(bus); 1455 pci_bus_add_devices(bus); 1456 1457 return max; 1458} 1459EXPORT_SYMBOL_GPL(pci_rescan_bus); 1460#endif | 1443 1444 pci_enable_bridges(bus); 1445 pci_bus_add_devices(bus); 1446 1447 return max; 1448} 1449EXPORT_SYMBOL_GPL(pci_rescan_bus); 1450#endif |