Subject: [PATCH] PCI, ACPI: remove acpi_root_bridge in pci_root_hp Tang noticed that hotplug through container will not update acpi_root_bridge list. After closely checking, we don't need that for struct for tracking and could use acpi_pci_root directly. Reported-by: Tang Chen Signed-off-by: Yinghai Lu --- drivers/acpi/pci_root_hp.c | 111 ++++++++------------------------------------- 1 file changed, 21 insertions(+), 90 deletions(-) Index: linux-2.6/drivers/acpi/pci_root_hp.c =================================================================== --- linux-2.6.orig/drivers/acpi/pci_root_hp.c +++ linux-2.6/drivers/acpi/pci_root_hp.c @@ -12,13 +12,6 @@ #include #include -static LIST_HEAD(acpi_root_bridge_list); -struct acpi_root_bridge { - struct list_head list; - acpi_handle handle; - u32 flags; -}; - static const struct acpi_device_id root_device_ids[] = { {"PNP0A03", 0}, {"PNP0A08", 0}, @@ -31,60 +24,6 @@ static const struct acpi_device_id root_ #define ACPI_STA_FUNCTIONING (0x00000008) -static struct acpi_root_bridge *acpi_root_handle_to_bridge(acpi_handle handle) -{ - struct acpi_root_bridge *bridge; - - list_for_each_entry(bridge, &acpi_root_bridge_list, list) - if (bridge->handle == handle) - return bridge; - - return NULL; -} - -/* allocate and initialize host bridge data structure */ -static void add_acpi_root_bridge(acpi_handle handle) -{ - struct acpi_root_bridge *bridge; - acpi_handle dummy_handle; - acpi_status status; - - /* if the bridge doesn't have _STA, we assume it is always there */ - status = acpi_get_handle(handle, "_STA", &dummy_handle); - if (ACPI_SUCCESS(status)) { - unsigned long long tmp; - - status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp); - if (ACPI_FAILURE(status)) { - printk(KERN_DEBUG "%s: _STA evaluation failure\n", - __func__); - return; - } - if ((tmp & ACPI_STA_FUNCTIONING) == 0) - /* don't register this object */ - return; - } - - bridge = kzalloc(sizeof(struct acpi_root_bridge), GFP_KERNEL); - if (!bridge) - return; - - bridge->handle = handle; - - if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle))) - bridge->flags |= ROOT_BRIDGE_HAS_EJ0; - if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle))) - bridge->flags |= ROOT_BRIDGE_HAS_PS3; - - list_add(&bridge->list, &acpi_root_bridge_list); -} - -static void remove_acpi_root_bridge(struct acpi_root_bridge *bridge) -{ - list_del(&bridge->list); - kfree(bridge); -} - struct acpi_root_hp_work { struct work_struct work; acpi_handle handle; @@ -166,28 +105,25 @@ static int acpi_root_evaluate_object(acp return 0; } -static void handle_root_bridge_removal(acpi_handle handle, - struct acpi_root_bridge *bridge) +static void handle_root_bridge_removal(struct acpi_device *device) { + int ret_val; u32 flags = 0; - struct acpi_device *device; - - if (bridge) { - flags = bridge->flags; - remove_acpi_root_bridge(bridge); - } - - if (!acpi_bus_get_device(handle, &device)) { - int ret_val; + acpi_handle dummy_handle; + acpi_handle handle = device->handle; - /* remove pci devices at first */ - ret_val = acpi_bus_trim(device, 0); - printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val); + if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle))) + flags |= ROOT_BRIDGE_HAS_EJ0; + if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle))) + flags |= ROOT_BRIDGE_HAS_PS3; - /* remove acpi devices */ - ret_val = acpi_bus_trim(device, 1); - printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val); - } + /* remove pci devices at first */ + ret_val = acpi_bus_trim(device, 0); + printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val); + + /* remove acpi devices */ + ret_val = acpi_bus_trim(device, 1); + printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val); if (flags & ROOT_BRIDGE_HAS_PS3) { acpi_status status; @@ -202,7 +138,7 @@ static void handle_root_bridge_removal(a static void _handle_hotplug_event_root(struct work_struct *work) { - struct acpi_root_bridge *bridge; + struct acpi_pci_root *root; char objname[64]; struct acpi_buffer buffer = { .length = sizeof(objname), .pointer = objname }; @@ -214,7 +150,7 @@ static void _handle_hotplug_event_root(s handle = hp_work->handle; type = hp_work->type; - bridge = acpi_root_handle_to_bridge(handle); + root = acpi_pci_find_root(handle); acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); @@ -223,10 +159,8 @@ static void _handle_hotplug_event_root(s /* bus enumerate */ printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__, objname); - if (!bridge) { + if (!root) handle_root_bridge_insertion(handle); - add_acpi_root_bridge(handle); - } break; @@ -234,17 +168,16 @@ static void _handle_hotplug_event_root(s /* device check */ printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__, objname); - if (!bridge) { + if (!root) handle_root_bridge_insertion(handle); - add_acpi_root_bridge(handle); - } break; case ACPI_NOTIFY_EJECT_REQUEST: /* request device eject */ printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__, objname); - handle_root_bridge_removal(handle, bridge); + if (root) + handle_root_bridge_removal(root->device); break; default: printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n", @@ -304,8 +237,6 @@ find_root_bridges(acpi_handle handle, u3 printk(KERN_DEBUG "acpi root: %s notify handler is installed\n", objname); - add_acpi_root_bridge(handle); - return AE_OK; }