📄 utmisc.c
字号:
/******************************************************************************* * * Module Name: utmisc - common utility procedures * ******************************************************************************//* * Copyright (C) 2000 - 2005, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */#include <acpi/acpi.h>#include <acpi/acnamesp.h>#define _COMPONENT ACPI_UTILITIESACPI_MODULE_NAME("utmisc")/******************************************************************************* * * FUNCTION: acpi_ut_allocate_owner_id * * PARAMETERS: owner_id - Where the new owner ID is returned * * RETURN: Status * * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to * track objects created by the table or method, to be deleted * when the method exits or the table is unloaded. * ******************************************************************************/acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id){ acpi_native_uint i; acpi_status status; ACPI_FUNCTION_TRACE("ut_allocate_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)); return_ACPI_STATUS(AE_ALREADY_EXISTS); } /* Mutex for the global ID mask */ status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Find a free owner ID */ 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))); acpi_gbl_owner_id_mask |= (1ULL << i); *owner_id = (acpi_owner_id) (i + 1); goto exit; } } /* * If we are here, all owner_ids have been allocated. This probably 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. */ *owner_id = 0; status = AE_OWNER_ID_LIMIT; ACPI_REPORT_ERROR(("Could not allocate new owner_id (64 max), AE_OWNER_ID_LIMIT\n")); exit: (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION: acpi_ut_release_owner_id * * PARAMETERS: owner_id_ptr - Pointer to a previously allocated owner_iD * * RETURN: None. No error is returned because we are either exiting a * 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 * ******************************************************************************/void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr){ acpi_owner_id owner_id = *owner_id_ptr; acpi_status status; ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id); /* Always clear the input owner_id (zero is an invalid ID) */ *owner_id_ptr = 0; /* 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)); return_VOID; } /* Mutex for the global ID mask */ status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); if (ACPI_FAILURE(status)) { return_VOID; } /* Normalize the ID to zero */ 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); } (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); return_VOID;}/******************************************************************************* * * FUNCTION: acpi_ut_strupr (strupr) * * PARAMETERS: src_string - The source string to convert * * RETURN: None * * DESCRIPTION: Convert string to uppercase * * NOTE: This is not a POSIX function, so it appears here, not in utclib.c * ******************************************************************************/void acpi_ut_strupr(char *src_string){ char *string; ACPI_FUNCTION_ENTRY(); if (!src_string) { return; } /* Walk entire string, uppercasing the letters */ for (string = src_string; *string; string++) { *string = (char)ACPI_TOUPPER(*string); } return;}/******************************************************************************* * * FUNCTION: acpi_ut_print_string * * PARAMETERS: String - Null terminated ASCII string * max_length - Maximum output length * * RETURN: None * * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape * sequences. * ******************************************************************************/void acpi_ut_print_string(char *string, u8 max_length){ u32 i; if (!string) { acpi_os_printf("<\"NULL STRING PTR\">"); return; } acpi_os_printf("\""); for (i = 0; string[i] && (i < max_length); i++) { /* Escape sequences */ switch (string[i]) { case 0x07: acpi_os_printf("\\a"); /* BELL */ break; case 0x08: acpi_os_printf("\\b"); /* BACKSPACE */ break; case 0x0C: acpi_os_printf("\\f"); /* FORMFEED */ break; case 0x0A: acpi_os_printf("\\n"); /* LINEFEED */ break; case 0x0D: acpi_os_printf("\\r"); /* CARRIAGE RETURN */ break; case 0x09: acpi_os_printf("\\t"); /* HORIZONTAL TAB */ break; case 0x0B: acpi_os_printf("\\v"); /* VERTICAL TAB */ break; case '\'': /* Single Quote */ case '\"': /* Double Quote */ case '\\': /* Backslash */ acpi_os_printf("\\%c", (int)string[i]); break; default: /* Check for printable character or hex escape */ if (ACPI_IS_PRINT(string[i])) { /* This is a normal character */ acpi_os_printf("%c", (int)string[i]); } else { /* All others will be Hex escapes */ acpi_os_printf("\\x%2.2X", (s32) string[i]); } break; } } acpi_os_printf("\""); if (i == max_length && string[i]) { acpi_os_printf("..."); }}/******************************************************************************* * * FUNCTION: acpi_ut_dword_byte_swap * * PARAMETERS: Value - Value to be converted * * RETURN: u32 integer with bytes swapped * * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) * ******************************************************************************/u32 acpi_ut_dword_byte_swap(u32 value){ union { u32 value; u8 bytes[4]; } out; union { u32 value; u8 bytes[4]; } in; ACPI_FUNCTION_ENTRY(); in.value = value; out.bytes[0] = in.bytes[3]; out.bytes[1] = in.bytes[2]; out.bytes[2] = in.bytes[1]; out.bytes[3] = in.bytes[0]; return (out.value);}/******************************************************************************* * * FUNCTION: acpi_ut_set_integer_width * * PARAMETERS: Revision From DSDT header * * RETURN: None * * DESCRIPTION: Set the global integer bit width based upon the revision * of the DSDT. For Revision 1 and 0, Integers are 32 bits. * For Revision 2 and above, Integers are 64 bits. Yes, this * makes a difference. * ******************************************************************************/void acpi_ut_set_integer_width(u8 revision){ if (revision <= 1) { acpi_gbl_integer_bit_width = 32; acpi_gbl_integer_nybble_width = 8; acpi_gbl_integer_byte_width = 4; } else { acpi_gbl_integer_bit_width = 64; acpi_gbl_integer_nybble_width = 16; acpi_gbl_integer_byte_width = 8; }}#ifdef ACPI_DEBUG_OUTPUT/******************************************************************************* * * FUNCTION: acpi_ut_display_init_pathname * * PARAMETERS: Type - Object type of the node * obj_handle - Handle whose pathname will be displayed * Path - Additional path string to be appended. * (NULL if no extra path) * * RETURN: acpi_status * * DESCRIPTION: Display full pathname of an object, DEBUG ONLY * ******************************************************************************/voidacpi_ut_display_init_pathname(u8 type, struct acpi_namespace_node *obj_handle, char *path){ acpi_status status; struct acpi_buffer buffer; ACPI_FUNCTION_ENTRY(); /* Only print the path if the appropriate debug level is enabled */ if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { return; } /* Get the full pathname to the node */ buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; status = acpi_ns_handle_to_pathname(obj_handle, &buffer); if (ACPI_FAILURE(status)) { return; } /* Print what we're doing */ switch (type) { case ACPI_TYPE_METHOD: acpi_os_printf("Executing "); break; default: acpi_os_printf("Initializing "); break; } /* Print the object type and pathname */ acpi_os_printf("%-12s %s", acpi_ut_get_type_name(type), (char *)buffer.pointer); /* Extra path is used to append names like _STA, _INI, etc. */ if (path) { acpi_os_printf(".%s", path); } acpi_os_printf("\n"); ACPI_MEM_FREE(buffer.pointer);}#endif/******************************************************************************* * * FUNCTION: acpi_ut_valid_acpi_name * * PARAMETERS: Name - The name to be examined * * RETURN: TRUE if the name is valid, FALSE otherwise * * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: * 1) Upper case alpha * 2) numeric * 3) underscore * ******************************************************************************/u8 acpi_ut_valid_acpi_name(u32 name){ char *name_ptr = (char *)&name; char character; acpi_native_uint i; ACPI_FUNCTION_ENTRY(); for (i = 0; i < ACPI_NAME_SIZE; i++) { character = *name_ptr; name_ptr++; if (!((character == '_') || (character >= 'A' && character <= 'Z') || (character >= '0' && character <= '9'))) { return (FALSE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -