Skip to content

Commit b97ea28

Browse files
YijingWangbjorn-helgaas
authored andcommitted
PCI: Assign resources before drivers claim devices (pci_scan_root_bus())
Previously, pci_scan_root_bus() created a root PCI bus, enumerated the devices on it, and called pci_bus_add_devices(), which made the devices available for drivers to claim them. Most callers assigned resources to devices after pci_scan_root_bus() returns, which may be after drivers have claimed the devices. This is incorrect; the PCI core should not change device resources while a driver is managing the device. Remove pci_bus_add_devices() from pci_scan_root_bus() and do it after any resource assignment in the callers. Note that ARM's pci_common_init_dev() already called pci_bus_add_devices() after pci_scan_root_bus(), so we only need to remove the first call: pci_common_init_dev pcibios_init_hw pci_scan_root_bus pci_bus_add_devices # first call pci_bus_assign_resources pci_bus_add_devices # second call [bhelgaas: changelog, drop "root_bus" var in alpha common_init_pci(), return failure earlier in mn10300, add "return" in x86 pcibios_scan_root(), return early if xtensa platform_pcibios_fixup() fails] Signed-off-by: Yijing Wang <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> CC: Richard Henderson <[email protected]> CC: Ivan Kokshaysky <[email protected]> CC: Matt Turner <[email protected]> CC: David Howells <[email protected]> CC: Tony Luck <[email protected]> CC: Michal Simek <[email protected]> CC: Ralf Baechle <[email protected]> CC: Koichi Yasutake <[email protected]> CC: Sebastian Ott <[email protected]> CC: "David S. Miller" <[email protected]> CC: Chris Metcalf <[email protected]> CC: Chris Zankel <[email protected]> CC: Max Filippov <[email protected]> CC: Thomas Gleixner <[email protected]>
1 parent c90570d commit b97ea28

File tree

15 files changed

+47
-6
lines changed

15 files changed

+47
-6
lines changed

arch/alpha/kernel/pci.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ common_init_pci(void)
338338

339339
bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops,
340340
hose, &resources);
341+
if (!bus)
342+
continue;
341343
hose->bus = bus;
342344
hose->need_domain_info = need_domain_info;
343345
next_busno = bus->busn_res.end + 1;
@@ -353,6 +355,11 @@ common_init_pci(void)
353355

354356
pci_assign_unassigned_resources();
355357
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
358+
for (hose = hose_head; hose; hose = hose->next) {
359+
bus = hose->bus;
360+
if (bus)
361+
pci_bus_add_devices(bus);
362+
}
356363
}
357364

358365

arch/frv/mb93090-mb00/pci-vdk.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ void pcibios_fixup_bus(struct pci_bus *bus)
316316

317317
int __init pcibios_init(void)
318318
{
319+
struct pci_bus *bus;
319320
struct pci_ops *dir = NULL;
320321
LIST_HEAD(resources);
321322

@@ -383,12 +384,15 @@ int __init pcibios_init(void)
383384
printk("PCI: Probing PCI hardware\n");
384385
pci_add_resource(&resources, &pci_ioport_resource);
385386
pci_add_resource(&resources, &pci_iomem_resource);
386-
pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, &resources);
387+
bus = pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, &resources);
387388

388389
pcibios_irq_init();
389390
pcibios_fixup_irqs();
390391
pcibios_resource_survey();
392+
if (!bus)
393+
return 0;
391394

395+
pci_bus_add_devices(bus);
392396
return 0;
393397
}
394398

arch/ia64/sn/kernel/io_init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,9 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
271271
if (bus == NULL) {
272272
kfree(res);
273273
kfree(controller);
274+
return;
274275
}
276+
pci_bus_add_devices(bus);
275277
}
276278

277279
/*

arch/microblaze/pci/pci-common.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,10 @@ static int __init pcibios_init(void)
13821382

13831383
/* Call common code to handle resource allocation */
13841384
pcibios_resource_survey();
1385+
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1386+
if (hose->bus)
1387+
pci_bus_add_devices(hose->bus);
1388+
}
13851389

13861390
return 0;
13871391
}

arch/mips/pci/pci.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static void pcibios_scanbus(struct pci_controller *hose)
114114
pci_bus_size_bridges(bus);
115115
pci_bus_assign_resources(bus);
116116
}
117+
pci_bus_add_devices(bus);
117118
}
118119
}
119120

arch/mn10300/unit-asb2305/pci.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ static int __init pcibios_init(void)
342342
{
343343
resource_size_t io_offset, mem_offset;
344344
LIST_HEAD(resources);
345+
struct pci_bus *bus;
345346

346347
ioport_resource.start = 0xA0000000;
347348
ioport_resource.end = 0xDFFFFFFF;
@@ -371,11 +372,14 @@ static int __init pcibios_init(void)
371372

372373
pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset);
373374
pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset);
374-
pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, &resources);
375+
bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, &resources);
376+
if (!bus)
377+
return 0;
375378

376379
pcibios_irq_init();
377380
pcibios_fixup_irqs();
378381
pcibios_resource_survey();
382+
pci_bus_add_devices(bus);
379383
return 0;
380384
}
381385

arch/s390/pci/pci.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,8 +776,8 @@ static int zpci_scan_bus(struct zpci_dev *zdev)
776776
zpci_cleanup_bus_resources(zdev);
777777
return -EIO;
778778
}
779-
780779
zdev->bus->max_bus_speed = zdev->max_bus_speed;
780+
pci_bus_add_devices(zdev->bus);
781781
return 0;
782782
}
783783

arch/sh/drivers/pci/pci.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static void pcibios_scanbus(struct pci_channel *hose)
6969

7070
pci_bus_size_bridges(bus);
7171
pci_bus_assign_resources(bus);
72+
pci_bus_add_devices(bus);
7273
} else {
7374
pci_free_resource_list(&resources);
7475
}

arch/sparc/kernel/leon_pci.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
4040

4141
/* Assign devices with resources */
4242
pci_assign_unassigned_resources();
43+
pci_bus_add_devices(root_bus);
4344
} else {
4445
pci_free_resource_list(&resources);
4546
}

arch/tile/kernel/pci.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ int __init pcibios_init(void)
339339
struct pci_bus *next_bus;
340340
struct pci_dev *dev;
341341

342+
pci_bus_add_devices(root_bus);
343+
342344
list_for_each_entry(dev, &root_bus->devices, bus_list) {
343345
/*
344346
* Find the PCI host controller, ie. the 1st

arch/tile/kernel/pci_gx.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,8 @@ int __init pcibios_init(void)
10301030
alloc_mem_map_failed:
10311031
break;
10321032
}
1033+
1034+
pci_bus_add_devices(root_bus);
10331035
}
10341036

10351037
return 0;

arch/x86/pci/common.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,9 @@ void pcibios_scan_root(int busnum)
490490
if (!bus) {
491491
pci_free_resource_list(&resources);
492492
kfree(sd);
493+
return;
493494
}
495+
pci_bus_add_devices(bus);
494496
}
495497

496498
void __init pcibios_set_cache_line_size(void)

arch/xtensa/kernel/pci.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static int __init pcibios_init(void)
174174
struct pci_controller *pci_ctrl;
175175
struct list_head resources;
176176
struct pci_bus *bus;
177-
int next_busno = 0;
177+
int next_busno = 0, ret;
178178

179179
printk("PCI: Probing PCI hardware\n");
180180

@@ -185,14 +185,25 @@ static int __init pcibios_init(void)
185185
pci_controller_apertures(pci_ctrl, &resources);
186186
bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno,
187187
pci_ctrl->ops, pci_ctrl, &resources);
188+
if (!bus)
189+
continue;
190+
188191
pci_ctrl->bus = bus;
189192
pci_ctrl->last_busno = bus->busn_res.end;
190193
if (next_busno <= pci_ctrl->last_busno)
191194
next_busno = pci_ctrl->last_busno+1;
192195
}
193196
pci_bus_count = next_busno;
197+
ret = platform_pcibios_fixup();
198+
if (ret)
199+
return ret;
194200

195-
return platform_pcibios_fixup();
201+
for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) {
202+
if (pci_ctrl->bus)
203+
pci_bus_add_devices(pci_ctrl->bus);
204+
}
205+
206+
return 0;
196207
}
197208

198209
subsys_initcall(pcibios_init);

drivers/pci/host/pci-versatile.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ static int versatile_pci_probe(struct platform_device *pdev)
214214

215215
pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
216216
pci_assign_unassigned_bus_resources(bus);
217+
pci_bus_add_devices(bus);
217218

218219
return 0;
219220
}

drivers/pci/probe.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2087,7 +2087,6 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
20872087
if (!found)
20882088
pci_bus_update_busn_res_end(b, max);
20892089

2090-
pci_bus_add_devices(b);
20912090
return b;
20922091
}
20932092
EXPORT_SYMBOL(pci_scan_root_bus);

0 commit comments

Comments
 (0)