2.5 vendor-specific ACPI resource cleanup
PATCH 1/1 2.5 vendor-specific ACPI resource cleanup
This is to
- handle _CRS with multiple vendor-specific resources
- use acpi_walk_resources() instead of doing it by hand
- make lookup of vendor resource by GUID generic
- cleanup now-unused helper functions
(This depends on the previous IO port space patches, because they removed the last of acpi_get_addr_space()).
My hope is that acpi_vendor_resource_match() and acpi_find_vendor_resource() can someday move into ACPI, but that probably depends on getting the idea of labelling vendor resources with a GUID into the spec. HP does this and I think is working on putting it in the spec.
Bjorn
arch/ia64/kernel/acpi-ext.c +75 -48
@@ -3,9 +3,9 @@* * Copyright (C) 2003 Hewlett-Packard * Copyright (C) Alex Williamson +* Copyright (C) Bjorn Helgaas * -* Vendor specific extensions to ACPI. These are used by both -* HP and NEC. +* Vendor specific extensions to ACPI. */ #include <linux/config.h>
@@ -16,58 +16,85 @@#include <asm/acpi-ext.h> -/* -* Note: Strictly speaking, this is only needed for HP and NEC machines. -* However, NEC machines identify themselves as DIG-compliant, so there is -* no easy way to #ifdef this out. -*/ +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 -hp_acpi_csr_space (acpi_handle obj,u64 *csr_base,u64 *csr_length) +acpi_vendor_resource_match (struct acpi_resource *resource,void *context) { -int i, offset =0 ; -acpi_status status; -struct acpi_buffer buf; -struct acpi_resource_vendor *res; -struct acpi_hp_vendor_long *hp_res; -efi_guid_t vendor_guid; - - *csr_base =0 ; - *csr_length =0 ; - - status =acpi_get_crs (obj, &buf); -if (ACPI_FAILURE (status)) { - printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n"); -return status; - } - - res = (struct acpi_resource_vendor *)acpi_get_crs_type (&buf, &offset,ACPI_RSTYPE_VENDOR ); -if (!res) { - printk(KERN_ERR PREFIX "Failed to find config space for device\n"); -acpi_dispose_crs (&buf); +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 =0 ; + +acpi_walk_resources (obj,METHOD_NAME__CRS , acpi_vendor_resource_match, &info); +if (!info.data)return AE_NOT_FOUND ; - } - hp_res = (struct acpi_hp_vendor_long *)(res->reserved); + *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; +int i; + + status =acpi_find_vendor_resource (obj, &hp_ccsr_descriptor, &data, &length); + +if (ACPI_FAILURE (status) || length !=16 ) +return AE_NOT_FOUND ; -if (res->length !=HP_CCSR_LENGTH || hp_res->guid_id !=HP_CCSR_TYPE ) { - printk(KERN_ERR PREFIX "Unknown Vendor data\n"); -acpi_dispose_crs (&buf); -return AE_TYPE ;/* Revisit error? */ - } - -memcpy (&vendor_guid, hp_res->guid,sizeof (efi_guid_t)); -if (efi_guidcmp (vendor_guid,HP_CCSR_GUID ) !=0 ) { - printk(KERN_ERR PREFIX "Vendor GUID does not match\n"); -acpi_dispose_crs (&buf); -return AE_TYPE ;/* Revisit error? */ - } - -for (i =0 ; i <8 ; i++) { - *csr_base |= ((u64)(hp_res->csr_base[i]) << (i *8 )); - *csr_length |= ((u64)(hp_res->csr_length[i]) << (i *8 )); - } +memcpy (csr_base, data,sizeof (*csr_base)); +memcpy (csr_length, data +8 ,sizeof (*csr_length)); +acpi_os_free (data); -acpi_dispose_crs (&buf);return AE_OK ; }
arch/ia64/kernel/acpi.c +0 -132
138 lines not on this page · raw message
include/asm-ia64/acpi-ext.h +2 -17
@@ -3,30 +3,15 @@* * Copyright (C) 2003 Hewlett-Packard * Copyright (C) Alex Williamson +* Copyright (C) Bjorn Helgaas * -* Vendor specific extensions to ACPI. The HP-specific extensiosn are also used by NEC. +* Vendor specific extensions to ACPI. */ #ifndef _ASM_IA64_ACPI_EXT_H#define _ASM_IA64_ACPI_EXT_H#include <linux/types.h> -#define HP_CCSR_LENGTH 0x21 -#define HP_CCSR_TYPE 0x2 -#define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, \ - 0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad) - -struct acpi_hp_vendor_long { -u8 guid_id; -u8 guid[16 ]; -u8 csr_base[8 ]; -u8 csr_length[8 ]; -}; -extern acpi_status hp_acpi_csr_space (acpi_handle ,u64 *base,u64 *length); -extern acpi_status acpi_get_crs (acpi_handle ,struct acpi_buffer *); -extern struct acpi_resource *acpi_get_crs_next (struct acpi_buffer *,int *); -extern union acpi_resource_data *acpi_get_crs_type (struct acpi_buffer *,int *,int ); -extern void acpi_dispose_crs (struct acpi_buffer *);#endif /* _ASM_IA64_ACPI_EXT_H */