diff options
-rw-r--r-- | arch/i386/pci/common.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/legacy.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/numa.c | 2 | ||||
-rw-r--r-- | arch/ia64/pci/pci.c | 2 | ||||
-rw-r--r-- | drivers/acpi/pci_bind.c | 16 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 24 | ||||
-rw-r--r-- | drivers/parisc/dino.c | 1 | ||||
-rw-r--r-- | drivers/parisc/lba_pci.c | 2 | ||||
-rw-r--r-- | drivers/pci/probe.c | 2 | ||||
-rw-r--r-- | include/linux/pci.h | 8 |
10 files changed, 53 insertions, 8 deletions
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 2a2e79fbfef8..87325263cd4f 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -134,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) | |||
134 | 134 | ||
135 | printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); | 135 | printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); |
136 | 136 | ||
137 | return pci_scan_bus(busnum, &pci_root_ops, NULL); | 137 | return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); |
138 | } | 138 | } |
139 | 139 | ||
140 | extern u8 pci_cache_line_size; | 140 | extern u8 pci_cache_line_size; |
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 1492e3753869..149a9588c256 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c | |||
@@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) | |||
45 | 45 | ||
46 | printk("PCI: Probing PCI hardware\n"); | 46 | printk("PCI: Probing PCI hardware\n"); |
47 | pci_root_bus = pcibios_scan_root(0); | 47 | pci_root_bus = pcibios_scan_root(0); |
48 | if (pci_root_bus) | ||
49 | pci_bus_add_devices(pci_root_bus); | ||
48 | 50 | ||
49 | pcibios_fixup_peer_bridges(); | 51 | pcibios_fixup_peer_bridges(); |
50 | 52 | ||
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index 9e3695461899..adbe17a38f6f 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c | |||
@@ -115,6 +115,8 @@ static int __init pci_numa_init(void) | |||
115 | return 0; | 115 | return 0; |
116 | 116 | ||
117 | pci_root_bus = pcibios_scan_root(0); | 117 | pci_root_bus = pcibios_scan_root(0); |
118 | if (pci_root_bus) | ||
119 | pci_bus_add_devices(pci_root_bus); | ||
118 | if (num_online_nodes() > 1) | 120 | if (num_online_nodes() > 1) |
119 | for_each_online_node(quad) { | 121 | for_each_online_node(quad) { |
120 | if (quad == 0) | 122 | if (quad == 0) |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index e3fc4edea113..c0661d3382e4 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
312 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, | 312 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, |
313 | &info); | 313 | &info); |
314 | 314 | ||
315 | pbus = pci_scan_bus(bus, &pci_root_ops, controller); | 315 | pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); |
316 | if (pbus) | 316 | if (pbus) |
317 | pcibios_setup_root_windows(pbus, controller); | 317 | pcibios_setup_root_windows(pbus, controller); |
318 | 318 | ||
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 5d19b39e9e2b..7753df1f9fb8 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c | |||
@@ -129,6 +129,8 @@ acpi_pci_bind ( | |||
129 | char *pathname = NULL; | 129 | char *pathname = NULL; |
130 | struct acpi_buffer buffer = {0, NULL}; | 130 | struct acpi_buffer buffer = {0, NULL}; |
131 | acpi_handle handle = NULL; | 131 | acpi_handle handle = NULL; |
132 | struct pci_dev *dev; | ||
133 | struct pci_bus *bus; | ||
132 | 134 | ||
133 | ACPI_FUNCTION_TRACE("acpi_pci_bind"); | 135 | ACPI_FUNCTION_TRACE("acpi_pci_bind"); |
134 | 136 | ||
@@ -193,8 +195,20 @@ acpi_pci_bind ( | |||
193 | * Locate matching device in PCI namespace. If it doesn't exist | 195 | * Locate matching device in PCI namespace. If it doesn't exist |
194 | * this typically means that the device isn't currently inserted | 196 | * this typically means that the device isn't currently inserted |
195 | * (e.g. docking station, port replicator, etc.). | 197 | * (e.g. docking station, port replicator, etc.). |
198 | * We cannot simply search the global pci device list, since | ||
199 | * PCI devices are added to the global pci list when the root | ||
200 | * bridge start ops are run, which may not have happened yet. | ||
196 | */ | 201 | */ |
197 | data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function)); | 202 | bus = pci_find_bus(data->id.segment, data->id.bus); |
203 | if (bus) { | ||
204 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
205 | if (dev->devfn == PCI_DEVFN(data->id.device, | ||
206 | data->id.function)) { | ||
207 | data->dev = dev; | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | } | ||
198 | if (!data->dev) { | 212 | if (!data->dev) { |
199 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 213 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
200 | "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", | 214 | "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 7e6b8e3b2ed4..5d2f77fcd50c 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -46,6 +46,7 @@ ACPI_MODULE_NAME ("pci_root") | |||
46 | 46 | ||
47 | static int acpi_pci_root_add (struct acpi_device *device); | 47 | static int acpi_pci_root_add (struct acpi_device *device); |
48 | static int acpi_pci_root_remove (struct acpi_device *device, int type); | 48 | static int acpi_pci_root_remove (struct acpi_device *device, int type); |
49 | static int acpi_pci_root_start (struct acpi_device *device); | ||
49 | 50 | ||
50 | static struct acpi_driver acpi_pci_root_driver = { | 51 | static struct acpi_driver acpi_pci_root_driver = { |
51 | .name = ACPI_PCI_ROOT_DRIVER_NAME, | 52 | .name = ACPI_PCI_ROOT_DRIVER_NAME, |
@@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_driver = { | |||
54 | .ops = { | 55 | .ops = { |
55 | .add = acpi_pci_root_add, | 56 | .add = acpi_pci_root_add, |
56 | .remove = acpi_pci_root_remove, | 57 | .remove = acpi_pci_root_remove, |
58 | .start = acpi_pci_root_start, | ||
57 | }, | 59 | }, |
58 | }; | 60 | }; |
59 | 61 | ||
@@ -169,6 +171,7 @@ acpi_pci_root_add ( | |||
169 | if (!root) | 171 | if (!root) |
170 | return_VALUE(-ENOMEM); | 172 | return_VALUE(-ENOMEM); |
171 | memset(root, 0, sizeof(struct acpi_pci_root)); | 173 | memset(root, 0, sizeof(struct acpi_pci_root)); |
174 | INIT_LIST_HEAD(&root->node); | ||
172 | 175 | ||
173 | root->handle = device->handle; | 176 | root->handle = device->handle; |
174 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 177 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
@@ -298,12 +301,31 @@ acpi_pci_root_add ( | |||
298 | root->id.bus); | 301 | root->id.bus); |
299 | 302 | ||
300 | end: | 303 | end: |
301 | if (result) | 304 | if (result) { |
305 | if (!list_empty(&root->node)) | ||
306 | list_del(&root->node); | ||
302 | kfree(root); | 307 | kfree(root); |
308 | } | ||
303 | 309 | ||
304 | return_VALUE(result); | 310 | return_VALUE(result); |
305 | } | 311 | } |
306 | 312 | ||
313 | static int | ||
314 | acpi_pci_root_start ( | ||
315 | struct acpi_device *device) | ||
316 | { | ||
317 | struct acpi_pci_root *root; | ||
318 | |||
319 | ACPI_FUNCTION_TRACE("acpi_pci_root_start"); | ||
320 | |||
321 | list_for_each_entry(root, &acpi_pci_roots, node) { | ||
322 | if (root->handle == device->handle) { | ||
323 | pci_bus_add_devices(root->bus); | ||
324 | return_VALUE(0); | ||
325 | } | ||
326 | } | ||
327 | return_VALUE(-ENODEV); | ||
328 | } | ||
307 | 329 | ||
308 | static int | 330 | static int |
309 | acpi_pci_root_remove ( | 331 | acpi_pci_root_remove ( |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index b0d2a73d1d47..2f2dbef2c3b7 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -993,6 +993,7 @@ dino_driver_callback(struct parisc_device *dev) | |||
993 | bus = pci_scan_bus_parented(&dev->dev, dino_current_bus, | 993 | bus = pci_scan_bus_parented(&dev->dev, dino_current_bus, |
994 | &dino_cfg_ops, NULL); | 994 | &dino_cfg_ops, NULL); |
995 | if(bus) { | 995 | if(bus) { |
996 | pci_bus_add_devices(bus); | ||
996 | /* This code *depends* on scanning being single threaded | 997 | /* This code *depends* on scanning being single threaded |
997 | * if it isn't, this global bus number count will fail | 998 | * if it isn't, this global bus number count will fail |
998 | */ | 999 | */ |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index dc838804c0dd..7fdd80b7eb47 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -1570,6 +1570,8 @@ lba_driver_probe(struct parisc_device *dev) | |||
1570 | lba_bus = lba_dev->hba.hba_bus = | 1570 | lba_bus = lba_dev->hba.hba_bus = |
1571 | pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, | 1571 | pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, |
1572 | cfg_ops, NULL); | 1572 | cfg_ops, NULL); |
1573 | if (lba_bus) | ||
1574 | pci_bus_add_devices(lba_bus); | ||
1573 | 1575 | ||
1574 | /* This is in lieu of calling pci_assign_unassigned_resources() */ | 1576 | /* This is in lieu of calling pci_assign_unassigned_resources() */ |
1575 | if (is_pdc_pat()) { | 1577 | if (is_pdc_pat()) { |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index fd48b201eb53..3dc00f0ca8a0 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -911,8 +911,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, | |||
911 | 911 | ||
912 | b->subordinate = pci_scan_child_bus(b); | 912 | b->subordinate = pci_scan_child_bus(b); |
913 | 913 | ||
914 | pci_bus_add_devices(b); | ||
915 | |||
916 | return b; | 914 | return b; |
917 | 915 | ||
918 | sys_create_link_err: | 916 | sys_create_link_err: |
diff --git a/include/linux/pci.h b/include/linux/pci.h index b5238bd18830..0e9844929fe3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -734,16 +734,20 @@ void pcibios_update_irq(struct pci_dev *, int irq); | |||
734 | /* Generic PCI functions used internally */ | 734 | /* Generic PCI functions used internally */ |
735 | 735 | ||
736 | extern struct pci_bus *pci_find_bus(int domain, int busnr); | 736 | extern struct pci_bus *pci_find_bus(int domain, int busnr); |
737 | void pci_bus_add_devices(struct pci_bus *bus); | ||
737 | struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); | 738 | struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); |
738 | static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) | 739 | static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) |
739 | { | 740 | { |
740 | return pci_scan_bus_parented(NULL, bus, ops, sysdata); | 741 | struct pci_bus *root_bus; |
742 | root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata); | ||
743 | if (root_bus) | ||
744 | pci_bus_add_devices(root_bus); | ||
745 | return root_bus; | ||
741 | } | 746 | } |
742 | int pci_scan_slot(struct pci_bus *bus, int devfn); | 747 | int pci_scan_slot(struct pci_bus *bus, int devfn); |
743 | struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); | 748 | struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); |
744 | unsigned int pci_scan_child_bus(struct pci_bus *bus); | 749 | unsigned int pci_scan_child_bus(struct pci_bus *bus); |
745 | void pci_bus_add_device(struct pci_dev *dev); | 750 | void pci_bus_add_device(struct pci_dev *dev); |
746 | void pci_bus_add_devices(struct pci_bus *bus); | ||
747 | void pci_name_device(struct pci_dev *dev); | 751 | void pci_name_device(struct pci_dev *dev); |
748 | char *pci_class_name(u32 class); | 752 | char *pci_class_name(u32 class); |
749 | void pci_read_bridge_bases(struct pci_bus *child); | 753 | void pci_read_bridge_bases(struct pci_bus *child); |