aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/pci.h
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2010-02-23 12:24:36 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2010-02-23 12:43:37 -0500
commit2fe2abf896c1e7a0ee65faaf3ef0ce654848abbd (patch)
treef066d5c94bbed5ca3556b4d2f0c4b3a9795b6eff /include/linux/pci.h
parent89a74ecccd1f78e51faf6287e5c0e93a92ac096e (diff)
PCI: augment bus resource table with a list
Previously we used a table of size PCI_BUS_NUM_RESOURCES (16) for resources forwarded to a bus by its upstream bridge. We've increased this size several times when the table overflowed. But there's no good limit on the number of resources because host bridges and subtractive decode bridges can forward any number of ranges to their secondary buses. This patch reduces the table to only PCI_BRIDGE_RESOURCE_NUM (4) entries, which corresponds to the number of windows a PCI-to-PCI (3) or CardBus (4) bridge can positively decode. Any additional resources, e.g., PCI host bridge windows or subtractively-decoded regions, are kept in a list. I'd prefer a single list rather than this split table/list approach, but that requires simultaneous changes to every architecture. This approach only requires immediate changes where we set up (a) host bridges with more than four windows and (b) subtractive-decode P2P bridges, and we can incrementally change other architectures to use the list. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'include/linux/pci.h')
-rw-r--r--include/linux/pci.h35
1 files changed, 29 insertions, 6 deletions
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2ff9d26a078..e19a69613d8 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -364,9 +364,26 @@ static inline void pci_add_saved_cap(struct pci_dev *pci_dev,
364 hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); 364 hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
365} 365}
366 366
367#ifndef PCI_BUS_NUM_RESOURCES 367/*
368#define PCI_BUS_NUM_RESOURCES 16 368 * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
369#endif 369 * to P2P or CardBus bridge windows) go in a table. Additional ones (for
370 * buses below host bridges or subtractive decode bridges) go in the list.
371 * Use pci_bus_for_each_resource() to iterate through all the resources.
372 */
373
374/*
375 * PCI_SUBTRACTIVE_DECODE means the bridge forwards the window implicitly
376 * and there's no way to program the bridge with the details of the window.
377 * This does not apply to ACPI _CRS windows, even with the _DEC subtractive-
378 * decode bit set, because they are explicit and can be programmed with _SRS.
379 */
380#define PCI_SUBTRACTIVE_DECODE 0x1
381
382struct pci_bus_resource {
383 struct list_head list;
384 struct resource *res;
385 unsigned int flags;
386};
370 387
371#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */ 388#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
372 389
@@ -377,8 +394,8 @@ struct pci_bus {
377 struct list_head devices; /* list of devices on this bus */ 394 struct list_head devices; /* list of devices on this bus */
378 struct pci_dev *self; /* bridge device as seen by parent */ 395 struct pci_dev *self; /* bridge device as seen by parent */
379 struct list_head slots; /* list of slots on this bus */ 396 struct list_head slots; /* list of slots on this bus */
380 struct resource *resource[PCI_BUS_NUM_RESOURCES]; 397 struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];
381 /* address space routed to this bus */ 398 struct list_head resources; /* address space routed to this bus */
382 399
383 struct pci_ops *ops; /* configuration access functions */ 400 struct pci_ops *ops; /* configuration access functions */
384 void *sysdata; /* hook for sys-specific extension */ 401 void *sysdata; /* hook for sys-specific extension */
@@ -829,8 +846,14 @@ int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *);
829void pci_release_selected_regions(struct pci_dev *, int); 846void pci_release_selected_regions(struct pci_dev *, int);
830 847
831/* drivers/pci/bus.c */ 848/* drivers/pci/bus.c */
849void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags);
850struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n);
851void pci_bus_remove_resources(struct pci_bus *bus);
852
832#define pci_bus_for_each_resource(bus, res, i) \ 853#define pci_bus_for_each_resource(bus, res, i) \
833 for (i = 0; res = bus->resource[i], i < PCI_BUS_NUM_RESOURCES; i++) 854 for (i = 0; \
855 (res = pci_bus_resource_n(bus, i)) || i < PCI_BRIDGE_RESOURCE_NUM; \
856 i++)
834 857
835int __must_check pci_bus_alloc_resource(struct pci_bus *bus, 858int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
836 struct resource *res, resource_size_t size, 859 struct resource *res, resource_size_t size,