#include <asm/sn/sn_sal.h>
#include "xtalk/hubdev.h"
#include <linux/acpi.h>
-#include <acpi/acnamesp.h>
+#include <linux/slab.h>
/*
/*
* Perform the early IO init in PROM.
*/
-static s64
+static long
sal_ioif_init(u64 *result)
{
struct ia64_sal_retval isrv = {0,0,0,0};
}
/*
- * sn_hubdev_add - The 'add' function of the acpi_sn_hubdev_driver.
- * Called for every "SGIHUB" or "SGITIO" device defined
- * in the ACPI namespace.
+ * sn_acpi_hubdev_init() - This function is called by acpi_ns_get_device_callback()
+ * for all SGIHUB and SGITIO acpi devices defined in the
+ * DSDT. It obtains the hubdev_info pointer from the
+ * ACPI vendor resource, which the PROM setup, and sets up the
+ * hubdev_info in the pda.
*/
-static int __init
-sn_hubdev_add(struct acpi_device *device)
+
+static acpi_status __init
+sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
u64 addr;
struct hubdev_info *hubdev;
struct hubdev_info *hubdev_ptr;
int i;
u64 nasid;
struct acpi_resource *resource;
- int ret = 0;
acpi_status status;
struct acpi_resource_vendor_typed *vendor;
extern void sn_common_hubdev_init(struct hubdev_info *);
- status = acpi_get_vendor_resource(device->handle, METHOD_NAME__CRS,
+ status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
&sn_uuid, &buffer);
if (ACPI_FAILURE(status)) {
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
printk(KERN_ERR
- "sn_hubdev_add: acpi_get_vendor_resource() failed: %d\n",
- status);
- return 1;
+ "sn_acpi_hubdev_init: acpi_get_vendor_resource() "
+ "(0x%x) failed for: %s\n", status,
+ (char *)name_buffer.pointer);
+ kfree(name_buffer.pointer);
+ return AE_OK; /* Continue walking namespace */
}
resource = buffer.pointer;
vendor = &resource->data.vendor_typed;
if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
sizeof(struct hubdev_info *)) {
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
printk(KERN_ERR
- "sn_hubdev_add: Invalid vendor data length: %d\n",
- vendor->byte_length);
- ret = 1;
+ "sn_acpi_hubdev_init: Invalid vendor data length: "
+ "%d for: %s\n",
+ vendor->byte_length, (char *)name_buffer.pointer);
+ kfree(name_buffer.pointer);
goto exit;
}
exit:
kfree(buffer.pointer);
- return ret;
+ return AE_OK; /* Continue walking namespace */
}
/*
{
u64 addr;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
acpi_handle handle;
struct pcibus_bussoft *prom_bussoft_ptr;
struct acpi_resource *resource;
status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
&sn_uuid, &buffer);
if (ACPI_FAILURE(status)) {
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
printk(KERN_ERR "%s: "
- "acpi_get_vendor_resource() failed (0x%x) for: ",
- __FUNCTION__, status);
- acpi_ns_print_node_pathname(handle, NULL);
- printk("\n");
+ "acpi_get_vendor_resource() failed (0x%x) for: %s\n",
+ __func__, status, (char *)name_buffer.pointer);
+ kfree(name_buffer.pointer);
return NULL;
}
resource = buffer.pointer;
sizeof(struct pcibus_bussoft *)) {
printk(KERN_ERR
"%s: Invalid vendor data length %d\n",
- __FUNCTION__, vendor->byte_length);
+ __func__, vendor->byte_length);
kfree(buffer.pointer);
return NULL;
}
{
u64 addr;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer name_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;
status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
&sn_uuid, &buffer);
if (ACPI_FAILURE(status)) {
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
printk(KERN_ERR
- "%s: acpi_get_vendor_resource() failed (0x%x) for: ",
- __FUNCTION__, status);
- acpi_ns_print_node_pathname(handle, NULL);
- printk("\n");
+ "%s: acpi_get_vendor_resource() failed (0x%x) for: %s\n",
+ __func__, status, (char *)name_buffer.pointer);
+ kfree(name_buffer.pointer);
return 1;
}
vendor = &resource->data.vendor_typed;
if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
sizeof(struct pci_devdev_info *)) {
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
printk(KERN_ERR
- "%s: Invalid vendor data length: %d for: ",
- __FUNCTION__, vendor->byte_length);
- acpi_ns_print_node_pathname(handle, NULL);
- printk("\n");
+ "%s: Invalid vendor data length: %d for: %s\n",
+ __func__, vendor->byte_length,
+ (char *)name_buffer.pointer);
+ kfree(name_buffer.pointer);
ret = 1;
goto exit;
}
pcidev_ptr = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
if (!pcidev_ptr)
- panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__);
+ panic("%s: Unable to alloc memory for pcidev_info", __func__);
memcpy(&addr, vendor->byte_data, sizeof(struct pcidev_info *));
pcidev_prom_ptr = __va(addr);
/* Get the IRQ info */
irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
if (!irq_info)
- panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__);
+ panic("%s: Unable to alloc memory for sn_irq_info", __func__);
if (pcidev_ptr->pdi_sn_irq_info) {
irq_info_prom = __va(pcidev_ptr->pdi_sn_irq_info);
static unsigned int
get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle)
{
- unsigned long adr;
+ unsigned long long adr;
acpi_handle child;
unsigned int devfn;
int function;
acpi_handle parent;
int slot;
acpi_status status;
+ struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ acpi_get_name(device_handle, ACPI_FULL_PATHNAME, &name_buffer);
/*
* Do an upward search to find the root bus device, and
status = acpi_get_parent(child, &parent);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR "%s: acpi_get_parent() failed "
- "(0x%x) for: ", __FUNCTION__, status);
- acpi_ns_print_node_pathname(child, NULL);
- printk("\n");
- panic("%s: Unable to find host devfn\n", __FUNCTION__);
+ "(0x%x) for: %s\n", __func__, status,
+ (char *)name_buffer.pointer);
+ panic("%s: Unable to find host devfn\n", __func__);
}
if (parent == rootbus_handle)
break;
child = parent;
}
if (!child) {
- printk(KERN_ERR "%s: Unable to find root bus for: ",
- __FUNCTION__);
- acpi_ns_print_node_pathname(device_handle, NULL);
- printk("\n");
+ printk(KERN_ERR "%s: Unable to find root bus for: %s\n",
+ __func__, (char *)name_buffer.pointer);
BUG();
}
status = acpi_evaluate_integer(child, METHOD_NAME__ADR, NULL, &adr);
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: ",
- __FUNCTION__, status);
- acpi_ns_print_node_pathname(child, NULL);
- printk("\n");
- panic("%s: Unable to find host devfn\n", __FUNCTION__);
+ printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: %s\n",
+ __func__, status, (char *)name_buffer.pointer);
+ panic("%s: Unable to find host devfn\n", __func__);
}
+ kfree(name_buffer.pointer);
+
slot = (adr >> 16) & 0xffff;
function = adr & 0xffff;
devfn = PCI_DEVFN(slot, function);
static acpi_status
find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv)
{
- unsigned long bbn = -1;
- unsigned long adr;
+ unsigned long long bbn = -1;
+ unsigned long long adr;
acpi_handle parent = NULL;
acpi_status status;
unsigned int devfn;
int function;
int slot;
struct sn_pcidev_match *info = context;
+ struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
&adr);
if (ACPI_SUCCESS(status)) {
status = acpi_get_parent(handle, &parent);
if (ACPI_FAILURE(status)) {
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
printk(KERN_ERR
- "%s: acpi_get_parent() failed (0x%x) for: ",
- __FUNCTION__, status);
- acpi_ns_print_node_pathname(handle, NULL);
- printk("\n");
+ "%s: acpi_get_parent() failed (0x%x) for: %s\n",
+ __func__, status, (char *)name_buffer.pointer);
+ kfree(name_buffer.pointer);
return AE_OK;
}
status = acpi_evaluate_integer(parent, METHOD_NAME__BBN,
NULL, &bbn);
if (ACPI_FAILURE(status)) {
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
printk(KERN_ERR
- "%s: Failed to find _BBN in parent of: ",
- __FUNCTION__);
- acpi_ns_print_node_pathname(handle, NULL);
- printk("\n");
+ "%s: Failed to find _BBN in parent of: %s\n",
+ __func__, (char *)name_buffer.pointer);
+ kfree(name_buffer.pointer);
return AE_OK;
}
unsigned int host_devfn;
struct sn_pcidev_match pcidev_match;
acpi_handle rootbus_handle;
- unsigned long segment;
+ unsigned long long segment;
acpi_status status;
+ struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
rootbus_handle = PCI_CONTROLLER(dev)->acpi_handle;
status = acpi_evaluate_integer(rootbus_handle, METHOD_NAME__SEG, NULL,
&segment);
if (ACPI_SUCCESS(status)) {
if (segment != pci_domain_nr(dev)) {
+ acpi_get_name(rootbus_handle, ACPI_FULL_PATHNAME,
+ &name_buffer);
printk(KERN_ERR
- "%s: Segment number mismatch, 0x%lx vs 0x%x for: ",
- __FUNCTION__, segment, pci_domain_nr(dev));
- acpi_ns_print_node_pathname(rootbus_handle, NULL);
- printk("\n");
+ "%s: Segment number mismatch, 0x%llx vs 0x%x for: %s\n",
+ __func__, segment, pci_domain_nr(dev),
+ (char *)name_buffer.pointer);
+ kfree(name_buffer.pointer);
return 1;
}
} else {
- printk(KERN_ERR "%s: Unable to get __SEG from: ",
- __FUNCTION__);
- acpi_ns_print_node_pathname(rootbus_handle, NULL);
- printk("\n");
+ acpi_get_name(rootbus_handle, ACPI_FULL_PATHNAME, &name_buffer);
+ printk(KERN_ERR "%s: Unable to get __SEG from: %s\n",
+ __func__, (char *)name_buffer.pointer);
+ kfree(name_buffer.pointer);
return 1;
}
pcidev_match.handle = NULL;
acpi_walk_namespace(ACPI_TYPE_DEVICE, rootbus_handle, ACPI_UINT32_MAX,
- find_matching_device, &pcidev_match, NULL);
+ find_matching_device, NULL, &pcidev_match, NULL);
if (!pcidev_match.handle) {
printk(KERN_ERR
"%s: Could not find matching ACPI device for %s.\n",
- __FUNCTION__, pci_name(dev));
+ __func__, pci_name(dev));
return 1;
}
void __iomem *addr;
struct pcidev_info *pcidev_info = NULL;
struct sn_irq_info *sn_irq_info = NULL;
- size_t size;
+ size_t image_size, size;
if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) {
panic("%s: Failure obtaining pcidev_info for %s\n",
- __FUNCTION__, pci_name(dev));
+ __func__, pci_name(dev));
}
if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) {
/*
* A valid ROM image exists and has been shadowed by the
- * PROM. Setup the pci_dev ROM resource to point to
- * the shadowed copy.
+ * PROM. Setup the pci_dev ROM resource with the address
+ * of the shadowed copy, and the actual length of the ROM image.
*/
- size = dev->resource[PCI_ROM_RESOURCE].end -
- dev->resource[PCI_ROM_RESOURCE].start;
- addr =
- ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
- size);
+ size = pci_resource_len(dev, PCI_ROM_RESOURCE);
+ addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
+ size);
+ image_size = pci_get_rom_size(dev, addr, size);
dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr;
dev->resource[PCI_ROM_RESOURCE].end =
- (unsigned long) addr + size;
+ (unsigned long) addr + image_size - 1;
dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY;
}
sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
EXPORT_SYMBOL(sn_acpi_slot_fixup);
-static struct acpi_driver acpi_sn_hubdev_driver = {
- .name = "SGI HUBDEV Driver",
- .ids = "SGIHUB,SGITIO",
- .ops = {
- .add = sn_hubdev_add,
- },
-};
-
/*
* sn_acpi_bus_fixup - Perform SN specific setup of software structs
printk(KERN_ERR
"%s: 0x%04x:0x%02x Unable to "
"obtain prom_bussoft_ptr\n",
- __FUNCTION__, pci_domain_nr(bus), bus->number);
+ __func__, pci_domain_nr(bus), bus->number);
return;
}
sn_common_bus_fixup(bus, prom_bussoft_ptr);
sn_io_acpi_init(void)
{
u64 result;
- s64 status;
+ long status;
/* SN Altix does not follow the IOSAPIC IRQ routing model */
acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM;
- acpi_bus_register_driver(&acpi_sn_hubdev_driver);
+ /* Setup hubdev_info for all SGIHUB/SGITIO devices */
+ acpi_get_devices("SGIHUB", sn_acpi_hubdev_init, NULL, NULL);
+ acpi_get_devices("SGITIO", sn_acpi_hubdev_init, NULL, NULL);
+
status = sal_ioif_init(&result);
if (status || result)
panic("sal_ioif_init failed: [%lx] %s\n",