diff options
author | Ram Pai <linuxram@us.ibm.com> | 2011-07-25 16:08:39 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-08-01 14:50:15 -0400 |
commit | 2bbc6942273b5b3097bd265d82227bdd84b351b2 (patch) | |
tree | 34d846f34a94dbe7b0c4800cb8efc3cf2e07ad74 /drivers/pci/setup-bus.c | |
parent | be768912a49b10b68e96fbd8fa3cab0adfbd3091 (diff) |
PCI : ability to relocate assigned pci-resources
Currently pci-bridges are allocated enough resources to satisfy their immediate
requirements. Any additional resource-requests fail if additional free space,
contiguous to the one already allocated, is not available. This behavior is not
reasonable since sufficient contiguous resources, that can satisfy the request,
are available at a different location.
This patch provides the ability to expand and relocate a allocated resource.
v2: Changelog: Fixed size calculation in pci_reassign_resource()
v3: Changelog : Split this patch. The resource.c changes are already
upstream. All the pci driver changes are in here.
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r-- | drivers/pci/setup-bus.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4409cd0e15fa..1796c6ffe91c 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, |
@@ -159,13 +163,16 @@ 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->end = res->start + add_size - 1; |
164 | if(pci_assign_resource(list->dev, idx)) | 168 | if(pci_assign_resource(list->dev, idx)) |
165 | reset_resource(res); | 169 | reset_resource(res); |
166 | } else if (add_size) { | 170 | } else { |
167 | adjust_resource(res, res->start, | 171 | resource_size_t align = list->min_align; |
168 | resource_size(res) + add_size); | 172 | res->flags |= list->flags & (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN); |
173 | if (pci_reassign_resource(list->dev, idx, add_size, align)) | ||
174 | dev_printk(KERN_DEBUG, &list->dev->dev, "failed to add optional resources res=%pR\n", | ||
175 | res); | ||
169 | } | 176 | } |
170 | out: | 177 | out: |
171 | tmp = list; | 178 | tmp = list; |
@@ -619,7 +626,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
619 | b_res->end = b_res->start + size0 - 1; | 626 | b_res->end = b_res->start + size0 - 1; |
620 | b_res->flags |= IORESOURCE_STARTALIGN; | 627 | b_res->flags |= IORESOURCE_STARTALIGN; |
621 | if (size1 > size0 && add_head) | 628 | if (size1 > size0 && add_head) |
622 | add_to_list(add_head, bus->self, b_res, size1-size0); | 629 | add_to_list(add_head, bus->self, b_res, size1-size0, 4096); |
623 | } | 630 | } |
624 | 631 | ||
625 | /** | 632 | /** |
@@ -722,7 +729,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
722 | b_res->end = size0 + min_align - 1; | 729 | b_res->end = size0 + min_align - 1; |
723 | b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask; | 730 | b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask; |
724 | if (size1 > size0 && add_head) | 731 | if (size1 > size0 && add_head) |
725 | add_to_list(add_head, bus->self, b_res, size1-size0); | 732 | add_to_list(add_head, bus->self, b_res, size1-size0, min_align); |
726 | return 1; | 733 | return 1; |
727 | } | 734 | } |
728 | 735 | ||