diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2012-02-24 17:25:33 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2012-02-24 17:25:33 -0500 |
commit | ecd58d667a6ac4350d2f67b9accaadf575bae4b0 (patch) | |
tree | 5209771a0a1f61820171e444d3e4a580ecf3955f /drivers/pci | |
parent | b07f2ebc109b607789f648dedcff4b125f9afec6 (diff) | |
parent | fb127cb9de791d62fb393d6e65fa9869bddd2460 (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.c | 30 | ||||
-rw-r--r-- | drivers/pci/probe.c | 208 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 3 |
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 | ||
21 | void pci_add_resource(struct list_head *resources, struct resource *res) | 21 | void 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 | } | ||
36 | EXPORT_SYMBOL(pci_add_resource_offset); | ||
37 | |||
38 | void pci_add_resource(struct list_head *resources, struct resource *res) | ||
39 | { | ||
40 | pci_add_resource_offset(resources, res, 0); | ||
33 | } | 41 | } |
34 | EXPORT_SYMBOL(pci_add_resource); | 42 | EXPORT_SYMBOL(pci_add_resource); |
35 | 43 | ||
36 | void pci_free_resource_list(struct list_head *resources) | 44 | void 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 | } |
45 | EXPORT_SYMBOL(pci_free_resource_list); | 53 | EXPORT_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 | ||
18 | static LIST_HEAD(pci_host_bridges); | ||
19 | |||
18 | /* Ugh. Need to stop exporting this to modules. */ | 20 | /* Ugh. Need to stop exporting this to modules. */ |
19 | LIST_HEAD(pci_root_buses); | 21 | LIST_HEAD(pci_root_buses); |
20 | EXPORT_SYMBOL(pci_root_buses); | 22 | EXPORT_SYMBOL(pci_root_buses); |
@@ -42,6 +44,82 @@ int no_pci_devices(void) | |||
42 | } | 44 | } |
43 | EXPORT_SYMBOL(no_pci_devices); | 45 | EXPORT_SYMBOL(no_pci_devices); |
44 | 46 | ||
47 | static 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 | |||
64 | static bool resource_contains(struct resource *res1, struct resource *res2) | ||
65 | { | ||
66 | return res1->start <= res2->start && res1->end >= res2->end; | ||
67 | } | ||
68 | |||
69 | void 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 | } | ||
89 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
90 | |||
91 | static 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 | |||
97 | void 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 | } | ||
121 | EXPORT_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, ®ion); | ||
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, ®ion); | ||
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, ®ion); | ||
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, ®ion); | ||
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, ®ion); | ||
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, ®ion); | ||
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, ®ion); |
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, ®ion); | ||
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, ®ion); |
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, ®ion); | ||
978 | } | 1078 | } |
979 | } | 1079 | } |
980 | break; | 1080 | break; |
@@ -1543,21 +1643,27 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1543 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 1643 | struct 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 | ||
1617 | class_dev_reg_err: | 1737 | class_dev_reg_err: |
1618 | device_unregister(dev); | 1738 | device_unregister(dev); |
1619 | dev_reg_err: | 1739 | dev_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); |
1623 | err_out: | 1744 | err_out: |
1624 | kfree(dev); | 1745 | kfree(dev); |
1746 | err_dev: | ||
1625 | kfree(b); | 1747 | kfree(b); |
1748 | err_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 | ||
31 | unsigned int pci_flags; | ||
32 | |||
30 | struct pci_dev_resource { | 33 | struct pci_dev_resource { |
31 | struct list_head list; | 34 | struct list_head list; |
32 | struct resource *res; | 35 | struct resource *res; |