diff options
Diffstat (limited to 'drivers/acpi/utilities/utmisc.c')
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 209 |
1 files changed, 123 insertions, 86 deletions
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 2ce872d7589..7364f5f8c9c 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.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 @@ -63,6 +63,8 @@ ACPI_MODULE_NAME("utmisc") acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) { acpi_native_uint i; + acpi_native_uint j; + acpi_native_uint k; acpi_status status; ACPI_FUNCTION_TRACE("ut_allocate_owner_id"); @@ -70,8 +72,8 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) /* Guard against multiple allocations of ID to the same location */ if (*owner_id) { - ACPI_REPORT_ERROR(("Owner ID [%2.2X] already exists\n", - *owner_id)); + ACPI_ERROR((AE_INFO, "Owner ID [%2.2X] already exists", + *owner_id)); return_ACPI_STATUS(AE_ALREADY_EXISTS); } @@ -82,31 +84,67 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) return_ACPI_STATUS(status); } - /* Find a free owner ID */ + /* + * Find a free owner ID, cycle through all possible IDs on repeated + * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have + * to be scanned twice. + */ + for (i = 0, j = acpi_gbl_last_owner_id_index; + i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) { + if (j >= ACPI_NUM_OWNERID_MASKS) { + j = 0; /* Wraparound to start of mask array */ + } + + for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) { + if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) { + /* There are no free IDs in this mask */ - for (i = 0; i < 64; i++) { - if (!(acpi_gbl_owner_id_mask & (1ULL << i))) { - ACPI_DEBUG_PRINT((ACPI_DB_VALUES, - "Current owner_id mask: %16.16LX New ID: %2.2X\n", - acpi_gbl_owner_id_mask, - (unsigned int)(i + 1))); + break; + } - acpi_gbl_owner_id_mask |= (1ULL << i); - *owner_id = (acpi_owner_id) (i + 1); - goto exit; + if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) { + /* + * Found a free ID. The actual ID is the bit index plus one, + * making zero an invalid Owner ID. Save this as the last ID + * allocated and update the global ID mask. + */ + acpi_gbl_owner_id_mask[j] |= (1 << k); + + acpi_gbl_last_owner_id_index = (u8) j; + acpi_gbl_next_owner_id_offset = (u8) (k + 1); + + /* + * Construct encoded ID from the index and bit position + * + * Note: Last [j].k (bit 255) is never used and is marked + * permanently allocated (prevents +1 overflow) + */ + *owner_id = + (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j)); + + ACPI_DEBUG_PRINT((ACPI_DB_VALUES, + "Allocated owner_id: %2.2X\n", + (unsigned int)*owner_id)); + goto exit; + } } + + acpi_gbl_next_owner_id_offset = 0; } /* - * If we are here, all owner_ids have been allocated. This probably should + * All owner_ids have been allocated. This typically should * not happen since the IDs are reused after deallocation. The IDs are * allocated upon table load (one per table) and method execution, and * they are released when a table is unloaded or a method completes * execution. + * + * If this error happens, there may be very deep nesting of invoked control + * methods, or there may be a bug where the IDs are not released. */ - *owner_id = 0; status = AE_OWNER_ID_LIMIT; - ACPI_REPORT_ERROR(("Could not allocate new owner_id (64 max), AE_OWNER_ID_LIMIT\n")); + ACPI_ERROR((AE_INFO, + "Could not allocate new owner_id (255 max), AE_OWNER_ID_LIMIT")); exit: (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); @@ -123,7 +161,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) * control method or unloading a table. Either way, we would * ignore any error anyway. * - * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 64 + * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255 * ******************************************************************************/ @@ -131,6 +169,8 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) { acpi_owner_id owner_id = *owner_id_ptr; acpi_status status; + acpi_native_uint index; + u32 bit; ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id); @@ -140,8 +180,8 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) /* Zero is not a valid owner_iD */ - if ((owner_id == 0) || (owner_id > 64)) { - ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id)); + if (owner_id == 0) { + ACPI_ERROR((AE_INFO, "Invalid owner_id: %2.2X", owner_id)); return_VOID; } @@ -156,10 +196,19 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) owner_id--; + /* Decode ID to index/offset pair */ + + index = ACPI_DIV_32(owner_id); + bit = 1 << ACPI_MOD_32(owner_id); + /* Free the owner ID only if it is valid */ - if (acpi_gbl_owner_id_mask & (1ULL << owner_id)) { - acpi_gbl_owner_id_mask ^= (1ULL << owner_id); + if (acpi_gbl_owner_id_mask[index] & bit) { + acpi_gbl_owner_id_mask[index] ^= bit; + } else { + ACPI_ERROR((AE_INFO, + "Release of non-allocated owner_id: %2.2X", + owner_id + 1)); } (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); @@ -790,109 +839,97 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) /******************************************************************************* * - * FUNCTION: acpi_ut_get_resource_end_tag + * FUNCTION: acpi_ut_error, acpi_ut_warning, acpi_ut_info * - * PARAMETERS: obj_desc - The resource template buffer object + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Format - Printf format string + additional args * - * RETURN: Pointer to the end tag + * RETURN: None * - * DESCRIPTION: Find the END_TAG resource descriptor in a resource template + * DESCRIPTION: Print message with module/line/version info * ******************************************************************************/ -u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc) +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_error(char *module_name, u32 line_number, char *format, ...) { - u8 buffer_byte; - u8 *buffer; - u8 *end_buffer; + va_list args; - buffer = obj_desc->buffer.pointer; - end_buffer = buffer + obj_desc->buffer.length; + acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); - while (buffer < end_buffer) { - buffer_byte = *buffer; - if (buffer_byte & ACPI_RDESC_TYPE_MASK) { - /* Large Descriptor - Length is next 2 bytes */ + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); +} - buffer += ((*(buffer + 1) | (*(buffer + 2) << 8)) + 3); - } else { - /* Small Descriptor. End Tag will be found here */ +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_exception(char *module_name, + u32 line_number, acpi_status status, char *format, ...) +{ + va_list args; - if ((buffer_byte & ACPI_RDESC_SMALL_MASK) == - ACPI_RDESC_TYPE_END_TAG) { - /* Found the end tag descriptor, all done. */ + acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name, + line_number, acpi_format_exception(status)); - return (buffer); - } + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); +} - /* Length is in the header */ +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) +{ + va_list args; - buffer += ((buffer_byte & 0x07) + 1); - } - } + acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); +} + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_info(char *module_name, u32 line_number, char *format, ...) +{ + va_list args; - /* End tag not found */ + acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number); - return (NULL); + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); } /******************************************************************************* * - * FUNCTION: acpi_ut_report_error + * FUNCTION: acpi_ut_report_error, Warning, Info * * PARAMETERS: module_name - Caller's module name (for error output) * line_number - Caller's line number (for error output) - * component_id - Caller's component ID (for error output) * * RETURN: None * * DESCRIPTION: Print error message * + * Note: Legacy only, should be removed when no longer used by drivers. + * ******************************************************************************/ -void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id) +void acpi_ut_report_error(char *module_name, u32 line_number) { - acpi_os_printf("%8s-%04d: *** Error: ", module_name, line_number); + acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); } -/******************************************************************************* - * - * FUNCTION: acpi_ut_report_warning - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * component_id - Caller's component ID (for error output) - * - * RETURN: None - * - * DESCRIPTION: Print warning message - * - ******************************************************************************/ - -void -acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id) +void acpi_ut_report_warning(char *module_name, u32 line_number) { - acpi_os_printf("%8s-%04d: *** Warning: ", module_name, line_number); + acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); } -/******************************************************************************* - * - * FUNCTION: acpi_ut_report_info - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * component_id - Caller's component ID (for error output) - * - * RETURN: None - * - * DESCRIPTION: Print information message - * - ******************************************************************************/ - -void acpi_ut_report_info(char *module_name, u32 line_number, u32 component_id) +void acpi_ut_report_info(char *module_name, u32 line_number) { - acpi_os_printf("%8s-%04d: *** Info: ", module_name, line_number); + acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number); } |