|  | /* | 
|  | * arch/ia64/kernel/acpi-ext.c | 
|  | * | 
|  | * Copyright (C) 2003 Hewlett-Packard | 
|  | * Copyright (C) Alex Williamson | 
|  | * Copyright (C) Bjorn Helgaas | 
|  | * | 
|  | * Vendor specific extensions to ACPI. | 
|  | */ | 
|  |  | 
|  | #include <linux/config.h> | 
|  | #include <linux/module.h> | 
|  | #include <linux/types.h> | 
|  | #include <linux/acpi.h> | 
|  | #include <linux/efi.h> | 
|  |  | 
|  | #include <asm/acpi-ext.h> | 
|  |  | 
|  | struct acpi_vendor_descriptor { | 
|  | u8 guid_id; | 
|  | efi_guid_t guid; | 
|  | }; | 
|  |  | 
|  | struct acpi_vendor_info { | 
|  | struct acpi_vendor_descriptor *descriptor; | 
|  | u8 *data; | 
|  | u32 length; | 
|  | }; | 
|  |  | 
|  | acpi_status | 
|  | acpi_vendor_resource_match(struct acpi_resource *resource, void *context) | 
|  | { | 
|  | struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; | 
|  | struct acpi_resource_vendor *vendor; | 
|  | struct acpi_vendor_descriptor *descriptor; | 
|  | u32 length; | 
|  |  | 
|  | if (resource->id != ACPI_RSTYPE_VENDOR) | 
|  | return AE_OK; | 
|  |  | 
|  | vendor = (struct acpi_resource_vendor *)&resource->data; | 
|  | descriptor = (struct acpi_vendor_descriptor *)vendor->reserved; | 
|  | if (vendor->length <= sizeof(*info->descriptor) || | 
|  | descriptor->guid_id != info->descriptor->guid_id || | 
|  | efi_guidcmp(descriptor->guid, info->descriptor->guid)) | 
|  | return AE_OK; | 
|  |  | 
|  | length = vendor->length - sizeof(struct acpi_vendor_descriptor); | 
|  | info->data = acpi_os_allocate(length); | 
|  | if (!info->data) | 
|  | return AE_NO_MEMORY; | 
|  |  | 
|  | memcpy(info->data, | 
|  | vendor->reserved + sizeof(struct acpi_vendor_descriptor), | 
|  | length); | 
|  | info->length = length; | 
|  | return AE_CTRL_TERMINATE; | 
|  | } | 
|  |  | 
|  | acpi_status | 
|  | acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, | 
|  | u8 ** data, u32 * length) | 
|  | { | 
|  | struct acpi_vendor_info info; | 
|  |  | 
|  | info.descriptor = id; | 
|  | info.data = NULL; | 
|  |  | 
|  | acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, | 
|  | &info); | 
|  | if (!info.data) | 
|  | return AE_NOT_FOUND; | 
|  |  | 
|  | *data = info.data; | 
|  | *length = info.length; | 
|  | return AE_OK; | 
|  | } | 
|  |  | 
|  | struct acpi_vendor_descriptor hp_ccsr_descriptor = { | 
|  | .guid_id = 2, | 
|  | .guid = | 
|  | EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, | 
|  | 0x37, 0x0e, 0xad) | 
|  | }; | 
|  |  | 
|  | acpi_status hp_acpi_csr_space(acpi_handle obj, u64 * csr_base, u64 * csr_length) | 
|  | { | 
|  | acpi_status status; | 
|  | u8 *data; | 
|  | u32 length; | 
|  |  | 
|  | status = | 
|  | acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); | 
|  |  | 
|  | if (ACPI_FAILURE(status) || length != 16) | 
|  | return AE_NOT_FOUND; | 
|  |  | 
|  | memcpy(csr_base, data, sizeof(*csr_base)); | 
|  | memcpy(csr_length, data + 8, sizeof(*csr_length)); | 
|  | acpi_os_free(data); | 
|  |  | 
|  | return AE_OK; | 
|  | } | 
|  |  | 
|  | EXPORT_SYMBOL(hp_acpi_csr_space); |