diff options
Diffstat (limited to 'drivers/pci/setup-bus.c')
| -rw-r--r-- | drivers/pci/setup-bus.c | 166 |
1 files changed, 116 insertions, 50 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 8a1d3c7863a..784da9d3602 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -34,6 +34,7 @@ struct resource_list_x { | |||
| 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 | resource_size_t add_size; |
| 37 | resource_size_t min_align; | ||
| 37 | unsigned long flags; | 38 | unsigned long flags; |
| 38 | }; | 39 | }; |
| 39 | 40 | ||
| @@ -65,7 +66,7 @@ void pci_realloc(void) | |||
| 65 | */ | 66 | */ |
| 66 | static void add_to_list(struct resource_list_x *head, | 67 | static void add_to_list(struct resource_list_x *head, |
| 67 | struct pci_dev *dev, struct resource *res, | 68 | struct pci_dev *dev, struct resource *res, |
| 68 | resource_size_t add_size) | 69 | resource_size_t add_size, resource_size_t min_align) |
| 69 | { | 70 | { |
| 70 | struct resource_list_x *list = head; | 71 | struct resource_list_x *list = head; |
| 71 | struct resource_list_x *ln = list->next; | 72 | struct resource_list_x *ln = list->next; |
| @@ -84,13 +85,16 @@ static void add_to_list(struct resource_list_x *head, | |||
| 84 | tmp->end = res->end; | 85 | tmp->end = res->end; |
| 85 | tmp->flags = res->flags; | 86 | tmp->flags = res->flags; |
| 86 | tmp->add_size = add_size; | 87 | tmp->add_size = add_size; |
| 88 | tmp->min_align = min_align; | ||
| 87 | list->next = tmp; | 89 | list->next = tmp; |
| 88 | } | 90 | } |
| 89 | 91 | ||
| 90 | static void add_to_failed_list(struct resource_list_x *head, | 92 | static void add_to_failed_list(struct resource_list_x *head, |
| 91 | struct pci_dev *dev, struct resource *res) | 93 | struct pci_dev *dev, struct resource *res) |
| 92 | { | 94 | { |
| 93 | add_to_list(head, dev, res, 0); | 95 | add_to_list(head, dev, res, |
| 96 | 0 /* dont care */, | ||
| 97 | 0 /* dont care */); | ||
| 94 | } | 98 | } |
| 95 | 99 | ||
| 96 | static void __dev_sort_resources(struct pci_dev *dev, | 100 | static void __dev_sort_resources(struct pci_dev *dev, |
| @@ -121,18 +125,18 @@ static inline void reset_resource(struct resource *res) | |||
| 121 | } | 125 | } |
| 122 | 126 | ||
| 123 | /** | 127 | /** |
| 124 | * adjust_resources_sorted() - satisfy any additional resource requests | 128 | * reassign_resources_sorted() - satisfy any additional resource requests |
| 125 | * | 129 | * |
| 126 | * @add_head : head of the list tracking requests requiring additional | 130 | * @realloc_head : head of the list tracking requests requiring additional |
| 127 | * resources | 131 | * resources |
| 128 | * @head : head of the list tracking requests with allocated | 132 | * @head : head of the list tracking requests with allocated |
| 129 | * resources | 133 | * resources |
| 130 | * | 134 | * |
| 131 | * Walk through each element of the add_head and try to procure | 135 | * Walk through each element of the realloc_head and try to procure |
| 132 | * additional resources for the element, provided the element | 136 | * additional resources for the element, provided the element |
| 133 | * is in the head list. | 137 | * is in the head list. |
| 134 | */ | 138 | */ |
| 135 | static void adjust_resources_sorted(struct resource_list_x *add_head, | 139 | static void reassign_resources_sorted(struct resource_list_x *realloc_head, |
| 136 | struct resource_list *head) | 140 | struct resource_list *head) |
| 137 | { | 141 | { |
| 138 | struct resource *res; | 142 | struct resource *res; |
| @@ -141,8 +145,8 @@ static void adjust_resources_sorted(struct resource_list_x *add_head, | |||
| 141 | resource_size_t add_size; | 145 | resource_size_t add_size; |
| 142 | int idx; | 146 | int idx; |
| 143 | 147 | ||
| 144 | prev = add_head; | 148 | prev = realloc_head; |
| 145 | for (list = add_head->next; list;) { | 149 | for (list = realloc_head->next; list;) { |
| 146 | res = list->res; | 150 | res = list->res; |
| 147 | /* skip resource that has been reset */ | 151 | /* skip resource that has been reset */ |
| 148 | if (!res->flags) | 152 | if (!res->flags) |
| @@ -159,13 +163,17 @@ static void adjust_resources_sorted(struct resource_list_x *add_head, | |||
| 159 | 163 | ||
| 160 | idx = res - &list->dev->resource[0]; | 164 | idx = res - &list->dev->resource[0]; |
| 161 | add_size=list->add_size; | 165 | add_size=list->add_size; |
| 162 | if (!resource_size(res) && add_size) { | 166 | if (!resource_size(res)) { |
| 163 | res->end = res->start + add_size - 1; | 167 | res->start = list->start; |
| 164 | if(pci_assign_resource(list->dev, idx)) | 168 | res->end = res->start + add_size - 1; |
| 169 | if(pci_assign_resource(list->dev, idx)) | ||
| 165 | reset_resource(res); | 170 | reset_resource(res); |
| 166 | } else if (add_size) { | 171 | } else { |
| 167 | adjust_resource(res, res->start, | 172 | resource_size_t align = list->min_align; |
| 168 | resource_size(res) + add_size); | 173 | res->flags |= list->flags & (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN); |
| 174 | if (pci_reassign_resource(list->dev, idx, add_size, align)) | ||
| 175 | dev_printk(KERN_DEBUG, &list->dev->dev, "failed to add optional resources res=%pR\n", | ||
| 176 | res); | ||
| 169 | } | 177 | } |
| 170 | out: | 178 | out: |
| 171 | tmp = list; | 179 | tmp = list; |
| @@ -210,16 +218,16 @@ static void assign_requested_resources_sorted(struct resource_list *head, | |||
| 210 | } | 218 | } |
| 211 | 219 | ||
| 212 | static void __assign_resources_sorted(struct resource_list *head, | 220 | static void __assign_resources_sorted(struct resource_list *head, |
| 213 | struct resource_list_x *add_head, | 221 | struct resource_list_x *realloc_head, |
| 214 | struct resource_list_x *fail_head) | 222 | struct resource_list_x *fail_head) |
| 215 | { | 223 | { |
| 216 | /* Satisfy the must-have resource requests */ | 224 | /* Satisfy the must-have resource requests */ |
| 217 | assign_requested_resources_sorted(head, fail_head); | 225 | assign_requested_resources_sorted(head, fail_head); |
| 218 | 226 | ||
| 219 | /* Try to satisfy any additional nice-to-have resource | 227 | /* Try to satisfy any additional optional resource |
| 220 | requests */ | 228 | requests */ |
| 221 | if (add_head) | 229 | if (realloc_head) |
| 222 | adjust_resources_sorted(add_head, head); | 230 | reassign_resources_sorted(realloc_head, head); |
| 223 | free_list(resource_list, head); | 231 | free_list(resource_list, head); |
| 224 | } | 232 | } |
| 225 | 233 | ||
| @@ -235,7 +243,7 @@ static void pdev_assign_resources_sorted(struct pci_dev *dev, | |||
| 235 | } | 243 | } |
| 236 | 244 | ||
| 237 | static void pbus_assign_resources_sorted(const struct pci_bus *bus, | 245 | static void pbus_assign_resources_sorted(const struct pci_bus *bus, |
| 238 | struct resource_list_x *add_head, | 246 | struct resource_list_x *realloc_head, |
| 239 | struct resource_list_x *fail_head) | 247 | struct resource_list_x *fail_head) |
| 240 | { | 248 | { |
| 241 | struct pci_dev *dev; | 249 | struct pci_dev *dev; |
| @@ -245,7 +253,7 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus, | |||
| 245 | list_for_each_entry(dev, &bus->devices, bus_list) | 253 | list_for_each_entry(dev, &bus->devices, bus_list) |
| 246 | __dev_sort_resources(dev, &head); | 254 | __dev_sort_resources(dev, &head); |
| 247 | 255 | ||
| 248 | __assign_resources_sorted(&head, add_head, fail_head); | 256 | __assign_resources_sorted(&head, realloc_head, fail_head); |
| 249 | } | 257 | } |
| 250 | 258 | ||
| 251 | void pci_setup_cardbus(struct pci_bus *bus) | 259 | void pci_setup_cardbus(struct pci_bus *bus) |
| @@ -540,13 +548,27 @@ static resource_size_t calculate_memsize(resource_size_t size, | |||
| 540 | return size; | 548 | return size; |
| 541 | } | 549 | } |
| 542 | 550 | ||
| 551 | static resource_size_t get_res_add_size(struct resource_list_x *realloc_head, | ||
| 552 | struct resource *res) | ||
| 553 | { | ||
| 554 | struct resource_list_x *list; | ||
| 555 | |||
| 556 | /* check if it is in realloc_head list */ | ||
| 557 | for (list = realloc_head->next; list && list->res != res; | ||
| 558 | list = list->next); | ||
| 559 | if (list) | ||
| 560 | return list->add_size; | ||
| 561 | |||
| 562 | return 0; | ||
| 563 | } | ||
| 564 | |||
| 543 | /** | 565 | /** |
| 544 | * pbus_size_io() - size the io window of a given bus | 566 | * pbus_size_io() - size the io window of a given bus |
| 545 | * | 567 | * |
| 546 | * @bus : the bus | 568 | * @bus : the bus |
| 547 | * @min_size : the minimum io window that must to be allocated | 569 | * @min_size : the minimum io window that must to be allocated |
| 548 | * @add_size : additional optional io window | 570 | * @add_size : additional optional io window |
| 549 | * @add_head : track the additional io window on this list | 571 | * @realloc_head : track the additional io window on this list |
| 550 | * | 572 | * |
| 551 | * Sizing the IO windows of the PCI-PCI bridge is trivial, | 573 | * Sizing the IO windows of the PCI-PCI bridge is trivial, |
| 552 | * since these windows have 4K granularity and the IO ranges | 574 | * since these windows have 4K granularity and the IO ranges |
| @@ -554,11 +576,12 @@ static resource_size_t calculate_memsize(resource_size_t size, | |||
| 554 | * We must be careful with the ISA aliasing though. | 576 | * We must be careful with the ISA aliasing though. |
| 555 | */ | 577 | */ |
| 556 | static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | 578 | static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, |
| 557 | resource_size_t add_size, struct resource_list_x *add_head) | 579 | resource_size_t add_size, struct resource_list_x *realloc_head) |
| 558 | { | 580 | { |
| 559 | struct pci_dev *dev; | 581 | struct pci_dev *dev; |
| 560 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); | 582 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); |
| 561 | unsigned long size = 0, size0 = 0, size1 = 0; | 583 | unsigned long size = 0, size0 = 0, size1 = 0; |
| 584 | resource_size_t children_add_size = 0; | ||
| 562 | 585 | ||
| 563 | if (!b_res) | 586 | if (!b_res) |
| 564 | return; | 587 | return; |
| @@ -579,11 +602,16 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
| 579 | size += r_size; | 602 | size += r_size; |
| 580 | else | 603 | else |
| 581 | size1 += r_size; | 604 | size1 += r_size; |
| 605 | |||
| 606 | if (realloc_head) | ||
| 607 | children_add_size += get_res_add_size(realloc_head, r); | ||
| 582 | } | 608 | } |
| 583 | } | 609 | } |
| 584 | size0 = calculate_iosize(size, min_size, size1, | 610 | size0 = calculate_iosize(size, min_size, size1, |
| 585 | resource_size(b_res), 4096); | 611 | resource_size(b_res), 4096); |
| 586 | size1 = (!add_head || (add_head && !add_size)) ? size0 : | 612 | if (children_add_size > add_size) |
| 613 | add_size = children_add_size; | ||
| 614 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : | ||
| 587 | calculate_iosize(size, min_size+add_size, size1, | 615 | calculate_iosize(size, min_size+add_size, size1, |
| 588 | resource_size(b_res), 4096); | 616 | resource_size(b_res), 4096); |
| 589 | if (!size0 && !size1) { | 617 | if (!size0 && !size1) { |
| @@ -598,8 +626,8 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
| 598 | b_res->start = 4096; | 626 | b_res->start = 4096; |
| 599 | b_res->end = b_res->start + size0 - 1; | 627 | b_res->end = b_res->start + size0 - 1; |
| 600 | b_res->flags |= IORESOURCE_STARTALIGN; | 628 | b_res->flags |= IORESOURCE_STARTALIGN; |
| 601 | if (size1 > size0 && add_head) | 629 | if (size1 > size0 && realloc_head) |
| 602 | add_to_list(add_head, bus->self, b_res, size1-size0); | 630 | add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096); |
| 603 | } | 631 | } |
| 604 | 632 | ||
| 605 | /** | 633 | /** |
| @@ -608,7 +636,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
| 608 | * @bus : the bus | 636 | * @bus : the bus |
| 609 | * @min_size : the minimum memory window that must to be allocated | 637 | * @min_size : the minimum memory window that must to be allocated |
| 610 | * @add_size : additional optional memory window | 638 | * @add_size : additional optional memory window |
| 611 | * @add_head : track the additional memory window on this list | 639 | * @realloc_head : track the additional memory window on this list |
| 612 | * | 640 | * |
| 613 | * Calculate the size of the bus and minimal alignment which | 641 | * Calculate the size of the bus and minimal alignment which |
| 614 | * guarantees that all child resources fit in this size. | 642 | * guarantees that all child resources fit in this size. |
| @@ -616,7 +644,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
| 616 | static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | 644 | static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, |
| 617 | unsigned long type, resource_size_t min_size, | 645 | unsigned long type, resource_size_t min_size, |
| 618 | resource_size_t add_size, | 646 | resource_size_t add_size, |
| 619 | struct resource_list_x *add_head) | 647 | struct resource_list_x *realloc_head) |
| 620 | { | 648 | { |
| 621 | struct pci_dev *dev; | 649 | struct pci_dev *dev; |
| 622 | resource_size_t min_align, align, size, size0, size1; | 650 | resource_size_t min_align, align, size, size0, size1; |
| @@ -624,6 +652,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
| 624 | int order, max_order; | 652 | int order, max_order; |
| 625 | struct resource *b_res = find_free_bus_resource(bus, type); | 653 | struct resource *b_res = find_free_bus_resource(bus, type); |
| 626 | unsigned int mem64_mask = 0; | 654 | unsigned int mem64_mask = 0; |
| 655 | resource_size_t children_add_size = 0; | ||
| 627 | 656 | ||
| 628 | if (!b_res) | 657 | if (!b_res) |
| 629 | return 0; | 658 | return 0; |
| @@ -645,6 +674,16 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
| 645 | if (r->parent || (r->flags & mask) != type) | 674 | if (r->parent || (r->flags & mask) != type) |
| 646 | continue; | 675 | continue; |
| 647 | r_size = resource_size(r); | 676 | r_size = resource_size(r); |
| 677 | #ifdef CONFIG_PCI_IOV | ||
| 678 | /* put SRIOV requested res to the optional list */ | ||
| 679 | if (realloc_head && i >= PCI_IOV_RESOURCES && | ||
| 680 | i <= PCI_IOV_RESOURCE_END) { | ||
| 681 | r->end = r->start - 1; | ||
| 682 | add_to_list(realloc_head, dev, r, r_size, 0/* dont' care */); | ||
| 683 | children_add_size += r_size; | ||
| 684 | continue; | ||
| 685 | } | ||
| 686 | #endif | ||
| 648 | /* For bridges size != alignment */ | 687 | /* For bridges size != alignment */ |
| 649 | align = pci_resource_alignment(dev, r); | 688 | align = pci_resource_alignment(dev, r); |
| 650 | order = __ffs(align) - 20; | 689 | order = __ffs(align) - 20; |
| @@ -665,6 +704,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
| 665 | if (order > max_order) | 704 | if (order > max_order) |
| 666 | max_order = order; | 705 | max_order = order; |
| 667 | mem64_mask &= r->flags & IORESOURCE_MEM_64; | 706 | mem64_mask &= r->flags & IORESOURCE_MEM_64; |
| 707 | |||
| 708 | if (realloc_head) | ||
| 709 | children_add_size += get_res_add_size(realloc_head, r); | ||
| 668 | } | 710 | } |
| 669 | } | 711 | } |
| 670 | align = 0; | 712 | align = 0; |
| @@ -681,7 +723,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
| 681 | align += aligns[order]; | 723 | align += aligns[order]; |
| 682 | } | 724 | } |
| 683 | size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); | 725 | size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); |
| 684 | size1 = (!add_head || (add_head && !add_size)) ? size0 : | 726 | if (children_add_size > add_size) |
| 727 | add_size = children_add_size; | ||
| 728 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : | ||
| 685 | calculate_memsize(size, min_size+add_size, 0, | 729 | calculate_memsize(size, min_size+add_size, 0, |
| 686 | resource_size(b_res), min_align); | 730 | resource_size(b_res), min_align); |
| 687 | if (!size0 && !size1) { | 731 | if (!size0 && !size1) { |
| @@ -695,12 +739,22 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
| 695 | b_res->start = min_align; | 739 | b_res->start = min_align; |
| 696 | b_res->end = size0 + min_align - 1; | 740 | b_res->end = size0 + min_align - 1; |
| 697 | b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask; | 741 | b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask; |
| 698 | if (size1 > size0 && add_head) | 742 | if (size1 > size0 && realloc_head) |
| 699 | add_to_list(add_head, bus->self, b_res, size1-size0); | 743 | add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); |
| 700 | return 1; | 744 | return 1; |
| 701 | } | 745 | } |
| 702 | 746 | ||
| 703 | static void pci_bus_size_cardbus(struct pci_bus *bus) | 747 | unsigned long pci_cardbus_resource_alignment(struct resource *res) |
| 748 | { | ||
| 749 | if (res->flags & IORESOURCE_IO) | ||
| 750 | return pci_cardbus_io_size; | ||
| 751 | if (res->flags & IORESOURCE_MEM) | ||
| 752 | return pci_cardbus_mem_size; | ||
| 753 | return 0; | ||
| 754 | } | ||
| 755 | |||
| 756 | static void pci_bus_size_cardbus(struct pci_bus *bus, | ||
| 757 | struct resource_list_x *realloc_head) | ||
| 704 | { | 758 | { |
| 705 | struct pci_dev *bridge = bus->self; | 759 | struct pci_dev *bridge = bus->self; |
| 706 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; | 760 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; |
| @@ -711,12 +765,14 @@ static void pci_bus_size_cardbus(struct pci_bus *bus) | |||
| 711 | * a fixed amount of bus space for CardBus bridges. | 765 | * a fixed amount of bus space for CardBus bridges. |
| 712 | */ | 766 | */ |
| 713 | b_res[0].start = 0; | 767 | b_res[0].start = 0; |
| 714 | b_res[0].end = pci_cardbus_io_size - 1; | ||
| 715 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 768 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; |
| 769 | if (realloc_head) | ||
| 770 | add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size, 0 /* dont care */); | ||
| 716 | 771 | ||
| 717 | b_res[1].start = 0; | 772 | b_res[1].start = 0; |
| 718 | b_res[1].end = pci_cardbus_io_size - 1; | ||
| 719 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 773 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; |
| 774 | if (realloc_head) | ||
| 775 | add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size, 0 /* dont care */); | ||
| 720 | 776 | ||
| 721 | /* | 777 | /* |
| 722 | * Check whether prefetchable memory is supported | 778 | * Check whether prefetchable memory is supported |
| @@ -736,21 +792,31 @@ static void pci_bus_size_cardbus(struct pci_bus *bus) | |||
| 736 | */ | 792 | */ |
| 737 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { | 793 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { |
| 738 | b_res[2].start = 0; | 794 | b_res[2].start = 0; |
| 739 | b_res[2].end = pci_cardbus_mem_size - 1; | ||
| 740 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; | 795 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; |
| 796 | if (realloc_head) | ||
| 797 | add_to_list(realloc_head, bridge, b_res+2, pci_cardbus_mem_size, 0 /* dont care */); | ||
| 741 | 798 | ||
| 742 | b_res[3].start = 0; | 799 | b_res[3].start = 0; |
| 743 | b_res[3].end = pci_cardbus_mem_size - 1; | ||
| 744 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 800 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; |
| 801 | if (realloc_head) | ||
| 802 | add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size, 0 /* dont care */); | ||
| 745 | } else { | 803 | } else { |
| 746 | b_res[3].start = 0; | 804 | b_res[3].start = 0; |
| 747 | b_res[3].end = pci_cardbus_mem_size * 2 - 1; | ||
| 748 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 805 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; |
| 806 | if (realloc_head) | ||
| 807 | add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size * 2, 0 /* dont care */); | ||
| 749 | } | 808 | } |
| 809 | |||
| 810 | /* set the size of the resource to zero, so that the resource does not | ||
| 811 | * get assigned during required-resource allocation cycle but gets assigned | ||
| 812 | * during the optional-resource allocation cycle. | ||
| 813 | */ | ||
| 814 | b_res[0].start = b_res[1].start = b_res[2].start = b_res[3].start = 1; | ||
| 815 | b_res[0].end = b_res[1].end = b_res[2].end = b_res[3].end = 0; | ||
| 750 | } | 816 | } |
| 751 | 817 | ||
| 752 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 818 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
| 753 | struct resource_list_x *add_head) | 819 | struct resource_list_x *realloc_head) |
| 754 | { | 820 | { |
| 755 | struct pci_dev *dev; | 821 | struct pci_dev *dev; |
| 756 | unsigned long mask, prefmask; | 822 | unsigned long mask, prefmask; |
| @@ -763,12 +829,12 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, | |||
| 763 | 829 | ||
| 764 | switch (dev->class >> 8) { | 830 | switch (dev->class >> 8) { |
| 765 | case PCI_CLASS_BRIDGE_CARDBUS: | 831 | case PCI_CLASS_BRIDGE_CARDBUS: |
| 766 | pci_bus_size_cardbus(b); | 832 | pci_bus_size_cardbus(b, realloc_head); |
| 767 | break; | 833 | break; |
| 768 | 834 | ||
| 769 | case PCI_CLASS_BRIDGE_PCI: | 835 | case PCI_CLASS_BRIDGE_PCI: |
| 770 | default: | 836 | default: |
| 771 | __pci_bus_size_bridges(b, add_head); | 837 | __pci_bus_size_bridges(b, realloc_head); |
| 772 | break; | 838 | break; |
| 773 | } | 839 | } |
| 774 | } | 840 | } |
| @@ -792,7 +858,7 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, | |||
| 792 | * Follow thru | 858 | * Follow thru |
| 793 | */ | 859 | */ |
| 794 | default: | 860 | default: |
| 795 | pbus_size_io(bus, 0, additional_io_size, add_head); | 861 | pbus_size_io(bus, 0, additional_io_size, realloc_head); |
| 796 | /* If the bridge supports prefetchable range, size it | 862 | /* If the bridge supports prefetchable range, size it |
| 797 | separately. If it doesn't, or its prefetchable window | 863 | separately. If it doesn't, or its prefetchable window |
| 798 | has already been allocated by arch code, try | 864 | has already been allocated by arch code, try |
| @@ -800,11 +866,11 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, | |||
| 800 | resources. */ | 866 | resources. */ |
| 801 | mask = IORESOURCE_MEM; | 867 | mask = IORESOURCE_MEM; |
| 802 | prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; | 868 | prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; |
| 803 | if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, add_head)) | 869 | if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, realloc_head)) |
| 804 | mask = prefmask; /* Success, size non-prefetch only. */ | 870 | mask = prefmask; /* Success, size non-prefetch only. */ |
| 805 | else | 871 | else |
| 806 | additional_mem_size += additional_mem_size; | 872 | additional_mem_size += additional_mem_size; |
| 807 | pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, add_head); | 873 | pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, realloc_head); |
| 808 | break; | 874 | break; |
| 809 | } | 875 | } |
| 810 | } | 876 | } |
| @@ -816,20 +882,20 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) | |||
| 816 | EXPORT_SYMBOL(pci_bus_size_bridges); | 882 | EXPORT_SYMBOL(pci_bus_size_bridges); |
| 817 | 883 | ||
| 818 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, | 884 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, |
| 819 | struct resource_list_x *add_head, | 885 | struct resource_list_x *realloc_head, |
| 820 | struct resource_list_x *fail_head) | 886 | struct resource_list_x *fail_head) |
| 821 | { | 887 | { |
| 822 | struct pci_bus *b; | 888 | struct pci_bus *b; |
| 823 | struct pci_dev *dev; | 889 | struct pci_dev *dev; |
| 824 | 890 | ||
| 825 | pbus_assign_resources_sorted(bus, add_head, fail_head); | 891 | pbus_assign_resources_sorted(bus, realloc_head, fail_head); |
| 826 | 892 | ||
| 827 | list_for_each_entry(dev, &bus->devices, bus_list) { | 893 | list_for_each_entry(dev, &bus->devices, bus_list) { |
| 828 | b = dev->subordinate; | 894 | b = dev->subordinate; |
| 829 | if (!b) | 895 | if (!b) |
| 830 | continue; | 896 | continue; |
| 831 | 897 | ||
| 832 | __pci_bus_assign_resources(b, add_head, fail_head); | 898 | __pci_bus_assign_resources(b, realloc_head, fail_head); |
| 833 | 899 | ||
| 834 | switch (dev->class >> 8) { | 900 | switch (dev->class >> 8) { |
| 835 | case PCI_CLASS_BRIDGE_PCI: | 901 | case PCI_CLASS_BRIDGE_PCI: |
| @@ -1039,7 +1105,7 @@ void __init | |||
| 1039 | pci_assign_unassigned_resources(void) | 1105 | pci_assign_unassigned_resources(void) |
| 1040 | { | 1106 | { |
| 1041 | struct pci_bus *bus; | 1107 | struct pci_bus *bus; |
| 1042 | struct resource_list_x add_list; /* list of resources that | 1108 | struct resource_list_x realloc_list; /* list of resources that |
| 1043 | want additional resources */ | 1109 | want additional resources */ |
| 1044 | int tried_times = 0; | 1110 | int tried_times = 0; |
| 1045 | enum release_type rel_type = leaf_only; | 1111 | enum release_type rel_type = leaf_only; |
| @@ -1052,7 +1118,7 @@ pci_assign_unassigned_resources(void) | |||
| 1052 | 1118 | ||
| 1053 | 1119 | ||
| 1054 | head.next = NULL; | 1120 | head.next = NULL; |
| 1055 | add_list.next = NULL; | 1121 | realloc_list.next = NULL; |
| 1056 | 1122 | ||
| 1057 | pci_try_num = max_depth + 1; | 1123 | pci_try_num = max_depth + 1; |
| 1058 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", | 1124 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", |
| @@ -1062,12 +1128,12 @@ again: | |||
| 1062 | /* Depth first, calculate sizes and alignments of all | 1128 | /* Depth first, calculate sizes and alignments of all |
| 1063 | subordinate buses. */ | 1129 | subordinate buses. */ |
| 1064 | list_for_each_entry(bus, &pci_root_buses, node) | 1130 | list_for_each_entry(bus, &pci_root_buses, node) |
| 1065 | __pci_bus_size_bridges(bus, &add_list); | 1131 | __pci_bus_size_bridges(bus, &realloc_list); |
| 1066 | 1132 | ||
| 1067 | /* Depth last, allocate resources and update the hardware. */ | 1133 | /* Depth last, allocate resources and update the hardware. */ |
| 1068 | list_for_each_entry(bus, &pci_root_buses, node) | 1134 | list_for_each_entry(bus, &pci_root_buses, node) |
| 1069 | __pci_bus_assign_resources(bus, &add_list, &head); | 1135 | __pci_bus_assign_resources(bus, &realloc_list, &head); |
| 1070 | BUG_ON(add_list.next); | 1136 | BUG_ON(realloc_list.next); |
| 1071 | tried_times++; | 1137 | tried_times++; |
| 1072 | 1138 | ||
| 1073 | /* any device complain? */ | 1139 | /* any device complain? */ |
