aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/setup-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r--drivers/pci/setup-bus.c455
1 files changed, 368 insertions, 87 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 66cb8f4cc5f4..9995842e45b5 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -33,11 +33,39 @@ struct resource_list_x {
33 struct pci_dev *dev; 33 struct pci_dev *dev;
34 resource_size_t start; 34 resource_size_t start;
35 resource_size_t end; 35 resource_size_t end;
36 resource_size_t add_size;
36 unsigned long flags; 37 unsigned long flags;
37}; 38};
38 39
39static void add_to_failed_list(struct resource_list_x *head, 40#define free_list(type, head) do { \
40 struct pci_dev *dev, struct resource *res) 41 struct type *list, *tmp; \
42 for (list = (head)->next; list;) { \
43 tmp = list; \
44 list = list->next; \
45 kfree(tmp); \
46 } \
47 (head)->next = NULL; \
48} while (0)
49
50int pci_realloc_enable = 0;
51#define pci_realloc_enabled() pci_realloc_enable
52void pci_realloc(void)
53{
54 pci_realloc_enable = 1;
55}
56
57/**
58 * add_to_list() - add a new resource tracker to the list
59 * @head: Head of the list
60 * @dev: device corresponding to which the resource
61 * belongs
62 * @res: The resource to be tracked
63 * @add_size: additional size to be optionally added
64 * to the resource
65 */
66static void add_to_list(struct resource_list_x *head,
67 struct pci_dev *dev, struct resource *res,
68 resource_size_t add_size)
41{ 69{
42 struct resource_list_x *list = head; 70 struct resource_list_x *list = head;
43 struct resource_list_x *ln = list->next; 71 struct resource_list_x *ln = list->next;
@@ -45,7 +73,7 @@ static void add_to_failed_list(struct resource_list_x *head,
45 73
46 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); 74 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
47 if (!tmp) { 75 if (!tmp) {
48 pr_warning("add_to_failed_list: kmalloc() failed!\n"); 76 pr_warning("add_to_list: kmalloc() failed!\n");
49 return; 77 return;
50 } 78 }
51 79
@@ -55,20 +83,14 @@ static void add_to_failed_list(struct resource_list_x *head,
55 tmp->start = res->start; 83 tmp->start = res->start;
56 tmp->end = res->end; 84 tmp->end = res->end;
57 tmp->flags = res->flags; 85 tmp->flags = res->flags;
86 tmp->add_size = add_size;
58 list->next = tmp; 87 list->next = tmp;
59} 88}
60 89
61static void free_failed_list(struct resource_list_x *head) 90static void add_to_failed_list(struct resource_list_x *head,
91 struct pci_dev *dev, struct resource *res)
62{ 92{
63 struct resource_list_x *list, *tmp; 93 add_to_list(head, dev, res, 0);
64
65 for (list = head->next; list;) {
66 tmp = list;
67 list = list->next;
68 kfree(tmp);
69 }
70
71 head->next = NULL;
72} 94}
73 95
74static void __dev_sort_resources(struct pci_dev *dev, 96static void __dev_sort_resources(struct pci_dev *dev,
@@ -91,18 +113,88 @@ static void __dev_sort_resources(struct pci_dev *dev,
91 pdev_sort_resources(dev, head); 113 pdev_sort_resources(dev, head);
92} 114}
93 115
94static void __assign_resources_sorted(struct resource_list *head, 116static inline void reset_resource(struct resource *res)
95 struct resource_list_x *fail_head) 117{
118 res->start = 0;
119 res->end = 0;
120 res->flags = 0;
121}
122
123/**
124 * adjust_resources_sorted() - satisfy any additional resource requests
125 *
126 * @add_head : head of the list tracking requests requiring additional
127 * resources
128 * @head : head of the list tracking requests with allocated
129 * resources
130 *
131 * Walk through each element of the add_head and try to procure
132 * additional resources for the element, provided the element
133 * is in the head list.
134 */
135static void adjust_resources_sorted(struct resource_list_x *add_head,
136 struct resource_list *head)
96{ 137{
97 struct resource *res; 138 struct resource *res;
98 struct resource_list *list, *tmp; 139 struct resource_list_x *list, *tmp, *prev;
140 struct resource_list *hlist;
141 resource_size_t add_size;
99 int idx; 142 int idx;
100 143
101 for (list = head->next; list;) { 144 prev = add_head;
145 for (list = add_head->next; list;) {
102 res = list->res; 146 res = list->res;
147 /* skip resource that has been reset */
148 if (!res->flags)
149 goto out;
150
151 /* skip this resource if not found in head list */
152 for (hlist = head->next; hlist && hlist->res != res;
153 hlist = hlist->next);
154 if (!hlist) { /* just skip */
155 prev = list;
156 list = list->next;
157 continue;
158 }
159
103 idx = res - &list->dev->resource[0]; 160 idx = res - &list->dev->resource[0];
161 add_size=list->add_size;
162 if (!resource_size(res) && add_size) {
163 res->end = res->start + add_size - 1;
164 if(pci_assign_resource(list->dev, idx))
165 reset_resource(res);
166 } else if (add_size) {
167 adjust_resource(res, res->start,
168 resource_size(res) + add_size);
169 }
170out:
171 tmp = list;
172 prev->next = list = list->next;
173 kfree(tmp);
174 }
175}
104 176
105 if (pci_assign_resource(list->dev, idx)) { 177/**
178 * assign_requested_resources_sorted() - satisfy resource requests
179 *
180 * @head : head of the list tracking requests for resources
181 * @failed_list : head of the list tracking requests that could
182 * not be allocated
183 *
184 * Satisfy resource requests of each element in the list. Add
185 * requests that could not satisfied to the failed_list.
186 */
187static void assign_requested_resources_sorted(struct resource_list *head,
188 struct resource_list_x *fail_head)
189{
190 struct resource *res;
191 struct resource_list *list;
192 int idx;
193
194 for (list = head->next; list; list = list->next) {
195 res = list->res;
196 idx = res - &list->dev->resource[0];
197 if (resource_size(res) && pci_assign_resource(list->dev, idx)) {
106 if (fail_head && !pci_is_root_bus(list->dev->bus)) { 198 if (fail_head && !pci_is_root_bus(list->dev->bus)) {
107 /* 199 /*
108 * if the failed res is for ROM BAR, and it will 200 * if the failed res is for ROM BAR, and it will
@@ -112,16 +204,25 @@ static void __assign_resources_sorted(struct resource_list *head,
112 (!(res->flags & IORESOURCE_ROM_ENABLE)))) 204 (!(res->flags & IORESOURCE_ROM_ENABLE))))
113 add_to_failed_list(fail_head, list->dev, res); 205 add_to_failed_list(fail_head, list->dev, res);
114 } 206 }
115 res->start = 0; 207 reset_resource(res);
116 res->end = 0;
117 res->flags = 0;
118 } 208 }
119 tmp = list;
120 list = list->next;
121 kfree(tmp);
122 } 209 }
123} 210}
124 211
212static void __assign_resources_sorted(struct resource_list *head,
213 struct resource_list_x *add_head,
214 struct resource_list_x *fail_head)
215{
216 /* Satisfy the must-have resource requests */
217 assign_requested_resources_sorted(head, fail_head);
218
219 /* Try to satisfy any additional nice-to-have resource
220 requests */
221 if (add_head)
222 adjust_resources_sorted(add_head, head);
223 free_list(resource_list, head);
224}
225
125static void pdev_assign_resources_sorted(struct pci_dev *dev, 226static void pdev_assign_resources_sorted(struct pci_dev *dev,
126 struct resource_list_x *fail_head) 227 struct resource_list_x *fail_head)
127{ 228{
@@ -129,11 +230,12 @@ static void pdev_assign_resources_sorted(struct pci_dev *dev,
129 230
130 head.next = NULL; 231 head.next = NULL;
131 __dev_sort_resources(dev, &head); 232 __dev_sort_resources(dev, &head);
132 __assign_resources_sorted(&head, fail_head); 233 __assign_resources_sorted(&head, NULL, fail_head);
133 234
134} 235}
135 236
136static void pbus_assign_resources_sorted(const struct pci_bus *bus, 237static void pbus_assign_resources_sorted(const struct pci_bus *bus,
238 struct resource_list_x *add_head,
137 struct resource_list_x *fail_head) 239 struct resource_list_x *fail_head)
138{ 240{
139 struct pci_dev *dev; 241 struct pci_dev *dev;
@@ -143,7 +245,7 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus,
143 list_for_each_entry(dev, &bus->devices, bus_list) 245 list_for_each_entry(dev, &bus->devices, bus_list)
144 __dev_sort_resources(dev, &head); 246 __dev_sort_resources(dev, &head);
145 247
146 __assign_resources_sorted(&head, fail_head); 248 __assign_resources_sorted(&head, add_head, fail_head);
147} 249}
148 250
149void pci_setup_cardbus(struct pci_bus *bus) 251void pci_setup_cardbus(struct pci_bus *bus)
@@ -404,15 +506,62 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon
404 return NULL; 506 return NULL;
405} 507}
406 508
407/* Sizing the IO windows of the PCI-PCI bridge is trivial, 509static resource_size_t calculate_iosize(resource_size_t size,
408 since these windows have 4K granularity and the IO ranges 510 resource_size_t min_size,
409 of non-bridge PCI devices are limited to 256 bytes. 511 resource_size_t size1,
410 We must be careful with the ISA aliasing though. */ 512 resource_size_t old_size,
411static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) 513 resource_size_t align)
514{
515 if (size < min_size)
516 size = min_size;
517 if (old_size == 1 )
518 old_size = 0;
519 /* To be fixed in 2.5: we should have sort of HAVE_ISA
520 flag in the struct pci_bus. */
521#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
522 size = (size & 0xff) + ((size & ~0xffUL) << 2);
523#endif
524 size = ALIGN(size + size1, align);
525 if (size < old_size)
526 size = old_size;
527 return size;
528}
529
530static resource_size_t calculate_memsize(resource_size_t size,
531 resource_size_t min_size,
532 resource_size_t size1,
533 resource_size_t old_size,
534 resource_size_t align)
535{
536 if (size < min_size)
537 size = min_size;
538 if (old_size == 1 )
539 old_size = 0;
540 if (size < old_size)
541 size = old_size;
542 size = ALIGN(size + size1, align);
543 return size;
544}
545
546/**
547 * pbus_size_io() - size the io window of a given bus
548 *
549 * @bus : the bus
550 * @min_size : the minimum io window that must to be allocated
551 * @add_size : additional optional io window
552 * @add_head : track the additional io window on this list
553 *
554 * Sizing the IO windows of the PCI-PCI bridge is trivial,
555 * since these windows have 4K granularity and the IO ranges
556 * of non-bridge PCI devices are limited to 256 bytes.
557 * We must be careful with the ISA aliasing though.
558 */
559static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
560 resource_size_t add_size, struct resource_list_x *add_head)
412{ 561{
413 struct pci_dev *dev; 562 struct pci_dev *dev;
414 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); 563 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
415 unsigned long size = 0, size1 = 0, old_size; 564 unsigned long size = 0, size0 = 0, size1 = 0;
416 565
417 if (!b_res) 566 if (!b_res)
418 return; 567 return;
@@ -435,20 +584,12 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
435 size1 += r_size; 584 size1 += r_size;
436 } 585 }
437 } 586 }
438 if (size < min_size) 587 size0 = calculate_iosize(size, min_size, size1,
439 size = min_size; 588 resource_size(b_res), 4096);
440 old_size = resource_size(b_res); 589 size1 = (!add_head || (add_head && !add_size)) ? size0 :
441 if (old_size == 1) 590 calculate_iosize(size, min_size+add_size, size1,
442 old_size = 0; 591 resource_size(b_res), 4096);
443/* To be fixed in 2.5: we should have sort of HAVE_ISA 592 if (!size0 && !size1) {
444 flag in the struct pci_bus. */
445#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
446 size = (size & 0xff) + ((size & ~0xffUL) << 2);
447#endif
448 size = ALIGN(size + size1, 4096);
449 if (size < old_size)
450 size = old_size;
451 if (!size) {
452 if (b_res->start || b_res->end) 593 if (b_res->start || b_res->end)
453 dev_info(&bus->self->dev, "disabling bridge window " 594 dev_info(&bus->self->dev, "disabling bridge window "
454 "%pR to [bus %02x-%02x] (unused)\n", b_res, 595 "%pR to [bus %02x-%02x] (unused)\n", b_res,
@@ -458,17 +599,30 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
458 } 599 }
459 /* Alignment of the IO window is always 4K */ 600 /* Alignment of the IO window is always 4K */
460 b_res->start = 4096; 601 b_res->start = 4096;
461 b_res->end = b_res->start + size - 1; 602 b_res->end = b_res->start + size0 - 1;
462 b_res->flags |= IORESOURCE_STARTALIGN; 603 b_res->flags |= IORESOURCE_STARTALIGN;
604 if (size1 > size0 && add_head)
605 add_to_list(add_head, bus->self, b_res, size1-size0);
463} 606}
464 607
465/* Calculate the size of the bus and minimal alignment which 608/**
466 guarantees that all child resources fit in this size. */ 609 * pbus_size_mem() - size the memory window of a given bus
610 *
611 * @bus : the bus
612 * @min_size : the minimum memory window that must to be allocated
613 * @add_size : additional optional memory window
614 * @add_head : track the additional memory window on this list
615 *
616 * Calculate the size of the bus and minimal alignment which
617 * guarantees that all child resources fit in this size.
618 */
467static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, 619static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
468 unsigned long type, resource_size_t min_size) 620 unsigned long type, resource_size_t min_size,
621 resource_size_t add_size,
622 struct resource_list_x *add_head)
469{ 623{
470 struct pci_dev *dev; 624 struct pci_dev *dev;
471 resource_size_t min_align, align, size, old_size; 625 resource_size_t min_align, align, size, size0, size1;
472 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ 626 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
473 int order, max_order; 627 int order, max_order;
474 struct resource *b_res = find_free_bus_resource(bus, type); 628 struct resource *b_res = find_free_bus_resource(bus, type);
@@ -516,14 +670,6 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
516 mem64_mask &= r->flags & IORESOURCE_MEM_64; 670 mem64_mask &= r->flags & IORESOURCE_MEM_64;
517 } 671 }
518 } 672 }
519 if (size < min_size)
520 size = min_size;
521 old_size = resource_size(b_res);
522 if (old_size == 1)
523 old_size = 0;
524 if (size < old_size)
525 size = old_size;
526
527 align = 0; 673 align = 0;
528 min_align = 0; 674 min_align = 0;
529 for (order = 0; order <= max_order; order++) { 675 for (order = 0; order <= max_order; order++) {
@@ -537,8 +683,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
537 min_align = align1 >> 1; 683 min_align = align1 >> 1;
538 align += aligns[order]; 684 align += aligns[order];
539 } 685 }
540 size = ALIGN(size, min_align); 686 size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
541 if (!size) { 687 size1 = (!add_head || (add_head && !add_size)) ? size0 :
688 calculate_memsize(size, min_size+add_size, 0,
689 resource_size(b_res), min_align);
690 if (!size0 && !size1) {
542 if (b_res->start || b_res->end) 691 if (b_res->start || b_res->end)
543 dev_info(&bus->self->dev, "disabling bridge window " 692 dev_info(&bus->self->dev, "disabling bridge window "
544 "%pR to [bus %02x-%02x] (unused)\n", b_res, 693 "%pR to [bus %02x-%02x] (unused)\n", b_res,
@@ -547,9 +696,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
547 return 1; 696 return 1;
548 } 697 }
549 b_res->start = min_align; 698 b_res->start = min_align;
550 b_res->end = size + min_align - 1; 699 b_res->end = size0 + min_align - 1;
551 b_res->flags |= IORESOURCE_STARTALIGN; 700 b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask;
552 b_res->flags |= mem64_mask; 701 if (size1 > size0 && add_head)
702 add_to_list(add_head, bus->self, b_res, size1-size0);
553 return 1; 703 return 1;
554} 704}
555 705
@@ -602,11 +752,12 @@ static void pci_bus_size_cardbus(struct pci_bus *bus)
602 } 752 }
603} 753}
604 754
605void __ref pci_bus_size_bridges(struct pci_bus *bus) 755void __ref __pci_bus_size_bridges(struct pci_bus *bus,
756 struct resource_list_x *add_head)
606{ 757{
607 struct pci_dev *dev; 758 struct pci_dev *dev;
608 unsigned long mask, prefmask; 759 unsigned long mask, prefmask;
609 resource_size_t min_mem_size = 0, min_io_size = 0; 760 resource_size_t additional_mem_size = 0, additional_io_size = 0;
610 761
611 list_for_each_entry(dev, &bus->devices, bus_list) { 762 list_for_each_entry(dev, &bus->devices, bus_list) {
612 struct pci_bus *b = dev->subordinate; 763 struct pci_bus *b = dev->subordinate;
@@ -620,7 +771,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
620 771
621 case PCI_CLASS_BRIDGE_PCI: 772 case PCI_CLASS_BRIDGE_PCI:
622 default: 773 default:
623 pci_bus_size_bridges(b); 774 __pci_bus_size_bridges(b, add_head);
624 break; 775 break;
625 } 776 }
626 } 777 }
@@ -637,11 +788,14 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
637 case PCI_CLASS_BRIDGE_PCI: 788 case PCI_CLASS_BRIDGE_PCI:
638 pci_bridge_check_ranges(bus); 789 pci_bridge_check_ranges(bus);
639 if (bus->self->is_hotplug_bridge) { 790 if (bus->self->is_hotplug_bridge) {
640 min_io_size = pci_hotplug_io_size; 791 additional_io_size = pci_hotplug_io_size;
641 min_mem_size = pci_hotplug_mem_size; 792 additional_mem_size = pci_hotplug_mem_size;
642 } 793 }
794 /*
795 * Follow thru
796 */
643 default: 797 default:
644 pbus_size_io(bus, min_io_size); 798 pbus_size_io(bus, 0, additional_io_size, add_head);
645 /* If the bridge supports prefetchable range, size it 799 /* If the bridge supports prefetchable range, size it
646 separately. If it doesn't, or its prefetchable window 800 separately. If it doesn't, or its prefetchable window
647 has already been allocated by arch code, try 801 has already been allocated by arch code, try
@@ -649,30 +803,36 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
649 resources. */ 803 resources. */
650 mask = IORESOURCE_MEM; 804 mask = IORESOURCE_MEM;
651 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; 805 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
652 if (pbus_size_mem(bus, prefmask, prefmask, min_mem_size)) 806 if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, add_head))
653 mask = prefmask; /* Success, size non-prefetch only. */ 807 mask = prefmask; /* Success, size non-prefetch only. */
654 else 808 else
655 min_mem_size += min_mem_size; 809 additional_mem_size += additional_mem_size;
656 pbus_size_mem(bus, mask, IORESOURCE_MEM, min_mem_size); 810 pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, add_head);
657 break; 811 break;
658 } 812 }
659} 813}
814
815void __ref pci_bus_size_bridges(struct pci_bus *bus)
816{
817 __pci_bus_size_bridges(bus, NULL);
818}
660EXPORT_SYMBOL(pci_bus_size_bridges); 819EXPORT_SYMBOL(pci_bus_size_bridges);
661 820
662static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, 821static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
822 struct resource_list_x *add_head,
663 struct resource_list_x *fail_head) 823 struct resource_list_x *fail_head)
664{ 824{
665 struct pci_bus *b; 825 struct pci_bus *b;
666 struct pci_dev *dev; 826 struct pci_dev *dev;
667 827
668 pbus_assign_resources_sorted(bus, fail_head); 828 pbus_assign_resources_sorted(bus, add_head, fail_head);
669 829
670 list_for_each_entry(dev, &bus->devices, bus_list) { 830 list_for_each_entry(dev, &bus->devices, bus_list) {
671 b = dev->subordinate; 831 b = dev->subordinate;
672 if (!b) 832 if (!b)
673 continue; 833 continue;
674 834
675 __pci_bus_assign_resources(b, fail_head); 835 __pci_bus_assign_resources(b, add_head, fail_head);
676 836
677 switch (dev->class >> 8) { 837 switch (dev->class >> 8) {
678 case PCI_CLASS_BRIDGE_PCI: 838 case PCI_CLASS_BRIDGE_PCI:
@@ -694,7 +854,7 @@ static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
694 854
695void __ref pci_bus_assign_resources(const struct pci_bus *bus) 855void __ref pci_bus_assign_resources(const struct pci_bus *bus)
696{ 856{
697 __pci_bus_assign_resources(bus, NULL); 857 __pci_bus_assign_resources(bus, NULL, NULL);
698} 858}
699EXPORT_SYMBOL(pci_bus_assign_resources); 859EXPORT_SYMBOL(pci_bus_assign_resources);
700 860
@@ -709,7 +869,7 @@ static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
709 if (!b) 869 if (!b)
710 return; 870 return;
711 871
712 __pci_bus_assign_resources(b, fail_head); 872 __pci_bus_assign_resources(b, NULL, fail_head);
713 873
714 switch (bridge->class >> 8) { 874 switch (bridge->class >> 8) {
715 case PCI_CLASS_BRIDGE_PCI: 875 case PCI_CLASS_BRIDGE_PCI:
@@ -838,26 +998,147 @@ static void pci_bus_dump_resources(struct pci_bus *bus)
838 } 998 }
839} 999}
840 1000
1001static int __init pci_bus_get_depth(struct pci_bus *bus)
1002{
1003 int depth = 0;
1004 struct pci_dev *dev;
1005
1006 list_for_each_entry(dev, &bus->devices, bus_list) {
1007 int ret;
1008 struct pci_bus *b = dev->subordinate;
1009 if (!b)
1010 continue;
1011
1012 ret = pci_bus_get_depth(b);
1013 if (ret + 1 > depth)
1014 depth = ret + 1;
1015 }
1016
1017 return depth;
1018}
1019static int __init pci_get_max_depth(void)
1020{
1021 int depth = 0;
1022 struct pci_bus *bus;
1023
1024 list_for_each_entry(bus, &pci_root_buses, node) {
1025 int ret;
1026
1027 ret = pci_bus_get_depth(bus);
1028 if (ret > depth)
1029 depth = ret;
1030 }
1031
1032 return depth;
1033}
1034
1035
1036/*
1037 * first try will not touch pci bridge res
1038 * second and later try will clear small leaf bridge res
1039 * will stop till to the max deepth if can not find good one
1040 */
841void __init 1041void __init
842pci_assign_unassigned_resources(void) 1042pci_assign_unassigned_resources(void)
843{ 1043{
844 struct pci_bus *bus; 1044 struct pci_bus *bus;
1045 struct resource_list_x add_list; /* list of resources that
1046 want additional resources */
1047 int tried_times = 0;
1048 enum release_type rel_type = leaf_only;
1049 struct resource_list_x head, *list;
1050 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1051 IORESOURCE_PREFETCH;
1052 unsigned long failed_type;
1053 int max_depth = pci_get_max_depth();
1054 int pci_try_num;
1055
1056
1057 head.next = NULL;
1058 add_list.next = NULL;
845 1059
1060 pci_try_num = max_depth + 1;
1061 printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
1062 max_depth, pci_try_num);
1063
1064again:
846 /* Depth first, calculate sizes and alignments of all 1065 /* Depth first, calculate sizes and alignments of all
847 subordinate buses. */ 1066 subordinate buses. */
848 list_for_each_entry(bus, &pci_root_buses, node) { 1067 list_for_each_entry(bus, &pci_root_buses, node)
849 pci_bus_size_bridges(bus); 1068 __pci_bus_size_bridges(bus, &add_list);
850 } 1069
851 /* Depth last, allocate resources and update the hardware. */ 1070 /* Depth last, allocate resources and update the hardware. */
852 list_for_each_entry(bus, &pci_root_buses, node) { 1071 list_for_each_entry(bus, &pci_root_buses, node)
853 pci_bus_assign_resources(bus); 1072 __pci_bus_assign_resources(bus, &add_list, &head);
854 pci_enable_bridges(bus); 1073 BUG_ON(add_list.next);
1074 tried_times++;
1075
1076 /* any device complain? */
1077 if (!head.next)
1078 goto enable_and_dump;
1079
1080 /* don't realloc if asked to do so */
1081 if (!pci_realloc_enabled()) {
1082 free_list(resource_list_x, &head);
1083 goto enable_and_dump;
1084 }
1085
1086 failed_type = 0;
1087 for (list = head.next; list;) {
1088 failed_type |= list->flags;
1089 list = list->next;
1090 }
1091 /*
1092 * io port are tight, don't try extra
1093 * or if reach the limit, don't want to try more
1094 */
1095 failed_type &= type_mask;
1096 if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
1097 free_list(resource_list_x, &head);
1098 goto enable_and_dump;
855 } 1099 }
856 1100
1101 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
1102 tried_times + 1);
1103
1104 /* third times and later will not check if it is leaf */
1105 if ((tried_times + 1) > 2)
1106 rel_type = whole_subtree;
1107
1108 /*
1109 * Try to release leaf bridge's resources that doesn't fit resource of
1110 * child device under that bridge
1111 */
1112 for (list = head.next; list;) {
1113 bus = list->dev->bus;
1114 pci_bus_release_bridge_resources(bus, list->flags & type_mask,
1115 rel_type);
1116 list = list->next;
1117 }
1118 /* restore size and flags */
1119 for (list = head.next; list;) {
1120 struct resource *res = list->res;
1121
1122 res->start = list->start;
1123 res->end = list->end;
1124 res->flags = list->flags;
1125 if (list->dev->subordinate)
1126 res->flags = 0;
1127
1128 list = list->next;
1129 }
1130 free_list(resource_list_x, &head);
1131
1132 goto again;
1133
1134enable_and_dump:
1135 /* Depth last, update the hardware. */
1136 list_for_each_entry(bus, &pci_root_buses, node)
1137 pci_enable_bridges(bus);
1138
857 /* dump the resource on buses */ 1139 /* dump the resource on buses */
858 list_for_each_entry(bus, &pci_root_buses, node) { 1140 list_for_each_entry(bus, &pci_root_buses, node)
859 pci_bus_dump_resources(bus); 1141 pci_bus_dump_resources(bus);
860 }
861} 1142}
862 1143
863void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) 1144void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
@@ -882,7 +1163,7 @@ again:
882 1163
883 if (tried_times >= 2) { 1164 if (tried_times >= 2) {
884 /* still fail, don't need to try more */ 1165 /* still fail, don't need to try more */
885 free_failed_list(&head); 1166 free_list(resource_list_x, &head);
886 goto enable_all; 1167 goto enable_all;
887 } 1168 }
888 1169
@@ -913,7 +1194,7 @@ again:
913 1194
914 list = list->next; 1195 list = list->next;
915 } 1196 }
916 free_failed_list(&head); 1197 free_list(resource_list_x, &head);
917 1198
918 goto again; 1199 goto again;
919 1200