* [patch 04/12] Prevent duplicate bus numbers when scanning PCI bridge
[not found] ` <20050318133856.A878-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
@ 2005-03-18 22:04 ` Rajesh Shah
2005-03-18 22:07 ` [patch 05/12] Take the PCI lock when modifying pci bus or device lists Rajesh Shah
` (6 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Rajesh Shah @ 2005-03-18 22:04 UTC (permalink / raw)
To: gregkh-l3A5Bk7waGM, tony.luck-ral2JQCrhuEAvxtiuMwx3w,
len.brown-ral2JQCrhuEAvxtiuMwx3w
Cc: linux-pci-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
pcihpd-discuss-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
When hot-plugging a root bridge, as we try to assign bus numbers
we may find that the hotplugged hieratchy has more PCI to PCI
bridges (i.e. bus requirements) than available. Make sure we
don't step over an existing bus when that happens.
Signed-off-by: Rajesh Shah <rajesh.shah-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
linux-2.6.11-mm4-iohp-rshah1/drivers/pci/probe.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff -puN drivers/pci/probe.c~prevent_duplicate_busnr drivers/pci/probe.c
--- linux-2.6.11-mm4-iohp/drivers/pci/probe.c~prevent_duplicate_busnr 2005-03-16 13:07:10.376304290 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/pci/probe.c 2005-03-16 13:07:10.496421476 -0800
@@ -417,7 +417,7 @@ int __devinit pci_scan_bridge(struct pci
{
struct pci_bus *child;
int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
- u32 buses;
+ u32 buses, i;
u16 bctl;
pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
@@ -476,6 +476,10 @@ int __devinit pci_scan_bridge(struct pci
/* Clear errors */
pci_write_config_word(dev, PCI_STATUS, 0xffff);
+ /* Prevent assigning a bus number that already exists.
+ * This can happen when a bridge is hot-plugged */
+ if (pci_find_bus(pci_domain_nr(bus), max+1))
+ return max;
child = pci_alloc_child_bus(bus, dev, ++max);
buses = (buses & 0xff000000)
| ((unsigned int)(child->primary) << 0)
@@ -507,7 +511,11 @@ int __devinit pci_scan_bridge(struct pci
* as cards with a PCI-to-PCI bridge can be
* inserted later.
*/
- max += CARDBUS_RESERVE_BUSNR;
+ for (i=0; i<CARDBUS_RESERVE_BUSNR; i++)
+ if (pci_find_bus(pci_domain_nr(bus),
+ max+i+1))
+ break;
+ max += i;
}
/*
* Set the subordinate bus number to its real value.
_
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread* [patch 05/12] Take the PCI lock when modifying pci bus or device lists
[not found] ` <20050318133856.A878-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
2005-03-18 22:04 ` [patch 04/12] Prevent duplicate bus numbers when scanning PCI bridge Rajesh Shah
@ 2005-03-18 22:07 ` Rajesh Shah
2005-03-18 22:09 ` [patch 06/12] Link newly created pci child bus to its parent on creation Rajesh Shah
` (5 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Rajesh Shah @ 2005-03-18 22:07 UTC (permalink / raw)
To: gregkh-l3A5Bk7waGM, tony.luck-ral2JQCrhuEAvxtiuMwx3w,
len.brown-ral2JQCrhuEAvxtiuMwx3w
Cc: linux-pci-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
pcihpd-discuss-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
With root bridge and pci bridge hot-plug, new buses and devices
can be added or removed at run time. Protect the pci bus and
device lists with the pci lock when doing so.
Signed-off-by: Rajesh Shah <rajesh.shah-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
linux-2.6.11-mm4-iohp-rshah1/drivers/pci/probe.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletion(-)
diff -puN drivers/pci/probe.c~lock-pci-root-bus-add drivers/pci/probe.c
--- linux-2.6.11-mm4-iohp/drivers/pci/probe.c~lock-pci-root-bus-add 2005-03-16 13:07:14.694663612 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/pci/probe.c 2005-03-16 13:07:14.802085486 -0800
@@ -8,6 +8,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/cpumask.h>
+#include "pci.h"
#undef DEBUG
@@ -380,8 +381,11 @@ struct pci_bus * __devinit pci_add_new_b
struct pci_bus *child;
child = pci_alloc_child_bus(parent, dev, busnr);
- if (child)
+ if (child) {
+ spin_lock(&pci_bus_lock);
list_add_tail(&child->node, &parent->children);
+ spin_unlock(&pci_bus_lock);
+ }
return child;
}
@@ -771,7 +775,9 @@ pci_scan_single_device(struct pci_bus *b
* and the bus list for fixup functions, etc.
*/
INIT_LIST_HEAD(&dev->global_list);
+ spin_lock(&pci_bus_lock);
list_add_tail(&dev->bus_list, &bus->devices);
+ spin_unlock(&pci_bus_lock);
return dev;
}
@@ -891,7 +897,9 @@ struct pci_bus * __devinit pci_scan_bus_
DBG("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
goto err_out;
}
+ spin_lock(&pci_bus_lock);
list_add_tail(&b->node, &pci_root_buses);
+ spin_unlock(&pci_bus_lock);
memset(dev, 0, sizeof(*dev));
dev->parent = parent;
@@ -933,7 +941,9 @@ class_dev_create_file_err:
class_dev_reg_err:
device_unregister(dev);
dev_reg_err:
+ spin_lock(&pci_bus_lock);
list_del(&b->node);
+ spin_unlock(&pci_bus_lock);
err_out:
kfree(dev);
kfree(b);
_
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread* [patch 06/12] Link newly created pci child bus to its parent on creation
[not found] ` <20050318133856.A878-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
2005-03-18 22:04 ` [patch 04/12] Prevent duplicate bus numbers when scanning PCI bridge Rajesh Shah
2005-03-18 22:07 ` [patch 05/12] Take the PCI lock when modifying pci bus or device lists Rajesh Shah
@ 2005-03-18 22:09 ` Rajesh Shah
[not found] ` <20050318140922.F1145-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
2005-03-18 22:11 ` [patch 07/12] Make the PCI remove routines safe for failed hot-plug Rajesh Shah
` (4 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Rajesh Shah @ 2005-03-18 22:09 UTC (permalink / raw)
To: gregkh-l3A5Bk7waGM, tony.luck-ral2JQCrhuEAvxtiuMwx3w,
len.brown-ral2JQCrhuEAvxtiuMwx3w
Cc: linux-pci-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
pcihpd-discuss-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
When a pci child bus is created, add it to the parent's children
list immediately rather than waiting till pci_bus_add_devices().
For hot-plug bridges/devices, pci_bus_add_devices() may be called
much later, after they have been properly configured. In the
meantime, this allows us to use the normal pci bus search functions
for the hot-plug bridges/buses.
Signed-off-by: Rajesh Shah <rajesh.shah-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
linux-2.6.11-mm4-iohp-rshah1/drivers/pci/bus.c | 11 +++++++----
linux-2.6.11-mm4-iohp-rshah1/drivers/pci/probe.c | 4 ++--
2 files changed, 9 insertions(+), 6 deletions(-)
diff -puN drivers/pci/probe.c~pci_link_child_bus drivers/pci/probe.c
--- linux-2.6.11-mm4-iohp/drivers/pci/probe.c~pci_link_child_bus 2005-03-16 13:07:18.745444812 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/pci/probe.c 2005-03-16 13:07:18.857749498 -0800
@@ -457,7 +457,7 @@ int __devinit pci_scan_bridge(struct pci
return max;
}
- child = pci_alloc_child_bus(bus, dev, busnr);
+ child = pci_add_new_bus(bus, dev, busnr);
if (!child)
return max;
child->primary = buses & 0xFF;
@@ -484,7 +484,7 @@ int __devinit pci_scan_bridge(struct pci
* This can happen when a bridge is hot-plugged */
if (pci_find_bus(pci_domain_nr(bus), max+1))
return max;
- child = pci_alloc_child_bus(bus, dev, ++max);
+ child = pci_add_new_bus(bus, dev, ++max);
buses = (buses & 0xff000000)
| ((unsigned int)(child->primary) << 0)
| ((unsigned int)(child->secondary) << 8)
diff -puN drivers/pci/bus.c~pci_link_child_bus drivers/pci/bus.c
--- linux-2.6.11-mm4-iohp/drivers/pci/bus.c~pci_link_child_bus 2005-03-16 13:07:18.749351062 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/pci/bus.c 2005-03-16 13:07:18.858726061 -0800
@@ -121,10 +121,13 @@ void __devinit pci_bus_add_devices(struc
* If there is an unattached subordinate bus, attach
* it and then scan for unattached PCI devices.
*/
- if (dev->subordinate && list_empty(&dev->subordinate->node)) {
- spin_lock(&pci_bus_lock);
- list_add_tail(&dev->subordinate->node, &dev->bus->children);
- spin_unlock(&pci_bus_lock);
+ if (dev->subordinate) {
+ if (list_empty(&dev->subordinate->node)) {
+ spin_lock(&pci_bus_lock);
+ list_add_tail(&dev->subordinate->node,
+ &dev->bus->children);
+ spin_unlock(&pci_bus_lock);
+ }
pci_bus_add_devices(dev->subordinate);
sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge");
_
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread* [patch 07/12] Make the PCI remove routines safe for failed hot-plug
[not found] ` <20050318133856.A878-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
` (2 preceding siblings ...)
2005-03-18 22:09 ` [patch 06/12] Link newly created pci child bus to its parent on creation Rajesh Shah
@ 2005-03-18 22:11 ` Rajesh Shah
2005-03-19 5:14 ` Greg KH
2005-03-18 22:16 ` [patch 09/12] Read bridge resources when fixing up the bus Rajesh Shah
` (3 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Rajesh Shah @ 2005-03-18 22:11 UTC (permalink / raw)
To: gregkh-l3A5Bk7waGM, tony.luck-ral2JQCrhuEAvxtiuMwx3w,
len.brown-ral2JQCrhuEAvxtiuMwx3w
Cc: linux-pci-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
pcihpd-discuss-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
When a root bridge hierarchy is hot-plugged, resource requirements
for the new devices may be greater than what the root bridge is
decoding. In this case, we want to remove devices that did not
get needed resources. These devices have been scanned into bus
specific lists but not yet added to the global device list.
Make sure the pci remove functions can handle this case.
Signed-off-by: Rajesh Shah <rajesh.shah-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
linux-2.6.11-mm4-iohp-rshah1/drivers/pci/remove.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff -puN drivers/pci/remove.c~pci-remove-device-hotplug-safe drivers/pci/remove.c
--- linux-2.6.11-mm4-iohp/drivers/pci/remove.c~pci-remove-device-hotplug-safe 2005-03-16 13:07:22.667319764 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/pci/remove.c 2005-03-16 13:07:22.775718200 -0800
@@ -26,17 +26,21 @@ static void pci_free_resources(struct pc
static void pci_destroy_dev(struct pci_dev *dev)
{
- pci_proc_detach_device(dev);
- pci_remove_sysfs_dev_files(dev);
- device_unregister(&dev->dev);
+ if (!list_empty(&dev->global_list)) {
+ pci_proc_detach_device(dev);
+ pci_remove_sysfs_dev_files(dev);
+ device_unregister(&dev->dev);
+ spin_lock(&pci_bus_lock);
+ list_del(&dev->global_list);
+ dev->global_list.next = dev->global_list.prev = NULL;
+ spin_unlock(&pci_bus_lock);
+ }
/* Remove the device from the device lists, and prevent any further
* list accesses from this device */
spin_lock(&pci_bus_lock);
list_del(&dev->bus_list);
- list_del(&dev->global_list);
dev->bus_list.next = dev->bus_list.prev = NULL;
- dev->global_list.next = dev->global_list.prev = NULL;
spin_unlock(&pci_bus_lock);
pci_free_resources(dev);
_
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [patch 07/12] Make the PCI remove routines safe for failed hot-plug
2005-03-18 22:11 ` [patch 07/12] Make the PCI remove routines safe for failed hot-plug Rajesh Shah
@ 2005-03-19 5:14 ` Greg KH
0 siblings, 0 replies; 16+ messages in thread
From: Greg KH @ 2005-03-19 5:14 UTC (permalink / raw)
To: Rajesh Shah
Cc: tony.luck, len.brown, linux-pci, linux-kernel, pcihpd-discuss,
linux-ia64, acpi-devel
On Fri, Mar 18, 2005 at 02:11:44PM -0800, Rajesh Shah wrote:
> diff -puN drivers/pci/remove.c~pci-remove-device-hotplug-safe drivers/pci/remove.c
> --- linux-2.6.11-mm4-iohp/drivers/pci/remove.c~pci-remove-device-hotplug-safe 2005-03-16 13:07:22.667319764 -0800
> +++ linux-2.6.11-mm4-iohp-rshah1/drivers/pci/remove.c 2005-03-16 13:07:22.775718200 -0800
> @@ -26,17 +26,21 @@ static void pci_free_resources(struct pc
>
> static void pci_destroy_dev(struct pci_dev *dev)
> {
> - pci_proc_detach_device(dev);
> - pci_remove_sysfs_dev_files(dev);
> - device_unregister(&dev->dev);
> + if (!list_empty(&dev->global_list)) {
> + pci_proc_detach_device(dev);
> + pci_remove_sysfs_dev_files(dev);
> + device_unregister(&dev->dev);
> + spin_lock(&pci_bus_lock);
> + list_del(&dev->global_list);
> + dev->global_list.next = dev->global_list.prev = NULL;
> + spin_unlock(&pci_bus_lock);
> + }
>
> /* Remove the device from the device lists, and prevent any further
> * list accesses from this device */
> spin_lock(&pci_bus_lock);
> list_del(&dev->bus_list);
> - list_del(&dev->global_list);
> dev->bus_list.next = dev->bus_list.prev = NULL;
> - dev->global_list.next = dev->global_list.prev = NULL;
> spin_unlock(&pci_bus_lock);
>
> pci_free_resources(dev);
I did have a comment about this code at first glance, but in reviewing
it again, nevermind, it looks fine...
thanks,
greg k-h
^ permalink raw reply [flat|nested] 16+ messages in thread
* [patch 09/12] Read bridge resources when fixing up the bus
[not found] ` <20050318133856.A878-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
` (3 preceding siblings ...)
2005-03-18 22:11 ` [patch 07/12] Make the PCI remove routines safe for failed hot-plug Rajesh Shah
@ 2005-03-18 22:16 ` Rajesh Shah
2005-03-18 22:18 ` [patch 10/12] Allow ACPI .add and .start operations to be done independently Rajesh Shah
` (2 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Rajesh Shah @ 2005-03-18 22:16 UTC (permalink / raw)
To: gregkh-l3A5Bk7waGM, tony.luck-ral2JQCrhuEAvxtiuMwx3w,
len.brown-ral2JQCrhuEAvxtiuMwx3w
Cc: linux-pci-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
pcihpd-discuss-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
Read bridge io/mem/pfmem ranges when fixing up the bus so that
bus resources are tracked. This is required to properly support
pci end device and bridge hotplug.
Signed-off-by: Rajesh Shah <rajesh.shah-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
linux-2.6.11-mm4-iohp-rshah1/arch/ia64/pci/pci.c | 4 ++++
1 files changed, 4 insertions(+)
diff -puN arch/ia64/pci/pci.c~ia64-read_bridge_bases arch/ia64/pci/pci.c
--- linux-2.6.11-mm4-iohp/arch/ia64/pci/pci.c~ia64-read_bridge_bases 2005-03-16 13:07:30.503257168 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/arch/ia64/pci/pci.c 2005-03-16 13:07:30.612632167 -0800
@@ -436,6 +436,10 @@ pcibios_fixup_bus (struct pci_bus *b)
{
struct pci_dev *dev;
+ if (b->self) {
+ pci_read_bridge_bases(b);
+ pcibios_fixup_device_resources(b->self);
+ }
list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev);
_
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread* [patch 10/12] Allow ACPI .add and .start operations to be done independently
[not found] ` <20050318133856.A878-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
` (4 preceding siblings ...)
2005-03-18 22:16 ` [patch 09/12] Read bridge resources when fixing up the bus Rajesh Shah
@ 2005-03-18 22:18 ` Rajesh Shah
2005-03-18 22:20 ` [patch 11/12] Export the interface to get PCI id for an ACPI handle Rajesh Shah
2005-03-18 22:22 ` [patch 12/12] ACPI based root bridge hot-add Rajesh Shah
7 siblings, 0 replies; 16+ messages in thread
From: Rajesh Shah @ 2005-03-18 22:18 UTC (permalink / raw)
To: gregkh-l3A5Bk7waGM, tony.luck-ral2JQCrhuEAvxtiuMwx3w,
len.brown-ral2JQCrhuEAvxtiuMwx3w
Cc: linux-pci-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
pcihpd-discuss-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
Create new interfaces to recursively add an acpi namespace object
to the acpi device list, and recursively start the namespace
object. This is needed for ACPI based hotplug of a root bridge
hierarchy where the add operation must be performed first and
the start operation must be performed separately after the
hot-plugged devices have been properly configured.
Signed-off-by: Rajesh Shah <rajesh.shah-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
linux-2.6.11-mm4-iohp-rshah1/drivers/acpi/container.c | 2
linux-2.6.11-mm4-iohp-rshah1/drivers/acpi/processor_core.c | 2
linux-2.6.11-mm4-iohp-rshah1/drivers/acpi/scan.c | 126 ++++++++++---
linux-2.6.11-mm4-iohp-rshah1/include/acpi/acpi_bus.h | 17 +
4 files changed, 119 insertions(+), 28 deletions(-)
diff -puN drivers/acpi/scan.c~acpi_separate_device_start drivers/acpi/scan.c
--- linux-2.6.11-mm4-iohp/drivers/acpi/scan.c~acpi_separate_device_start 2005-03-16 13:07:34.326499309 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/acpi/scan.c 2005-03-16 13:07:34.452475870 -0800
@@ -553,20 +553,29 @@ acpi_bus_driver_init (
* upon possible configuration and currently allocated resources.
*/
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
+ return_VALUE(0);
+}
+
+int
+acpi_start_single_object (
+ struct acpi_device *device)
+{
+ int result = 0;
+ struct acpi_driver *driver;
+
+ ACPI_FUNCTION_TRACE("acpi_start_single_object");
+
+ if (!(driver = device->driver))
+ return_VALUE(0);
+
if (driver->ops.start) {
result = driver->ops.start(device);
if (result && driver->ops.remove)
driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
- return_VALUE(result);
- }
-
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
-
- if (driver->ops.scan) {
- driver->ops.scan(device);
}
- return_VALUE(0);
+ return_VALUE(result);
}
static int acpi_driver_attach(struct acpi_driver * drv)
@@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acp
if (!acpi_bus_match(dev, drv)) {
if (!acpi_bus_driver_init(dev, drv)) {
+ acpi_start_single_object(dev);
atomic_inc(&drv->references);
count++;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
@@ -1009,8 +1019,8 @@ acpi_bus_remove (
}
-int
-acpi_bus_add (
+static int
+acpi_add_single_object (
struct acpi_device **child,
struct acpi_device *parent,
acpi_handle handle,
@@ -1019,7 +1029,7 @@ acpi_bus_add (
int result = 0;
struct acpi_device *device = NULL;
- ACPI_FUNCTION_TRACE("acpi_bus_add");
+ ACPI_FUNCTION_TRACE("acpi_add_single_object");
if (!child)
return_VALUE(-EINVAL);
@@ -1140,7 +1150,7 @@ acpi_bus_add (
*
* TBD: Assumes LDM provides driver hot-plug capability.
*/
- acpi_bus_find_driver(device);
+ result = acpi_bus_find_driver(device);
end:
if (!result)
@@ -1153,10 +1163,10 @@ end:
return_VALUE(result);
}
-EXPORT_SYMBOL(acpi_bus_add);
-int acpi_bus_scan (struct acpi_device *start)
+static int acpi_bus_scan (struct acpi_device *start,
+ struct acpi_bus_ops *ops)
{
acpi_status status = AE_OK;
struct acpi_device *parent = NULL;
@@ -1229,9 +1239,20 @@ int acpi_bus_scan (struct acpi_device *s
continue;
}
- status = acpi_bus_add(&child, parent, chandle, type);
- if (ACPI_FAILURE(status))
- continue;
+ if (ops->acpi_op_add)
+ status = acpi_add_single_object(&child, parent,
+ chandle, type);
+ else
+ status = acpi_bus_get_device(chandle, &child);
+
+ if (ACPI_FAILURE(status))
+ continue;
+
+ if (ops->acpi_op_start) {
+ status = acpi_start_single_object(child);
+ if (ACPI_FAILURE(status))
+ continue;
+ }
/*
* If the device is present, enabled, and functioning then
@@ -1257,8 +1278,50 @@ int acpi_bus_scan (struct acpi_device *s
return_VALUE(0);
}
-EXPORT_SYMBOL(acpi_bus_scan);
+int
+acpi_bus_add (
+ struct acpi_device **child,
+ struct acpi_device *parent,
+ acpi_handle handle,
+ int type)
+{
+ int result;
+ struct acpi_bus_ops ops;
+
+ ACPI_FUNCTION_TRACE("acpi_bus_add");
+
+ result = acpi_add_single_object(child, parent, handle, type);
+ if (!result) {
+ memset(&ops, 0, sizeof(ops));
+ ops.acpi_op_add = 1;
+ result = acpi_bus_scan(*child, &ops);
+ }
+ return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_add);
+
+int
+acpi_bus_start (
+ struct acpi_device *device)
+{
+ int result;
+ struct acpi_bus_ops ops;
+
+ ACPI_FUNCTION_TRACE("acpi_bus_start");
+
+ if (!device)
+ return_VALUE(-EINVAL);
+
+ result = acpi_start_single_object(device);
+ if (!result) {
+ memset(&ops, 0, sizeof(ops));
+ ops.acpi_op_start = 1;
+ result = acpi_bus_scan(device, &ops);
+ }
+ return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_start);
static int
acpi_bus_trim(struct acpi_device *start,
@@ -1331,13 +1394,19 @@ acpi_bus_scan_fixed (
/*
* Enumerate all fixed-feature devices.
*/
- if (acpi_fadt.pwr_button == 0)
- result = acpi_bus_add(&device, acpi_root,
+ if (acpi_fadt.pwr_button == 0) {
+ result = acpi_add_single_object(&device, acpi_root,
NULL, ACPI_BUS_TYPE_POWER_BUTTON);
+ if (!result)
+ result = acpi_start_single_object(device);
+ }
- if (acpi_fadt.sleep_button == 0)
- result = acpi_bus_add(&device, acpi_root,
+ if (acpi_fadt.sleep_button == 0) {
+ result = acpi_add_single_object(&device, acpi_root,
NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
+ if (!result)
+ result = acpi_start_single_object(device);
+ }
return_VALUE(result);
}
@@ -1346,6 +1415,7 @@ acpi_bus_scan_fixed (
static int __init acpi_scan_init(void)
{
int result;
+ struct acpi_bus_ops ops;
ACPI_FUNCTION_TRACE("acpi_scan_init");
@@ -1357,17 +1427,23 @@ static int __init acpi_scan_init(void)
/*
* Create the root device in the bus's device tree
*/
- result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT,
+ result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
ACPI_BUS_TYPE_SYSTEM);
if (result)
goto Done;
+ result = acpi_start_single_object(acpi_root);
+
/*
* Enumerate devices in the ACPI namespace.
*/
result = acpi_bus_scan_fixed(acpi_root);
- if (!result)
- result = acpi_bus_scan(acpi_root);
+ if (!result) {
+ memset(&ops, 0, sizeof(ops));
+ ops.acpi_op_add = 1;
+ ops.acpi_op_start = 1;
+ result = acpi_bus_scan(acpi_root, &ops);
+ }
if (result)
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
diff -puN include/acpi/acpi_bus.h~acpi_separate_device_start include/acpi/acpi_bus.h
--- linux-2.6.11-mm4-iohp/include/acpi/acpi_bus.h~acpi_separate_device_start 2005-03-16 13:07:34.330405559 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/include/acpi/acpi_bus.h 2005-03-16 13:07:34.453452432 -0800
@@ -108,6 +108,21 @@ typedef int (*acpi_op_unbind) (struct ac
typedef int (*acpi_op_match) (struct acpi_device *device,
struct acpi_driver *driver);
+struct acpi_bus_ops {
+ u32 acpi_op_add:1;
+ u32 acpi_op_remove:1;
+ u32 acpi_op_lock:1;
+ u32 acpi_op_start:1;
+ u32 acpi_op_stop:1;
+ u32 acpi_op_suspend:1;
+ u32 acpi_op_resume:1;
+ u32 acpi_op_scan:1;
+ u32 acpi_op_bind:1;
+ u32 acpi_op_unbind:1;
+ u32 acpi_op_match:1;
+ u32 reserved:21;
+};
+
struct acpi_device_ops {
acpi_op_add add;
acpi_op_remove remove;
@@ -327,9 +342,9 @@ int acpi_bus_generate_event (struct acpi
int acpi_bus_receive_event (struct acpi_bus_event *event);
int acpi_bus_register_driver (struct acpi_driver *driver);
int acpi_bus_unregister_driver (struct acpi_driver *driver);
-int acpi_bus_scan (struct acpi_device *start);
int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent,
acpi_handle handle, int type);
+int acpi_bus_start (struct acpi_device *device);
int acpi_match_ids (struct acpi_device *device, char *ids);
diff -puN drivers/acpi/container.c~acpi_separate_device_start drivers/acpi/container.c
--- linux-2.6.11-mm4-iohp/drivers/acpi/container.c~acpi_separate_device_start 2005-03-16 13:07:34.335288371 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/acpi/container.c 2005-03-16 13:07:34.454428995 -0800
@@ -153,7 +153,7 @@ container_device_add(struct acpi_device
return_VALUE(-ENODEV);
}
- result = acpi_bus_scan(*device);
+ result = acpi_bus_start(*device);
return_VALUE(result);
}
diff -puN drivers/acpi/processor_core.c~acpi_separate_device_start drivers/acpi/processor_core.c
--- linux-2.6.11-mm4-iohp/drivers/acpi/processor_core.c~acpi_separate_device_start 2005-03-16 13:07:34.339194621 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/acpi/processor_core.c 2005-03-16 13:07:34.455405557 -0800
@@ -723,7 +723,7 @@ int acpi_processor_device_add(
return_VALUE(-ENODEV);
}
- acpi_bus_scan(*device);
+ acpi_bus_start(*device);
pr = acpi_driver_data(*device);
if (!pr)
_
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread* [patch 11/12] Export the interface to get PCI id for an ACPI handle
[not found] ` <20050318133856.A878-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
` (5 preceding siblings ...)
2005-03-18 22:18 ` [patch 10/12] Allow ACPI .add and .start operations to be done independently Rajesh Shah
@ 2005-03-18 22:20 ` Rajesh Shah
2005-03-18 22:22 ` [patch 12/12] ACPI based root bridge hot-add Rajesh Shah
7 siblings, 0 replies; 16+ messages in thread
From: Rajesh Shah @ 2005-03-18 22:20 UTC (permalink / raw)
To: gregkh-l3A5Bk7waGM, tony.luck-ral2JQCrhuEAvxtiuMwx3w,
len.brown-ral2JQCrhuEAvxtiuMwx3w
Cc: linux-pci-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
pcihpd-discuss-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
Export an acpi interface to get PCI domain/bus/devfn information
from the corresponding namespace handle. Used by acpiphp code
to transpate the device handle of the hot-plugged root bridge to
the corresponding pci location information.
Signed-off-by: Rajesh Shah <rajesh.shah-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
linux-2.6.11-mm4-iohp-rshah1/drivers/acpi/pci_bind.c | 11 +++++------
linux-2.6.11-mm4-iohp-rshah1/include/acpi/acpi_drivers.h | 1 +
2 files changed, 6 insertions(+), 6 deletions(-)
diff -puN drivers/acpi/pci_bind.c~acpi-get-pci-id drivers/acpi/pci_bind.c
--- linux-2.6.11-mm4-iohp/drivers/acpi/pci_bind.c~acpi-get-pci-id 2005-03-16 13:07:39.028647689 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/acpi/pci_bind.c 2005-03-16 13:07:39.141928937 -0800
@@ -61,15 +61,14 @@ acpi_pci_data_handler (
/**
- * acpi_os_get_pci_id
+ * acpi_get_pci_id
* ------------------
* This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
* to resolve PCI information for ACPI-PCI devices defined in the namespace.
* This typically occurs when resolving PCI operation region information.
*/
-#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_os_get_pci_id (
+acpi_get_pci_id (
acpi_handle handle,
struct acpi_pci_id *id)
{
@@ -78,7 +77,7 @@ acpi_os_get_pci_id (
struct acpi_device *device = NULL;
struct acpi_pci_data *data = NULL;
- ACPI_FUNCTION_TRACE("acpi_os_get_pci_id");
+ ACPI_FUNCTION_TRACE("acpi_get_pci_id");
if (!id)
return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -92,7 +91,7 @@ acpi_os_get_pci_id (
}
status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data);
- if (ACPI_FAILURE(status) || !data || !data->dev) {
+ if (ACPI_FAILURE(status) || !data) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Invalid ACPI-PCI context for device %s\n",
acpi_device_bid(device)));
@@ -115,7 +114,7 @@ acpi_os_get_pci_id (
return_ACPI_STATUS(AE_OK);
}
-#endif /* ACPI_FUTURE_USAGE */
+EXPORT_SYMBOL(acpi_get_pci_id);
int
diff -puN include/acpi/acpi_drivers.h~acpi-get-pci-id include/acpi/acpi_drivers.h
--- linux-2.6.11-mm4-iohp/include/acpi/acpi_drivers.h~acpi-get-pci-id 2005-03-16 13:07:39.033530501 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/include/acpi/acpi_drivers.h 2005-03-16 13:07:39.142905500 -0800
@@ -68,6 +68,7 @@ void acpi_pci_irq_del_prt (int segment,
struct pci_bus;
+acpi_status acpi_get_pci_id (acpi_handle handle, struct acpi_pci_id *id);
int acpi_pci_bind (struct acpi_device *device);
int acpi_pci_unbind (struct acpi_device *device);
int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus);
_
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread* [patch 12/12] ACPI based root bridge hot-add
[not found] ` <20050318133856.A878-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
` (6 preceding siblings ...)
2005-03-18 22:20 ` [patch 11/12] Export the interface to get PCI id for an ACPI handle Rajesh Shah
@ 2005-03-18 22:22 ` Rajesh Shah
7 siblings, 0 replies; 16+ messages in thread
From: Rajesh Shah @ 2005-03-18 22:22 UTC (permalink / raw)
To: gregkh-l3A5Bk7waGM, tony.luck-ral2JQCrhuEAvxtiuMwx3w,
len.brown-ral2JQCrhuEAvxtiuMwx3w
Cc: linux-pci-jyMamyUUXNJG4ohzP4jBZS1Fcj925eT/,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
pcihpd-discuss-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
acpiphp changes to support acpi based root bridge hot-add.
This patch applies on top of the acpiphp re-write patch by
Matthew Wilcox at:
http://marc.theaimsgroup.com/?l=linux-ia64&m=110616116714938&w=2
Signed-off-by: Rajesh Shah <rajesh.shah-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
linux-2.6.11-mm4-iohp-rshah1/drivers/pci/hotplug/acpiphp_glue.c | 211 +++++++++-
1 files changed, 202 insertions(+), 9 deletions(-)
diff -puN drivers/pci/hotplug/acpiphp_glue.c~acpiphp_h2p_add drivers/pci/hotplug/acpiphp_glue.c
--- linux-2.6.11-mm4-iohp/drivers/pci/hotplug/acpiphp_glue.c~acpiphp_h2p_add 2005-03-16 13:37:08.716126010 -0800
+++ linux-2.6.11-mm4-iohp-rshah1/drivers/pci/hotplug/acpiphp_glue.c 2005-03-16 13:37:08.825501009 -0800
@@ -6,6 +6,8 @@
* Copyright (C) 2002,2003 NEC Corporation
* Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox-VXdhtT5mjnY@public.gmane.org)
* Copyright (C) 2003-2005 Hewlett Packard
+ * Copyright (C) 2005 Rajesh Shah (rajesh.shah-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org)
+ * Copyright (C) 2005 Intel Corporation
*
* All rights reserved.
*
@@ -304,13 +306,15 @@ static void init_bridge_misc(struct acpi
register_slot, bridge, NULL);
/* install notify handler */
- status = acpi_install_notify_handler(bridge->handle,
+ if (bridge->type != BRIDGE_TYPE_HOST) {
+ status = acpi_install_notify_handler(bridge->handle,
ACPI_SYSTEM_NOTIFY,
handle_hotplug_event_bridge,
bridge);
- if (ACPI_FAILURE(status)) {
- err("failed to register interrupt notify handler\n");
+ if (ACPI_FAILURE(status)) {
+ err("failed to register interrupt notify handler\n");
+ }
}
list_add(&bridge->list, &bridge_list);
@@ -802,6 +806,143 @@ static int acpiphp_check_bridge(struct a
return retval;
}
+static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
+{
+ u16 pci_cmd, pci_bctl;
+ struct pci_dev *cdev;
+
+ /* Program hpp values for this device */
+ if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
+ (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
+ return;
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+ bridge->hpp.cache_line_size);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER,
+ bridge->hpp.latency_timer);
+ pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+ if (bridge->hpp.enable_SERR)
+ pci_cmd |= PCI_COMMAND_SERR;
+ else
+ pci_cmd &= ~PCI_COMMAND_SERR;
+ if (bridge->hpp.enable_PERR)
+ pci_cmd |= PCI_COMMAND_PARITY;
+ else
+ pci_cmd &= ~PCI_COMMAND_PARITY;
+ pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+
+ /* Program bridge control value and child devices */
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
+ bridge->hpp.latency_timer);
+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
+ if (bridge->hpp.enable_SERR)
+ pci_bctl |= PCI_BRIDGE_CTL_SERR;
+ else
+ pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
+ if (bridge->hpp.enable_PERR)
+ pci_bctl |= PCI_BRIDGE_CTL_PARITY;
+ else
+ pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
+ if (dev->subordinate) {
+ list_for_each_entry(cdev, &dev->subordinate->devices,
+ bus_list)
+ program_hpp(cdev, bridge);
+ }
+ }
+}
+
+static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
+{
+ struct acpiphp_bridge bridge;
+ struct pci_dev *dev;
+
+ memset(&bridge, 0, sizeof(bridge));
+ bridge.handle = handle;
+ decode_hpp(&bridge);
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ program_hpp(dev, &bridge);
+
+}
+
+/*
+ * Remove devices for which we could not assign resources, call
+ * arch specific code to fix-up the bus
+ */
+static void acpiphp_sanitize_bus(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+ int i;
+ unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {
+ struct resource *res = &dev->resource[i];
+ if ((res->flags & type_mask) && !res->start &&
+ res->end) {
+ /* Could not assign a required resources
+ * for this device, remove it */
+ pci_remove_bus_device(dev);
+ break;
+ }
+ }
+ }
+}
+
+/* Program resources in newly inserted bridge */
+static int acpiphp_configure_bridge (acpi_handle handle)
+{
+ struct acpi_pci_id pci_id;
+ struct pci_bus *bus;
+
+ if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) {
+ err("cannot get PCI domain and bus number for bridge\n");
+ return -EINVAL;
+ }
+ bus = pci_find_bus(pci_id.segment, pci_id.bus);
+ if (!bus) {
+ err("cannot find bus %d:%d\n",
+ pci_id.segment, pci_id.bus);
+ return -EINVAL;
+ }
+
+ pci_bus_size_bridges(bus);
+ pci_bus_assign_resources(bus);
+ acpiphp_sanitize_bus(bus);
+ acpiphp_set_hpp_values(handle, bus);
+ pci_enable_bridges(bus);
+ return 0;
+}
+
+static void handle_bridge_insertion(acpi_handle handle, u32 type)
+{
+ struct acpi_device *device, *pdevice;
+ acpi_handle phandle;
+
+ if ((type != ACPI_NOTIFY_BUS_CHECK) &&
+ (type != ACPI_NOTIFY_DEVICE_CHECK)) {
+ err("unexpected notification type %d\n", type);
+ return;
+ }
+
+ acpi_get_parent(handle, &phandle);
+ if (acpi_bus_get_device(phandle, &pdevice)) {
+ dbg("no parent device, assuming NULL\n");
+ pdevice = NULL;
+ }
+ if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
+ err("cannot add bridge to acpi list\n");
+ return;
+ }
+ if (!acpiphp_configure_bridge(handle) &&
+ !acpi_bus_start(device))
+ add_bridge(handle);
+ else
+ err("cannot configure and start bridge\n");
+
+}
+
/*
* ACPI event handlers
*/
@@ -822,8 +963,19 @@ static void handle_hotplug_event_bridge(
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
+ struct acpi_device *device;
- bridge = (struct acpiphp_bridge *)context;
+ if (acpi_bus_get_device(handle, &device)) {
+ /* This bridge must have just been physically inserted */
+ handle_bridge_insertion(handle, type);
+ return;
+ }
+
+ bridge = acpiphp_handle_to_bridge(handle);
+ if (!bridge) {
+ err("cannot get bridge info\n");
+ return;
+ }
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
@@ -923,6 +1075,47 @@ static void handle_hotplug_event_func(ac
}
}
+static int is_root_bridge(acpi_handle handle)
+{
+ acpi_status status;
+ struct acpi_device_info *info;
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ int i;
+
+ status = acpi_get_object_info(handle, &buffer);
+ if (ACPI_SUCCESS(status)) {
+ info = buffer.pointer;
+ if ((info->valid & ACPI_VALID_HID) &&
+ !strcmp(PCI_ROOT_HID_STRING,
+ info->hardware_id.value)) {
+ acpi_os_free(buffer.pointer);
+ return 1;
+ }
+ if (info->valid & ACPI_VALID_CID) {
+ for (i=0; i < info->compatibility_id.count; i++) {
+ if (!strcmp(PCI_ROOT_HID_STRING,
+ info->compatibility_id.id[i].value)) {
+ acpi_os_free(buffer.pointer);
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static acpi_status
+find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ int *count = (int *)context;
+
+ if (is_root_bridge(handle)) {
+ acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+ handle_hotplug_event_bridge, NULL);
+ (*count)++;
+ }
+ return AE_OK ;
+}
static struct acpi_pci_driver acpi_pci_hp_driver = {
.add = add_bridge,
@@ -935,15 +1128,15 @@ static struct acpi_pci_driver acpi_pci_h
*/
int __init acpiphp_glue_init(void)
{
- int num;
-
- if (list_empty(&pci_root_buses))
- return -1;
+ int num = 0;
- num = acpi_pci_register_driver(&acpi_pci_hp_driver);
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, find_root_bridges, &num, NULL);
if (num <= 0)
return -1;
+ else
+ acpi_pci_register_driver(&acpi_pci_hp_driver);
return 0;
}
_
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread