Tony, What is the status of this patch? Is it still possible to get this, and Altix: ACPI SSDT PCI device support into 2.6.20? I see that the ACPI patch that these are dependent on has been pulled into Linus' tree. Thanks, John > > Acked-By: Len Brown <len.brown@xxxxxxxxx> > > Tony, > This should probably be sent via your tree. > > thanks, > -Len > > On Tuesday 19 December 2006 15:56, akpm@xxxxxxxx wrote: > > From: John Keller <jpk@xxxxxxx> > > > > Support for dynamic loading and unloading of ACPI SSDT tables upon slot > > hotplugs and unplugs. > > > > On SN platforms, we now represent every populated root bus slot with a single > > ACPI SSDT table containing info for every device and PPB attached to the slot. > > These SSDTs are generated by the prom at initial boot and hotplug time. The > > info in these SSDT tables is used by the SN kernel IO "fixup" code (which is > > called at boot and hotplug time). > > > > On hotplugs (i.e. enable_slot()), if running with an ACPI capable prom, > > attempt to obtain a new ACPI SSDT table for the slot being hotplugged. If > > successful, add the table to the ACPI namespace (acpi_load_table()) and then > > walk the new devices and add them to the ACPI infrastructure (acpi_bus_add()). > > > > On hot unplugs (i.e. disable_slot()), if running with an ACPI capable prom, > > attempt to remove the SSDT table associated with the slot from the ACPI > > namespace (acpi_unload_table_id()) and infastructure (acpi_bus_trim()). > > > > 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(). > > > > Signed-off-by: Aaron Young <ayoung@xxxxxxx> > > Cc: "Brown, Len" <len.brown@xxxxxxxxx> > > Cc: Greg KH <greg@xxxxxxxxx> > > Cc: "Luck, Tony" <tony.luck@xxxxxxxxx> > > Signed-off-by: Andrew Morton <akpm@xxxxxxxx> > > --- > > > > drivers/pci/hotplug/sgi_hotplug.c | 155 ++++++++++++++++++++++++++-- > > 1 files changed, 148 insertions(+), 7 deletions(-) > > > > diff -puN drivers/pci/hotplug/sgi_hotplug.c~altix-add-acpi-ssdt-pci-device-support-hotplug drivers/pci/hotplug/sgi_hotplug.c > > --- a/drivers/pci/hotplug/sgi_hotplug.c~altix-add-acpi-ssdt-pci-device-support-hotplug > > +++ a/drivers/pci/hotplug/sgi_hotplug.c > > @@ -28,6 +28,8 @@ > > #include <asm/sn/sn_feature_sets.h> > > #include <asm/sn/sn_sal.h> > > #include <asm/sn/types.h> > > +#include <linux/acpi.h> > > +#include <asm/sn/acpi.h> > > > > #include "../pci.h" > > > > @@ -35,14 +37,17 @@ MODULE_LICENSE("GPL"); > > MODULE_AUTHOR("SGI (prarit@xxxxxxx, dickie@xxxxxxx, habeck@xxxxxxx)"); > > MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver"); > > > > -#define PCIIO_ASIC_TYPE_TIOCA 4 > > + > > +/* SAL call error codes. Keep in sync with prom header io/include/pcibr.h */ > > #define PCI_SLOT_ALREADY_UP 2 /* slot already up */ > > #define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */ > > #define PCI_L1_ERR 7 /* L1 console command error */ > > #define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */ > > + > > + > > +#define PCIIO_ASIC_TYPE_TIOCA 4 > > #define PCI_L1_QSIZE 128 /* our L1 message buffer size */ > > #define SN_MAX_HP_SLOTS 32 /* max hotplug slots */ > > -#define SGI_HOTPLUG_PROM_REV 0x0430 /* Min. required PROM version */ > > #define SN_SLOT_NAME_SIZE 33 /* size of name string */ > > > > /* internal list head */ > > @@ -227,7 +232,7 @@ static void sn_bus_free_data(struct pci_ > > } > > > > static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, > > - int device_num) > > + int device_num, char **ssdt) > > { > > struct slot *slot = bss_hotplug_slot->private; > > struct pcibus_info *pcibus_info; > > @@ -240,7 +245,8 @@ static int sn_slot_enable(struct hotplug > > * Power-on and initialize the slot in the SN > > * PCI infrastructure. > > */ > > - rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp); > > + rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp, ssdt); > > + > > > > if (rc == PCI_SLOT_ALREADY_UP) { > > dev_dbg(slot->pci_bus->self, "is already active\n"); > > @@ -335,6 +341,7 @@ static int enable_slot(struct hotplug_sl > > int func, num_funcs; > > int new_ppb = 0; > > int rc; > > + char *ssdt = NULL; > > void pcibios_fixup_device_resources(struct pci_dev *); > > > > /* Serialize the Linux PCI infrastructure */ > > @@ -342,14 +349,29 @@ static int enable_slot(struct hotplug_sl > > > > /* > > * Power-on and initialize the slot in the SN > > - * PCI infrastructure. > > + * PCI infrastructure. Also, retrieve the ACPI SSDT > > + * table for the slot (if ACPI capable PROM). > > */ > > - rc = sn_slot_enable(bss_hotplug_slot, slot->device_num); > > + rc = sn_slot_enable(bss_hotplug_slot, slot->device_num, &ssdt); > > if (rc) { > > mutex_unlock(&sn_hotplug_mutex); > > return rc; > > } > > > > + if (ssdt) > > + ssdt = __va(ssdt); > > + /* Add the new SSDT for the slot to the ACPI namespace */ > > + if (SN_ACPI_BASE_SUPPORT() && ssdt) { > > + acpi_status ret; > > + > > + ret = acpi_load_table((struct acpi_table_header *)ssdt); > > + if (ACPI_FAILURE(ret)) { > > + printk(KERN_ERR "%s: acpi_load_table failed (0x%x)\n", > > + __FUNCTION__, ret); > > + /* try to continue on */ > > + } > > + } > > + > > num_funcs = pci_scan_slot(slot->pci_bus, > > PCI_DEVFN(slot->device_num + 1, 0)); > > if (!num_funcs) { > > @@ -374,7 +396,10 @@ static int enable_slot(struct hotplug_sl > > * pdi_host_pcidev_info). > > */ > > pcibios_fixup_device_resources(dev); > > - sn_pci_fixup_slot(dev); > > + if (SN_ACPI_BASE_SUPPORT()) > > + sn_acpi_slot_fixup(dev); > > + else > > + sn_io_slot_fixup(dev); > > if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { > > unsigned char sec_bus; > > pci_read_config_byte(dev, PCI_SECONDARY_BUS, > > @@ -388,6 +413,63 @@ 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_device *pdevice; > > + 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; > > + > > + if (acpi_bus_get_device(phandle, &pdevice)) { > > + dev_dbg(slot->pci_bus->self, > > + "no parent device, assuming NULL\n"); > > + pdevice = NULL; > > + } > > + > > + /* > > + * Walk the rootbus node's immediate children looking for > > + * the slot's device node(s). There can be more than > > + * one for multifunction devices. > > + */ > > + for (;;) { > > + rethandle = NULL; > > + ret = acpi_get_next_object(ACPI_TYPE_DEVICE, > > + phandle, chandle, > > + &rethandle); > > + > > + if (ret == AE_NOT_FOUND || rethandle == NULL) > > + break; > > + > > + chandle = rethandle; > > + > > + 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, chandle, > > + ACPI_BUS_TYPE_DEVICE); > > + if (ACPI_FAILURE(ret)) { > > + printk(KERN_ERR "%s: acpi_bus_add " > > + "failed (0x%x) for slot %d " > > + "func %d\n", __FUNCTION__, > > + ret, (int)(adr>>16), > > + (int)(adr&0xffff)); > > + /* try to continue on */ > > + } else { > > + acpi_bus_start(device); > > + } > > + } > > + } > > + } > > + > > /* Call the driver for the new device */ > > pci_bus_add_devices(slot->pci_bus); > > /* Call the drivers for the new devices subordinate to PPB */ > > @@ -412,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); > > @@ -422,6 +505,52 @@ static int disable_slot(struct hotplug_s > > if (rc) > > goto leaving; > > > > + /* 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; > > + acpi_handle phandle; > > + acpi_handle chandle = NULL; > > + acpi_handle rethandle; > > + acpi_status ret; > > + > > + /* Get the rootbus node pointer */ > > + phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; > > + > > + /* > > + * Walk the rootbus node's immediate children looking for > > + * the slot's device node(s). There can be more than > > + * one for multifunction devices. > > + */ > > + for (;;) { > > + rethandle = NULL; > > + ret = acpi_get_next_object(ACPI_TYPE_DEVICE, > > + phandle, chandle, > > + &rethandle); > > + > > + if (ret == AE_NOT_FOUND || rethandle == NULL) > > + break; > > + > > + chandle = rethandle; > > + > > + ret = acpi_evaluate_integer(chandle, > > + METHOD_NAME__ADR, > > + NULL, &adr); > > + if (ACPI_SUCCESS(ret) && > > + (adr>>16) == (slot->device_num + 1)) { > > + /* retain the owner id */ > > + acpi_get_id(chandle, &ssdt_id); > > + > > + ret = acpi_bus_get_device(chandle, > > + &device); > > + if (ACPI_SUCCESS(ret)) > > + acpi_bus_trim(device, 1); > > + } > > + } > > + > > + } > > + > > /* Free the SN resources assigned to the Linux device.*/ > > for (func = 0; func < 8; func++) { > > dev = pci_get_slot(slot->pci_bus, > > @@ -434,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(); > > > > _ > > - > > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in > > the body of a message to majordomo@xxxxxxxxxxxxxxx > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html