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