X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Facpi%2Fresources%2Frsutils.c;h=25b5aedd661201eb7d6573d758d380e993025d1e;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=ee9ce13c053d76bc252fd8d4ee4a0a889528cd3f;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index ee9ce13c0..25b5aedd6 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2005, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,15 +41,395 @@ * POSSIBILITY OF SUCH DAMAGES. */ - #include #include #include - #define _COMPONENT ACPI_RESOURCES - ACPI_MODULE_NAME ("rsutils") +ACPI_MODULE_NAME("rsutils") + +/******************************************************************************* + * + * FUNCTION: acpi_rs_decode_bitmask + * + * PARAMETERS: Mask - Bitmask to decode + * List - Where the converted list is returned + * + * RETURN: Count of bits set (length of list) + * + * DESCRIPTION: Convert a bit mask into a list of values + * + ******************************************************************************/ +u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) +{ + acpi_native_uint i; + u8 bit_count; + + ACPI_FUNCTION_ENTRY(); + + /* Decode the mask bits */ + + for (i = 0, bit_count = 0; mask; i++) { + if (mask & 0x0001) { + list[bit_count] = (u8) i; + bit_count++; + } + + mask >>= 1; + } + + return (bit_count); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_encode_bitmask + * + * PARAMETERS: List - List of values to encode + * Count - Length of list + * + * RETURN: Encoded bitmask + * + * DESCRIPTION: Convert a list of values to an encoded bitmask + * + ******************************************************************************/ + +u16 acpi_rs_encode_bitmask(u8 * list, u8 count) +{ + acpi_native_uint i; + u16 mask; + + ACPI_FUNCTION_ENTRY(); + + /* Encode the list into a single bitmask */ + + for (i = 0, mask = 0; i < count; i++) { + mask |= (0x0001 << list[i]); + } + + return (mask); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_move_data + * + * PARAMETERS: Destination - Pointer to the destination descriptor + * Source - Pointer to the source descriptor + * item_count - How many items to move + * move_type - Byte width + * + * RETURN: None + * + * DESCRIPTION: Move multiple data items from one descriptor to another. Handles + * alignment issues and endian issues if necessary, as configured + * via the ACPI_MOVE_* macros. (This is why a memcpy is not used) + * + ******************************************************************************/ + +void +acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) +{ + acpi_native_uint i; + + ACPI_FUNCTION_ENTRY(); + + /* One move per item */ + + for (i = 0; i < item_count; i++) { + switch (move_type) { + /* + * For the 8-bit case, we can perform the move all at once + * since there are no alignment or endian issues + */ + case ACPI_RSC_MOVE8: + ACPI_MEMCPY(destination, source, item_count); + return; + + /* + * 16-, 32-, and 64-bit cases must use the move macros that perform + * endian conversion and/or accomodate hardware that cannot perform + * misaligned memory transfers + */ + case ACPI_RSC_MOVE16: + ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i], + &ACPI_CAST_PTR(u16, source)[i]); + break; + + case ACPI_RSC_MOVE32: + ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i], + &ACPI_CAST_PTR(u32, source)[i]); + break; + + case ACPI_RSC_MOVE64: + ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i], + &ACPI_CAST_PTR(u64, source)[i]); + break; + + default: + return; + } + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_resource_length + * + * PARAMETERS: total_length - Length of the AML descriptor, including + * the header and length fields. + * Aml - Pointer to the raw AML descriptor + * + * RETURN: None + * + * DESCRIPTION: Set the resource_length field of an AML + * resource descriptor, both Large and Small descriptors are + * supported automatically. Note: Descriptor Type field must + * be valid. + * + ******************************************************************************/ + +void +acpi_rs_set_resource_length(acpi_rsdesc_size total_length, + union aml_resource *aml) +{ + acpi_rs_length resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* Length is the total descriptor length minus the header length */ + + resource_length = (acpi_rs_length) + (total_length - acpi_ut_get_resource_header_length(aml)); + + /* Length is stored differently for large and small descriptors */ + + if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { + /* Large descriptor -- bytes 1-2 contain the 16-bit length */ + + ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, + &resource_length); + } else { + /* Small descriptor -- bits 2:0 of byte 0 contain the length */ + + aml->small_header.descriptor_type = (u8) + + /* Clear any existing length, preserving descriptor type bits */ + ((aml->small_header. + descriptor_type & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK) + + | resource_length); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_resource_header + * + * PARAMETERS: descriptor_type - Byte to be inserted as the type + * total_length - Length of the AML descriptor, including + * the header and length fields. + * Aml - Pointer to the raw AML descriptor + * + * RETURN: None + * + * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML + * resource descriptor, both Large and Small descriptors are + * supported automatically + * + ******************************************************************************/ + +void +acpi_rs_set_resource_header(u8 descriptor_type, + acpi_rsdesc_size total_length, + union aml_resource *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* Set the Resource Type */ + + aml->small_header.descriptor_type = descriptor_type; + + /* Set the Resource Length */ + + acpi_rs_set_resource_length(total_length, aml); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_strcpy + * + * PARAMETERS: Destination - Pointer to the destination string + * Source - Pointer to the source string + * + * RETURN: String length, including NULL terminator + * + * DESCRIPTION: Local string copy that returns the string length, saving a + * strcpy followed by a strlen. + * + ******************************************************************************/ + +static u16 acpi_rs_strcpy(char *destination, char *source) +{ + u16 i; + + ACPI_FUNCTION_ENTRY(); + + for (i = 0; source[i]; i++) { + destination[i] = source[i]; + } + + destination[i] = 0; + + /* Return string length including the NULL terminator */ + return ((u16) (i + 1)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_get_resource_source + * + * PARAMETERS: resource_length - Length field of the descriptor + * minimum_length - Minimum length of the descriptor (minus + * any optional fields) + * resource_source - Where the resource_source is returned + * Aml - Pointer to the raw AML descriptor + * string_ptr - (optional) where to store the actual + * resource_source string + * + * RETURN: Length of the string plus NULL terminator, rounded up to 32 bit + * + * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor + * to an internal resource descriptor + * + ******************************************************************************/ + +acpi_rs_length +acpi_rs_get_resource_source(acpi_rs_length resource_length, + acpi_rs_length minimum_length, + struct acpi_resource_source * resource_source, + union aml_resource * aml, char *string_ptr) +{ + acpi_rsdesc_size total_length; + u8 *aml_resource_source; + + ACPI_FUNCTION_ENTRY(); + + total_length = + resource_length + sizeof(struct aml_resource_large_header); + aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); + + /* + * resource_source is present if the length of the descriptor is longer than + * the minimum length. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the minimum length. + */ + if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) { + /* Get the resource_source_index */ + + resource_source->index = aml_resource_source[0]; + + resource_source->string_ptr = string_ptr; + if (!string_ptr) { + /* + * String destination pointer is not specified; Set the String + * pointer to the end of the current resource_source structure. + */ + resource_source->string_ptr = + ACPI_ADD_PTR(char, resource_source, + sizeof(struct acpi_resource_source)); + } + + /* + * In order for the struct_size to fall on a 32-bit boundary, calculate + * the length of the string (+1 for the NULL terminator) and expand the + * struct_size to the next 32-bit boundary. + * + * Zero the entire area of the buffer. + */ + total_length = + ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN + ((char *)&aml_resource_source[1]) + + 1); + ACPI_MEMSET(resource_source->string_ptr, 0, total_length); + + /* Copy the resource_source string to the destination */ + + resource_source->string_length = + acpi_rs_strcpy(resource_source->string_ptr, + (char *)&aml_resource_source[1]); + + return ((acpi_rs_length) total_length); + } + + /* resource_source is not present */ + + resource_source->index = 0; + resource_source->string_length = 0; + resource_source->string_ptr = NULL; + return (0); +} + +/******************************************************************************* + * + * FUNCTION: acpi_rs_set_resource_source + * + * PARAMETERS: Aml - Pointer to the raw AML descriptor + * minimum_length - Minimum length of the descriptor (minus + * any optional fields) + * resource_source - Internal resource_source + + * + * RETURN: Total length of the AML descriptor + * + * DESCRIPTION: Convert an optional resource_source from internal format to a + * raw AML resource descriptor + * + ******************************************************************************/ + +acpi_rsdesc_size +acpi_rs_set_resource_source(union aml_resource * aml, + acpi_rs_length minimum_length, + struct acpi_resource_source * resource_source) +{ + u8 *aml_resource_source; + acpi_rsdesc_size descriptor_length; + + ACPI_FUNCTION_ENTRY(); + + descriptor_length = minimum_length; + + /* Non-zero string length indicates presence of a resource_source */ + + if (resource_source->string_length) { + /* Point to the end of the AML descriptor */ + + aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); + + /* Copy the resource_source_index */ + + aml_resource_source[0] = (u8) resource_source->index; + + /* Copy the resource_source string */ + + ACPI_STRCPY((char *)&aml_resource_source[1], + resource_source->string_ptr); + + /* + * Add the length of the string (+ 1 for null terminator) to the + * final descriptor length + */ + descriptor_length += + ((acpi_rsdesc_size) resource_source->string_length + 1); + } + + /* Return the new total length of the AML descriptor */ + + return (descriptor_length); +} /******************************************************************************* * @@ -70,40 +450,35 @@ ******************************************************************************/ acpi_status -acpi_rs_get_prt_method_data ( - acpi_handle handle, - struct acpi_buffer *ret_buffer) +acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) { - union acpi_operand_object *obj_desc; - acpi_status status; - - - ACPI_FUNCTION_TRACE ("rs_get_prt_method_data"); + union acpi_operand_object *obj_desc; + acpi_status status; + ACPI_FUNCTION_TRACE("rs_get_prt_method_data"); /* Parameters guaranteed valid by caller */ - /* - * Execute the method, no parameters - */ - status = acpi_ut_evaluate_object (handle, "_PRT", ACPI_BTYPE_PACKAGE, &obj_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + /* Execute the method, no parameters */ + + status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRT, + ACPI_BTYPE_PACKAGE, &obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } /* * Create a resource linked list from the byte stream buffer that comes * back from the _CRS method execution. */ - status = acpi_rs_create_pci_routing_table (obj_desc, ret_buffer); + status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer); /* On exit, we must delete the object returned by evaluate_object */ - acpi_ut_remove_reference (obj_desc); - return_ACPI_STATUS (status); + acpi_ut_remove_reference(obj_desc); + return_ACPI_STATUS(status); } - /******************************************************************************* * * FUNCTION: acpi_rs_get_crs_method_data @@ -123,25 +498,21 @@ acpi_rs_get_prt_method_data ( ******************************************************************************/ acpi_status -acpi_rs_get_crs_method_data ( - acpi_handle handle, - struct acpi_buffer *ret_buffer) +acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) { - union acpi_operand_object *obj_desc; - acpi_status status; - - - ACPI_FUNCTION_TRACE ("rs_get_crs_method_data"); + union acpi_operand_object *obj_desc; + acpi_status status; + ACPI_FUNCTION_TRACE("rs_get_crs_method_data"); /* Parameters guaranteed valid by caller */ - /* - * Execute the method, no parameters - */ - status = acpi_ut_evaluate_object (handle, "_CRS", ACPI_BTYPE_BUFFER, &obj_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + /* Execute the method, no parameters */ + + status = acpi_ut_evaluate_object(handle, METHOD_NAME__CRS, + ACPI_BTYPE_BUFFER, &obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } /* @@ -149,15 +520,14 @@ acpi_rs_get_crs_method_data ( * byte stream buffer that comes back from the _CRS method * execution. */ - status = acpi_rs_create_resource_list (obj_desc, ret_buffer); + status = acpi_rs_create_resource_list(obj_desc, ret_buffer); /* on exit, we must delete the object returned by evaluate_object */ - acpi_ut_remove_reference (obj_desc); - return_ACPI_STATUS (status); + acpi_ut_remove_reference(obj_desc); + return_ACPI_STATUS(status); } - /******************************************************************************* * * FUNCTION: acpi_rs_get_prs_method_data @@ -175,27 +545,24 @@ acpi_rs_get_crs_method_data ( * and the contents of the callers buffer is undefined. * ******************************************************************************/ + #ifdef ACPI_FUTURE_USAGE acpi_status -acpi_rs_get_prs_method_data ( - acpi_handle handle, - struct acpi_buffer *ret_buffer) +acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) { - union acpi_operand_object *obj_desc; - acpi_status status; - - - ACPI_FUNCTION_TRACE ("rs_get_prs_method_data"); + union acpi_operand_object *obj_desc; + acpi_status status; + ACPI_FUNCTION_TRACE("rs_get_prs_method_data"); /* Parameters guaranteed valid by caller */ - /* - * Execute the method, no parameters - */ - status = acpi_ut_evaluate_object (handle, "_PRS", ACPI_BTYPE_BUFFER, &obj_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + /* Execute the method, no parameters */ + + status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRS, + ACPI_BTYPE_BUFFER, &obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } /* @@ -203,21 +570,21 @@ acpi_rs_get_prs_method_data ( * byte stream buffer that comes back from the _CRS method * execution. */ - status = acpi_rs_create_resource_list (obj_desc, ret_buffer); + status = acpi_rs_create_resource_list(obj_desc, ret_buffer); /* on exit, we must delete the object returned by evaluate_object */ - acpi_ut_remove_reference (obj_desc); - return_ACPI_STATUS (status); + acpi_ut_remove_reference(obj_desc); + return_ACPI_STATUS(status); } -#endif /* ACPI_FUTURE_USAGE */ - +#endif /* ACPI_FUTURE_USAGE */ /******************************************************************************* * * FUNCTION: acpi_rs_get_method_data * * PARAMETERS: Handle - a handle to the containing object + * Path - Path to method, relative to Handle * ret_buffer - a pointer to a buffer structure for the * results * @@ -232,26 +599,22 @@ acpi_rs_get_prs_method_data ( ******************************************************************************/ acpi_status -acpi_rs_get_method_data ( - acpi_handle handle, - char *path, - struct acpi_buffer *ret_buffer) +acpi_rs_get_method_data(acpi_handle handle, + char *path, struct acpi_buffer *ret_buffer) { - union acpi_operand_object *obj_desc; - acpi_status status; - - - ACPI_FUNCTION_TRACE ("rs_get_method_data"); + union acpi_operand_object *obj_desc; + acpi_status status; + ACPI_FUNCTION_TRACE("rs_get_method_data"); /* Parameters guaranteed valid by caller */ - /* - * Execute the method, no parameters - */ - status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + /* Execute the method, no parameters */ + + status = + acpi_ut_evaluate_object(handle, path, ACPI_BTYPE_BUFFER, &obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } /* @@ -259,12 +622,12 @@ acpi_rs_get_method_data ( * byte stream buffer that comes back from the method * execution. */ - status = acpi_rs_create_resource_list (obj_desc, ret_buffer); + status = acpi_rs_create_resource_list(obj_desc, ret_buffer); /* On exit, we must delete the object returned by evaluate_object */ - acpi_ut_remove_reference (obj_desc); - return_ACPI_STATUS (status); + acpi_ut_remove_reference(obj_desc); + return_ACPI_STATUS(status); } /******************************************************************************* @@ -286,18 +649,14 @@ acpi_rs_get_method_data ( ******************************************************************************/ acpi_status -acpi_rs_set_srs_method_data ( - acpi_handle handle, - struct acpi_buffer *in_buffer) +acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer) { - struct acpi_parameter_info info; - union acpi_operand_object *params[2]; - acpi_status status; - struct acpi_buffer buffer; - - - ACPI_FUNCTION_TRACE ("rs_set_srs_method_data"); + struct acpi_parameter_info info; + union acpi_operand_object *params[2]; + acpi_status status; + struct acpi_buffer buffer; + ACPI_FUNCTION_TRACE("rs_set_srs_method_data"); /* Parameters guaranteed valid by caller */ @@ -309,48 +668,43 @@ acpi_rs_set_srs_method_data ( * Convert the linked list into a byte stream */ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_rs_create_byte_stream (in_buffer->pointer, &buffer); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - /* - * Init the param object - */ - params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); + /* Init the param object */ + + params[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER); if (!params[0]) { - acpi_os_free (buffer.pointer); - return_ACPI_STATUS (AE_NO_MEMORY); + acpi_os_free(buffer.pointer); + return_ACPI_STATUS(AE_NO_MEMORY); } - /* - * Set up the parameter object - */ - params[0]->buffer.length = (u32) buffer.length; + /* Set up the parameter object */ + + params[0]->buffer.length = (u32) buffer.length; params[0]->buffer.pointer = buffer.pointer; - params[0]->common.flags = AOPOBJ_DATA_VALID; + params[0]->common.flags = AOPOBJ_DATA_VALID; params[1] = NULL; info.node = handle; info.parameters = params; info.parameter_type = ACPI_PARAM_ARGS; - /* - * Execute the method, no return value - */ - status = acpi_ns_evaluate_relative ("_SRS", &info); - if (ACPI_SUCCESS (status)) { + /* Execute the method, no return value */ + + status = acpi_ns_evaluate_relative(METHOD_NAME__SRS, &info); + if (ACPI_SUCCESS(status)) { /* Delete any return object (especially if implicit_return is enabled) */ if (info.return_object) { - acpi_ut_remove_reference (info.return_object); + acpi_ut_remove_reference(info.return_object); } } - /* - * Clean up and return the status from acpi_ns_evaluate_relative - */ - acpi_ut_remove_reference (params[0]); - return_ACPI_STATUS (status); -} + /* Clean up and return the status from acpi_ns_evaluate_relative */ + acpi_ut_remove_reference(params[0]); + return_ACPI_STATUS(status); +}