Re: [patch 16/19] Altix: Add ACPI SSDT PCI device support (hotplug)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux