aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2012-02-24 17:25:33 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2012-02-24 17:25:33 -0500
commitecd58d667a6ac4350d2f67b9accaadf575bae4b0 (patch)
tree5209771a0a1f61820171e444d3e4a580ecf3955f /drivers/pci
parentb07f2ebc109b607789f648dedcff4b125f9afec6 (diff)
parentfb127cb9de791d62fb393d6e65fa9869bddd2460 (diff)
Merge branch 'pci-next+probe_only+bus2res-fb127cb' of git://github.com/bjorn-helgaas/linux into linux-next
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/bus.c30
-rw-r--r--drivers/pci/probe.c208
-rw-r--r--drivers/pci/setup-bus.c3
3 files changed, 188 insertions, 53 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 398f5d859791..4ce5ef2f2826 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -18,28 +18,36 @@
18 18
19#include "pci.h" 19#include "pci.h"
20 20
21void pci_add_resource(struct list_head *resources, struct resource *res) 21void pci_add_resource_offset(struct list_head *resources, struct resource *res,
22 resource_size_t offset)
22{ 23{
23 struct pci_bus_resource *bus_res; 24 struct pci_host_bridge_window *window;
24 25
25 bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL); 26 window = kzalloc(sizeof(struct pci_host_bridge_window), GFP_KERNEL);
26 if (!bus_res) { 27 if (!window) {
27 printk(KERN_ERR "PCI: can't add bus resource %pR\n", res); 28 printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res);
28 return; 29 return;
29 } 30 }
30 31
31 bus_res->res = res; 32 window->res = res;
32 list_add_tail(&bus_res->list, resources); 33 window->offset = offset;
34 list_add_tail(&window->list, resources);
35}
36EXPORT_SYMBOL(pci_add_resource_offset);
37
38void pci_add_resource(struct list_head *resources, struct resource *res)
39{
40 pci_add_resource_offset(resources, res, 0);
33} 41}
34EXPORT_SYMBOL(pci_add_resource); 42EXPORT_SYMBOL(pci_add_resource);
35 43
36void pci_free_resource_list(struct list_head *resources) 44void pci_free_resource_list(struct list_head *resources)
37{ 45{
38 struct pci_bus_resource *bus_res, *tmp; 46 struct pci_host_bridge_window *window, *tmp;
39 47
40 list_for_each_entry_safe(bus_res, tmp, resources, list) { 48 list_for_each_entry_safe(window, tmp, resources, list) {
41 list_del(&bus_res->list); 49 list_del(&window->list);
42 kfree(bus_res); 50 kfree(window);
43 } 51 }
44} 52}
45EXPORT_SYMBOL(pci_free_resource_list); 53EXPORT_SYMBOL(pci_free_resource_list);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dc904bd4b569..36c22032ea14 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,8 @@
15#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ 15#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
16#define CARDBUS_RESERVE_BUSNR 3 16#define CARDBUS_RESERVE_BUSNR 3
17 17
18static LIST_HEAD(pci_host_bridges);
19
18/* Ugh. Need to stop exporting this to modules. */ 20/* Ugh. Need to stop exporting this to modules. */
19LIST_HEAD(pci_root_buses); 21LIST_HEAD(pci_root_buses);
20EXPORT_SYMBOL(pci_root_buses); 22EXPORT_SYMBOL(pci_root_buses);
@@ -42,6 +44,82 @@ int no_pci_devices(void)
42} 44}
43EXPORT_SYMBOL(no_pci_devices); 45EXPORT_SYMBOL(no_pci_devices);
44 46
47static struct pci_host_bridge *pci_host_bridge(struct pci_dev *dev)
48{
49 struct pci_bus *bus;
50 struct pci_host_bridge *bridge;
51
52 bus = dev->bus;
53 while (bus->parent)
54 bus = bus->parent;
55
56 list_for_each_entry(bridge, &pci_host_bridges, list) {
57 if (bridge->bus == bus)
58 return bridge;
59 }
60
61 return NULL;
62}
63
64static bool resource_contains(struct resource *res1, struct resource *res2)
65{
66 return res1->start <= res2->start && res1->end >= res2->end;
67}
68
69void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
70 struct resource *res)
71{
72 struct pci_host_bridge *bridge = pci_host_bridge(dev);
73 struct pci_host_bridge_window *window;
74 resource_size_t offset = 0;
75
76 list_for_each_entry(window, &bridge->windows, list) {
77 if (resource_type(res) != resource_type(window->res))
78 continue;
79
80 if (resource_contains(window->res, res)) {
81 offset = window->offset;
82 break;
83 }
84 }
85
86 region->start = res->start - offset;
87 region->end = res->end - offset;
88}
89EXPORT_SYMBOL(pcibios_resource_to_bus);
90
91static bool region_contains(struct pci_bus_region *region1,
92 struct pci_bus_region *region2)
93{
94 return region1->start <= region2->start && region1->end >= region2->end;
95}
96
97void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
98 struct pci_bus_region *region)
99{
100 struct pci_host_bridge *bridge = pci_host_bridge(dev);
101 struct pci_host_bridge_window *window;
102 struct pci_bus_region bus_region;
103 resource_size_t offset = 0;
104
105 list_for_each_entry(window, &bridge->windows, list) {
106 if (resource_type(res) != resource_type(window->res))
107 continue;
108
109 bus_region.start = window->res->start - window->offset;
110 bus_region.end = window->res->end - window->offset;
111
112 if (region_contains(&bus_region, region)) {
113 offset = window->offset;
114 break;
115 }
116 }
117
118 res->start = region->start + offset;
119 res->end = region->end + offset;
120}
121EXPORT_SYMBOL(pcibios_bus_to_resource);
122
45/* 123/*
46 * PCI Bus Class 124 * PCI Bus Class
47 */ 125 */
@@ -135,6 +213,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
135{ 213{
136 u32 l, sz, mask; 214 u32 l, sz, mask;
137 u16 orig_cmd; 215 u16 orig_cmd;
216 struct pci_bus_region region;
138 217
139 mask = type ? PCI_ROM_ADDRESS_MASK : ~0; 218 mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
140 219
@@ -214,11 +293,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
214 /* Address above 32-bit boundary; disable the BAR */ 293 /* Address above 32-bit boundary; disable the BAR */
215 pci_write_config_dword(dev, pos, 0); 294 pci_write_config_dword(dev, pos, 0);
216 pci_write_config_dword(dev, pos + 4, 0); 295 pci_write_config_dword(dev, pos + 4, 0);
217 res->start = 0; 296 region.start = 0;
218 res->end = sz64; 297 region.end = sz64;
298 pcibios_bus_to_resource(dev, res, &region);
219 } else { 299 } else {
220 res->start = l64; 300 region.start = l64;
221 res->end = l64 + sz64; 301 region.end = l64 + sz64;
302 pcibios_bus_to_resource(dev, res, &region);
222 dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", 303 dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n",
223 pos, res); 304 pos, res);
224 } 305 }
@@ -228,8 +309,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
228 if (!sz) 309 if (!sz)
229 goto fail; 310 goto fail;
230 311
231 res->start = l; 312 region.start = l;
232 res->end = l + sz; 313 region.end = l + sz;
314 pcibios_bus_to_resource(dev, res, &region);
233 315
234 dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); 316 dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);
235 } 317 }
@@ -266,7 +348,8 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
266 struct pci_dev *dev = child->self; 348 struct pci_dev *dev = child->self;
267 u8 io_base_lo, io_limit_lo; 349 u8 io_base_lo, io_limit_lo;
268 unsigned long base, limit; 350 unsigned long base, limit;
269 struct resource *res; 351 struct pci_bus_region region;
352 struct resource *res, res2;
270 353
271 res = child->resource[0]; 354 res = child->resource[0];
272 pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); 355 pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
@@ -284,10 +367,13 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
284 367
285 if (base && base <= limit) { 368 if (base && base <= limit) {
286 res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; 369 res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
370 region.start = base;
371 region.end = limit + 0xfff;
372 pcibios_bus_to_resource(dev, &res2, &region);
287 if (!res->start) 373 if (!res->start)
288 res->start = base; 374 res->start = res2.start;
289 if (!res->end) 375 if (!res->end)
290 res->end = limit + 0xfff; 376 res->end = res2.end;
291 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 377 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
292 } 378 }
293} 379}
@@ -297,6 +383,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
297 struct pci_dev *dev = child->self; 383 struct pci_dev *dev = child->self;
298 u16 mem_base_lo, mem_limit_lo; 384 u16 mem_base_lo, mem_limit_lo;
299 unsigned long base, limit; 385 unsigned long base, limit;
386 struct pci_bus_region region;
300 struct resource *res; 387 struct resource *res;
301 388
302 res = child->resource[1]; 389 res = child->resource[1];
@@ -306,8 +393,9 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
306 limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; 393 limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
307 if (base && base <= limit) { 394 if (base && base <= limit) {
308 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; 395 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
309 res->start = base; 396 region.start = base;
310 res->end = limit + 0xfffff; 397 region.end = limit + 0xfffff;
398 pcibios_bus_to_resource(dev, res, &region);
311 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 399 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
312 } 400 }
313} 401}
@@ -317,6 +405,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
317 struct pci_dev *dev = child->self; 405 struct pci_dev *dev = child->self;
318 u16 mem_base_lo, mem_limit_lo; 406 u16 mem_base_lo, mem_limit_lo;
319 unsigned long base, limit; 407 unsigned long base, limit;
408 struct pci_bus_region region;
320 struct resource *res; 409 struct resource *res;
321 410
322 res = child->resource[2]; 411 res = child->resource[2];
@@ -353,8 +442,9 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
353 IORESOURCE_MEM | IORESOURCE_PREFETCH; 442 IORESOURCE_MEM | IORESOURCE_PREFETCH;
354 if (res->flags & PCI_PREF_RANGE_TYPE_64) 443 if (res->flags & PCI_PREF_RANGE_TYPE_64)
355 res->flags |= IORESOURCE_MEM_64; 444 res->flags |= IORESOURCE_MEM_64;
356 res->start = base; 445 region.start = base;
357 res->end = limit + 0xfffff; 446 region.end = limit + 0xfffff;
447 pcibios_bus_to_resource(dev, res, &region);
358 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 448 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
359 } 449 }
360} 450}
@@ -900,6 +990,8 @@ int pci_setup_device(struct pci_dev *dev)
900 u8 hdr_type; 990 u8 hdr_type;
901 struct pci_slot *slot; 991 struct pci_slot *slot;
902 int pos = 0; 992 int pos = 0;
993 struct pci_bus_region region;
994 struct resource *res;
903 995
904 if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) 996 if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
905 return -EIO; 997 return -EIO;
@@ -961,20 +1053,28 @@ int pci_setup_device(struct pci_dev *dev)
961 u8 progif; 1053 u8 progif;
962 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); 1054 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
963 if ((progif & 1) == 0) { 1055 if ((progif & 1) == 0) {
964 dev->resource[0].start = 0x1F0; 1056 region.start = 0x1F0;
965 dev->resource[0].end = 0x1F7; 1057 region.end = 0x1F7;
966 dev->resource[0].flags = LEGACY_IO_RESOURCE; 1058 res = &dev->resource[0];
967 dev->resource[1].start = 0x3F6; 1059 res->flags = LEGACY_IO_RESOURCE;
968 dev->resource[1].end = 0x3F6; 1060 pcibios_bus_to_resource(dev, res, &region);
969 dev->resource[1].flags = LEGACY_IO_RESOURCE; 1061 region.start = 0x3F6;
1062 region.end = 0x3F6;
1063 res = &dev->resource[1];
1064 res->flags = LEGACY_IO_RESOURCE;
1065 pcibios_bus_to_resource(dev, res, &region);
970 } 1066 }
971 if ((progif & 4) == 0) { 1067 if ((progif & 4) == 0) {
972 dev->resource[2].start = 0x170; 1068 region.start = 0x170;
973 dev->resource[2].end = 0x177; 1069 region.end = 0x177;
974 dev->resource[2].flags = LEGACY_IO_RESOURCE; 1070 res = &dev->resource[2];
975 dev->resource[3].start = 0x376; 1071 res->flags = LEGACY_IO_RESOURCE;
976 dev->resource[3].end = 0x376; 1072 pcibios_bus_to_resource(dev, res, &region);
977 dev->resource[3].flags = LEGACY_IO_RESOURCE; 1073 region.start = 0x376;
1074 region.end = 0x376;
1075 res = &dev->resource[3];
1076 res->flags = LEGACY_IO_RESOURCE;
1077 pcibios_bus_to_resource(dev, res, &region);
978 } 1078 }
979 } 1079 }
980 break; 1080 break;
@@ -1543,21 +1643,27 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
1543struct pci_bus *pci_create_root_bus(struct device *parent, int bus, 1643struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1544 struct pci_ops *ops, void *sysdata, struct list_head *resources) 1644 struct pci_ops *ops, void *sysdata, struct list_head *resources)
1545{ 1645{
1546 int error, i; 1646 int error;
1647 struct pci_host_bridge *bridge;
1547 struct pci_bus *b, *b2; 1648 struct pci_bus *b, *b2;
1548 struct device *dev; 1649 struct device *dev;
1549 struct pci_bus_resource *bus_res, *n; 1650 struct pci_host_bridge_window *window, *n;
1550 struct resource *res; 1651 struct resource *res;
1652 resource_size_t offset;
1653 char bus_addr[64];
1654 char *fmt;
1655
1656 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
1657 if (!bridge)
1658 return NULL;
1551 1659
1552 b = pci_alloc_bus(); 1660 b = pci_alloc_bus();
1553 if (!b) 1661 if (!b)
1554 return NULL; 1662 goto err_bus;
1555 1663
1556 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 1664 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1557 if (!dev) { 1665 if (!dev)
1558 kfree(b); 1666 goto err_dev;
1559 return NULL;
1560 }
1561 1667
1562 b->sysdata = sysdata; 1668 b->sysdata = sysdata;
1563 b->ops = ops; 1669 b->ops = ops;
@@ -1569,10 +1675,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1569 goto err_out; 1675 goto err_out;
1570 } 1676 }
1571 1677
1572 down_write(&pci_bus_sem);
1573 list_add_tail(&b->node, &pci_root_buses);
1574 up_write(&pci_bus_sem);
1575
1576 dev->parent = parent; 1678 dev->parent = parent;
1577 dev->release = pci_release_bus_bridge_dev; 1679 dev->release = pci_release_bus_bridge_dev;
1578 dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus); 1680 dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus);
@@ -1598,31 +1700,53 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1598 1700
1599 b->number = b->secondary = bus; 1701 b->number = b->secondary = bus;
1600 1702
1601 /* Add initial resources to the bus */ 1703 bridge->bus = b;
1602 list_for_each_entry_safe(bus_res, n, resources, list) 1704 INIT_LIST_HEAD(&bridge->windows);
1603 list_move_tail(&bus_res->list, &b->resources);
1604 1705
1605 if (parent) 1706 if (parent)
1606 dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); 1707 dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
1607 else 1708 else
1608 printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); 1709 printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev));
1609 1710
1610 pci_bus_for_each_resource(b, res, i) { 1711 /* Add initial resources to the bus */
1611 if (res) 1712 list_for_each_entry_safe(window, n, resources, list) {
1612 dev_info(&b->dev, "root bus resource %pR\n", res); 1713 list_move_tail(&window->list, &bridge->windows);
1714 res = window->res;
1715 offset = window->offset;
1716 pci_bus_add_resource(b, res, 0);
1717 if (offset) {
1718 if (resource_type(res) == IORESOURCE_IO)
1719 fmt = " (bus address [%#06llx-%#06llx])";
1720 else
1721 fmt = " (bus address [%#010llx-%#010llx])";
1722 snprintf(bus_addr, sizeof(bus_addr), fmt,
1723 (unsigned long long) (res->start - offset),
1724 (unsigned long long) (res->end - offset));
1725 } else
1726 bus_addr[0] = '\0';
1727 dev_info(&b->dev, "root bus resource %pR%s\n", res, bus_addr);
1613 } 1728 }
1614 1729
1730 down_write(&pci_bus_sem);
1731 list_add_tail(&bridge->list, &pci_host_bridges);
1732 list_add_tail(&b->node, &pci_root_buses);
1733 up_write(&pci_bus_sem);
1734
1615 return b; 1735 return b;
1616 1736
1617class_dev_reg_err: 1737class_dev_reg_err:
1618 device_unregister(dev); 1738 device_unregister(dev);
1619dev_reg_err: 1739dev_reg_err:
1620 down_write(&pci_bus_sem); 1740 down_write(&pci_bus_sem);
1741 list_del(&bridge->list);
1621 list_del(&b->node); 1742 list_del(&b->node);
1622 up_write(&pci_bus_sem); 1743 up_write(&pci_bus_sem);
1623err_out: 1744err_out:
1624 kfree(dev); 1745 kfree(dev);
1746err_dev:
1625 kfree(b); 1747 kfree(b);
1748err_bus:
1749 kfree(bridge);
1626 return NULL; 1750 return NULL;
1627} 1751}
1628 1752
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index c9214a14b49b..8fa2d4be88de 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,8 +25,11 @@
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/cache.h> 26#include <linux/cache.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <asm-generic/pci-bridge.h>
28#include "pci.h" 29#include "pci.h"
29 30
31unsigned int pci_flags;
32
30struct pci_dev_resource { 33struct pci_dev_resource {
31 struct list_head list; 34 struct list_head list;
32 struct resource *res; 35 struct resource *res;