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

Reply via email to