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 length; 37 38 if (resource->id != ACPI_RSTYPE_VENDOR) 39 return AE_OK; 40 41 vendor = (struct acpi_resource_vendor *) &resource->data; 42 descriptor = (struct acpi_vendor_descriptor *) vendor->reserved; 43 if (vendor->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 length = vendor->length - sizeof(struct acpi_vendor_descriptor); 49 info->data = acpi_os_allocate(length); 50 if (!info->data) 51 return AE_NO_MEMORY; 52 53 memcpy(info->data, vendor->reserved + sizeof(struct acpi_vendor_descriptor), length); 54 info->length = length; 55 return AE_CTRL_TERMINATE; 56 } 57 58 acpi_status 59 acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor *id, 60 u8 **data, u32 *length) 61 { 62 struct acpi_vendor_info info; 63 64 info.descriptor = id; 65 info.data = NULL; 66 67 acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, &info); 68 if (!info.data) 69 return AE_NOT_FOUND; 70 71 *data = info.data; 72 *length = info.length; 73 return AE_OK; 74 } 75 76 struct acpi_vendor_descriptor hp_ccsr_descriptor = { 77 .guid_id = 2, 78 .guid = EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad) 79 }; 80 81 acpi_status 82 hp_acpi_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length) 83 { 84 acpi_status status; 85 u8 *data; 86 u32 length; 87 88 status = acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); 89 90 if (ACPI_FAILURE(status) || length != 16) 91 return AE_NOT_FOUND; 92 93 memcpy(csr_base, data, sizeof(*csr_base)); 94 memcpy(csr_length, data + 8, sizeof(*csr_length)); 95 acpi_os_free(data); 96 97 return AE_OK; 98 } 99 100 EXPORT_SYMBOL(hp_acpi_csr_space); 101