blob: 1796c6ffe91c68b7aeb6d3cfdc5fb9870b6f9384 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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 *
9 * Support routines for initializing a PCI subsystem.
10 */
11
12/*
13 * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
14 * PCI-PCI bridges cleanup, sorted resource allocation.
15 * Feb 2002, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
16 * Converted to allocation in 3 passes, which gives
17 * tighter packing. Prefetchable range support.
18 */
19
20#include <linux/init.h>
21#include <linux/kernel.h>
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>
Chris Wright6faf17f2009-08-28 13:00:06 -070028#include "pci.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
Yinghai Lu568ddef2010-01-22 01:02:21 -080030struct resource_list_x {
31 struct resource_list_x *next;
32 struct resource *res;
33 struct pci_dev *dev;
34 resource_size_t start;
35 resource_size_t end;
Ram Paic8adf9a2011-02-14 17:43:20 -080036 resource_size_t add_size;
Ram Pai2bbc6942011-07-25 13:08:39 -070037 resource_size_t min_align;
Yinghai Lu568ddef2010-01-22 01:02:21 -080038 unsigned long flags;
39};
40
Ram Pai094732a2011-02-14 17:43:18 -080041#define free_list(type, head) do { \
42 struct type *list, *tmp; \
43 for (list = (head)->next; list;) { \
44 tmp = list; \
45 list = list->next; \
46 kfree(tmp); \
47 } \
48 (head)->next = NULL; \
49} while (0)
50
Ram Paif483d392011-07-07 11:19:10 -070051int pci_realloc_enable = 0;
52#define pci_realloc_enabled() pci_realloc_enable
53void pci_realloc(void)
54{
55 pci_realloc_enable = 1;
56}
57
Ram Paic8adf9a2011-02-14 17:43:20 -080058/**
59 * add_to_list() - add a new resource tracker to the list
60 * @head: Head of the list
61 * @dev: device corresponding to which the resource
62 * belongs
63 * @res: The resource to be tracked
64 * @add_size: additional size to be optionally added
65 * to the resource
66 */
67static void add_to_list(struct resource_list_x *head,
68 struct pci_dev *dev, struct resource *res,
Ram Pai2bbc6942011-07-25 13:08:39 -070069 resource_size_t add_size, resource_size_t min_align)
Yinghai Lu568ddef2010-01-22 01:02:21 -080070{
71 struct resource_list_x *list = head;
72 struct resource_list_x *ln = list->next;
73 struct resource_list_x *tmp;
74
75 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
76 if (!tmp) {
Ram Paic8adf9a2011-02-14 17:43:20 -080077 pr_warning("add_to_list: kmalloc() failed!\n");
Yinghai Lu568ddef2010-01-22 01:02:21 -080078 return;
79 }
80
81 tmp->next = ln;
82 tmp->res = res;
83 tmp->dev = dev;
84 tmp->start = res->start;
85 tmp->end = res->end;
86 tmp->flags = res->flags;
Ram Paic8adf9a2011-02-14 17:43:20 -080087 tmp->add_size = add_size;
Ram Pai2bbc6942011-07-25 13:08:39 -070088 tmp->min_align = min_align;
Yinghai Lu568ddef2010-01-22 01:02:21 -080089 list->next = tmp;
90}
91
Ram Paic8adf9a2011-02-14 17:43:20 -080092static void add_to_failed_list(struct resource_list_x *head,
93 struct pci_dev *dev, struct resource *res)
94{
Ram Pai2bbc6942011-07-25 13:08:39 -070095 add_to_list(head, dev, res,
96 0 /* dont care */,
97 0 /* dont care */);
Ram Paic8adf9a2011-02-14 17:43:20 -080098}
99
Yinghai Lu6841ec62010-01-22 01:02:25 -0800100static void __dev_sort_resources(struct pci_dev *dev,
101 struct resource_list *head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102{
Yinghai Lu6841ec62010-01-22 01:02:25 -0800103 u16 class = dev->class >> 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Yinghai Lu6841ec62010-01-22 01:02:25 -0800105 /* Don't touch classless devices or host bridges or ioapics. */
106 if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST)
107 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
Yinghai Lu6841ec62010-01-22 01:02:25 -0800109 /* Don't touch ioapic devices already enabled by firmware */
110 if (class == PCI_CLASS_SYSTEM_PIC) {
111 u16 command;
112 pci_read_config_word(dev, PCI_COMMAND, &command);
113 if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
114 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 }
116
Yinghai Lu6841ec62010-01-22 01:02:25 -0800117 pdev_sort_resources(dev, head);
118}
119
Ram Paifc075e12011-02-14 17:43:19 -0800120static inline void reset_resource(struct resource *res)
121{
122 res->start = 0;
123 res->end = 0;
124 res->flags = 0;
125}
126
Ram Paic8adf9a2011-02-14 17:43:20 -0800127/**
128 * adjust_resources_sorted() - satisfy any additional resource requests
129 *
130 * @add_head : head of the list tracking requests requiring additional
131 * resources
132 * @head : head of the list tracking requests with allocated
133 * resources
134 *
135 * Walk through each element of the add_head and try to procure
136 * additional resources for the element, provided the element
137 * is in the head list.
138 */
139static void adjust_resources_sorted(struct resource_list_x *add_head,
140 struct resource_list *head)
141{
142 struct resource *res;
143 struct resource_list_x *list, *tmp, *prev;
144 struct resource_list *hlist;
145 resource_size_t add_size;
146 int idx;
147
148 prev = add_head;
149 for (list = add_head->next; list;) {
150 res = list->res;
151 /* skip resource that has been reset */
152 if (!res->flags)
153 goto out;
154
155 /* skip this resource if not found in head list */
156 for (hlist = head->next; hlist && hlist->res != res;
157 hlist = hlist->next);
158 if (!hlist) { /* just skip */
159 prev = list;
160 list = list->next;
161 continue;
162 }
163
164 idx = res - &list->dev->resource[0];
165 add_size=list->add_size;
Ram Pai2bbc6942011-07-25 13:08:39 -0700166 if (!resource_size(res)) {
167 res->end = res->start + add_size - 1;
168 if(pci_assign_resource(list->dev, idx))
Ram Paic8adf9a2011-02-14 17:43:20 -0800169 reset_resource(res);
Ram Pai2bbc6942011-07-25 13:08:39 -0700170 } else {
171 resource_size_t align = list->min_align;
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);
Ram Paic8adf9a2011-02-14 17:43:20 -0800176 }
177out:
178 tmp = list;
179 prev->next = list = list->next;
180 kfree(tmp);
181 }
182}
183
184/**
185 * assign_requested_resources_sorted() - satisfy resource requests
186 *
187 * @head : head of the list tracking requests for resources
188 * @failed_list : head of the list tracking requests that could
189 * not be allocated
190 *
191 * Satisfy resource requests of each element in the list. Add
192 * requests that could not satisfied to the failed_list.
193 */
194static void assign_requested_resources_sorted(struct resource_list *head,
Yinghai Lu6841ec62010-01-22 01:02:25 -0800195 struct resource_list_x *fail_head)
196{
197 struct resource *res;
Ram Paic8adf9a2011-02-14 17:43:20 -0800198 struct resource_list *list;
Yinghai Lu6841ec62010-01-22 01:02:25 -0800199 int idx;
200
Ram Paic8adf9a2011-02-14 17:43:20 -0800201 for (list = head->next; list; list = list->next) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 res = list->res;
203 idx = res - &list->dev->resource[0];
Ram Paic8adf9a2011-02-14 17:43:20 -0800204 if (resource_size(res) && pci_assign_resource(list->dev, idx)) {
Yinghai Lu9a928662010-02-28 15:49:39 -0800205 if (fail_head && !pci_is_root_bus(list->dev->bus)) {
206 /*
207 * if the failed res is for ROM BAR, and it will
208 * be enabled later, don't add it to the list
209 */
210 if (!((idx == PCI_ROM_RESOURCE) &&
211 (!(res->flags & IORESOURCE_ROM_ENABLE))))
212 add_to_failed_list(fail_head, list->dev, res);
213 }
Ram Paifc075e12011-02-14 17:43:19 -0800214 reset_resource(res);
Rajesh Shah542df5d2005-04-28 00:25:50 -0700215 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 }
217}
218
Ram Paic8adf9a2011-02-14 17:43:20 -0800219static void __assign_resources_sorted(struct resource_list *head,
220 struct resource_list_x *add_head,
221 struct resource_list_x *fail_head)
222{
223 /* Satisfy the must-have resource requests */
224 assign_requested_resources_sorted(head, fail_head);
225
226 /* Try to satisfy any additional nice-to-have resource
227 requests */
228 if (add_head)
229 adjust_resources_sorted(add_head, head);
230 free_list(resource_list, head);
231}
232
Yinghai Lu6841ec62010-01-22 01:02:25 -0800233static void pdev_assign_resources_sorted(struct pci_dev *dev,
234 struct resource_list_x *fail_head)
235{
236 struct resource_list head;
237
238 head.next = NULL;
239 __dev_sort_resources(dev, &head);
Ram Paic8adf9a2011-02-14 17:43:20 -0800240 __assign_resources_sorted(&head, NULL, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -0800241
242}
243
244static void pbus_assign_resources_sorted(const struct pci_bus *bus,
Ram Paic8adf9a2011-02-14 17:43:20 -0800245 struct resource_list_x *add_head,
Yinghai Lu6841ec62010-01-22 01:02:25 -0800246 struct resource_list_x *fail_head)
247{
248 struct pci_dev *dev;
249 struct resource_list head;
250
251 head.next = NULL;
252 list_for_each_entry(dev, &bus->devices, bus_list)
253 __dev_sort_resources(dev, &head);
254
Ram Paic8adf9a2011-02-14 17:43:20 -0800255 __assign_resources_sorted(&head, add_head, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -0800256}
257
Dominik Brodowskib3743fa2005-09-09 13:03:23 -0700258void pci_setup_cardbus(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259{
260 struct pci_dev *bridge = bus->self;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600261 struct resource *res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 struct pci_bus_region region;
263
Bjorn Helgaas865df572009-11-04 10:32:57 -0700264 dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
265 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600267 res = bus->resource[0];
268 pcibios_resource_to_bus(bridge, &region, res);
269 if (res->flags & IORESOURCE_IO) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 /*
271 * The IO resource is allocated a range twice as large as it
272 * would normally need. This allows us to set both IO regs.
273 */
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600274 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
276 region.start);
277 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
278 region.end);
279 }
280
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600281 res = bus->resource[1];
282 pcibios_resource_to_bus(bridge, &region, res);
283 if (res->flags & IORESOURCE_IO) {
284 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
286 region.start);
287 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
288 region.end);
289 }
290
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600291 res = bus->resource[2];
292 pcibios_resource_to_bus(bridge, &region, res);
293 if (res->flags & IORESOURCE_MEM) {
294 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
296 region.start);
297 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
298 region.end);
299 }
300
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600301 res = bus->resource[3];
302 pcibios_resource_to_bus(bridge, &region, res);
303 if (res->flags & IORESOURCE_MEM) {
304 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
306 region.start);
307 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
308 region.end);
309 }
310}
Dominik Brodowskib3743fa2005-09-09 13:03:23 -0700311EXPORT_SYMBOL(pci_setup_cardbus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
313/* Initialize bridges with base/limit values we have collected.
314 PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
315 requires that if there is no I/O ports or memory behind the
316 bridge, corresponding range must be turned off by writing base
317 value greater than limit to the bridge's base/limit registers.
318
319 Note: care must be taken when updating I/O base/limit registers
320 of bridges which support 32-bit I/O. This update requires two
321 config space writes, so it's quite possible that an I/O window of
322 the bridge will have some undesirable address (e.g. 0) after the
323 first write. Ditto 64-bit prefetchable MMIO. */
Yinghai Lu7cc59972009-12-22 15:02:21 -0800324static void pci_setup_bridge_io(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325{
326 struct pci_dev *bridge = bus->self;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600327 struct resource *res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 struct pci_bus_region region;
Yinghai Lu7cc59972009-12-22 15:02:21 -0800329 u32 l, io_upper16;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330
331 /* Set up the top and bottom of the PCI I/O segment for this bus. */
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600332 res = bus->resource[0];
333 pcibios_resource_to_bus(bridge, &region, res);
334 if (res->flags & IORESOURCE_IO) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 pci_read_config_dword(bridge, PCI_IO_BASE, &l);
336 l &= 0xffff0000;
337 l |= (region.start >> 8) & 0x00f0;
338 l |= region.end & 0xf000;
339 /* Set up upper 16 bits of I/O base/limit. */
340 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600341 dev_info(&bridge->dev, " bridge window %pR\n", res);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800342 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 /* Clear upper 16 bits of I/O base/limit. */
344 io_upper16 = 0;
345 l = 0x00f0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 }
347 /* Temporarily disable the I/O range before updating PCI_IO_BASE. */
348 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
349 /* Update lower 16 bits of I/O base/limit. */
350 pci_write_config_dword(bridge, PCI_IO_BASE, l);
351 /* Update upper 16 bits of I/O base/limit. */
352 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800353}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
Yinghai Lu7cc59972009-12-22 15:02:21 -0800355static void pci_setup_bridge_mmio(struct pci_bus *bus)
356{
357 struct pci_dev *bridge = bus->self;
358 struct resource *res;
359 struct pci_bus_region region;
360 u32 l;
361
362 /* Set up the top and bottom of the PCI Memory segment for this bus. */
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600363 res = bus->resource[1];
364 pcibios_resource_to_bus(bridge, &region, res);
365 if (res->flags & IORESOURCE_MEM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 l = (region.start >> 16) & 0xfff0;
367 l |= region.end & 0xfff00000;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600368 dev_info(&bridge->dev, " bridge window %pR\n", res);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800369 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 l = 0x0000fff0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 }
372 pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800373}
374
375static void pci_setup_bridge_mmio_pref(struct pci_bus *bus)
376{
377 struct pci_dev *bridge = bus->self;
378 struct resource *res;
379 struct pci_bus_region region;
380 u32 l, bu, lu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381
382 /* Clear out the upper 32 bits of PREF limit.
383 If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily
384 disables PREF range, which is ok. */
385 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
386
387 /* Set up PREF base/limit. */
Benjamin Herrenschmidtc40a22e2007-12-10 17:32:15 +1100388 bu = lu = 0;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600389 res = bus->resource[2];
390 pcibios_resource_to_bus(bridge, &region, res);
391 if (res->flags & IORESOURCE_PREFETCH) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 l = (region.start >> 16) & 0xfff0;
393 l |= region.end & 0xfff00000;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600394 if (res->flags & IORESOURCE_MEM_64) {
Yinghai Lu1f82de12009-04-23 20:48:32 -0700395 bu = upper_32_bits(region.start);
396 lu = upper_32_bits(region.end);
Yinghai Lu1f82de12009-04-23 20:48:32 -0700397 }
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600398 dev_info(&bridge->dev, " bridge window %pR\n", res);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800399 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 l = 0x0000fff0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 }
402 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
403
Alex Williamson59353ea2009-11-30 14:51:44 -0700404 /* Set the upper 32 bits of PREF base & limit. */
405 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
406 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800407}
408
409static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
410{
411 struct pci_dev *bridge = bus->self;
412
Yinghai Lu7cc59972009-12-22 15:02:21 -0800413 dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
414 bus->secondary, bus->subordinate);
415
416 if (type & IORESOURCE_IO)
417 pci_setup_bridge_io(bus);
418
419 if (type & IORESOURCE_MEM)
420 pci_setup_bridge_mmio(bus);
421
422 if (type & IORESOURCE_PREFETCH)
423 pci_setup_bridge_mmio_pref(bus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
425 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
426}
427
Yinghai Lu7cc59972009-12-22 15:02:21 -0800428static void pci_setup_bridge(struct pci_bus *bus)
429{
430 unsigned long type = IORESOURCE_IO | IORESOURCE_MEM |
431 IORESOURCE_PREFETCH;
432
433 __pci_setup_bridge(bus, type);
434}
435
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436/* Check whether the bridge supports optional I/O and
437 prefetchable memory ranges. If not, the respective
438 base/limit registers must be read-only and read as 0. */
Sam Ravnborg96bde062007-03-26 21:53:30 -0800439static void pci_bridge_check_ranges(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440{
441 u16 io;
442 u32 pmem;
443 struct pci_dev *bridge = bus->self;
444 struct resource *b_res;
445
446 b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
447 b_res[1].flags |= IORESOURCE_MEM;
448
449 pci_read_config_word(bridge, PCI_IO_BASE, &io);
450 if (!io) {
451 pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
452 pci_read_config_word(bridge, PCI_IO_BASE, &io);
453 pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
454 }
455 if (io)
456 b_res[0].flags |= IORESOURCE_IO;
457 /* DECchip 21050 pass 2 errata: the bridge may miss an address
458 disconnect boundary by one PCI data phase.
459 Workaround: do not use prefetching on this device. */
460 if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001)
461 return;
462 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
463 if (!pmem) {
464 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE,
465 0xfff0fff0);
466 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
467 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
468 }
Yinghai Lu1f82de12009-04-23 20:48:32 -0700469 if (pmem) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
Yinghai Lu99586102010-01-22 01:02:28 -0800471 if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
472 PCI_PREF_RANGE_TYPE_64) {
Yinghai Lu1f82de12009-04-23 20:48:32 -0700473 b_res[2].flags |= IORESOURCE_MEM_64;
Yinghai Lu99586102010-01-22 01:02:28 -0800474 b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
475 }
Yinghai Lu1f82de12009-04-23 20:48:32 -0700476 }
477
478 /* double check if bridge does support 64 bit pref */
479 if (b_res[2].flags & IORESOURCE_MEM_64) {
480 u32 mem_base_hi, tmp;
481 pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32,
482 &mem_base_hi);
483 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
484 0xffffffff);
485 pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
486 if (!tmp)
487 b_res[2].flags &= ~IORESOURCE_MEM_64;
488 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
489 mem_base_hi);
490 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491}
492
493/* Helper function for sizing routines: find first available
494 bus resource of a given type. Note: we intentionally skip
495 the bus resources which have already been assigned (that is,
496 have non-NULL parent resource). */
Sam Ravnborg96bde062007-03-26 21:53:30 -0800497static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498{
499 int i;
500 struct resource *r;
501 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
502 IORESOURCE_PREFETCH;
503
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -0700504 pci_bus_for_each_resource(bus, r, i) {
Ivan Kokshaysky299de032005-06-15 18:59:27 +0400505 if (r == &ioport_resource || r == &iomem_resource)
506 continue;
Jesse Barnes55a10982009-10-27 09:39:18 -0700507 if (r && (r->flags & type_mask) == type && !r->parent)
508 return r;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 }
510 return NULL;
511}
512
Ram Pai13583b12011-02-14 17:43:17 -0800513static resource_size_t calculate_iosize(resource_size_t size,
514 resource_size_t min_size,
515 resource_size_t size1,
516 resource_size_t old_size,
517 resource_size_t align)
518{
519 if (size < min_size)
520 size = min_size;
521 if (old_size == 1 )
522 old_size = 0;
523 /* To be fixed in 2.5: we should have sort of HAVE_ISA
524 flag in the struct pci_bus. */
525#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
526 size = (size & 0xff) + ((size & ~0xffUL) << 2);
527#endif
528 size = ALIGN(size + size1, align);
529 if (size < old_size)
530 size = old_size;
531 return size;
532}
533
534static resource_size_t calculate_memsize(resource_size_t size,
535 resource_size_t min_size,
536 resource_size_t size1,
537 resource_size_t old_size,
538 resource_size_t align)
539{
540 if (size < min_size)
541 size = min_size;
542 if (old_size == 1 )
543 old_size = 0;
544 if (size < old_size)
545 size = old_size;
546 size = ALIGN(size + size1, align);
547 return size;
548}
549
Yinghai Lube768912011-07-25 13:08:38 -0700550static resource_size_t get_res_add_size(struct resource_list_x *add_head,
551 struct resource *res)
552{
553 struct resource_list_x *list;
554
555 /* check if it is in add_head list */
556 for (list = add_head->next; list && list->res != res;
557 list = list->next);
558 if (list)
559 return list->add_size;
560
561 return 0;
562}
563
Ram Paic8adf9a2011-02-14 17:43:20 -0800564/**
565 * pbus_size_io() - size the io window of a given bus
566 *
567 * @bus : the bus
568 * @min_size : the minimum io window that must to be allocated
569 * @add_size : additional optional io window
570 * @add_head : track the additional io window on this list
571 *
572 * Sizing the IO windows of the PCI-PCI bridge is trivial,
573 * since these windows have 4K granularity and the IO ranges
574 * of non-bridge PCI devices are limited to 256 bytes.
575 * We must be careful with the ISA aliasing though.
576 */
577static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
578 resource_size_t add_size, struct resource_list_x *add_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579{
580 struct pci_dev *dev;
581 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
Ram Paic8adf9a2011-02-14 17:43:20 -0800582 unsigned long size = 0, size0 = 0, size1 = 0;
Yinghai Lube768912011-07-25 13:08:38 -0700583 resource_size_t children_add_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584
585 if (!b_res)
586 return;
587
588 list_for_each_entry(dev, &bus->devices, bus_list) {
589 int i;
590
591 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
592 struct resource *r = &dev->resource[i];
593 unsigned long r_size;
594
595 if (r->parent || !(r->flags & IORESOURCE_IO))
596 continue;
Zhao, Yu022edd82008-10-13 19:24:28 +0800597 r_size = resource_size(r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
599 if (r_size < 0x400)
600 /* Might be re-aligned for ISA */
601 size += r_size;
602 else
603 size1 += r_size;
Yinghai Lube768912011-07-25 13:08:38 -0700604
605 if (add_head)
606 children_add_size += get_res_add_size(add_head, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 }
608 }
Ram Paic8adf9a2011-02-14 17:43:20 -0800609 size0 = calculate_iosize(size, min_size, size1,
Ram Pai13583b12011-02-14 17:43:17 -0800610 resource_size(b_res), 4096);
Yinghai Lube768912011-07-25 13:08:38 -0700611 if (children_add_size > add_size)
612 add_size = children_add_size;
Yinghai Lu93d21752011-05-13 18:06:17 -0700613 size1 = (!add_head || (add_head && !add_size)) ? size0 :
Ram Paic8adf9a2011-02-14 17:43:20 -0800614 calculate_iosize(size, min_size+add_size, size1,
615 resource_size(b_res), 4096);
616 if (!size0 && !size1) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700617 if (b_res->start || b_res->end)
618 dev_info(&bus->self->dev, "disabling bridge window "
619 "%pR to [bus %02x-%02x] (unused)\n", b_res,
620 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 b_res->flags = 0;
622 return;
623 }
624 /* Alignment of the IO window is always 4K */
625 b_res->start = 4096;
Ram Paic8adf9a2011-02-14 17:43:20 -0800626 b_res->end = b_res->start + size0 - 1;
Ivan Kokshaysky88452562008-03-30 19:50:14 +0400627 b_res->flags |= IORESOURCE_STARTALIGN;
Ram Paic8adf9a2011-02-14 17:43:20 -0800628 if (size1 > size0 && add_head)
Ram Pai2bbc6942011-07-25 13:08:39 -0700629 add_to_list(add_head, bus->self, b_res, size1-size0, 4096);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630}
631
Ram Paic8adf9a2011-02-14 17:43:20 -0800632/**
633 * pbus_size_mem() - size the memory window of a given bus
634 *
635 * @bus : the bus
636 * @min_size : the minimum memory window that must to be allocated
637 * @add_size : additional optional memory window
638 * @add_head : track the additional memory window on this list
639 *
640 * Calculate the size of the bus and minimal alignment which
641 * guarantees that all child resources fit in this size.
642 */
Eric W. Biederman28760482009-09-09 14:09:24 -0700643static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
Ram Paic8adf9a2011-02-14 17:43:20 -0800644 unsigned long type, resource_size_t min_size,
645 resource_size_t add_size,
646 struct resource_list_x *add_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647{
648 struct pci_dev *dev;
Ram Paic8adf9a2011-02-14 17:43:20 -0800649 resource_size_t min_align, align, size, size0, size1;
Benjamin Herrenschmidtc40a22e2007-12-10 17:32:15 +1100650 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 int order, max_order;
652 struct resource *b_res = find_free_bus_resource(bus, type);
Yinghai Lu1f82de12009-04-23 20:48:32 -0700653 unsigned int mem64_mask = 0;
Yinghai Lube768912011-07-25 13:08:38 -0700654 resource_size_t children_add_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655
656 if (!b_res)
657 return 0;
658
659 memset(aligns, 0, sizeof(aligns));
660 max_order = 0;
661 size = 0;
662
Yinghai Lu1f82de12009-04-23 20:48:32 -0700663 mem64_mask = b_res->flags & IORESOURCE_MEM_64;
664 b_res->flags &= ~IORESOURCE_MEM_64;
665
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 list_for_each_entry(dev, &bus->devices, bus_list) {
667 int i;
Yinghai Lu1f82de12009-04-23 20:48:32 -0700668
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
670 struct resource *r = &dev->resource[i];
Benjamin Herrenschmidtc40a22e2007-12-10 17:32:15 +1100671 resource_size_t r_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672
673 if (r->parent || (r->flags & mask) != type)
674 continue;
Zhao, Yu022edd82008-10-13 19:24:28 +0800675 r_size = resource_size(r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 /* For bridges size != alignment */
Chris Wright6faf17f2009-08-28 13:00:06 -0700677 align = pci_resource_alignment(dev, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 order = __ffs(align) - 20;
679 if (order > 11) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700680 dev_warn(&dev->dev, "disabling BAR %d: %pR "
681 "(bad alignment %#llx)\n", i, r,
682 (unsigned long long) align);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 r->flags = 0;
684 continue;
685 }
686 size += r_size;
687 if (order < 0)
688 order = 0;
689 /* Exclude ranges with size > align from
690 calculation of the alignment. */
691 if (r_size == align)
692 aligns[order] += align;
693 if (order > max_order)
694 max_order = order;
Yinghai Lu1f82de12009-04-23 20:48:32 -0700695 mem64_mask &= r->flags & IORESOURCE_MEM_64;
Yinghai Lube768912011-07-25 13:08:38 -0700696
697 if (add_head)
698 children_add_size += get_res_add_size(add_head, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 }
700 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 align = 0;
702 min_align = 0;
703 for (order = 0; order <= max_order; order++) {
Jeremy Fitzhardinge8308c542008-09-11 01:31:50 -0700704 resource_size_t align1 = 1;
705
706 align1 <<= (order + 20);
707
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 if (!align)
709 min_align = align1;
Milind Arun Choudhary6f6f8c22007-07-09 11:55:51 -0700710 else if (ALIGN(align + min_align, min_align) < align1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 min_align = align1 >> 1;
712 align += aligns[order];
713 }
Linus Torvaldsb42282e2011-04-11 10:53:11 -0700714 size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
Yinghai Lube768912011-07-25 13:08:38 -0700715 if (children_add_size > add_size)
716 add_size = children_add_size;
Yinghai Lu93d21752011-05-13 18:06:17 -0700717 size1 = (!add_head || (add_head && !add_size)) ? size0 :
Ram Paic8adf9a2011-02-14 17:43:20 -0800718 calculate_memsize(size, min_size+add_size, 0,
Linus Torvaldsb42282e2011-04-11 10:53:11 -0700719 resource_size(b_res), min_align);
Ram Paic8adf9a2011-02-14 17:43:20 -0800720 if (!size0 && !size1) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700721 if (b_res->start || b_res->end)
722 dev_info(&bus->self->dev, "disabling bridge window "
723 "%pR to [bus %02x-%02x] (unused)\n", b_res,
724 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 b_res->flags = 0;
726 return 1;
727 }
728 b_res->start = min_align;
Ram Paic8adf9a2011-02-14 17:43:20 -0800729 b_res->end = size0 + min_align - 1;
730 b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask;
731 if (size1 > size0 && add_head)
Ram Pai2bbc6942011-07-25 13:08:39 -0700732 add_to_list(add_head, bus->self, b_res, size1-size0, min_align);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 return 1;
734}
735
Adrian Bunk5468ae62008-04-18 13:53:56 -0700736static void pci_bus_size_cardbus(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737{
738 struct pci_dev *bridge = bus->self;
739 struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
740 u16 ctrl;
741
742 /*
743 * Reserve some resources for CardBus. We reserve
744 * a fixed amount of bus space for CardBus bridges.
745 */
Linus Torvalds934b7022008-04-22 18:16:30 -0700746 b_res[0].start = 0;
747 b_res[0].end = pci_cardbus_io_size - 1;
748 b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749
Linus Torvalds934b7022008-04-22 18:16:30 -0700750 b_res[1].start = 0;
751 b_res[1].end = pci_cardbus_io_size - 1;
752 b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753
754 /*
755 * Check whether prefetchable memory is supported
756 * by this bridge.
757 */
758 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
759 if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) {
760 ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
761 pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl);
762 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
763 }
764
765 /*
766 * If we have prefetchable memory support, allocate
767 * two regions. Otherwise, allocate one region of
768 * twice the size.
769 */
770 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
Linus Torvalds934b7022008-04-22 18:16:30 -0700771 b_res[2].start = 0;
772 b_res[2].end = pci_cardbus_mem_size - 1;
773 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774
Linus Torvalds934b7022008-04-22 18:16:30 -0700775 b_res[3].start = 0;
776 b_res[3].end = pci_cardbus_mem_size - 1;
777 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 } else {
Linus Torvalds934b7022008-04-22 18:16:30 -0700779 b_res[3].start = 0;
780 b_res[3].end = pci_cardbus_mem_size * 2 - 1;
781 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 }
783}
784
Ram Paic8adf9a2011-02-14 17:43:20 -0800785void __ref __pci_bus_size_bridges(struct pci_bus *bus,
786 struct resource_list_x *add_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787{
788 struct pci_dev *dev;
789 unsigned long mask, prefmask;
Ram Paic8adf9a2011-02-14 17:43:20 -0800790 resource_size_t additional_mem_size = 0, additional_io_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791
792 list_for_each_entry(dev, &bus->devices, bus_list) {
793 struct pci_bus *b = dev->subordinate;
794 if (!b)
795 continue;
796
797 switch (dev->class >> 8) {
798 case PCI_CLASS_BRIDGE_CARDBUS:
799 pci_bus_size_cardbus(b);
800 break;
801
802 case PCI_CLASS_BRIDGE_PCI:
803 default:
Ram Paic8adf9a2011-02-14 17:43:20 -0800804 __pci_bus_size_bridges(b, add_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 break;
806 }
807 }
808
809 /* The root bus? */
810 if (!bus->self)
811 return;
812
813 switch (bus->self->class >> 8) {
814 case PCI_CLASS_BRIDGE_CARDBUS:
815 /* don't size cardbuses yet. */
816 break;
817
818 case PCI_CLASS_BRIDGE_PCI:
819 pci_bridge_check_ranges(bus);
Eric W. Biederman28760482009-09-09 14:09:24 -0700820 if (bus->self->is_hotplug_bridge) {
Ram Paic8adf9a2011-02-14 17:43:20 -0800821 additional_io_size = pci_hotplug_io_size;
822 additional_mem_size = pci_hotplug_mem_size;
Eric W. Biederman28760482009-09-09 14:09:24 -0700823 }
Ram Paic8adf9a2011-02-14 17:43:20 -0800824 /*
825 * Follow thru
826 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 default:
Ram Paic8adf9a2011-02-14 17:43:20 -0800828 pbus_size_io(bus, 0, additional_io_size, add_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829 /* If the bridge supports prefetchable range, size it
830 separately. If it doesn't, or its prefetchable window
831 has already been allocated by arch code, try
832 non-prefetchable range for both types of PCI memory
833 resources. */
834 mask = IORESOURCE_MEM;
835 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
Ram Paic8adf9a2011-02-14 17:43:20 -0800836 if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, add_head))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 mask = prefmask; /* Success, size non-prefetch only. */
Eric W. Biederman28760482009-09-09 14:09:24 -0700838 else
Ram Paic8adf9a2011-02-14 17:43:20 -0800839 additional_mem_size += additional_mem_size;
840 pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, add_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 break;
842 }
843}
Ram Paic8adf9a2011-02-14 17:43:20 -0800844
845void __ref pci_bus_size_bridges(struct pci_bus *bus)
846{
847 __pci_bus_size_bridges(bus, NULL);
848}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849EXPORT_SYMBOL(pci_bus_size_bridges);
850
Yinghai Lu568ddef2010-01-22 01:02:21 -0800851static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
Ram Paic8adf9a2011-02-14 17:43:20 -0800852 struct resource_list_x *add_head,
Yinghai Lu568ddef2010-01-22 01:02:21 -0800853 struct resource_list_x *fail_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854{
855 struct pci_bus *b;
856 struct pci_dev *dev;
857
Ram Paic8adf9a2011-02-14 17:43:20 -0800858 pbus_assign_resources_sorted(bus, add_head, fail_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 list_for_each_entry(dev, &bus->devices, bus_list) {
861 b = dev->subordinate;
862 if (!b)
863 continue;
864
Ram Paic8adf9a2011-02-14 17:43:20 -0800865 __pci_bus_assign_resources(b, add_head, fail_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866
867 switch (dev->class >> 8) {
868 case PCI_CLASS_BRIDGE_PCI:
Yinghai Lu6841ec62010-01-22 01:02:25 -0800869 if (!pci_is_enabled(dev))
870 pci_setup_bridge(b);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 break;
872
873 case PCI_CLASS_BRIDGE_CARDBUS:
874 pci_setup_cardbus(b);
875 break;
876
877 default:
Bjorn Helgaas80ccba12008-06-13 10:52:11 -0600878 dev_info(&dev->dev, "not setting up bridge for bus "
879 "%04x:%02x\n", pci_domain_nr(b), b->number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 break;
881 }
882 }
883}
Yinghai Lu568ddef2010-01-22 01:02:21 -0800884
885void __ref pci_bus_assign_resources(const struct pci_bus *bus)
886{
Ram Paic8adf9a2011-02-14 17:43:20 -0800887 __pci_bus_assign_resources(bus, NULL, NULL);
Yinghai Lu568ddef2010-01-22 01:02:21 -0800888}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889EXPORT_SYMBOL(pci_bus_assign_resources);
890
Yinghai Lu6841ec62010-01-22 01:02:25 -0800891static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
892 struct resource_list_x *fail_head)
893{
894 struct pci_bus *b;
895
896 pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head);
897
898 b = bridge->subordinate;
899 if (!b)
900 return;
901
Ram Paic8adf9a2011-02-14 17:43:20 -0800902 __pci_bus_assign_resources(b, NULL, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -0800903
904 switch (bridge->class >> 8) {
905 case PCI_CLASS_BRIDGE_PCI:
906 pci_setup_bridge(b);
907 break;
908
909 case PCI_CLASS_BRIDGE_CARDBUS:
910 pci_setup_cardbus(b);
911 break;
912
913 default:
914 dev_info(&bridge->dev, "not setting up bridge for bus "
915 "%04x:%02x\n", pci_domain_nr(b), b->number);
916 break;
917 }
918}
Yinghai Lu5009b462010-01-22 01:02:20 -0800919static void pci_bridge_release_resources(struct pci_bus *bus,
920 unsigned long type)
921{
922 int idx;
923 bool changed = false;
924 struct pci_dev *dev;
925 struct resource *r;
926 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
927 IORESOURCE_PREFETCH;
928
929 dev = bus->self;
930 for (idx = PCI_BRIDGE_RESOURCES; idx <= PCI_BRIDGE_RESOURCE_END;
931 idx++) {
932 r = &dev->resource[idx];
933 if ((r->flags & type_mask) != type)
934 continue;
935 if (!r->parent)
936 continue;
937 /*
938 * if there are children under that, we should release them
939 * all
940 */
941 release_child_resources(r);
942 if (!release_resource(r)) {
943 dev_printk(KERN_DEBUG, &dev->dev,
944 "resource %d %pR released\n", idx, r);
945 /* keep the old size */
946 r->end = resource_size(r) - 1;
947 r->start = 0;
948 r->flags = 0;
949 changed = true;
950 }
951 }
952
953 if (changed) {
954 /* avoiding touch the one without PREF */
955 if (type & IORESOURCE_PREFETCH)
956 type = IORESOURCE_PREFETCH;
957 __pci_setup_bridge(bus, type);
958 }
959}
960
961enum release_type {
962 leaf_only,
963 whole_subtree,
964};
965/*
966 * try to release pci bridge resources that is from leaf bridge,
967 * so we can allocate big new one later
968 */
969static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus,
970 unsigned long type,
971 enum release_type rel_type)
972{
973 struct pci_dev *dev;
974 bool is_leaf_bridge = true;
975
976 list_for_each_entry(dev, &bus->devices, bus_list) {
977 struct pci_bus *b = dev->subordinate;
978 if (!b)
979 continue;
980
981 is_leaf_bridge = false;
982
983 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
984 continue;
985
986 if (rel_type == whole_subtree)
987 pci_bus_release_bridge_resources(b, type,
988 whole_subtree);
989 }
990
991 if (pci_is_root_bus(bus))
992 return;
993
994 if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI)
995 return;
996
997 if ((rel_type == whole_subtree) || is_leaf_bridge)
998 pci_bridge_release_resources(bus, type);
999}
1000
Yinghai Lu76fbc262008-06-23 20:33:06 +02001001static void pci_bus_dump_res(struct pci_bus *bus)
1002{
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -07001003 struct resource *res;
1004 int i;
Yinghai Lu76fbc262008-06-23 20:33:06 +02001005
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -07001006 pci_bus_for_each_resource(bus, res, i) {
Yinghai Lu7c9342b2009-12-22 15:02:24 -08001007 if (!res || !res->end || !res->flags)
Yinghai Lu76fbc262008-06-23 20:33:06 +02001008 continue;
1009
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -06001010 dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res);
Yinghai Lu76fbc262008-06-23 20:33:06 +02001011 }
1012}
1013
1014static void pci_bus_dump_resources(struct pci_bus *bus)
1015{
1016 struct pci_bus *b;
1017 struct pci_dev *dev;
1018
1019
1020 pci_bus_dump_res(bus);
1021
1022 list_for_each_entry(dev, &bus->devices, bus_list) {
1023 b = dev->subordinate;
1024 if (!b)
1025 continue;
1026
1027 pci_bus_dump_resources(b);
1028 }
1029}
1030
Yinghai Luda7822e2011-05-12 17:11:37 -07001031static int __init pci_bus_get_depth(struct pci_bus *bus)
1032{
1033 int depth = 0;
1034 struct pci_dev *dev;
1035
1036 list_for_each_entry(dev, &bus->devices, bus_list) {
1037 int ret;
1038 struct pci_bus *b = dev->subordinate;
1039 if (!b)
1040 continue;
1041
1042 ret = pci_bus_get_depth(b);
1043 if (ret + 1 > depth)
1044 depth = ret + 1;
1045 }
1046
1047 return depth;
1048}
1049static int __init pci_get_max_depth(void)
1050{
1051 int depth = 0;
1052 struct pci_bus *bus;
1053
1054 list_for_each_entry(bus, &pci_root_buses, node) {
1055 int ret;
1056
1057 ret = pci_bus_get_depth(bus);
1058 if (ret > depth)
1059 depth = ret;
1060 }
1061
1062 return depth;
1063}
1064
Ram Paif483d392011-07-07 11:19:10 -07001065
Yinghai Luda7822e2011-05-12 17:11:37 -07001066/*
1067 * first try will not touch pci bridge res
1068 * second and later try will clear small leaf bridge res
1069 * will stop till to the max deepth if can not find good one
1070 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071void __init
1072pci_assign_unassigned_resources(void)
1073{
1074 struct pci_bus *bus;
Ram Paic8adf9a2011-02-14 17:43:20 -08001075 struct resource_list_x add_list; /* list of resources that
1076 want additional resources */
Yinghai Luda7822e2011-05-12 17:11:37 -07001077 int tried_times = 0;
1078 enum release_type rel_type = leaf_only;
1079 struct resource_list_x head, *list;
1080 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1081 IORESOURCE_PREFETCH;
1082 unsigned long failed_type;
1083 int max_depth = pci_get_max_depth();
1084 int pci_try_num;
1085
1086
1087 head.next = NULL;
Ram Paic8adf9a2011-02-14 17:43:20 -08001088 add_list.next = NULL;
Yinghai Luda7822e2011-05-12 17:11:37 -07001089
1090 pci_try_num = max_depth + 1;
1091 printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
1092 max_depth, pci_try_num);
1093
1094again:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 /* Depth first, calculate sizes and alignments of all
1096 subordinate buses. */
Yinghai Luda7822e2011-05-12 17:11:37 -07001097 list_for_each_entry(bus, &pci_root_buses, node)
Ram Paic8adf9a2011-02-14 17:43:20 -08001098 __pci_bus_size_bridges(bus, &add_list);
Ram Paic8adf9a2011-02-14 17:43:20 -08001099
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 /* Depth last, allocate resources and update the hardware. */
Yinghai Luda7822e2011-05-12 17:11:37 -07001101 list_for_each_entry(bus, &pci_root_buses, node)
1102 __pci_bus_assign_resources(bus, &add_list, &head);
Ram Paic8adf9a2011-02-14 17:43:20 -08001103 BUG_ON(add_list.next);
Yinghai Luda7822e2011-05-12 17:11:37 -07001104 tried_times++;
1105
1106 /* any device complain? */
1107 if (!head.next)
1108 goto enable_and_dump;
Ram Paif483d392011-07-07 11:19:10 -07001109
1110 /* don't realloc if asked to do so */
1111 if (!pci_realloc_enabled()) {
1112 free_list(resource_list_x, &head);
1113 goto enable_and_dump;
1114 }
1115
Yinghai Luda7822e2011-05-12 17:11:37 -07001116 failed_type = 0;
1117 for (list = head.next; list;) {
1118 failed_type |= list->flags;
1119 list = list->next;
1120 }
1121 /*
1122 * io port are tight, don't try extra
1123 * or if reach the limit, don't want to try more
1124 */
1125 failed_type &= type_mask;
1126 if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
1127 free_list(resource_list_x, &head);
1128 goto enable_and_dump;
1129 }
1130
1131 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
1132 tried_times + 1);
1133
1134 /* third times and later will not check if it is leaf */
1135 if ((tried_times + 1) > 2)
1136 rel_type = whole_subtree;
1137
1138 /*
1139 * Try to release leaf bridge's resources that doesn't fit resource of
1140 * child device under that bridge
1141 */
1142 for (list = head.next; list;) {
1143 bus = list->dev->bus;
1144 pci_bus_release_bridge_resources(bus, list->flags & type_mask,
1145 rel_type);
1146 list = list->next;
1147 }
1148 /* restore size and flags */
1149 for (list = head.next; list;) {
1150 struct resource *res = list->res;
1151
1152 res->start = list->start;
1153 res->end = list->end;
1154 res->flags = list->flags;
1155 if (list->dev->subordinate)
1156 res->flags = 0;
1157
1158 list = list->next;
1159 }
1160 free_list(resource_list_x, &head);
1161
1162 goto again;
1163
1164enable_and_dump:
1165 /* Depth last, update the hardware. */
1166 list_for_each_entry(bus, &pci_root_buses, node)
1167 pci_enable_bridges(bus);
Yinghai Lu76fbc262008-06-23 20:33:06 +02001168
1169 /* dump the resource on buses */
Yinghai Luda7822e2011-05-12 17:11:37 -07001170 list_for_each_entry(bus, &pci_root_buses, node)
Yinghai Lu76fbc262008-06-23 20:33:06 +02001171 pci_bus_dump_resources(bus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172}
Yinghai Lu6841ec62010-01-22 01:02:25 -08001173
1174void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
1175{
1176 struct pci_bus *parent = bridge->subordinate;
Yinghai Lu32180e402010-01-22 01:02:27 -08001177 int tried_times = 0;
1178 struct resource_list_x head, *list;
Yinghai Lu6841ec62010-01-22 01:02:25 -08001179 int retval;
Yinghai Lu32180e402010-01-22 01:02:27 -08001180 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1181 IORESOURCE_PREFETCH;
Yinghai Lu6841ec62010-01-22 01:02:25 -08001182
Yinghai Lu32180e402010-01-22 01:02:27 -08001183 head.next = NULL;
1184
1185again:
Yinghai Lu6841ec62010-01-22 01:02:25 -08001186 pci_bus_size_bridges(parent);
Yinghai Lu32180e402010-01-22 01:02:27 -08001187 __pci_bridge_assign_resources(bridge, &head);
Yinghai Lu32180e402010-01-22 01:02:27 -08001188
1189 tried_times++;
1190
1191 if (!head.next)
Yinghai Lu3f579c32010-05-21 14:35:06 -07001192 goto enable_all;
Yinghai Lu32180e402010-01-22 01:02:27 -08001193
1194 if (tried_times >= 2) {
1195 /* still fail, don't need to try more */
Ram Pai094732a2011-02-14 17:43:18 -08001196 free_list(resource_list_x, &head);
Yinghai Lu3f579c32010-05-21 14:35:06 -07001197 goto enable_all;
Yinghai Lu32180e402010-01-22 01:02:27 -08001198 }
1199
1200 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
1201 tried_times + 1);
1202
1203 /*
1204 * Try to release leaf bridge's resources that doesn't fit resource of
1205 * child device under that bridge
1206 */
1207 for (list = head.next; list;) {
1208 struct pci_bus *bus = list->dev->bus;
1209 unsigned long flags = list->flags;
1210
1211 pci_bus_release_bridge_resources(bus, flags & type_mask,
1212 whole_subtree);
1213 list = list->next;
1214 }
1215 /* restore size and flags */
1216 for (list = head.next; list;) {
1217 struct resource *res = list->res;
1218
1219 res->start = list->start;
1220 res->end = list->end;
1221 res->flags = list->flags;
1222 if (list->dev->subordinate)
1223 res->flags = 0;
1224
1225 list = list->next;
1226 }
Ram Pai094732a2011-02-14 17:43:18 -08001227 free_list(resource_list_x, &head);
Yinghai Lu32180e402010-01-22 01:02:27 -08001228
1229 goto again;
Yinghai Lu3f579c32010-05-21 14:35:06 -07001230
1231enable_all:
1232 retval = pci_reenable_device(bridge);
1233 pci_set_master(bridge);
1234 pci_enable_bridges(parent);
Yinghai Lu6841ec62010-01-22 01:02:25 -08001235}
1236EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);