blob: 1c19b9f4019aa504637ffdf8e52a9c558552b339 [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);
Yinghai Lu2aceefc2011-07-25 13:08:40 -0700676#ifdef CONFIG_PCI_IOV
677 /* put SRIOV requested res to the optional list */
678 if (add_head && i >= PCI_IOV_RESOURCES &&
679 i <= PCI_IOV_RESOURCE_END) {
680 r->end = r->start - 1;
681 add_to_list(add_head, dev, r, r_size, 1);
682 children_add_size += r_size;
683 continue;
684 }
685#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 /* For bridges size != alignment */
Chris Wright6faf17f2009-08-28 13:00:06 -0700687 align = pci_resource_alignment(dev, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 order = __ffs(align) - 20;
689 if (order > 11) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700690 dev_warn(&dev->dev, "disabling BAR %d: %pR "
691 "(bad alignment %#llx)\n", i, r,
692 (unsigned long long) align);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 r->flags = 0;
694 continue;
695 }
696 size += r_size;
697 if (order < 0)
698 order = 0;
699 /* Exclude ranges with size > align from
700 calculation of the alignment. */
701 if (r_size == align)
702 aligns[order] += align;
703 if (order > max_order)
704 max_order = order;
Yinghai Lu1f82de12009-04-23 20:48:32 -0700705 mem64_mask &= r->flags & IORESOURCE_MEM_64;
Yinghai Lube768912011-07-25 13:08:38 -0700706
707 if (add_head)
708 children_add_size += get_res_add_size(add_head, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 }
710 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 align = 0;
712 min_align = 0;
713 for (order = 0; order <= max_order; order++) {
Jeremy Fitzhardinge8308c542008-09-11 01:31:50 -0700714 resource_size_t align1 = 1;
715
716 align1 <<= (order + 20);
717
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 if (!align)
719 min_align = align1;
Milind Arun Choudhary6f6f8c22007-07-09 11:55:51 -0700720 else if (ALIGN(align + min_align, min_align) < align1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 min_align = align1 >> 1;
722 align += aligns[order];
723 }
Linus Torvaldsb42282e2011-04-11 10:53:11 -0700724 size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
Yinghai Lube768912011-07-25 13:08:38 -0700725 if (children_add_size > add_size)
726 add_size = children_add_size;
Yinghai Lu93d21752011-05-13 18:06:17 -0700727 size1 = (!add_head || (add_head && !add_size)) ? size0 :
Ram Paic8adf9a2011-02-14 17:43:20 -0800728 calculate_memsize(size, min_size+add_size, 0,
Linus Torvaldsb42282e2011-04-11 10:53:11 -0700729 resource_size(b_res), min_align);
Ram Paic8adf9a2011-02-14 17:43:20 -0800730 if (!size0 && !size1) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700731 if (b_res->start || b_res->end)
732 dev_info(&bus->self->dev, "disabling bridge window "
733 "%pR to [bus %02x-%02x] (unused)\n", b_res,
734 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 b_res->flags = 0;
736 return 1;
737 }
738 b_res->start = min_align;
Ram Paic8adf9a2011-02-14 17:43:20 -0800739 b_res->end = size0 + min_align - 1;
740 b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask;
741 if (size1 > size0 && add_head)
Ram Pai2bbc6942011-07-25 13:08:39 -0700742 add_to_list(add_head, bus->self, b_res, size1-size0, min_align);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 return 1;
744}
745
Adrian Bunk5468ae62008-04-18 13:53:56 -0700746static void pci_bus_size_cardbus(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747{
748 struct pci_dev *bridge = bus->self;
749 struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
750 u16 ctrl;
751
752 /*
753 * Reserve some resources for CardBus. We reserve
754 * a fixed amount of bus space for CardBus bridges.
755 */
Linus Torvalds934b7022008-04-22 18:16:30 -0700756 b_res[0].start = 0;
757 b_res[0].end = pci_cardbus_io_size - 1;
758 b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
Linus Torvalds934b7022008-04-22 18:16:30 -0700760 b_res[1].start = 0;
761 b_res[1].end = pci_cardbus_io_size - 1;
762 b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763
764 /*
765 * Check whether prefetchable memory is supported
766 * by this bridge.
767 */
768 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
769 if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) {
770 ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
771 pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl);
772 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
773 }
774
775 /*
776 * If we have prefetchable memory support, allocate
777 * two regions. Otherwise, allocate one region of
778 * twice the size.
779 */
780 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
Linus Torvalds934b7022008-04-22 18:16:30 -0700781 b_res[2].start = 0;
782 b_res[2].end = pci_cardbus_mem_size - 1;
783 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
Linus Torvalds934b7022008-04-22 18:16:30 -0700785 b_res[3].start = 0;
786 b_res[3].end = pci_cardbus_mem_size - 1;
787 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 } else {
Linus Torvalds934b7022008-04-22 18:16:30 -0700789 b_res[3].start = 0;
790 b_res[3].end = pci_cardbus_mem_size * 2 - 1;
791 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 }
793}
794
Ram Paic8adf9a2011-02-14 17:43:20 -0800795void __ref __pci_bus_size_bridges(struct pci_bus *bus,
796 struct resource_list_x *add_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797{
798 struct pci_dev *dev;
799 unsigned long mask, prefmask;
Ram Paic8adf9a2011-02-14 17:43:20 -0800800 resource_size_t additional_mem_size = 0, additional_io_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
802 list_for_each_entry(dev, &bus->devices, bus_list) {
803 struct pci_bus *b = dev->subordinate;
804 if (!b)
805 continue;
806
807 switch (dev->class >> 8) {
808 case PCI_CLASS_BRIDGE_CARDBUS:
809 pci_bus_size_cardbus(b);
810 break;
811
812 case PCI_CLASS_BRIDGE_PCI:
813 default:
Ram Paic8adf9a2011-02-14 17:43:20 -0800814 __pci_bus_size_bridges(b, add_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 break;
816 }
817 }
818
819 /* The root bus? */
820 if (!bus->self)
821 return;
822
823 switch (bus->self->class >> 8) {
824 case PCI_CLASS_BRIDGE_CARDBUS:
825 /* don't size cardbuses yet. */
826 break;
827
828 case PCI_CLASS_BRIDGE_PCI:
829 pci_bridge_check_ranges(bus);
Eric W. Biederman28760482009-09-09 14:09:24 -0700830 if (bus->self->is_hotplug_bridge) {
Ram Paic8adf9a2011-02-14 17:43:20 -0800831 additional_io_size = pci_hotplug_io_size;
832 additional_mem_size = pci_hotplug_mem_size;
Eric W. Biederman28760482009-09-09 14:09:24 -0700833 }
Ram Paic8adf9a2011-02-14 17:43:20 -0800834 /*
835 * Follow thru
836 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 default:
Ram Paic8adf9a2011-02-14 17:43:20 -0800838 pbus_size_io(bus, 0, additional_io_size, add_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 /* If the bridge supports prefetchable range, size it
840 separately. If it doesn't, or its prefetchable window
841 has already been allocated by arch code, try
842 non-prefetchable range for both types of PCI memory
843 resources. */
844 mask = IORESOURCE_MEM;
845 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
Ram Paic8adf9a2011-02-14 17:43:20 -0800846 if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, add_head))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 mask = prefmask; /* Success, size non-prefetch only. */
Eric W. Biederman28760482009-09-09 14:09:24 -0700848 else
Ram Paic8adf9a2011-02-14 17:43:20 -0800849 additional_mem_size += additional_mem_size;
850 pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, add_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 break;
852 }
853}
Ram Paic8adf9a2011-02-14 17:43:20 -0800854
855void __ref pci_bus_size_bridges(struct pci_bus *bus)
856{
857 __pci_bus_size_bridges(bus, NULL);
858}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859EXPORT_SYMBOL(pci_bus_size_bridges);
860
Yinghai Lu568ddef2010-01-22 01:02:21 -0800861static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
Ram Paic8adf9a2011-02-14 17:43:20 -0800862 struct resource_list_x *add_head,
Yinghai Lu568ddef2010-01-22 01:02:21 -0800863 struct resource_list_x *fail_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864{
865 struct pci_bus *b;
866 struct pci_dev *dev;
867
Ram Paic8adf9a2011-02-14 17:43:20 -0800868 pbus_assign_resources_sorted(bus, add_head, fail_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 list_for_each_entry(dev, &bus->devices, bus_list) {
871 b = dev->subordinate;
872 if (!b)
873 continue;
874
Ram Paic8adf9a2011-02-14 17:43:20 -0800875 __pci_bus_assign_resources(b, add_head, fail_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
877 switch (dev->class >> 8) {
878 case PCI_CLASS_BRIDGE_PCI:
Yinghai Lu6841ec62010-01-22 01:02:25 -0800879 if (!pci_is_enabled(dev))
880 pci_setup_bridge(b);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 break;
882
883 case PCI_CLASS_BRIDGE_CARDBUS:
884 pci_setup_cardbus(b);
885 break;
886
887 default:
Bjorn Helgaas80ccba12008-06-13 10:52:11 -0600888 dev_info(&dev->dev, "not setting up bridge for bus "
889 "%04x:%02x\n", pci_domain_nr(b), b->number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 break;
891 }
892 }
893}
Yinghai Lu568ddef2010-01-22 01:02:21 -0800894
895void __ref pci_bus_assign_resources(const struct pci_bus *bus)
896{
Ram Paic8adf9a2011-02-14 17:43:20 -0800897 __pci_bus_assign_resources(bus, NULL, NULL);
Yinghai Lu568ddef2010-01-22 01:02:21 -0800898}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899EXPORT_SYMBOL(pci_bus_assign_resources);
900
Yinghai Lu6841ec62010-01-22 01:02:25 -0800901static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
902 struct resource_list_x *fail_head)
903{
904 struct pci_bus *b;
905
906 pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head);
907
908 b = bridge->subordinate;
909 if (!b)
910 return;
911
Ram Paic8adf9a2011-02-14 17:43:20 -0800912 __pci_bus_assign_resources(b, NULL, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -0800913
914 switch (bridge->class >> 8) {
915 case PCI_CLASS_BRIDGE_PCI:
916 pci_setup_bridge(b);
917 break;
918
919 case PCI_CLASS_BRIDGE_CARDBUS:
920 pci_setup_cardbus(b);
921 break;
922
923 default:
924 dev_info(&bridge->dev, "not setting up bridge for bus "
925 "%04x:%02x\n", pci_domain_nr(b), b->number);
926 break;
927 }
928}
Yinghai Lu5009b462010-01-22 01:02:20 -0800929static void pci_bridge_release_resources(struct pci_bus *bus,
930 unsigned long type)
931{
932 int idx;
933 bool changed = false;
934 struct pci_dev *dev;
935 struct resource *r;
936 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
937 IORESOURCE_PREFETCH;
938
939 dev = bus->self;
940 for (idx = PCI_BRIDGE_RESOURCES; idx <= PCI_BRIDGE_RESOURCE_END;
941 idx++) {
942 r = &dev->resource[idx];
943 if ((r->flags & type_mask) != type)
944 continue;
945 if (!r->parent)
946 continue;
947 /*
948 * if there are children under that, we should release them
949 * all
950 */
951 release_child_resources(r);
952 if (!release_resource(r)) {
953 dev_printk(KERN_DEBUG, &dev->dev,
954 "resource %d %pR released\n", idx, r);
955 /* keep the old size */
956 r->end = resource_size(r) - 1;
957 r->start = 0;
958 r->flags = 0;
959 changed = true;
960 }
961 }
962
963 if (changed) {
964 /* avoiding touch the one without PREF */
965 if (type & IORESOURCE_PREFETCH)
966 type = IORESOURCE_PREFETCH;
967 __pci_setup_bridge(bus, type);
968 }
969}
970
971enum release_type {
972 leaf_only,
973 whole_subtree,
974};
975/*
976 * try to release pci bridge resources that is from leaf bridge,
977 * so we can allocate big new one later
978 */
979static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus,
980 unsigned long type,
981 enum release_type rel_type)
982{
983 struct pci_dev *dev;
984 bool is_leaf_bridge = true;
985
986 list_for_each_entry(dev, &bus->devices, bus_list) {
987 struct pci_bus *b = dev->subordinate;
988 if (!b)
989 continue;
990
991 is_leaf_bridge = false;
992
993 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
994 continue;
995
996 if (rel_type == whole_subtree)
997 pci_bus_release_bridge_resources(b, type,
998 whole_subtree);
999 }
1000
1001 if (pci_is_root_bus(bus))
1002 return;
1003
1004 if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI)
1005 return;
1006
1007 if ((rel_type == whole_subtree) || is_leaf_bridge)
1008 pci_bridge_release_resources(bus, type);
1009}
1010
Yinghai Lu76fbc262008-06-23 20:33:06 +02001011static void pci_bus_dump_res(struct pci_bus *bus)
1012{
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -07001013 struct resource *res;
1014 int i;
Yinghai Lu76fbc262008-06-23 20:33:06 +02001015
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -07001016 pci_bus_for_each_resource(bus, res, i) {
Yinghai Lu7c9342b2009-12-22 15:02:24 -08001017 if (!res || !res->end || !res->flags)
Yinghai Lu76fbc262008-06-23 20:33:06 +02001018 continue;
1019
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -06001020 dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res);
Yinghai Lu76fbc262008-06-23 20:33:06 +02001021 }
1022}
1023
1024static void pci_bus_dump_resources(struct pci_bus *bus)
1025{
1026 struct pci_bus *b;
1027 struct pci_dev *dev;
1028
1029
1030 pci_bus_dump_res(bus);
1031
1032 list_for_each_entry(dev, &bus->devices, bus_list) {
1033 b = dev->subordinate;
1034 if (!b)
1035 continue;
1036
1037 pci_bus_dump_resources(b);
1038 }
1039}
1040
Yinghai Luda7822e2011-05-12 17:11:37 -07001041static int __init pci_bus_get_depth(struct pci_bus *bus)
1042{
1043 int depth = 0;
1044 struct pci_dev *dev;
1045
1046 list_for_each_entry(dev, &bus->devices, bus_list) {
1047 int ret;
1048 struct pci_bus *b = dev->subordinate;
1049 if (!b)
1050 continue;
1051
1052 ret = pci_bus_get_depth(b);
1053 if (ret + 1 > depth)
1054 depth = ret + 1;
1055 }
1056
1057 return depth;
1058}
1059static int __init pci_get_max_depth(void)
1060{
1061 int depth = 0;
1062 struct pci_bus *bus;
1063
1064 list_for_each_entry(bus, &pci_root_buses, node) {
1065 int ret;
1066
1067 ret = pci_bus_get_depth(bus);
1068 if (ret > depth)
1069 depth = ret;
1070 }
1071
1072 return depth;
1073}
1074
Ram Paif483d392011-07-07 11:19:10 -07001075
Yinghai Luda7822e2011-05-12 17:11:37 -07001076/*
1077 * first try will not touch pci bridge res
1078 * second and later try will clear small leaf bridge res
1079 * will stop till to the max deepth if can not find good one
1080 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081void __init
1082pci_assign_unassigned_resources(void)
1083{
1084 struct pci_bus *bus;
Ram Paic8adf9a2011-02-14 17:43:20 -08001085 struct resource_list_x add_list; /* list of resources that
1086 want additional resources */
Yinghai Luda7822e2011-05-12 17:11:37 -07001087 int tried_times = 0;
1088 enum release_type rel_type = leaf_only;
1089 struct resource_list_x head, *list;
1090 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1091 IORESOURCE_PREFETCH;
1092 unsigned long failed_type;
1093 int max_depth = pci_get_max_depth();
1094 int pci_try_num;
1095
1096
1097 head.next = NULL;
Ram Paic8adf9a2011-02-14 17:43:20 -08001098 add_list.next = NULL;
Yinghai Luda7822e2011-05-12 17:11:37 -07001099
1100 pci_try_num = max_depth + 1;
1101 printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
1102 max_depth, pci_try_num);
1103
1104again:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 /* Depth first, calculate sizes and alignments of all
1106 subordinate buses. */
Yinghai Luda7822e2011-05-12 17:11:37 -07001107 list_for_each_entry(bus, &pci_root_buses, node)
Ram Paic8adf9a2011-02-14 17:43:20 -08001108 __pci_bus_size_bridges(bus, &add_list);
Ram Paic8adf9a2011-02-14 17:43:20 -08001109
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 /* Depth last, allocate resources and update the hardware. */
Yinghai Luda7822e2011-05-12 17:11:37 -07001111 list_for_each_entry(bus, &pci_root_buses, node)
1112 __pci_bus_assign_resources(bus, &add_list, &head);
Ram Paic8adf9a2011-02-14 17:43:20 -08001113 BUG_ON(add_list.next);
Yinghai Luda7822e2011-05-12 17:11:37 -07001114 tried_times++;
1115
1116 /* any device complain? */
1117 if (!head.next)
1118 goto enable_and_dump;
Ram Paif483d392011-07-07 11:19:10 -07001119
1120 /* don't realloc if asked to do so */
1121 if (!pci_realloc_enabled()) {
1122 free_list(resource_list_x, &head);
1123 goto enable_and_dump;
1124 }
1125
Yinghai Luda7822e2011-05-12 17:11:37 -07001126 failed_type = 0;
1127 for (list = head.next; list;) {
1128 failed_type |= list->flags;
1129 list = list->next;
1130 }
1131 /*
1132 * io port are tight, don't try extra
1133 * or if reach the limit, don't want to try more
1134 */
1135 failed_type &= type_mask;
1136 if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
1137 free_list(resource_list_x, &head);
1138 goto enable_and_dump;
1139 }
1140
1141 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
1142 tried_times + 1);
1143
1144 /* third times and later will not check if it is leaf */
1145 if ((tried_times + 1) > 2)
1146 rel_type = whole_subtree;
1147
1148 /*
1149 * Try to release leaf bridge's resources that doesn't fit resource of
1150 * child device under that bridge
1151 */
1152 for (list = head.next; list;) {
1153 bus = list->dev->bus;
1154 pci_bus_release_bridge_resources(bus, list->flags & type_mask,
1155 rel_type);
1156 list = list->next;
1157 }
1158 /* restore size and flags */
1159 for (list = head.next; list;) {
1160 struct resource *res = list->res;
1161
1162 res->start = list->start;
1163 res->end = list->end;
1164 res->flags = list->flags;
1165 if (list->dev->subordinate)
1166 res->flags = 0;
1167
1168 list = list->next;
1169 }
1170 free_list(resource_list_x, &head);
1171
1172 goto again;
1173
1174enable_and_dump:
1175 /* Depth last, update the hardware. */
1176 list_for_each_entry(bus, &pci_root_buses, node)
1177 pci_enable_bridges(bus);
Yinghai Lu76fbc262008-06-23 20:33:06 +02001178
1179 /* dump the resource on buses */
Yinghai Luda7822e2011-05-12 17:11:37 -07001180 list_for_each_entry(bus, &pci_root_buses, node)
Yinghai Lu76fbc262008-06-23 20:33:06 +02001181 pci_bus_dump_resources(bus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182}
Yinghai Lu6841ec62010-01-22 01:02:25 -08001183
1184void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
1185{
1186 struct pci_bus *parent = bridge->subordinate;
Yinghai Lu32180e42010-01-22 01:02:27 -08001187 int tried_times = 0;
1188 struct resource_list_x head, *list;
Yinghai Lu6841ec62010-01-22 01:02:25 -08001189 int retval;
Yinghai Lu32180e42010-01-22 01:02:27 -08001190 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1191 IORESOURCE_PREFETCH;
Yinghai Lu6841ec62010-01-22 01:02:25 -08001192
Yinghai Lu32180e42010-01-22 01:02:27 -08001193 head.next = NULL;
1194
1195again:
Yinghai Lu6841ec62010-01-22 01:02:25 -08001196 pci_bus_size_bridges(parent);
Yinghai Lu32180e42010-01-22 01:02:27 -08001197 __pci_bridge_assign_resources(bridge, &head);
Yinghai Lu32180e42010-01-22 01:02:27 -08001198
1199 tried_times++;
1200
1201 if (!head.next)
Yinghai Lu3f579c32010-05-21 14:35:06 -07001202 goto enable_all;
Yinghai Lu32180e42010-01-22 01:02:27 -08001203
1204 if (tried_times >= 2) {
1205 /* still fail, don't need to try more */
Ram Pai094732a2011-02-14 17:43:18 -08001206 free_list(resource_list_x, &head);
Yinghai Lu3f579c32010-05-21 14:35:06 -07001207 goto enable_all;
Yinghai Lu32180e42010-01-22 01:02:27 -08001208 }
1209
1210 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
1211 tried_times + 1);
1212
1213 /*
1214 * Try to release leaf bridge's resources that doesn't fit resource of
1215 * child device under that bridge
1216 */
1217 for (list = head.next; list;) {
1218 struct pci_bus *bus = list->dev->bus;
1219 unsigned long flags = list->flags;
1220
1221 pci_bus_release_bridge_resources(bus, flags & type_mask,
1222 whole_subtree);
1223 list = list->next;
1224 }
1225 /* restore size and flags */
1226 for (list = head.next; list;) {
1227 struct resource *res = list->res;
1228
1229 res->start = list->start;
1230 res->end = list->end;
1231 res->flags = list->flags;
1232 if (list->dev->subordinate)
1233 res->flags = 0;
1234
1235 list = list->next;
1236 }
Ram Pai094732a2011-02-14 17:43:18 -08001237 free_list(resource_list_x, &head);
Yinghai Lu32180e42010-01-22 01:02:27 -08001238
1239 goto again;
Yinghai Lu3f579c32010-05-21 14:35:06 -07001240
1241enable_all:
1242 retval = pci_reenable_device(bridge);
1243 pci_set_master(bridge);
1244 pci_enable_bridges(parent);
Yinghai Lu6841ec62010-01-22 01:02:25 -08001245}
1246EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);