From: Len Brown <lenb@kernel.org>
To: akpm@osdl.org
Cc: linux-acpi@vger.kernel.org, jpk@sgi.com, ayoung@sgi.com,
greg@kroah.com, tony.luck@intel.com
Subject: Re: [patch 16/19] Altix: Add ACPI SSDT PCI device support (hotplug)
Date: Wed, 20 Dec 2006 01:56:09 -0500 [thread overview]
Message-ID: <200612200156.09612.lenb@kernel.org> (raw)
In-Reply-To: <200612192056.kBJKuMD8010059@shell0.pdx.osdl.net>
Acked-By: Len Brown <len.brown@intel.com>
Tony,
This should probably be sent via your tree.
thanks,
-Len
On Tuesday 19 December 2006 15:56, akpm@osdl.org wrote:
> From: John Keller <jpk@sgi.com>
>
> 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@sgi.com>
>
> 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@sgi.com>
> Cc: "Brown, Len" <len.brown@intel.com>
> Cc: Greg KH <greg@kroah.com>
> Cc: "Luck, Tony" <tony.luck@intel.com>
> Signed-off-by: Andrew Morton <akpm@osdl.org>
> ---
>
> 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@sgi.com, dickie@sgi.com, habeck@sgi.com)");
> 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@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
next prev parent reply other threads:[~2006-12-20 6:56 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-19 20:56 [patch 16/19] Altix: Add ACPI SSDT PCI device support (hotplug) akpm
2006-12-20 6:56 ` Len Brown [this message]
2006-12-20 8:39 ` Andrew Morton
2006-12-20 14:27 ` John Keller
2006-12-28 17:06 ` John Keller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200612200156.09612.lenb@kernel.org \
--to=lenb@kernel.org \
--cc=akpm@osdl.org \
--cc=ayoung@sgi.com \
--cc=greg@kroah.com \
--cc=jpk@sgi.com \
--cc=linux-acpi@vger.kernel.org \
--cc=tony.luck@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox