blob: 75d43eb3784247e50b1d12fcbb5f36451a61c98e [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 */
Yinghai Luef62dfe2012-01-21 02:08:18 -080067static int add_to_list(struct resource_list_x *head,
Ram Paic8adf9a2011-02-14 17:43:20 -080068 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 Luef62dfe2012-01-21 02:08:18 -080078 return -ENOMEM;
Yinghai Lu568ddef2010-01-22 01:02:21 -080079 }
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;
Yinghai Luef62dfe2012-01-21 02:08:18 -080090
91 return 0;
Yinghai Lu568ddef2010-01-22 01:02:21 -080092}
93
Ram Paic8adf9a2011-02-14 17:43:20 -080094static void add_to_failed_list(struct resource_list_x *head,
95 struct pci_dev *dev, struct resource *res)
96{
Ram Pai2bbc6942011-07-25 13:08:39 -070097 add_to_list(head, dev, res,
98 0 /* dont care */,
99 0 /* dont care */);
Ram Paic8adf9a2011-02-14 17:43:20 -0800100}
101
Yinghai Lu1c372352012-01-21 02:08:19 -0800102static resource_size_t get_res_add_size(struct resource_list_x *realloc_head,
103 struct resource *res)
104{
105 struct resource_list_x *list;
106
107 /* check if it is in realloc_head list */
108 for (list = realloc_head->next; list && list->res != res;
109 list = list->next)
110 ;
111 if (list)
112 return list->add_size;
113
114 return 0;
115}
116
Yinghai Lu6841ec62010-01-22 01:02:25 -0800117static void __dev_sort_resources(struct pci_dev *dev,
118 struct resource_list *head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119{
Yinghai Lu6841ec62010-01-22 01:02:25 -0800120 u16 class = dev->class >> 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
Yinghai Lu6841ec62010-01-22 01:02:25 -0800122 /* Don't touch classless devices or host bridges or ioapics. */
123 if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST)
124 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
Yinghai Lu6841ec62010-01-22 01:02:25 -0800126 /* Don't touch ioapic devices already enabled by firmware */
127 if (class == PCI_CLASS_SYSTEM_PIC) {
128 u16 command;
129 pci_read_config_word(dev, PCI_COMMAND, &command);
130 if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
131 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 }
133
Yinghai Lu6841ec62010-01-22 01:02:25 -0800134 pdev_sort_resources(dev, head);
135}
136
Ram Paifc075e12011-02-14 17:43:19 -0800137static inline void reset_resource(struct resource *res)
138{
139 res->start = 0;
140 res->end = 0;
141 res->flags = 0;
142}
143
Ram Paic8adf9a2011-02-14 17:43:20 -0800144/**
Ram Pai9e8bf932011-07-25 13:08:42 -0700145 * reassign_resources_sorted() - satisfy any additional resource requests
Ram Paic8adf9a2011-02-14 17:43:20 -0800146 *
Ram Pai9e8bf932011-07-25 13:08:42 -0700147 * @realloc_head : head of the list tracking requests requiring additional
Ram Paic8adf9a2011-02-14 17:43:20 -0800148 * resources
149 * @head : head of the list tracking requests with allocated
150 * resources
151 *
Ram Pai9e8bf932011-07-25 13:08:42 -0700152 * Walk through each element of the realloc_head and try to procure
Ram Paic8adf9a2011-02-14 17:43:20 -0800153 * additional resources for the element, provided the element
154 * is in the head list.
155 */
Ram Pai9e8bf932011-07-25 13:08:42 -0700156static void reassign_resources_sorted(struct resource_list_x *realloc_head,
Ram Paic8adf9a2011-02-14 17:43:20 -0800157 struct resource_list *head)
158{
159 struct resource *res;
160 struct resource_list_x *list, *tmp, *prev;
161 struct resource_list *hlist;
162 resource_size_t add_size;
163 int idx;
164
Ram Pai9e8bf932011-07-25 13:08:42 -0700165 prev = realloc_head;
166 for (list = realloc_head->next; list;) {
Ram Paic8adf9a2011-02-14 17:43:20 -0800167 res = list->res;
168 /* skip resource that has been reset */
169 if (!res->flags)
170 goto out;
171
172 /* skip this resource if not found in head list */
173 for (hlist = head->next; hlist && hlist->res != res;
174 hlist = hlist->next);
175 if (!hlist) { /* just skip */
176 prev = list;
177 list = list->next;
178 continue;
179 }
180
181 idx = res - &list->dev->resource[0];
182 add_size=list->add_size;
Ram Pai2bbc6942011-07-25 13:08:39 -0700183 if (!resource_size(res)) {
Ram Pai0a2daa12011-07-25 13:08:41 -0700184 res->start = list->start;
Ram Pai2bbc6942011-07-25 13:08:39 -0700185 res->end = res->start + add_size - 1;
186 if(pci_assign_resource(list->dev, idx))
Ram Paic8adf9a2011-02-14 17:43:20 -0800187 reset_resource(res);
Ram Pai2bbc6942011-07-25 13:08:39 -0700188 } else {
189 resource_size_t align = list->min_align;
190 res->flags |= list->flags & (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN);
191 if (pci_reassign_resource(list->dev, idx, add_size, align))
192 dev_printk(KERN_DEBUG, &list->dev->dev, "failed to add optional resources res=%pR\n",
193 res);
Ram Paic8adf9a2011-02-14 17:43:20 -0800194 }
195out:
196 tmp = list;
197 prev->next = list = list->next;
198 kfree(tmp);
199 }
200}
201
202/**
203 * assign_requested_resources_sorted() - satisfy resource requests
204 *
205 * @head : head of the list tracking requests for resources
206 * @failed_list : head of the list tracking requests that could
207 * not be allocated
208 *
209 * Satisfy resource requests of each element in the list. Add
210 * requests that could not satisfied to the failed_list.
211 */
212static void assign_requested_resources_sorted(struct resource_list *head,
Yinghai Lu6841ec62010-01-22 01:02:25 -0800213 struct resource_list_x *fail_head)
214{
215 struct resource *res;
Ram Paic8adf9a2011-02-14 17:43:20 -0800216 struct resource_list *list;
Yinghai Lu6841ec62010-01-22 01:02:25 -0800217 int idx;
218
Ram Paic8adf9a2011-02-14 17:43:20 -0800219 for (list = head->next; list; list = list->next) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 res = list->res;
221 idx = res - &list->dev->resource[0];
Ram Paic8adf9a2011-02-14 17:43:20 -0800222 if (resource_size(res) && pci_assign_resource(list->dev, idx)) {
Yinghai Lu9a928662010-02-28 15:49:39 -0800223 if (fail_head && !pci_is_root_bus(list->dev->bus)) {
224 /*
225 * if the failed res is for ROM BAR, and it will
226 * be enabled later, don't add it to the list
227 */
228 if (!((idx == PCI_ROM_RESOURCE) &&
229 (!(res->flags & IORESOURCE_ROM_ENABLE))))
230 add_to_failed_list(fail_head, list->dev, res);
231 }
Ram Paifc075e12011-02-14 17:43:19 -0800232 reset_resource(res);
Rajesh Shah542df5d2005-04-28 00:25:50 -0700233 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 }
235}
236
Ram Paic8adf9a2011-02-14 17:43:20 -0800237static void __assign_resources_sorted(struct resource_list *head,
Ram Pai9e8bf932011-07-25 13:08:42 -0700238 struct resource_list_x *realloc_head,
Ram Paic8adf9a2011-02-14 17:43:20 -0800239 struct resource_list_x *fail_head)
240{
241 /* Satisfy the must-have resource requests */
242 assign_requested_resources_sorted(head, fail_head);
243
Ram Pai0a2daa12011-07-25 13:08:41 -0700244 /* Try to satisfy any additional optional resource
Ram Paic8adf9a2011-02-14 17:43:20 -0800245 requests */
Ram Pai9e8bf932011-07-25 13:08:42 -0700246 if (realloc_head)
247 reassign_resources_sorted(realloc_head, head);
Ram Paic8adf9a2011-02-14 17:43:20 -0800248 free_list(resource_list, head);
249}
250
Yinghai Lu6841ec62010-01-22 01:02:25 -0800251static void pdev_assign_resources_sorted(struct pci_dev *dev,
252 struct resource_list_x *fail_head)
253{
254 struct resource_list head;
255
256 head.next = NULL;
257 __dev_sort_resources(dev, &head);
Ram Paic8adf9a2011-02-14 17:43:20 -0800258 __assign_resources_sorted(&head, NULL, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -0800259
260}
261
262static void pbus_assign_resources_sorted(const struct pci_bus *bus,
Ram Pai9e8bf932011-07-25 13:08:42 -0700263 struct resource_list_x *realloc_head,
Yinghai Lu6841ec62010-01-22 01:02:25 -0800264 struct resource_list_x *fail_head)
265{
266 struct pci_dev *dev;
267 struct resource_list head;
268
269 head.next = NULL;
270 list_for_each_entry(dev, &bus->devices, bus_list)
271 __dev_sort_resources(dev, &head);
272
Ram Pai9e8bf932011-07-25 13:08:42 -0700273 __assign_resources_sorted(&head, realloc_head, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -0800274}
275
Dominik Brodowskib3743fa2005-09-09 13:03:23 -0700276void pci_setup_cardbus(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277{
278 struct pci_dev *bridge = bus->self;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600279 struct resource *res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 struct pci_bus_region region;
281
Bjorn Helgaas865df572009-11-04 10:32:57 -0700282 dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
283 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600285 res = bus->resource[0];
286 pcibios_resource_to_bus(bridge, &region, res);
287 if (res->flags & IORESOURCE_IO) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 /*
289 * The IO resource is allocated a range twice as large as it
290 * would normally need. This allows us to set both IO regs.
291 */
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600292 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
294 region.start);
295 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
296 region.end);
297 }
298
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600299 res = bus->resource[1];
300 pcibios_resource_to_bus(bridge, &region, res);
301 if (res->flags & IORESOURCE_IO) {
302 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
304 region.start);
305 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
306 region.end);
307 }
308
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600309 res = bus->resource[2];
310 pcibios_resource_to_bus(bridge, &region, res);
311 if (res->flags & IORESOURCE_MEM) {
312 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
314 region.start);
315 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
316 region.end);
317 }
318
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600319 res = bus->resource[3];
320 pcibios_resource_to_bus(bridge, &region, res);
321 if (res->flags & IORESOURCE_MEM) {
322 dev_info(&bridge->dev, " bridge window %pR\n", res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
324 region.start);
325 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
326 region.end);
327 }
328}
Dominik Brodowskib3743fa2005-09-09 13:03:23 -0700329EXPORT_SYMBOL(pci_setup_cardbus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330
331/* Initialize bridges with base/limit values we have collected.
332 PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
333 requires that if there is no I/O ports or memory behind the
334 bridge, corresponding range must be turned off by writing base
335 value greater than limit to the bridge's base/limit registers.
336
337 Note: care must be taken when updating I/O base/limit registers
338 of bridges which support 32-bit I/O. This update requires two
339 config space writes, so it's quite possible that an I/O window of
340 the bridge will have some undesirable address (e.g. 0) after the
341 first write. Ditto 64-bit prefetchable MMIO. */
Yinghai Lu7cc59972009-12-22 15:02:21 -0800342static void pci_setup_bridge_io(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343{
344 struct pci_dev *bridge = bus->self;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600345 struct resource *res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 struct pci_bus_region region;
Yinghai Lu7cc59972009-12-22 15:02:21 -0800347 u32 l, io_upper16;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348
349 /* Set up the top and bottom of the PCI I/O segment for this bus. */
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600350 res = bus->resource[0];
351 pcibios_resource_to_bus(bridge, &region, res);
352 if (res->flags & IORESOURCE_IO) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 pci_read_config_dword(bridge, PCI_IO_BASE, &l);
354 l &= 0xffff0000;
355 l |= (region.start >> 8) & 0x00f0;
356 l |= region.end & 0xf000;
357 /* Set up upper 16 bits of I/O base/limit. */
358 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600359 dev_info(&bridge->dev, " bridge window %pR\n", res);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800360 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 /* Clear upper 16 bits of I/O base/limit. */
362 io_upper16 = 0;
363 l = 0x00f0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 }
365 /* Temporarily disable the I/O range before updating PCI_IO_BASE. */
366 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
367 /* Update lower 16 bits of I/O base/limit. */
368 pci_write_config_dword(bridge, PCI_IO_BASE, l);
369 /* Update upper 16 bits of I/O base/limit. */
370 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800371}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Yinghai Lu7cc59972009-12-22 15:02:21 -0800373static void pci_setup_bridge_mmio(struct pci_bus *bus)
374{
375 struct pci_dev *bridge = bus->self;
376 struct resource *res;
377 struct pci_bus_region region;
378 u32 l;
379
380 /* Set up the top and bottom of the PCI Memory segment for this bus. */
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600381 res = bus->resource[1];
382 pcibios_resource_to_bus(bridge, &region, res);
383 if (res->flags & IORESOURCE_MEM) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 l = (region.start >> 16) & 0xfff0;
385 l |= region.end & 0xfff00000;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600386 dev_info(&bridge->dev, " bridge window %pR\n", res);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800387 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 l = 0x0000fff0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 }
390 pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800391}
392
393static void pci_setup_bridge_mmio_pref(struct pci_bus *bus)
394{
395 struct pci_dev *bridge = bus->self;
396 struct resource *res;
397 struct pci_bus_region region;
398 u32 l, bu, lu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399
400 /* Clear out the upper 32 bits of PREF limit.
401 If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily
402 disables PREF range, which is ok. */
403 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
404
405 /* Set up PREF base/limit. */
Benjamin Herrenschmidtc40a22e2007-12-10 17:32:15 +1100406 bu = lu = 0;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600407 res = bus->resource[2];
408 pcibios_resource_to_bus(bridge, &region, res);
409 if (res->flags & IORESOURCE_PREFETCH) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 l = (region.start >> 16) & 0xfff0;
411 l |= region.end & 0xfff00000;
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600412 if (res->flags & IORESOURCE_MEM_64) {
Yinghai Lu1f82de12009-04-23 20:48:32 -0700413 bu = upper_32_bits(region.start);
414 lu = upper_32_bits(region.end);
Yinghai Lu1f82de12009-04-23 20:48:32 -0700415 }
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -0600416 dev_info(&bridge->dev, " bridge window %pR\n", res);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800417 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 l = 0x0000fff0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 }
420 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
421
Alex Williamson59353ea2009-11-30 14:51:44 -0700422 /* Set the upper 32 bits of PREF base & limit. */
423 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
424 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
Yinghai Lu7cc59972009-12-22 15:02:21 -0800425}
426
427static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
428{
429 struct pci_dev *bridge = bus->self;
430
Yinghai Lu7cc59972009-12-22 15:02:21 -0800431 dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
432 bus->secondary, bus->subordinate);
433
434 if (type & IORESOURCE_IO)
435 pci_setup_bridge_io(bus);
436
437 if (type & IORESOURCE_MEM)
438 pci_setup_bridge_mmio(bus);
439
440 if (type & IORESOURCE_PREFETCH)
441 pci_setup_bridge_mmio_pref(bus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442
443 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
444}
445
Benjamin Herrenschmidte2444272011-09-11 14:08:38 -0300446void pci_setup_bridge(struct pci_bus *bus)
Yinghai Lu7cc59972009-12-22 15:02:21 -0800447{
448 unsigned long type = IORESOURCE_IO | IORESOURCE_MEM |
449 IORESOURCE_PREFETCH;
450
451 __pci_setup_bridge(bus, type);
452}
453
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454/* Check whether the bridge supports optional I/O and
455 prefetchable memory ranges. If not, the respective
456 base/limit registers must be read-only and read as 0. */
Sam Ravnborg96bde062007-03-26 21:53:30 -0800457static void pci_bridge_check_ranges(struct pci_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458{
459 u16 io;
460 u32 pmem;
461 struct pci_dev *bridge = bus->self;
462 struct resource *b_res;
463
464 b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
465 b_res[1].flags |= IORESOURCE_MEM;
466
467 pci_read_config_word(bridge, PCI_IO_BASE, &io);
468 if (!io) {
469 pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
470 pci_read_config_word(bridge, PCI_IO_BASE, &io);
471 pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
472 }
473 if (io)
474 b_res[0].flags |= IORESOURCE_IO;
475 /* DECchip 21050 pass 2 errata: the bridge may miss an address
476 disconnect boundary by one PCI data phase.
477 Workaround: do not use prefetching on this device. */
478 if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001)
479 return;
480 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
481 if (!pmem) {
482 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE,
483 0xfff0fff0);
484 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
485 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
486 }
Yinghai Lu1f82de12009-04-23 20:48:32 -0700487 if (pmem) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
Yinghai Lu99586102010-01-22 01:02:28 -0800489 if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
490 PCI_PREF_RANGE_TYPE_64) {
Yinghai Lu1f82de12009-04-23 20:48:32 -0700491 b_res[2].flags |= IORESOURCE_MEM_64;
Yinghai Lu99586102010-01-22 01:02:28 -0800492 b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
493 }
Yinghai Lu1f82de12009-04-23 20:48:32 -0700494 }
495
496 /* double check if bridge does support 64 bit pref */
497 if (b_res[2].flags & IORESOURCE_MEM_64) {
498 u32 mem_base_hi, tmp;
499 pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32,
500 &mem_base_hi);
501 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
502 0xffffffff);
503 pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
504 if (!tmp)
505 b_res[2].flags &= ~IORESOURCE_MEM_64;
506 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
507 mem_base_hi);
508 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509}
510
511/* Helper function for sizing routines: find first available
512 bus resource of a given type. Note: we intentionally skip
513 the bus resources which have already been assigned (that is,
514 have non-NULL parent resource). */
Sam Ravnborg96bde062007-03-26 21:53:30 -0800515static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516{
517 int i;
518 struct resource *r;
519 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
520 IORESOURCE_PREFETCH;
521
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -0700522 pci_bus_for_each_resource(bus, r, i) {
Ivan Kokshaysky299de032005-06-15 18:59:27 +0400523 if (r == &ioport_resource || r == &iomem_resource)
524 continue;
Jesse Barnes55a10982009-10-27 09:39:18 -0700525 if (r && (r->flags & type_mask) == type && !r->parent)
526 return r;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 }
528 return NULL;
529}
530
Ram Pai13583b12011-02-14 17:43:17 -0800531static resource_size_t calculate_iosize(resource_size_t size,
532 resource_size_t min_size,
533 resource_size_t size1,
534 resource_size_t old_size,
535 resource_size_t align)
536{
537 if (size < min_size)
538 size = min_size;
539 if (old_size == 1 )
540 old_size = 0;
541 /* To be fixed in 2.5: we should have sort of HAVE_ISA
542 flag in the struct pci_bus. */
543#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
544 size = (size & 0xff) + ((size & ~0xffUL) << 2);
545#endif
546 size = ALIGN(size + size1, align);
547 if (size < old_size)
548 size = old_size;
549 return size;
550}
551
552static resource_size_t calculate_memsize(resource_size_t size,
553 resource_size_t min_size,
554 resource_size_t size1,
555 resource_size_t old_size,
556 resource_size_t align)
557{
558 if (size < min_size)
559 size = min_size;
560 if (old_size == 1 )
561 old_size = 0;
562 if (size < old_size)
563 size = old_size;
564 size = ALIGN(size + size1, align);
565 return size;
566}
567
Ram Paic8adf9a2011-02-14 17:43:20 -0800568/**
569 * pbus_size_io() - size the io window of a given bus
570 *
571 * @bus : the bus
572 * @min_size : the minimum io window that must to be allocated
573 * @add_size : additional optional io window
Ram Pai9e8bf932011-07-25 13:08:42 -0700574 * @realloc_head : track the additional io window on this list
Ram Paic8adf9a2011-02-14 17:43:20 -0800575 *
576 * Sizing the IO windows of the PCI-PCI bridge is trivial,
577 * since these windows have 4K granularity and the IO ranges
578 * of non-bridge PCI devices are limited to 256 bytes.
579 * We must be careful with the ISA aliasing though.
580 */
581static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
Ram Pai9e8bf932011-07-25 13:08:42 -0700582 resource_size_t add_size, struct resource_list_x *realloc_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583{
584 struct pci_dev *dev;
585 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
Ram Paic8adf9a2011-02-14 17:43:20 -0800586 unsigned long size = 0, size0 = 0, size1 = 0;
Yinghai Lube768912011-07-25 13:08:38 -0700587 resource_size_t children_add_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
589 if (!b_res)
590 return;
591
592 list_for_each_entry(dev, &bus->devices, bus_list) {
593 int i;
594
595 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
596 struct resource *r = &dev->resource[i];
597 unsigned long r_size;
598
599 if (r->parent || !(r->flags & IORESOURCE_IO))
600 continue;
Zhao, Yu022edd82008-10-13 19:24:28 +0800601 r_size = resource_size(r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
603 if (r_size < 0x400)
604 /* Might be re-aligned for ISA */
605 size += r_size;
606 else
607 size1 += r_size;
Yinghai Lube768912011-07-25 13:08:38 -0700608
Ram Pai9e8bf932011-07-25 13:08:42 -0700609 if (realloc_head)
610 children_add_size += get_res_add_size(realloc_head, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611 }
612 }
Ram Paic8adf9a2011-02-14 17:43:20 -0800613 size0 = calculate_iosize(size, min_size, size1,
Ram Pai13583b12011-02-14 17:43:17 -0800614 resource_size(b_res), 4096);
Yinghai Lube768912011-07-25 13:08:38 -0700615 if (children_add_size > add_size)
616 add_size = children_add_size;
Ram Pai9e8bf932011-07-25 13:08:42 -0700617 size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
Yinghai Lua4ac9fe2012-01-21 02:08:17 -0800618 calculate_iosize(size, min_size, add_size + size1,
Ram Paic8adf9a2011-02-14 17:43:20 -0800619 resource_size(b_res), 4096);
620 if (!size0 && !size1) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700621 if (b_res->start || b_res->end)
622 dev_info(&bus->self->dev, "disabling bridge window "
623 "%pR to [bus %02x-%02x] (unused)\n", b_res,
624 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 b_res->flags = 0;
626 return;
627 }
628 /* Alignment of the IO window is always 4K */
629 b_res->start = 4096;
Ram Paic8adf9a2011-02-14 17:43:20 -0800630 b_res->end = b_res->start + size0 - 1;
Ivan Kokshaysky88452562008-03-30 19:50:14 +0400631 b_res->flags |= IORESOURCE_STARTALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700632 if (size1 > size0 && realloc_head)
633 add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634}
635
Ram Paic8adf9a2011-02-14 17:43:20 -0800636/**
637 * pbus_size_mem() - size the memory window of a given bus
638 *
639 * @bus : the bus
640 * @min_size : the minimum memory window that must to be allocated
641 * @add_size : additional optional memory window
Ram Pai9e8bf932011-07-25 13:08:42 -0700642 * @realloc_head : track the additional memory window on this list
Ram Paic8adf9a2011-02-14 17:43:20 -0800643 *
644 * Calculate the size of the bus and minimal alignment which
645 * guarantees that all child resources fit in this size.
646 */
Eric W. Biederman28760482009-09-09 14:09:24 -0700647static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
Ram Paic8adf9a2011-02-14 17:43:20 -0800648 unsigned long type, resource_size_t min_size,
649 resource_size_t add_size,
Ram Pai9e8bf932011-07-25 13:08:42 -0700650 struct resource_list_x *realloc_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651{
652 struct pci_dev *dev;
Ram Paic8adf9a2011-02-14 17:43:20 -0800653 resource_size_t min_align, align, size, size0, size1;
Benjamin Herrenschmidtc40a22e2007-12-10 17:32:15 +1100654 resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 int order, max_order;
656 struct resource *b_res = find_free_bus_resource(bus, type);
Yinghai Lu1f82de12009-04-23 20:48:32 -0700657 unsigned int mem64_mask = 0;
Yinghai Lube768912011-07-25 13:08:38 -0700658 resource_size_t children_add_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659
660 if (!b_res)
661 return 0;
662
663 memset(aligns, 0, sizeof(aligns));
664 max_order = 0;
665 size = 0;
666
Yinghai Lu1f82de12009-04-23 20:48:32 -0700667 mem64_mask = b_res->flags & IORESOURCE_MEM_64;
668 b_res->flags &= ~IORESOURCE_MEM_64;
669
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 list_for_each_entry(dev, &bus->devices, bus_list) {
671 int i;
Yinghai Lu1f82de12009-04-23 20:48:32 -0700672
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
674 struct resource *r = &dev->resource[i];
Benjamin Herrenschmidtc40a22e2007-12-10 17:32:15 +1100675 resource_size_t r_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676
677 if (r->parent || (r->flags & mask) != type)
678 continue;
Zhao, Yu022edd82008-10-13 19:24:28 +0800679 r_size = resource_size(r);
Yinghai Lu2aceefc2011-07-25 13:08:40 -0700680#ifdef CONFIG_PCI_IOV
681 /* put SRIOV requested res to the optional list */
Ram Pai9e8bf932011-07-25 13:08:42 -0700682 if (realloc_head && i >= PCI_IOV_RESOURCES &&
Yinghai Lu2aceefc2011-07-25 13:08:40 -0700683 i <= PCI_IOV_RESOURCE_END) {
684 r->end = r->start - 1;
Ram Pai9e8bf932011-07-25 13:08:42 -0700685 add_to_list(realloc_head, dev, r, r_size, 0/* dont' care */);
Yinghai Lu2aceefc2011-07-25 13:08:40 -0700686 children_add_size += r_size;
687 continue;
688 }
689#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 /* For bridges size != alignment */
Chris Wright6faf17f2009-08-28 13:00:06 -0700691 align = pci_resource_alignment(dev, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 order = __ffs(align) - 20;
693 if (order > 11) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700694 dev_warn(&dev->dev, "disabling BAR %d: %pR "
695 "(bad alignment %#llx)\n", i, r,
696 (unsigned long long) align);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 r->flags = 0;
698 continue;
699 }
700 size += r_size;
701 if (order < 0)
702 order = 0;
703 /* Exclude ranges with size > align from
704 calculation of the alignment. */
705 if (r_size == align)
706 aligns[order] += align;
707 if (order > max_order)
708 max_order = order;
Yinghai Lu1f82de12009-04-23 20:48:32 -0700709 mem64_mask &= r->flags & IORESOURCE_MEM_64;
Yinghai Lube768912011-07-25 13:08:38 -0700710
Ram Pai9e8bf932011-07-25 13:08:42 -0700711 if (realloc_head)
712 children_add_size += get_res_add_size(realloc_head, r);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 }
714 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 align = 0;
716 min_align = 0;
717 for (order = 0; order <= max_order; order++) {
Jeremy Fitzhardinge8308c542008-09-11 01:31:50 -0700718 resource_size_t align1 = 1;
719
720 align1 <<= (order + 20);
721
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 if (!align)
723 min_align = align1;
Milind Arun Choudhary6f6f8c22007-07-09 11:55:51 -0700724 else if (ALIGN(align + min_align, min_align) < align1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 min_align = align1 >> 1;
726 align += aligns[order];
727 }
Linus Torvaldsb42282e2011-04-11 10:53:11 -0700728 size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
Yinghai Lube768912011-07-25 13:08:38 -0700729 if (children_add_size > add_size)
730 add_size = children_add_size;
Ram Pai9e8bf932011-07-25 13:08:42 -0700731 size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
Yinghai Lua4ac9fe2012-01-21 02:08:17 -0800732 calculate_memsize(size, min_size, add_size,
Linus Torvaldsb42282e2011-04-11 10:53:11 -0700733 resource_size(b_res), min_align);
Ram Paic8adf9a2011-02-14 17:43:20 -0800734 if (!size0 && !size1) {
Bjorn Helgaas865df572009-11-04 10:32:57 -0700735 if (b_res->start || b_res->end)
736 dev_info(&bus->self->dev, "disabling bridge window "
737 "%pR to [bus %02x-%02x] (unused)\n", b_res,
738 bus->secondary, bus->subordinate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 b_res->flags = 0;
740 return 1;
741 }
742 b_res->start = min_align;
Ram Paic8adf9a2011-02-14 17:43:20 -0800743 b_res->end = size0 + min_align - 1;
744 b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask;
Ram Pai9e8bf932011-07-25 13:08:42 -0700745 if (size1 > size0 && realloc_head)
746 add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 return 1;
748}
749
Ram Pai0a2daa12011-07-25 13:08:41 -0700750unsigned long pci_cardbus_resource_alignment(struct resource *res)
751{
752 if (res->flags & IORESOURCE_IO)
753 return pci_cardbus_io_size;
754 if (res->flags & IORESOURCE_MEM)
755 return pci_cardbus_mem_size;
756 return 0;
757}
758
759static void pci_bus_size_cardbus(struct pci_bus *bus,
Ram Pai9e8bf932011-07-25 13:08:42 -0700760 struct resource_list_x *realloc_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761{
762 struct pci_dev *bridge = bus->self;
763 struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
764 u16 ctrl;
765
766 /*
767 * Reserve some resources for CardBus. We reserve
768 * a fixed amount of bus space for CardBus bridges.
769 */
Linus Torvalds934b7022008-04-22 18:16:30 -0700770 b_res[0].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700771 b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700772 if (realloc_head)
773 add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774
Linus Torvalds934b7022008-04-22 18:16:30 -0700775 b_res[1].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700776 b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700777 if (realloc_head)
778 add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779
780 /*
781 * Check whether prefetchable memory is supported
782 * by this bridge.
783 */
784 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
785 if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) {
786 ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
787 pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl);
788 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
789 }
790
791 /*
792 * If we have prefetchable memory support, allocate
793 * two regions. Otherwise, allocate one region of
794 * twice the size.
795 */
796 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
Linus Torvalds934b7022008-04-22 18:16:30 -0700797 b_res[2].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700798 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700799 if (realloc_head)
800 add_to_list(realloc_head, bridge, b_res+2, pci_cardbus_mem_size, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
Linus Torvalds934b7022008-04-22 18:16:30 -0700802 b_res[3].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700803 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700804 if (realloc_head)
805 add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 } else {
Linus Torvalds934b7022008-04-22 18:16:30 -0700807 b_res[3].start = 0;
Linus Torvalds934b7022008-04-22 18:16:30 -0700808 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
Ram Pai9e8bf932011-07-25 13:08:42 -0700809 if (realloc_head)
810 add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size * 2, 0 /* dont care */);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 }
Ram Pai0a2daa12011-07-25 13:08:41 -0700812
813 /* set the size of the resource to zero, so that the resource does not
814 * get assigned during required-resource allocation cycle but gets assigned
815 * during the optional-resource allocation cycle.
816 */
817 b_res[0].start = b_res[1].start = b_res[2].start = b_res[3].start = 1;
818 b_res[0].end = b_res[1].end = b_res[2].end = b_res[3].end = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819}
820
Ram Paic8adf9a2011-02-14 17:43:20 -0800821void __ref __pci_bus_size_bridges(struct pci_bus *bus,
Ram Pai9e8bf932011-07-25 13:08:42 -0700822 struct resource_list_x *realloc_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823{
824 struct pci_dev *dev;
825 unsigned long mask, prefmask;
Ram Paic8adf9a2011-02-14 17:43:20 -0800826 resource_size_t additional_mem_size = 0, additional_io_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
828 list_for_each_entry(dev, &bus->devices, bus_list) {
829 struct pci_bus *b = dev->subordinate;
830 if (!b)
831 continue;
832
833 switch (dev->class >> 8) {
834 case PCI_CLASS_BRIDGE_CARDBUS:
Ram Pai9e8bf932011-07-25 13:08:42 -0700835 pci_bus_size_cardbus(b, realloc_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 break;
837
838 case PCI_CLASS_BRIDGE_PCI:
839 default:
Ram Pai9e8bf932011-07-25 13:08:42 -0700840 __pci_bus_size_bridges(b, realloc_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 break;
842 }
843 }
844
845 /* The root bus? */
846 if (!bus->self)
847 return;
848
849 switch (bus->self->class >> 8) {
850 case PCI_CLASS_BRIDGE_CARDBUS:
851 /* don't size cardbuses yet. */
852 break;
853
854 case PCI_CLASS_BRIDGE_PCI:
855 pci_bridge_check_ranges(bus);
Eric W. Biederman28760482009-09-09 14:09:24 -0700856 if (bus->self->is_hotplug_bridge) {
Ram Paic8adf9a2011-02-14 17:43:20 -0800857 additional_io_size = pci_hotplug_io_size;
858 additional_mem_size = pci_hotplug_mem_size;
Eric W. Biederman28760482009-09-09 14:09:24 -0700859 }
Ram Paic8adf9a2011-02-14 17:43:20 -0800860 /*
861 * Follow thru
862 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 default:
Ram Pai9e8bf932011-07-25 13:08:42 -0700864 pbus_size_io(bus, 0, additional_io_size, realloc_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 /* If the bridge supports prefetchable range, size it
866 separately. If it doesn't, or its prefetchable window
867 has already been allocated by arch code, try
868 non-prefetchable range for both types of PCI memory
869 resources. */
870 mask = IORESOURCE_MEM;
871 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
Ram Pai9e8bf932011-07-25 13:08:42 -0700872 if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, realloc_head))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 mask = prefmask; /* Success, size non-prefetch only. */
Eric W. Biederman28760482009-09-09 14:09:24 -0700874 else
Ram Paic8adf9a2011-02-14 17:43:20 -0800875 additional_mem_size += additional_mem_size;
Ram Pai9e8bf932011-07-25 13:08:42 -0700876 pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, realloc_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 break;
878 }
879}
Ram Paic8adf9a2011-02-14 17:43:20 -0800880
881void __ref pci_bus_size_bridges(struct pci_bus *bus)
882{
883 __pci_bus_size_bridges(bus, NULL);
884}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885EXPORT_SYMBOL(pci_bus_size_bridges);
886
Yinghai Lu568ddef2010-01-22 01:02:21 -0800887static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
Ram Pai9e8bf932011-07-25 13:08:42 -0700888 struct resource_list_x *realloc_head,
Yinghai Lu568ddef2010-01-22 01:02:21 -0800889 struct resource_list_x *fail_head)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890{
891 struct pci_bus *b;
892 struct pci_dev *dev;
893
Ram Pai9e8bf932011-07-25 13:08:42 -0700894 pbus_assign_resources_sorted(bus, realloc_head, fail_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 list_for_each_entry(dev, &bus->devices, bus_list) {
897 b = dev->subordinate;
898 if (!b)
899 continue;
900
Ram Pai9e8bf932011-07-25 13:08:42 -0700901 __pci_bus_assign_resources(b, realloc_head, fail_head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902
903 switch (dev->class >> 8) {
904 case PCI_CLASS_BRIDGE_PCI:
Yinghai Lu6841ec62010-01-22 01:02:25 -0800905 if (!pci_is_enabled(dev))
906 pci_setup_bridge(b);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 break;
908
909 case PCI_CLASS_BRIDGE_CARDBUS:
910 pci_setup_cardbus(b);
911 break;
912
913 default:
Bjorn Helgaas80ccba12008-06-13 10:52:11 -0600914 dev_info(&dev->dev, "not setting up bridge for bus "
915 "%04x:%02x\n", pci_domain_nr(b), b->number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 break;
917 }
918 }
919}
Yinghai Lu568ddef2010-01-22 01:02:21 -0800920
921void __ref pci_bus_assign_resources(const struct pci_bus *bus)
922{
Ram Paic8adf9a2011-02-14 17:43:20 -0800923 __pci_bus_assign_resources(bus, NULL, NULL);
Yinghai Lu568ddef2010-01-22 01:02:21 -0800924}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925EXPORT_SYMBOL(pci_bus_assign_resources);
926
Yinghai Lu6841ec62010-01-22 01:02:25 -0800927static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
928 struct resource_list_x *fail_head)
929{
930 struct pci_bus *b;
931
932 pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head);
933
934 b = bridge->subordinate;
935 if (!b)
936 return;
937
Ram Paic8adf9a2011-02-14 17:43:20 -0800938 __pci_bus_assign_resources(b, NULL, fail_head);
Yinghai Lu6841ec62010-01-22 01:02:25 -0800939
940 switch (bridge->class >> 8) {
941 case PCI_CLASS_BRIDGE_PCI:
942 pci_setup_bridge(b);
943 break;
944
945 case PCI_CLASS_BRIDGE_CARDBUS:
946 pci_setup_cardbus(b);
947 break;
948
949 default:
950 dev_info(&bridge->dev, "not setting up bridge for bus "
951 "%04x:%02x\n", pci_domain_nr(b), b->number);
952 break;
953 }
954}
Yinghai Lu5009b462010-01-22 01:02:20 -0800955static void pci_bridge_release_resources(struct pci_bus *bus,
956 unsigned long type)
957{
958 int idx;
959 bool changed = false;
960 struct pci_dev *dev;
961 struct resource *r;
962 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
963 IORESOURCE_PREFETCH;
964
965 dev = bus->self;
966 for (idx = PCI_BRIDGE_RESOURCES; idx <= PCI_BRIDGE_RESOURCE_END;
967 idx++) {
968 r = &dev->resource[idx];
969 if ((r->flags & type_mask) != type)
970 continue;
971 if (!r->parent)
972 continue;
973 /*
974 * if there are children under that, we should release them
975 * all
976 */
977 release_child_resources(r);
978 if (!release_resource(r)) {
979 dev_printk(KERN_DEBUG, &dev->dev,
980 "resource %d %pR released\n", idx, r);
981 /* keep the old size */
982 r->end = resource_size(r) - 1;
983 r->start = 0;
984 r->flags = 0;
985 changed = true;
986 }
987 }
988
989 if (changed) {
990 /* avoiding touch the one without PREF */
991 if (type & IORESOURCE_PREFETCH)
992 type = IORESOURCE_PREFETCH;
993 __pci_setup_bridge(bus, type);
994 }
995}
996
997enum release_type {
998 leaf_only,
999 whole_subtree,
1000};
1001/*
1002 * try to release pci bridge resources that is from leaf bridge,
1003 * so we can allocate big new one later
1004 */
1005static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus,
1006 unsigned long type,
1007 enum release_type rel_type)
1008{
1009 struct pci_dev *dev;
1010 bool is_leaf_bridge = true;
1011
1012 list_for_each_entry(dev, &bus->devices, bus_list) {
1013 struct pci_bus *b = dev->subordinate;
1014 if (!b)
1015 continue;
1016
1017 is_leaf_bridge = false;
1018
1019 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
1020 continue;
1021
1022 if (rel_type == whole_subtree)
1023 pci_bus_release_bridge_resources(b, type,
1024 whole_subtree);
1025 }
1026
1027 if (pci_is_root_bus(bus))
1028 return;
1029
1030 if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI)
1031 return;
1032
1033 if ((rel_type == whole_subtree) || is_leaf_bridge)
1034 pci_bridge_release_resources(bus, type);
1035}
1036
Yinghai Lu76fbc262008-06-23 20:33:06 +02001037static void pci_bus_dump_res(struct pci_bus *bus)
1038{
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -07001039 struct resource *res;
1040 int i;
Yinghai Lu76fbc262008-06-23 20:33:06 +02001041
Bjorn Helgaas89a74ec2010-02-23 10:24:31 -07001042 pci_bus_for_each_resource(bus, res, i) {
Yinghai Lu7c9342b2009-12-22 15:02:24 -08001043 if (!res || !res->end || !res->flags)
Yinghai Lu76fbc262008-06-23 20:33:06 +02001044 continue;
1045
Bjorn Helgaasc7dabef2009-10-27 13:26:47 -06001046 dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res);
Yinghai Lu76fbc262008-06-23 20:33:06 +02001047 }
1048}
1049
1050static void pci_bus_dump_resources(struct pci_bus *bus)
1051{
1052 struct pci_bus *b;
1053 struct pci_dev *dev;
1054
1055
1056 pci_bus_dump_res(bus);
1057
1058 list_for_each_entry(dev, &bus->devices, bus_list) {
1059 b = dev->subordinate;
1060 if (!b)
1061 continue;
1062
1063 pci_bus_dump_resources(b);
1064 }
1065}
1066
Yinghai Luda7822e2011-05-12 17:11:37 -07001067static int __init pci_bus_get_depth(struct pci_bus *bus)
1068{
1069 int depth = 0;
1070 struct pci_dev *dev;
1071
1072 list_for_each_entry(dev, &bus->devices, bus_list) {
1073 int ret;
1074 struct pci_bus *b = dev->subordinate;
1075 if (!b)
1076 continue;
1077
1078 ret = pci_bus_get_depth(b);
1079 if (ret + 1 > depth)
1080 depth = ret + 1;
1081 }
1082
1083 return depth;
1084}
1085static int __init pci_get_max_depth(void)
1086{
1087 int depth = 0;
1088 struct pci_bus *bus;
1089
1090 list_for_each_entry(bus, &pci_root_buses, node) {
1091 int ret;
1092
1093 ret = pci_bus_get_depth(bus);
1094 if (ret > depth)
1095 depth = ret;
1096 }
1097
1098 return depth;
1099}
1100
Ram Paif483d392011-07-07 11:19:10 -07001101
Yinghai Luda7822e2011-05-12 17:11:37 -07001102/*
1103 * first try will not touch pci bridge res
1104 * second and later try will clear small leaf bridge res
1105 * will stop till to the max deepth if can not find good one
1106 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107void __init
1108pci_assign_unassigned_resources(void)
1109{
1110 struct pci_bus *bus;
Ram Pai9e8bf932011-07-25 13:08:42 -07001111 struct resource_list_x realloc_list; /* list of resources that
Ram Paic8adf9a2011-02-14 17:43:20 -08001112 want additional resources */
Yinghai Luda7822e2011-05-12 17:11:37 -07001113 int tried_times = 0;
1114 enum release_type rel_type = leaf_only;
1115 struct resource_list_x head, *list;
1116 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1117 IORESOURCE_PREFETCH;
1118 unsigned long failed_type;
1119 int max_depth = pci_get_max_depth();
1120 int pci_try_num;
1121
1122
1123 head.next = NULL;
Ram Pai9e8bf932011-07-25 13:08:42 -07001124 realloc_list.next = NULL;
Yinghai Luda7822e2011-05-12 17:11:37 -07001125
1126 pci_try_num = max_depth + 1;
1127 printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
1128 max_depth, pci_try_num);
1129
1130again:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 /* Depth first, calculate sizes and alignments of all
1132 subordinate buses. */
Yinghai Luda7822e2011-05-12 17:11:37 -07001133 list_for_each_entry(bus, &pci_root_buses, node)
Ram Pai9e8bf932011-07-25 13:08:42 -07001134 __pci_bus_size_bridges(bus, &realloc_list);
Ram Paic8adf9a2011-02-14 17:43:20 -08001135
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 /* Depth last, allocate resources and update the hardware. */
Yinghai Luda7822e2011-05-12 17:11:37 -07001137 list_for_each_entry(bus, &pci_root_buses, node)
Ram Pai9e8bf932011-07-25 13:08:42 -07001138 __pci_bus_assign_resources(bus, &realloc_list, &head);
1139 BUG_ON(realloc_list.next);
Yinghai Luda7822e2011-05-12 17:11:37 -07001140 tried_times++;
1141
1142 /* any device complain? */
1143 if (!head.next)
1144 goto enable_and_dump;
Ram Paif483d392011-07-07 11:19:10 -07001145
1146 /* don't realloc if asked to do so */
1147 if (!pci_realloc_enabled()) {
1148 free_list(resource_list_x, &head);
1149 goto enable_and_dump;
1150 }
1151
Yinghai Luda7822e2011-05-12 17:11:37 -07001152 failed_type = 0;
1153 for (list = head.next; list;) {
1154 failed_type |= list->flags;
1155 list = list->next;
1156 }
1157 /*
1158 * io port are tight, don't try extra
1159 * or if reach the limit, don't want to try more
1160 */
1161 failed_type &= type_mask;
1162 if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
1163 free_list(resource_list_x, &head);
1164 goto enable_and_dump;
1165 }
1166
1167 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
1168 tried_times + 1);
1169
1170 /* third times and later will not check if it is leaf */
1171 if ((tried_times + 1) > 2)
1172 rel_type = whole_subtree;
1173
1174 /*
1175 * Try to release leaf bridge's resources that doesn't fit resource of
1176 * child device under that bridge
1177 */
1178 for (list = head.next; list;) {
1179 bus = list->dev->bus;
1180 pci_bus_release_bridge_resources(bus, list->flags & type_mask,
1181 rel_type);
1182 list = list->next;
1183 }
1184 /* restore size and flags */
1185 for (list = head.next; list;) {
1186 struct resource *res = list->res;
1187
1188 res->start = list->start;
1189 res->end = list->end;
1190 res->flags = list->flags;
1191 if (list->dev->subordinate)
1192 res->flags = 0;
1193
1194 list = list->next;
1195 }
1196 free_list(resource_list_x, &head);
1197
1198 goto again;
1199
1200enable_and_dump:
1201 /* Depth last, update the hardware. */
1202 list_for_each_entry(bus, &pci_root_buses, node)
1203 pci_enable_bridges(bus);
Yinghai Lu76fbc262008-06-23 20:33:06 +02001204
1205 /* dump the resource on buses */
Yinghai Luda7822e2011-05-12 17:11:37 -07001206 list_for_each_entry(bus, &pci_root_buses, node)
Yinghai Lu76fbc262008-06-23 20:33:06 +02001207 pci_bus_dump_resources(bus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208}
Yinghai Lu6841ec62010-01-22 01:02:25 -08001209
1210void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
1211{
1212 struct pci_bus *parent = bridge->subordinate;
Yinghai Lu32180e42010-01-22 01:02:27 -08001213 int tried_times = 0;
1214 struct resource_list_x head, *list;
Yinghai Lu6841ec62010-01-22 01:02:25 -08001215 int retval;
Yinghai Lu32180e42010-01-22 01:02:27 -08001216 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
1217 IORESOURCE_PREFETCH;
Yinghai Lu6841ec62010-01-22 01:02:25 -08001218
Yinghai Lu32180e42010-01-22 01:02:27 -08001219 head.next = NULL;
1220
1221again:
Yinghai Lu6841ec62010-01-22 01:02:25 -08001222 pci_bus_size_bridges(parent);
Yinghai Lu32180e42010-01-22 01:02:27 -08001223 __pci_bridge_assign_resources(bridge, &head);
Yinghai Lu32180e42010-01-22 01:02:27 -08001224
1225 tried_times++;
1226
1227 if (!head.next)
Yinghai Lu3f579c32010-05-21 14:35:06 -07001228 goto enable_all;
Yinghai Lu32180e42010-01-22 01:02:27 -08001229
1230 if (tried_times >= 2) {
1231 /* still fail, don't need to try more */
Ram Pai094732a2011-02-14 17:43:18 -08001232 free_list(resource_list_x, &head);
Yinghai Lu3f579c32010-05-21 14:35:06 -07001233 goto enable_all;
Yinghai Lu32180e42010-01-22 01:02:27 -08001234 }
1235
1236 printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
1237 tried_times + 1);
1238
1239 /*
1240 * Try to release leaf bridge's resources that doesn't fit resource of
1241 * child device under that bridge
1242 */
1243 for (list = head.next; list;) {
1244 struct pci_bus *bus = list->dev->bus;
1245 unsigned long flags = list->flags;
1246
1247 pci_bus_release_bridge_resources(bus, flags & type_mask,
1248 whole_subtree);
1249 list = list->next;
1250 }
1251 /* restore size and flags */
1252 for (list = head.next; list;) {
1253 struct resource *res = list->res;
1254
1255 res->start = list->start;
1256 res->end = list->end;
1257 res->flags = list->flags;
1258 if (list->dev->subordinate)
1259 res->flags = 0;
1260
1261 list = list->next;
1262 }
Ram Pai094732a2011-02-14 17:43:18 -08001263 free_list(resource_list_x, &head);
Yinghai Lu32180e42010-01-22 01:02:27 -08001264
1265 goto again;
Yinghai Lu3f579c32010-05-21 14:35:06 -07001266
1267enable_all:
1268 retval = pci_reenable_device(bridge);
1269 pci_set_master(bridge);
1270 pci_enable_bridges(parent);
Yinghai Lu6841ec62010-01-22 01:02:25 -08001271}
1272EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);