1 /* 2 * arch/ia64/kernel/acpi-ext.c 3 * 4 * Copyright (C) 2003 Hewlett-Packard 5 * Copyright (C) Alex Williamson 6 * Copyright (C) Bjorn Helgaas 7 * 8 * Vendor specific extensions to ACPI. 9 */ 10 11 #include <linux/config.h> 12 #include <linux/module.h> 13 #include <linux/types.h> 14 #include <linux/acpi.h> 15 #include <linux/efi.h> 16 17 #include <asm/acpi-ext.h> 18 19 struct acpi_vendor_descriptor { 20 u8 guid_id; 21 efi_guid_t guid; 22 }; 23 24 struct acpi_vendor_info { 25 struct acpi_vendor_descriptor *descriptor; 26 u8 *data; 27 u32 length; 28 }; 29 30 acpi_status 31 acpi_vendor_resource_match(struct acpi_resource *resource, void *context) 32 { 33 struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; 34 struct acpi_resource_vendor *vendor; 35 struct acpi_vendor_descriptor *descriptor; 36 u32 byte_length; 37 38 if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) 39 return AE_OK; 40 41 vendor = (struct acpi_resource_vendor *)&resource->data; 42 descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data; 43 if (vendor->byte_length <= sizeof(*info->descriptor) || 44 descriptor->guid_id != info->descriptor->guid_id || 45 efi_guidcmp(descriptor->guid, info->descriptor->guid)) 46 return AE_OK; 47 48 byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor); 49 info->data = acpi_os_allocate(byte_length); 50 if (!info->data) 51 return AE_NO_MEMORY; 52 53 memcpy(info->data, 54 vendor->byte_data + sizeof(struct acpi_vendor_descriptor), 55 byte_length); 56 info->length = byte_length; 57 return AE_CTRL_TERMINATE; 58 } 59 60 acpi_status 61 acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, 62 u8 ** data, u32 * byte_length) 63 { 64 struct acpi_vendor_info info; 65 66 info.descriptor = id; 67 info.data = NULL; 68 69 acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, 70 &info); 71 if (!info.data) 72 return AE_NOT_FOUND; 73 74 *data = info.data; 75 *byte_length = info.length; 76 return AE_OK; 77 } 78 79 struct acpi_vendor_descriptor hp_ccsr_descriptor = { 80 .guid_id = 2, 81 .guid = 82 EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, 83 0x37, 0x0e, 0xad) 84 }; 85 86 acpi_status hp_acpi_csr_space(acpi_handle obj, u64 * csr_base, u64 * csr_length) 87 { 88 acpi_status status; 89 u8 *data; 90 u32 length; 91 92 status = 93 acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); 94 95 if (ACPI_FAILURE(status) || length != 16) 96 return AE_NOT_FOUND; 97 98 memcpy(csr_base, data, sizeof(*csr_base)); 99 memcpy(csr_length, data + 8, sizeof(*csr_length)); 100 acpi_os_free(data); 101 102 return AE_OK; 103 } 104 105 EXPORT_SYMBOL(hp_acpi_csr_space); 106