The patch titled altix-add-acpi-ssdt-pci-device-support-hotplug fix has been added to the -mm tree. Its filename is altix-add-acpi-ssdt-pci-device-support-hotplug-fix.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: altix-add-acpi-ssdt-pci-device-support-hotplug fix From: John Keller <jpk@xxxxxxx> A bug was fixed where the sgi hotplug driver was removing the slot's SSDT table from the ACPI namespace a bit too early in disable_slot(). Also, we now call acpi_bus_start() subsequent to acpi_bus_add(). Cc: "Brown, Len" <len.brown@xxxxxxxxx> Cc: Greg KH <greg@xxxxxxxxx> Cc: "Luck, Tony" <tony.luck@xxxxxxxxx> Cc: Aaron Young <ayoung@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- drivers/pci/hotplug/sgi_hotplug.c | 82 +++++++++++++++------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff -puN drivers/pci/hotplug/sgi_hotplug.c~altix-add-acpi-ssdt-pci-device-support-hotplug-fix drivers/pci/hotplug/sgi_hotplug.c --- a/drivers/pci/hotplug/sgi_hotplug.c~altix-add-acpi-ssdt-pci-device-support-hotplug-fix +++ a/drivers/pci/hotplug/sgi_hotplug.c @@ -29,7 +29,6 @@ #include <asm/sn/sn_sal.h> #include <asm/sn/types.h> #include <linux/acpi.h> -#include <acpi/acnamesp.h> #include <asm/sn/acpi.h> #include "../pci.h" @@ -418,12 +417,11 @@ static int enable_slot(struct hotplug_sl * Add the slot's devices to the ACPI infrastructure */ if (SN_ACPI_BASE_SUPPORT() && ssdt) { unsigned long adr; - struct acpi_namespace_node *cnode = NULL; - struct acpi_namespace_node *rootbus_node; - struct acpi_device *device; struct acpi_device *pdevice; - acpi_handle handle; + struct acpi_device *device; acpi_handle phandle; + acpi_handle chandle = NULL; + acpi_handle rethandle; acpi_status ret; phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; @@ -434,26 +432,29 @@ static int enable_slot(struct hotplug_sl pdevice = NULL; } - /* Get the rootbus node pointer */ - rootbus_node = acpi_ns_map_handle_to_node(phandle); - /* * Walk the rootbus node's immediate children looking for * the slot's device node(s). There can be more than * one for multifunction devices. */ - while ((cnode = acpi_ns_get_next_node(ACPI_TYPE_DEVICE, - rootbus_node, - cnode))) { + for (;;) { + rethandle = NULL; + ret = acpi_get_next_object(ACPI_TYPE_DEVICE, + phandle, chandle, + &rethandle); + + if (ret == AE_NOT_FOUND || rethandle == NULL) + break; - handle = acpi_ns_convert_entry_to_handle(cnode); + chandle = rethandle; - ret = acpi_evaluate_integer(handle, METHOD_NAME__ADR, + ret = acpi_evaluate_integer(chandle, METHOD_NAME__ADR, NULL, &adr); if (ACPI_SUCCESS(ret) && (adr>>16) == (slot->device_num + 1)) { - ret = acpi_bus_add(&device, pdevice, handle, + + ret = acpi_bus_add(&device, pdevice, chandle, ACPI_BUS_TYPE_DEVICE); if (ACPI_FAILURE(ret)) { printk(KERN_ERR "%s: acpi_bus_add " @@ -462,6 +463,8 @@ static int enable_slot(struct hotplug_sl ret, (int)(adr>>16), (int)(adr&0xffff)); /* try to continue on */ + } else { + acpi_bus_start(device); } } } @@ -491,6 +494,7 @@ static int disable_slot(struct hotplug_s struct pci_dev *dev; int func; int rc; + acpi_owner_id ssdt_id = 0; /* Acquire update access to the bus */ mutex_lock(&sn_hotplug_mutex); @@ -501,56 +505,50 @@ static int disable_slot(struct hotplug_s if (rc) goto leaving; - /* Remove the SSDT for the slot from the ACPI namespace */ + /* free the ACPI resources for the slot */ if (SN_ACPI_BASE_SUPPORT() && PCI_CONTROLLER(slot->pci_bus)->acpi_handle) { unsigned long adr; struct acpi_device *device; - struct acpi_namespace_node *cnode = NULL; - struct acpi_namespace_node *rootbus_node; - acpi_handle child_handle; acpi_handle phandle; + acpi_handle chandle = NULL; + acpi_handle rethandle; acpi_status ret; - acpi_owner_id ssdt_id = 0; /* Get the rootbus node pointer */ phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; - rootbus_node = acpi_ns_map_handle_to_node(phandle); /* * Walk the rootbus node's immediate children looking for * the slot's device node(s). There can be more than * one for multifunction devices. */ - while ((cnode = acpi_ns_get_next_node(ACPI_TYPE_DEVICE, - rootbus_node, - cnode))) { + for (;;) { + rethandle = NULL; + ret = acpi_get_next_object(ACPI_TYPE_DEVICE, + phandle, chandle, + &rethandle); + + if (ret == AE_NOT_FOUND || rethandle == NULL) + break; + + chandle = rethandle; - child_handle = acpi_ns_convert_entry_to_handle(cnode); - ret = acpi_evaluate_integer(child_handle, + ret = acpi_evaluate_integer(chandle, METHOD_NAME__ADR, NULL, &adr); if (ACPI_SUCCESS(ret) && (adr>>16) == (slot->device_num + 1)) { /* retain the owner id */ - ssdt_id = cnode->owner_id; + acpi_get_id(chandle, &ssdt_id); - ret = acpi_bus_get_device(child_handle, + ret = acpi_bus_get_device(chandle, &device); if (ACPI_SUCCESS(ret)) acpi_bus_trim(device, 1); } } - if (ssdt_id) { - ret = acpi_unload_table_id(ACPI_TABLE_ID_SSDT, ssdt_id); - if (ACPI_FAILURE(ret)) { - printk(KERN_ERR "%s: acpi_unload_table_id " - "failed (0x%x) for id %d\n", - __FUNCTION__, ret, ssdt_id); - /* try to continue on */ - } - } } /* Free the SN resources assigned to the Linux device.*/ @@ -565,6 +563,18 @@ static int disable_slot(struct hotplug_s } } + /* Remove the SSDT for the slot from the ACPI namespace */ + if (SN_ACPI_BASE_SUPPORT() && ssdt_id) { + acpi_status ret; + ret = acpi_unload_table_id(ACPI_TABLE_ID_SSDT, ssdt_id); + if (ACPI_FAILURE(ret)) { + printk(KERN_ERR "%s: acpi_unload_table_id " + "failed (0x%x) for id %d\n", + __FUNCTION__, ret, ssdt_id); + /* try to continue on */ + } + } + /* free the collected sysdata pointers */ sn_bus_free_sysdata(); _ Patches currently in -mm which might be from jpk@xxxxxxx are altix-acpi-ssdt-pci-device-support.patch altix-add-acpi-ssdt-pci-device-support-hotplug.patch altix-add-acpi-ssdt-pci-device-support-hotplug-fix.patch add-support-for-acpi_load_table-acpi_unload_table_id.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html