[PATCH 2/3] Altix: ACPI SSDT PCI device support

2007-01-26 Thread Len Brown
From: John Keller <[EMAIL PROTECTED]>

Add SN platform support for running with an ACPI
capable PROM that defines PCI devices in SSDT
tables. There is a SSDT table for every occupied
slot on a root bus, containing info for every
PPB and/or device on the bus. The SSDTs will be
dynamically loaded/unloaded at hotplug enable/disable.

Platform specific information that is currently
passed via a SAL call, will now be passed via the
Vendor resource in the ACPI Device object(s) defined
in each SSDT.

Signed-off-by: John Keller <[EMAIL PROTECTED]>
Cc: Greg KH <[EMAIL PROTECTED]>
Cc: "Luck, Tony" <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
Signed-off-by: Len Brown <[EMAIL PROTECTED]>
---

 arch/ia64/sn/kernel/io_acpi_init.c  |  314 +---
 arch/ia64/sn/kernel/io_common.c |   83 +---
 arch/ia64/sn/kernel/io_init.c   |   54 -
 arch/ia64/sn/pci/pcibr/pcibr_provider.c |6
 include/asm-ia64/sn/acpi.h  |5
 include/asm-ia64/sn/pcibr_provider.h|2
 include/asm-ia64/sn/pcidev.h|8
 7 files changed, 368 insertions(+), 104 deletions(-)

Index: acpi/arch/ia64/sn/kernel/io_acpi_init.c
===
--- acpi.orig/arch/ia64/sn/kernel/io_acpi_init.c
+++ acpi/arch/ia64/sn/kernel/io_acpi_init.c
@@ -13,6 +13,7 @@
 #include 
 #include "xtalk/hubdev.h"
 #include 
+#include 
 
 
 /*
@@ -31,6 +32,12 @@ struct acpi_vendor_uuid sn_uuid = {
0xa2, 0x7c, 0x08, 0x00, 0x69, 0x13, 0xea, 0x51 },
 };
 
+struct sn_pcidev_match {
+   u8 bus;
+   unsigned int devfn;
+   acpi_handle handle;
+};
+
 /*
  * Perform the early IO init in PROM.
  */
@@ -119,9 +126,11 @@ sn_get_bussoft_ptr(struct pci_bus *bus)
status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
  _uuid, );
if (ACPI_FAILURE(status)) {
-   printk(KERN_ERR "get_acpi_pcibus_ptr: "
-  "get_acpi_bussoft_info() failed: %d\n",
-  status);
+   printk(KERN_ERR "%s: "
+  "acpi_get_vendor_resource() failed (0x%x) for: ",
+  __FUNCTION__, status);
+   acpi_ns_print_node_pathname(handle, NULL);
+   printk("\n");
return NULL;
}
resource = buffer.pointer;
@@ -130,8 +139,8 @@ sn_get_bussoft_ptr(struct pci_bus *bus)
if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
 sizeof(struct pcibus_bussoft *)) {
printk(KERN_ERR
-  "get_acpi_bussoft_ptr: Invalid vendor data "
-  "length %d\n", vendor->byte_length);
+  "%s: Invalid vendor data length %d\n",
+   __FUNCTION__, vendor->byte_length);
kfree(buffer.pointer);
return NULL;
}
@@ -143,34 +152,254 @@ sn_get_bussoft_ptr(struct pci_bus *bus)
 }
 
 /*
- * sn_acpi_bus_fixup
+ * sn_extract_device_info - Extract the pcidev_info and the sn_irq_info
+ * pointers from the vendor resource using the
+ * provided acpi handle, and copy the structures
+ * into the argument buffers.
  */
-void
-sn_acpi_bus_fixup(struct pci_bus *bus)
+static int
+sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info,
+   struct sn_irq_info **sn_irq_info)
 {
-   struct pci_dev *pci_dev = NULL;
-   struct pcibus_bussoft *prom_bussoft_ptr;
-   extern void sn_common_bus_fixup(struct pci_bus *,
-   struct pcibus_bussoft *);
+   u64 addr;
+   struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+   struct sn_irq_info *irq_info, *irq_info_prom;
+   struct pcidev_info *pcidev_ptr, *pcidev_prom_ptr;
+   struct acpi_resource *resource;
+   int ret = 0;
+   acpi_status status;
+   struct acpi_resource_vendor_typed *vendor;
 
-   if (!bus->parent) { /* If root bus */
-   prom_bussoft_ptr = sn_get_bussoft_ptr(bus);
-   if (prom_bussoft_ptr == NULL) {
+   /*
+* The pointer to this device's pcidev_info structure in
+* the PROM, is in the vendor resource.
+*/
+   status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
+ _uuid, );
+   if (ACPI_FAILURE(status)) {
+   printk(KERN_ERR
+  "%s: acpi_get_vendor_resource() failed (0x%x) for: ",
+   __FUNCTION__, status);
+   acpi_ns_print_node_pathname(handle, NULL);
+   printk("\n");
+   return 1;
+   }
+
+   resource = buffer.pointer;
+   vendor = >data.vendor_typed;
+   if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
+   sizeof(struct pci_devdev_info *)) 

[PATCH 2/3] Altix: ACPI SSDT PCI device support

2007-01-26 Thread Len Brown
From: John Keller [EMAIL PROTECTED]

Add SN platform support for running with an ACPI
capable PROM that defines PCI devices in SSDT
tables. There is a SSDT table for every occupied
slot on a root bus, containing info for every
PPB and/or device on the bus. The SSDTs will be
dynamically loaded/unloaded at hotplug enable/disable.

Platform specific information that is currently
passed via a SAL call, will now be passed via the
Vendor resource in the ACPI Device object(s) defined
in each SSDT.

Signed-off-by: John Keller [EMAIL PROTECTED]
Cc: Greg KH [EMAIL PROTECTED]
Cc: Luck, Tony [EMAIL PROTECTED]
Signed-off-by: Andrew Morton [EMAIL PROTECTED]
Signed-off-by: Len Brown [EMAIL PROTECTED]
---

 arch/ia64/sn/kernel/io_acpi_init.c  |  314 +---
 arch/ia64/sn/kernel/io_common.c |   83 +---
 arch/ia64/sn/kernel/io_init.c   |   54 -
 arch/ia64/sn/pci/pcibr/pcibr_provider.c |6
 include/asm-ia64/sn/acpi.h  |5
 include/asm-ia64/sn/pcibr_provider.h|2
 include/asm-ia64/sn/pcidev.h|8
 7 files changed, 368 insertions(+), 104 deletions(-)

Index: acpi/arch/ia64/sn/kernel/io_acpi_init.c
===
--- acpi.orig/arch/ia64/sn/kernel/io_acpi_init.c
+++ acpi/arch/ia64/sn/kernel/io_acpi_init.c
@@ -13,6 +13,7 @@
 #include asm/sn/sn_sal.h
 #include xtalk/hubdev.h
 #include linux/acpi.h
+#include acpi/acnamesp.h
 
 
 /*
@@ -31,6 +32,12 @@ struct acpi_vendor_uuid sn_uuid = {
0xa2, 0x7c, 0x08, 0x00, 0x69, 0x13, 0xea, 0x51 },
 };
 
+struct sn_pcidev_match {
+   u8 bus;
+   unsigned int devfn;
+   acpi_handle handle;
+};
+
 /*
  * Perform the early IO init in PROM.
  */
@@ -119,9 +126,11 @@ sn_get_bussoft_ptr(struct pci_bus *bus)
status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
  sn_uuid, buffer);
if (ACPI_FAILURE(status)) {
-   printk(KERN_ERR get_acpi_pcibus_ptr: 
-  get_acpi_bussoft_info() failed: %d\n,
-  status);
+   printk(KERN_ERR %s: 
+  acpi_get_vendor_resource() failed (0x%x) for: ,
+  __FUNCTION__, status);
+   acpi_ns_print_node_pathname(handle, NULL);
+   printk(\n);
return NULL;
}
resource = buffer.pointer;
@@ -130,8 +139,8 @@ sn_get_bussoft_ptr(struct pci_bus *bus)
if ((vendor-byte_length - sizeof(struct acpi_vendor_uuid)) !=
 sizeof(struct pcibus_bussoft *)) {
printk(KERN_ERR
-  get_acpi_bussoft_ptr: Invalid vendor data 
-  length %d\n, vendor-byte_length);
+  %s: Invalid vendor data length %d\n,
+   __FUNCTION__, vendor-byte_length);
kfree(buffer.pointer);
return NULL;
}
@@ -143,34 +152,254 @@ sn_get_bussoft_ptr(struct pci_bus *bus)
 }
 
 /*
- * sn_acpi_bus_fixup
+ * sn_extract_device_info - Extract the pcidev_info and the sn_irq_info
+ * pointers from the vendor resource using the
+ * provided acpi handle, and copy the structures
+ * into the argument buffers.
  */
-void
-sn_acpi_bus_fixup(struct pci_bus *bus)
+static int
+sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info,
+   struct sn_irq_info **sn_irq_info)
 {
-   struct pci_dev *pci_dev = NULL;
-   struct pcibus_bussoft *prom_bussoft_ptr;
-   extern void sn_common_bus_fixup(struct pci_bus *,
-   struct pcibus_bussoft *);
+   u64 addr;
+   struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+   struct sn_irq_info *irq_info, *irq_info_prom;
+   struct pcidev_info *pcidev_ptr, *pcidev_prom_ptr;
+   struct acpi_resource *resource;
+   int ret = 0;
+   acpi_status status;
+   struct acpi_resource_vendor_typed *vendor;
 
-   if (!bus-parent) { /* If root bus */
-   prom_bussoft_ptr = sn_get_bussoft_ptr(bus);
-   if (prom_bussoft_ptr == NULL) {
+   /*
+* The pointer to this device's pcidev_info structure in
+* the PROM, is in the vendor resource.
+*/
+   status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
+ sn_uuid, buffer);
+   if (ACPI_FAILURE(status)) {
+   printk(KERN_ERR
+  %s: acpi_get_vendor_resource() failed (0x%x) for: ,
+   __FUNCTION__, status);
+   acpi_ns_print_node_pathname(handle, NULL);
+   printk(\n);
+   return 1;
+   }
+
+   resource = buffer.pointer;
+   vendor = resource-data.vendor_typed;
+   if ((vendor-byte_length - sizeof(struct acpi_vendor_uuid)) !=
+