diff options
| -rw-r--r-- | drivers/pci/pci.h | 4 | ||||
| -rw-r--r-- | drivers/pci/setup-bus.c | 41 |
2 files changed, 36 insertions, 9 deletions
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index c8cee764b0de..b74084e9ca12 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -283,6 +283,8 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) | |||
| 283 | 283 | ||
| 284 | #endif /* CONFIG_PCI_IOV */ | 284 | #endif /* CONFIG_PCI_IOV */ |
| 285 | 285 | ||
| 286 | extern unsigned long pci_cardbus_resource_alignment(struct resource *); | ||
| 287 | |||
| 286 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, | 288 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, |
| 287 | struct resource *res) | 289 | struct resource *res) |
| 288 | { | 290 | { |
| @@ -292,6 +294,8 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, | |||
| 292 | if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) | 294 | if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) |
| 293 | return pci_sriov_resource_alignment(dev, resno); | 295 | return pci_sriov_resource_alignment(dev, resno); |
| 294 | #endif | 296 | #endif |
| 297 | if (dev->class >> 8 == PCI_CLASS_BRIDGE_CARDBUS) | ||
| 298 | return pci_cardbus_resource_alignment(res); | ||
| 295 | return resource_alignment(res); | 299 | return resource_alignment(res); |
| 296 | } | 300 | } |
| 297 | 301 | ||
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1c19b9f4019a..29e7cc73537c 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -164,6 +164,7 @@ static void adjust_resources_sorted(struct resource_list_x *add_head, | |||
| 164 | idx = res - &list->dev->resource[0]; | 164 | idx = res - &list->dev->resource[0]; |
| 165 | add_size=list->add_size; | 165 | add_size=list->add_size; |
| 166 | if (!resource_size(res)) { | 166 | if (!resource_size(res)) { |
| 167 | res->start = list->start; | ||
| 167 | res->end = res->start + add_size - 1; | 168 | res->end = res->start + add_size - 1; |
| 168 | if(pci_assign_resource(list->dev, idx)) | 169 | if(pci_assign_resource(list->dev, idx)) |
| 169 | reset_resource(res); | 170 | reset_resource(res); |
| @@ -223,7 +224,7 @@ static void __assign_resources_sorted(struct resource_list *head, | |||
| 223 | /* Satisfy the must-have resource requests */ | 224 | /* Satisfy the must-have resource requests */ |
| 224 | assign_requested_resources_sorted(head, fail_head); | 225 | assign_requested_resources_sorted(head, fail_head); |
| 225 | 226 | ||
| 226 | /* Try to satisfy any additional nice-to-have resource | 227 | /* Try to satisfy any additional optional resource |
| 227 | requests */ | 228 | requests */ |
| 228 | if (add_head) | 229 | if (add_head) |
| 229 | adjust_resources_sorted(add_head, head); | 230 | adjust_resources_sorted(add_head, head); |
| @@ -678,7 +679,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
| 678 | if (add_head && i >= PCI_IOV_RESOURCES && | 679 | if (add_head && i >= PCI_IOV_RESOURCES && |
| 679 | i <= PCI_IOV_RESOURCE_END) { | 680 | i <= PCI_IOV_RESOURCE_END) { |
| 680 | r->end = r->start - 1; | 681 | r->end = r->start - 1; |
| 681 | add_to_list(add_head, dev, r, r_size, 1); | 682 | add_to_list(add_head, dev, r, r_size, 0/* dont' care */); |
| 682 | children_add_size += r_size; | 683 | children_add_size += r_size; |
| 683 | continue; | 684 | continue; |
| 684 | } | 685 | } |
| @@ -743,7 +744,17 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
| 743 | return 1; | 744 | return 1; |
| 744 | } | 745 | } |
| 745 | 746 | ||
| 746 | 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 *add_head) | ||
| 747 | { | 758 | { |
| 748 | struct pci_dev *bridge = bus->self; | 759 | struct pci_dev *bridge = bus->self; |
| 749 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; | 760 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; |
| @@ -754,12 +765,14 @@ static void pci_bus_size_cardbus(struct pci_bus *bus) | |||
| 754 | * a fixed amount of bus space for CardBus bridges. | 765 | * a fixed amount of bus space for CardBus bridges. |
| 755 | */ | 766 | */ |
| 756 | b_res[0].start = 0; | 767 | b_res[0].start = 0; |
| 757 | b_res[0].end = pci_cardbus_io_size - 1; | ||
| 758 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 768 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; |
| 769 | if (add_head) | ||
| 770 | add_to_list(add_head, bridge, b_res, pci_cardbus_io_size, 0 /* dont care */); | ||
| 759 | 771 | ||
| 760 | b_res[1].start = 0; | 772 | b_res[1].start = 0; |
| 761 | b_res[1].end = pci_cardbus_io_size - 1; | ||
| 762 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 773 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; |
| 774 | if (add_head) | ||
| 775 | add_to_list(add_head, bridge, b_res+1, pci_cardbus_io_size, 0 /* dont care */); | ||
| 763 | 776 | ||
| 764 | /* | 777 | /* |
| 765 | * Check whether prefetchable memory is supported | 778 | * Check whether prefetchable memory is supported |
| @@ -779,17 +792,27 @@ static void pci_bus_size_cardbus(struct pci_bus *bus) | |||
| 779 | */ | 792 | */ |
| 780 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { | 793 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { |
| 781 | b_res[2].start = 0; | 794 | b_res[2].start = 0; |
| 782 | b_res[2].end = pci_cardbus_mem_size - 1; | ||
| 783 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; | 795 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; |
| 796 | if (add_head) | ||
| 797 | add_to_list(add_head, bridge, b_res+2, pci_cardbus_mem_size, 0 /* dont care */); | ||
| 784 | 798 | ||
| 785 | b_res[3].start = 0; | 799 | b_res[3].start = 0; |
| 786 | b_res[3].end = pci_cardbus_mem_size - 1; | ||
| 787 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 800 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; |
| 801 | if (add_head) | ||
| 802 | add_to_list(add_head, bridge, b_res+3, pci_cardbus_mem_size, 0 /* dont care */); | ||
| 788 | } else { | 803 | } else { |
| 789 | b_res[3].start = 0; | 804 | b_res[3].start = 0; |
| 790 | b_res[3].end = pci_cardbus_mem_size * 2 - 1; | ||
| 791 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 805 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; |
| 806 | if (add_head) | ||
| 807 | add_to_list(add_head, bridge, b_res+3, pci_cardbus_mem_size * 2, 0 /* dont care */); | ||
| 792 | } | 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; | ||
| 793 | } | 816 | } |
| 794 | 817 | ||
| 795 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 818 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
| @@ -806,7 +829,7 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, | |||
| 806 | 829 | ||
| 807 | switch (dev->class >> 8) { | 830 | switch (dev->class >> 8) { |
| 808 | case PCI_CLASS_BRIDGE_CARDBUS: | 831 | case PCI_CLASS_BRIDGE_CARDBUS: |
| 809 | pci_bus_size_cardbus(b); | 832 | pci_bus_size_cardbus(b, add_head); |
| 810 | break; | 833 | break; |
| 811 | 834 | ||
| 812 | case PCI_CLASS_BRIDGE_PCI: | 835 | case PCI_CLASS_BRIDGE_PCI: |
