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 <[EMAIL PROTECTED]>
>
> Tony,
> This should probably be sent via your tree.
>
> thanks,
> -Len
>
> On Tuesday 19 December 2006 15:56, [EMAIL PROTECTED] wrote:
> > From: John Keller <[EMAIL PROTECTED]>
> >
> > 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 <[EMAIL PROTECTED]>
> >
> > 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 <[EMAIL PROTECTED]>
> > Cc: "Brown, Len" <[EMAIL PROTECTED]>
> > Cc: Greg KH <[EMAIL PROTECTED]>
> > Cc: "Luck, Tony" <[EMAIL PROTECTED]>
> > Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
> > ---
> >
> > 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 ([EMAIL PROTECTED], [EMAIL PROTECTED], [EMAIL
> > PROTECTED])");
> > 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 [EMAIL PROTECTED]
> > 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 [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html