summaryrefslogtreecommitdiff
path: root/drivers/acpi/utilities
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/utilities')
-rw-r--r--drivers/acpi/utilities/Makefile8
-rw-r--r--drivers/acpi/utilities/utalloc.c988
-rw-r--r--drivers/acpi/utilities/utcopy.c930
-rw-r--r--drivers/acpi/utilities/utdebug.c624
-rw-r--r--drivers/acpi/utilities/utdelete.c700
-rw-r--r--drivers/acpi/utilities/uteval.c696
-rw-r--r--drivers/acpi/utilities/utglobal.c935
-rw-r--r--drivers/acpi/utilities/utinit.c266
-rw-r--r--drivers/acpi/utilities/utmath.c333
-rw-r--r--drivers/acpi/utilities/utmisc.c1516
-rw-r--r--drivers/acpi/utilities/utobject.c671
-rw-r--r--drivers/acpi/utilities/utxface.c525
12 files changed, 8192 insertions, 0 deletions
diff --git a/drivers/acpi/utilities/Makefile b/drivers/acpi/utilities/Makefile
new file mode 100644
index 000000000000..939c447dd52a
--- /dev/null
+++ b/drivers/acpi/utilities/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
+ utcopy.o utdelete.o utglobal.o utmath.o utobject.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
new file mode 100644
index 000000000000..3313439c4bc7
--- /dev/null
+++ b/drivers/acpi/utilities/utalloc.c
@@ -0,0 +1,988 @@
+/******************************************************************************
+ *
+ * Module Name: utalloc - local cache and memory allocation routines
+ *
+ *****************************************************************************/
+
+/*
+ * 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>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utalloc")
+
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_ut_release_to_cache
+ *
+ * PARAMETERS: list_id - Memory list/cache ID
+ * Object - The object to be released
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release an object to the specified cache. If cache is full,
+ * the object is deleted.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_release_to_cache (
+ u32 list_id,
+ void *object)
+{
+ struct acpi_memory_list *cache_info;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ cache_info = &acpi_gbl_memory_lists[list_id];
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+
+ /* If walk cache is full, just free this wallkstate object */
+
+ if (cache_info->cache_depth >= cache_info->max_cache_depth) {
+ ACPI_MEM_FREE (object);
+ ACPI_MEM_TRACKING (cache_info->total_freed++);
+ }
+
+ /* Otherwise put this object back into the cache */
+
+ else {
+ if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
+ return;
+ }
+
+ /* Mark the object as cached */
+
+ ACPI_MEMSET (object, 0xCA, cache_info->object_size);
+ ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED);
+
+ /* Put the object at the head of the cache list */
+
+ * (ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head;
+ cache_info->list_head = object;
+ cache_info->cache_depth++;
+
+ (void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
+ }
+
+#else
+
+ /* Object cache is disabled; just free the object */
+
+ ACPI_MEM_FREE (object);
+ ACPI_MEM_TRACKING (cache_info->total_freed++);
+#endif
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_ut_acquire_from_cache
+ *
+ * PARAMETERS: list_id - Memory list ID
+ *
+ * RETURN: A requested object. NULL if the object could not be
+ * allocated.
+ *
+ * DESCRIPTION: Get an object from the specified cache. If cache is empty,
+ * the object is allocated.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_acquire_from_cache (
+ u32 list_id)
+{
+ struct acpi_memory_list *cache_info;
+ void *object;
+
+
+ ACPI_FUNCTION_NAME ("ut_acquire_from_cache");
+
+
+ cache_info = &acpi_gbl_memory_lists[list_id];
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+
+ if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
+ return (NULL);
+ }
+
+ ACPI_MEM_TRACKING (cache_info->cache_requests++);
+
+ /* Check the cache first */
+
+ if (cache_info->list_head) {
+ /* There is an object available, use it */
+
+ object = cache_info->list_head;
+ cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset])));
+
+ ACPI_MEM_TRACKING (cache_info->cache_hits++);
+ cache_info->cache_depth--;
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n",
+ object, acpi_gbl_memory_lists[list_id].list_name));
+#endif
+
+ if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
+ return (NULL);
+ }
+
+ /* Clear (zero) the previously used Object */
+
+ ACPI_MEMSET (object, 0, cache_info->object_size);
+ }
+
+ else {
+ /* The cache is empty, create a new object */
+
+ /* Avoid deadlock with ACPI_MEM_CALLOCATE */
+
+ if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
+ return (NULL);
+ }
+
+ object = ACPI_MEM_CALLOCATE (cache_info->object_size);
+ ACPI_MEM_TRACKING (cache_info->total_allocated++);
+ }
+
+#else
+
+ /* Object cache is disabled; just allocate the object */
+
+ object = ACPI_MEM_CALLOCATE (cache_info->object_size);
+ ACPI_MEM_TRACKING (cache_info->total_allocated++);
+#endif
+
+ return (object);
+}
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+/******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_generic_cache
+ *
+ * PARAMETERS: list_id - Memory list ID
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Free all objects within the requested cache.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_generic_cache (
+ u32 list_id)
+{
+ struct acpi_memory_list *cache_info;
+ char *next;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ cache_info = &acpi_gbl_memory_lists[list_id];
+ while (cache_info->list_head) {
+ /* Delete one cached state object */
+
+ next = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) cache_info->list_head)[cache_info->link_offset])));
+ ACPI_MEM_FREE (cache_info->list_head);
+
+ cache_info->list_head = next;
+ cache_info->cache_depth--;
+ }
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_validate_buffer
+ *
+ * PARAMETERS: Buffer - Buffer descriptor to be validated
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_validate_buffer (
+ struct acpi_buffer *buffer)
+{
+
+ /* Obviously, the structure pointer must be valid */
+
+ if (!buffer) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Special semantics for the length */
+
+ if ((buffer->length == ACPI_NO_BUFFER) ||
+ (buffer->length == ACPI_ALLOCATE_BUFFER) ||
+ (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
+ return (AE_OK);
+ }
+
+ /* Length is valid, the buffer pointer must be also */
+
+ if (!buffer->pointer) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_initialize_buffer
+ *
+ * PARAMETERS: Buffer - Buffer to be validated
+ * required_length - Length needed
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validate that the buffer is of the required length or
+ * allocate a new buffer. Returned buffer is always zeroed.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_initialize_buffer (
+ struct acpi_buffer *buffer,
+ acpi_size required_length)
+{
+ acpi_status status = AE_OK;
+
+
+ switch (buffer->length) {
+ case ACPI_NO_BUFFER:
+
+ /* Set the exception and returned the required length */
+
+ status = AE_BUFFER_OVERFLOW;
+ break;
+
+
+ case ACPI_ALLOCATE_BUFFER:
+
+ /* Allocate a new buffer */
+
+ buffer->pointer = acpi_os_allocate (required_length);
+ if (!buffer->pointer) {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Clear the buffer */
+
+ ACPI_MEMSET (buffer->pointer, 0, required_length);
+ break;
+
+
+ case ACPI_ALLOCATE_LOCAL_BUFFER:
+
+ /* Allocate a new buffer with local interface to allow tracking */
+
+ buffer->pointer = ACPI_MEM_CALLOCATE (required_length);
+ if (!buffer->pointer) {
+ return (AE_NO_MEMORY);
+ }
+ break;
+
+
+ default:
+
+ /* Existing buffer: Validate the size of the buffer */
+
+ if (buffer->length < required_length) {
+ status = AE_BUFFER_OVERFLOW;
+ break;
+ }
+
+ /* Clear the buffer */
+
+ ACPI_MEMSET (buffer->pointer, 0, required_length);
+ break;
+ }
+
+ buffer->length = required_length;
+ return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_allocate
+ *
+ * PARAMETERS: Size - Size of the allocation
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: The subsystem's equivalent of malloc.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_allocate (
+ acpi_size size,
+ u32 component,
+ char *module,
+ u32 line)
+{
+ void *allocation;
+
+
+ ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size);
+
+
+ /* Check for an inadvertent size of zero bytes */
+
+ if (!size) {
+ _ACPI_REPORT_ERROR (module, line, component,
+ ("ut_allocate: Attempt to allocate zero bytes\n"));
+ size = 1;
+ }
+
+ allocation = acpi_os_allocate (size);
+ if (!allocation) {
+ /* Report allocation error */
+
+ _ACPI_REPORT_ERROR (module, line, component,
+ ("ut_allocate: Could not allocate size %X\n", (u32) size));
+
+ return_PTR (NULL);
+ }
+
+ return_PTR (allocation);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_callocate
+ *
+ * PARAMETERS: Size - Size of the allocation
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: Subsystem equivalent of calloc.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_callocate (
+ acpi_size size,
+ u32 component,
+ char *module,
+ u32 line)
+{
+ void *allocation;
+
+
+ ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size);
+
+
+ /* Check for an inadvertent size of zero bytes */
+
+ if (!size) {
+ _ACPI_REPORT_ERROR (module, line, component,
+ ("ut_callocate: Attempt to allocate zero bytes\n"));
+ return_PTR (NULL);
+ }
+
+ allocation = acpi_os_allocate (size);
+ if (!allocation) {
+ /* Report allocation error */
+
+ _ACPI_REPORT_ERROR (module, line, component,
+ ("ut_callocate: Could not allocate size %X\n", (u32) size));
+ return_PTR (NULL);
+ }
+
+ /* Clear the memory block */
+
+ ACPI_MEMSET (allocation, 0, size);
+ return_PTR (allocation);
+}
+
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+/*
+ * These procedures are used for tracking memory leaks in the subsystem, and
+ * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
+ *
+ * Each memory allocation is tracked via a doubly linked list. Each
+ * element contains the caller's component, module name, function name, and
+ * line number. acpi_ut_allocate and acpi_ut_callocate call
+ * acpi_ut_track_allocation to add an element to the list; deletion
+ * occurs in the body of acpi_ut_free.
+ */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_allocate_and_track
+ *
+ * PARAMETERS: Size - Size of the allocation
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: The subsystem's equivalent of malloc.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_allocate_and_track (
+ acpi_size size,
+ u32 component,
+ char *module,
+ u32 line)
+{
+ struct acpi_debug_mem_block *allocation;
+ acpi_status status;
+
+
+ allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component,
+ module, line);
+ if (!allocation) {
+ return (NULL);
+ }
+
+ status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
+ ACPI_MEM_MALLOC, component, module, line);
+ if (ACPI_FAILURE (status)) {
+ acpi_os_free (allocation);
+ return (NULL);
+ }
+
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
+
+ return ((void *) &allocation->user_space);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_callocate_and_track
+ *
+ * PARAMETERS: Size - Size of the allocation
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: Subsystem equivalent of calloc.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_callocate_and_track (
+ acpi_size size,
+ u32 component,
+ char *module,
+ u32 line)
+{
+ struct acpi_debug_mem_block *allocation;
+ acpi_status status;
+
+
+ allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component,
+ module, line);
+ if (!allocation) {
+ /* Report allocation error */
+
+ _ACPI_REPORT_ERROR (module, line, component,
+ ("ut_callocate: Could not allocate size %X\n", (u32) size));
+ return (NULL);
+ }
+
+ status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
+ ACPI_MEM_CALLOC, component, module, line);
+ if (ACPI_FAILURE (status)) {
+ acpi_os_free (allocation);
+ return (NULL);
+ }
+
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
+
+ return ((void *) &allocation->user_space);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_free_and_track
+ *
+ * PARAMETERS: Allocation - Address of the memory to deallocate
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Frees the memory at Allocation
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_free_and_track (
+ void *allocation,
+ u32 component,
+ char *module,
+ u32 line)
+{
+ struct acpi_debug_mem_block *debug_block;
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation);
+
+
+ if (NULL == allocation) {
+ _ACPI_REPORT_ERROR (module, line, component,
+ ("acpi_ut_free: Attempt to delete a NULL address\n"));
+
+ return_VOID;
+ }
+
+ debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block,
+ (((char *) allocation) - sizeof (struct acpi_debug_mem_header)));
+
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++;
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size;
+
+ status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block,
+ component, module, line);
+ if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n",
+ acpi_format_exception (status)));
+ }
+
+ acpi_os_free (debug_block);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_find_allocation
+ *
+ * PARAMETERS: list_id - Memory list to search
+ * Allocation - Address of allocated memory
+ *
+ * RETURN: A list element if found; NULL otherwise.
+ *
+ * DESCRIPTION: Searches for an element in the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+struct acpi_debug_mem_block *
+acpi_ut_find_allocation (
+ u32 list_id,
+ void *allocation)
+{
+ struct acpi_debug_mem_block *element;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if (list_id > ACPI_MEM_LIST_MAX) {
+ return (NULL);
+ }
+
+ element = acpi_gbl_memory_lists[list_id].list_head;
+
+ /* Search for the address. */
+
+ while (element) {
+ if (element == allocation) {
+ return (element);
+ }
+
+ element = element->next;
+ }
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_track_allocation
+ *
+ * PARAMETERS: list_id - Memory list to search
+ * Allocation - Address of allocated memory
+ * Size - Size of the allocation
+ * alloc_type - MEM_MALLOC or MEM_CALLOC
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Inserts an element into the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_track_allocation (
+ u32 list_id,
+ struct acpi_debug_mem_block *allocation,
+ acpi_size size,
+ u8 alloc_type,
+ u32 component,
+ char *module,
+ u32 line)
+{
+ struct acpi_memory_list *mem_list;
+ struct acpi_debug_mem_block *element;
+ acpi_status status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
+
+
+ if (list_id > ACPI_MEM_LIST_MAX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ mem_list = &acpi_gbl_memory_lists[list_id];
+ status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /*
+ * Search list for this address to make sure it is not already on the list.
+ * This will catch several kinds of problems.
+ */
+
+ element = acpi_ut_find_allocation (list_id, allocation);
+ if (element) {
+ ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n",
+ allocation));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation));
+
+ goto unlock_and_exit;
+ }
+
+ /* Fill in the instance data. */
+
+ allocation->size = (u32) size;
+ allocation->alloc_type = alloc_type;
+ allocation->component = component;
+ allocation->line = line;
+
+ ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
+ allocation->module[ACPI_MAX_MODULE_NAME-1] = 0;
+
+ /* Insert at list head */
+
+ if (mem_list->list_head) {
+ ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
+ }
+
+ allocation->next = mem_list->list_head;
+ allocation->previous = NULL;
+
+ mem_list->list_head = allocation;
+
+
+unlock_and_exit:
+ status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_remove_allocation
+ *
+ * PARAMETERS: list_id - Memory list to search
+ * Allocation - Address of allocated memory
+ * Component - Component type of caller
+ * Module - Source file name of caller
+ * Line - Line number of caller
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Deletes an element from the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_remove_allocation (
+ u32 list_id,
+ struct acpi_debug_mem_block *allocation,
+ u32 component,
+ char *module,
+ u32 line)
+{
+ struct acpi_memory_list *mem_list;
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ut_remove_allocation");
+
+
+ if (list_id > ACPI_MEM_LIST_MAX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ mem_list = &acpi_gbl_memory_lists[list_id];
+ if (NULL == mem_list->list_head) {
+ /* No allocations! */
+
+ _ACPI_REPORT_ERROR (module, line, component,
+ ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /* Unlink */
+
+ if (allocation->previous) {
+ (allocation->previous)->next = allocation->next;
+ }
+ else {
+ mem_list->list_head = allocation->next;
+ }
+
+ if (allocation->next) {
+ (allocation->next)->previous = allocation->previous;
+ }
+
+ /* Mark the segment as deleted */
+
+ ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
+
+ status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_dump_allocation_info
+ *
+ * PARAMETERS:
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print some info about the outstanding allocations.
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+void
+acpi_ut_dump_allocation_info (
+ void)
+{
+/*
+ struct acpi_memory_list *mem_list;
+*/
+
+ ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
+
+/*
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Current allocations",
+ mem_list->current_count,
+ ROUND_UP_TO_1K (mem_list->current_size)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
+ mem_list->max_concurrent_count,
+ ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
+
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
+ running_object_count,
+ ROUND_UP_TO_1K (running_object_size)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
+ running_alloc_count,
+ ROUND_UP_TO_1K (running_alloc_size)));
+
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Current Nodes",
+ acpi_gbl_current_node_count,
+ ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
+
+ ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+ ("%30s: %4d (%3d Kb)\n", "Max Nodes",
+ acpi_gbl_max_concurrent_node_count,
+ ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node)))));
+*/
+ return_VOID;
+}
+#endif /* ACPI_FUTURE_USAGE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_dump_allocations
+ *
+ * PARAMETERS: Component - Component(s) to dump info for.
+ * Module - Module to dump info for. NULL means all.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print a list of all outstanding allocations.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_dump_allocations (
+ u32 component,
+ char *module)
+{
+ struct acpi_debug_mem_block *element;
+ union acpi_descriptor *descriptor;
+ u32 num_outstanding = 0;
+
+
+ ACPI_FUNCTION_TRACE ("ut_dump_allocations");
+
+
+ /*
+ * Walk the allocation list.
+ */
+ if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
+ return;
+ }
+
+ element = acpi_gbl_memory_lists[0].list_head;
+ while (element) {
+ if ((element->component & component) &&
+ ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
+ /* Ignore allocated objects that are in a cache */
+
+ descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
+ if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
+ acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
+ descriptor, element->size, element->module,
+ element->line, acpi_ut_get_descriptor_name (descriptor));
+
+ /* Most of the elements will be Operand objects. */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
+ case ACPI_DESC_TYPE_OPERAND:
+ acpi_os_printf ("%12.12s R%hd",
+ acpi_ut_get_type_name (descriptor->object.common.type),
+ descriptor->object.common.reference_count);
+ break;
+
+ case ACPI_DESC_TYPE_PARSER:
+ acpi_os_printf ("aml_opcode %04hX",
+ descriptor->op.asl.aml_opcode);
+ break;
+
+ case ACPI_DESC_TYPE_NAMED:
+ acpi_os_printf ("%4.4s",
+ acpi_ut_get_node_name (&descriptor->node));
+ break;
+
+ default:
+ break;
+ }
+
+ acpi_os_printf ( "\n");
+ num_outstanding++;
+ }
+ }
+ element = element->next;
+ }
+
+ (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
+
+ /* Print summary */
+
+ if (!num_outstanding) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "No outstanding allocations.\n"));
+ }
+ else {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "%d(%X) Outstanding allocations\n",
+ num_outstanding, num_outstanding));
+ }
+
+ return_VOID;
+}
+
+
+#endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
+
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
new file mode 100644
index 000000000000..0fcd98bde0d1
--- /dev/null
+++ b/drivers/acpi/utilities/utcopy.c
@@ -0,0 +1,930 @@
+/******************************************************************************
+ *
+ * Module Name: utcopy - Internal to external object translation utilities
+ *
+ *****************************************************************************/
+
+/*
+ * 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/amlcode.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utcopy")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_isimple_to_esimple
+ *
+ * PARAMETERS: *internal_object - Pointer to the object we are examining
+ * *Buffer - Where the object is returned
+ * *space_used - Where the data length is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to place a simple object in a user
+ * buffer.
+ *
+ * The buffer is assumed to have sufficient space for the object.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_copy_isimple_to_esimple (
+ union acpi_operand_object *internal_object,
+ union acpi_object *external_object,
+ u8 *data_space,
+ acpi_size *buffer_space_used)
+{
+ acpi_status status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE ("ut_copy_isimple_to_esimple");
+
+
+ *buffer_space_used = 0;
+
+ /*
+ * Check for NULL object case (could be an uninitialized
+ * package element)
+ */
+ if (!internal_object) {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Always clear the external object */
+
+ ACPI_MEMSET (external_object, 0, sizeof (union acpi_object));
+
+ /*
+ * In general, the external object will be the same type as
+ * the internal object
+ */
+ external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
+
+ /* However, only a limited number of external types are supported */
+
+ switch (ACPI_GET_OBJECT_TYPE (internal_object)) {
+ case ACPI_TYPE_STRING:
+
+ external_object->string.pointer = (char *) data_space;
+ external_object->string.length = internal_object->string.length;
+ *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD ((acpi_size) internal_object->string.length + 1);
+
+ ACPI_MEMCPY ((void *) data_space, (void *) internal_object->string.pointer,
+ (acpi_size) internal_object->string.length + 1);
+ break;
+
+
+ case ACPI_TYPE_BUFFER:
+
+ external_object->buffer.pointer = data_space;
+ external_object->buffer.length = internal_object->buffer.length;
+ *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (internal_object->string.length);
+
+ ACPI_MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer,
+ internal_object->buffer.length);
+ break;
+
+
+ case ACPI_TYPE_INTEGER:
+
+ external_object->integer.value = internal_object->integer.value;
+ break;
+
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ /*
+ * This is an object reference. Attempt to dereference it.
+ */
+ switch (internal_object->reference.opcode) {
+ case AML_INT_NAMEPATH_OP:
+
+ /* For namepath, return the object handle ("reference") */
+
+ default:
+ /*
+ * Use the object type of "Any" to indicate a reference
+ * to object containing a handle to an ACPI named object.
+ */
+ external_object->type = ACPI_TYPE_ANY;
+ external_object->reference.handle = internal_object->reference.node;
+ break;
+ }
+ break;
+
+
+ case ACPI_TYPE_PROCESSOR:
+
+ external_object->processor.proc_id = internal_object->processor.proc_id;
+ external_object->processor.pblk_address = internal_object->processor.address;
+ external_object->processor.pblk_length = internal_object->processor.length;
+ break;
+
+
+ case ACPI_TYPE_POWER:
+
+ external_object->power_resource.system_level =
+ internal_object->power_resource.system_level;
+
+ external_object->power_resource.resource_order =
+ internal_object->power_resource.resource_order;
+ break;
+
+
+ default:
+ /*
+ * There is no corresponding external object type
+ */
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_ielement_to_eelement
+ *
+ * PARAMETERS: acpi_pkg_callback
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy one package element to another package element
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_ielement_to_eelement (
+ u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context)
+{
+ acpi_status status = AE_OK;
+ struct acpi_pkg_info *info = (struct acpi_pkg_info *) context;
+ acpi_size object_space;
+ u32 this_index;
+ union acpi_object *target_object;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ this_index = state->pkg.index;
+ target_object = (union acpi_object *)
+ &((union acpi_object *)(state->pkg.dest_object))->package.elements[this_index];
+
+ switch (object_type) {
+ case ACPI_COPY_TYPE_SIMPLE:
+
+ /*
+ * This is a simple or null object
+ */
+ status = acpi_ut_copy_isimple_to_esimple (source_object,
+ target_object, info->free_space, &object_space);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+ break;
+
+
+ case ACPI_COPY_TYPE_PACKAGE:
+
+ /*
+ * Build the package object
+ */
+ target_object->type = ACPI_TYPE_PACKAGE;
+ target_object->package.count = source_object->package.count;
+ target_object->package.elements = ACPI_CAST_PTR (union acpi_object, info->free_space);
+
+ /*
+ * Pass the new package object back to the package walk routine
+ */
+ state->pkg.this_target_obj = target_object;
+
+ /*
+ * Save space for the array of objects (Package elements)
+ * update the buffer length counter
+ */
+ object_space = ACPI_ROUND_UP_TO_NATIVE_WORD (
+ (acpi_size) target_object->package.count * sizeof (union acpi_object));
+ break;
+
+
+ default:
+ return (AE_BAD_PARAMETER);
+ }
+
+ info->free_space += object_space;
+ info->length += object_space;
+ return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_ipackage_to_epackage
+ *
+ * PARAMETERS: *internal_object - Pointer to the object we are returning
+ * *Buffer - Where the object is returned
+ * *space_used - Where the object length is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to place a package object in a user
+ * buffer. A package object by definition contains other objects.
+ *
+ * The buffer is assumed to have sufficient space for the object.
+ * The caller must have verified the buffer length needed using the
+ * acpi_ut_get_object_size function before calling this function.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_copy_ipackage_to_epackage (
+ union acpi_operand_object *internal_object,
+ u8 *buffer,
+ acpi_size *space_used)
+{
+ union acpi_object *external_object;
+ acpi_status status;
+ struct acpi_pkg_info info;
+
+
+ ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_epackage");
+
+
+ /*
+ * First package at head of the buffer
+ */
+ external_object = ACPI_CAST_PTR (union acpi_object, buffer);
+
+ /*
+ * Free space begins right after the first package
+ */
+ info.length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+ info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+ info.object_space = 0;
+ info.num_packages = 1;
+
+ external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
+ external_object->package.count = internal_object->package.count;
+ external_object->package.elements = ACPI_CAST_PTR (union acpi_object, info.free_space);
+
+ /*
+ * Leave room for an array of ACPI_OBJECTS in the buffer
+ * and move the free space past it
+ */
+ info.length += (acpi_size) external_object->package.count *
+ ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+ info.free_space += external_object->package.count *
+ ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+
+ status = acpi_ut_walk_package_tree (internal_object, external_object,
+ acpi_ut_copy_ielement_to_eelement, &info);
+
+ *space_used = info.length;
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_iobject_to_eobject
+ *
+ * PARAMETERS: *internal_object - The internal object to be converted
+ * *buffer_ptr - Where the object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to build an API object to be returned to
+ * the caller.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_iobject_to_eobject (
+ union acpi_operand_object *internal_object,
+ struct acpi_buffer *ret_buffer)
+{
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_eobject");
+
+
+ if (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE) {
+ /*
+ * Package object: Copy all subobjects (including
+ * nested packages)
+ */
+ status = acpi_ut_copy_ipackage_to_epackage (internal_object,
+ ret_buffer->pointer, &ret_buffer->length);
+ }
+ else {
+ /*
+ * Build a simple object (no nested objects)
+ */
+ status = acpi_ut_copy_isimple_to_esimple (internal_object,
+ (union acpi_object *) ret_buffer->pointer,
+ ((u8 *) ret_buffer->pointer +
+ ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object))),
+ &ret_buffer->length);
+ /*
+ * build simple does not include the object size in the length
+ * so we add it in here
+ */
+ ret_buffer->length += sizeof (union acpi_object);
+ }
+
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_esimple_to_isimple
+ *
+ * PARAMETERS: *external_object - The external object to be converted
+ * *internal_object - Where the internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function copies an external object to an internal one.
+ * NOTE: Pointers can be copied, we don't need to copy data.
+ * (The pointers have to be valid in our address space no matter
+ * what we do with them!)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_esimple_to_isimple (
+ union acpi_object *external_object,
+ union acpi_operand_object **ret_internal_object)
+{
+ union acpi_operand_object *internal_object;
+
+
+ ACPI_FUNCTION_TRACE ("ut_copy_esimple_to_isimple");
+
+
+ /*
+ * Simple types supported are: String, Buffer, Integer
+ */
+ switch (external_object->type) {
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ case ACPI_TYPE_INTEGER:
+
+ internal_object = acpi_ut_create_internal_object ((u8) external_object->type);
+ if (!internal_object) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ break;
+
+ default:
+ /* All other types are not supported */
+
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+
+ /* Must COPY string and buffer contents */
+
+ switch (external_object->type) {
+ case ACPI_TYPE_STRING:
+
+ internal_object->string.pointer =
+ ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1);
+ if (!internal_object->string.pointer) {
+ goto error_exit;
+ }
+
+ ACPI_MEMCPY (internal_object->string.pointer,
+ external_object->string.pointer,
+ external_object->string.length);
+
+ internal_object->string.length = external_object->string.length;
+ break;
+
+
+ case ACPI_TYPE_BUFFER:
+
+ internal_object->buffer.pointer =
+ ACPI_MEM_CALLOCATE (external_object->buffer.length);
+ if (!internal_object->buffer.pointer) {
+ goto error_exit;
+ }
+
+ ACPI_MEMCPY (internal_object->buffer.pointer,
+ external_object->buffer.pointer,
+ external_object->buffer.length);
+
+ internal_object->buffer.length = external_object->buffer.length;
+ break;
+
+
+ case ACPI_TYPE_INTEGER:
+
+ internal_object->integer.value = external_object->integer.value;
+ break;
+
+ default:
+ /* Other types can't get here */
+ break;
+ }
+
+ *ret_internal_object = internal_object;
+ return_ACPI_STATUS (AE_OK);
+
+
+error_exit:
+ acpi_ut_remove_reference (internal_object);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+}
+
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+
+/* Code to convert packages that are parameters to control methods */
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_epackage_to_ipackage
+ *
+ * PARAMETERS: *internal_object - Pointer to the object we are returning
+ * *Buffer - Where the object is returned
+ * *space_used - Where the length of the object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to place a package object in a user
+ * buffer. A package object by definition contains other objects.
+ *
+ * The buffer is assumed to have sufficient space for the object.
+ * The caller must have verified the buffer length needed using the
+ * acpi_ut_get_object_size function before calling this function.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_copy_epackage_to_ipackage (
+ union acpi_operand_object *internal_object,
+ u8 *buffer,
+ u32 *space_used)
+{
+ u8 *free_space;
+ union acpi_object *external_object;
+ u32 length = 0;
+ u32 this_index;
+ u32 object_space = 0;
+ union acpi_operand_object *this_internal_obj;
+ union acpi_object *this_external_obj;
+
+
+ ACPI_FUNCTION_TRACE ("ut_copy_epackage_to_ipackage");
+
+
+ /*
+ * First package at head of the buffer
+ */
+ external_object = (union acpi_object *)buffer;
+
+ /*
+ * Free space begins right after the first package
+ */
+ free_space = buffer + sizeof(union acpi_object);
+
+
+ external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
+ external_object->package.count = internal_object->package.count;
+ external_object->package.elements = (union acpi_object *)free_space;
+
+ /*
+ * Build an array of ACPI_OBJECTS in the buffer
+ * and move the free space past it
+ */
+ free_space += external_object->package.count * sizeof(union acpi_object);
+
+
+ /* Call walk_package */
+
+}
+
+#endif /* Future implementation */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_eobject_to_iobject
+ *
+ * PARAMETERS: *internal_object - The external object to be converted
+ * *buffer_ptr - Where the internal object is returned
+ *
+ * RETURN: Status - the status of the call
+ *
+ * DESCRIPTION: Converts an external object to an internal object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_eobject_to_iobject (
+ union acpi_object *external_object,
+ union acpi_operand_object **internal_object)
+{
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ut_copy_eobject_to_iobject");
+
+
+ if (external_object->type == ACPI_TYPE_PACKAGE) {
+ /*
+ * Packages as external input to control methods are not supported,
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Packages as parameters not implemented!\n"));
+
+ return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+ }
+
+ else {
+ /*
+ * Build a simple object (no nested objects)
+ */
+ status = acpi_ut_copy_esimple_to_isimple (external_object, internal_object);
+ }
+
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_simple_object
+ *
+ * PARAMETERS: source_desc - The internal object to be copied
+ * dest_desc - New target object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Simple copy of one internal object to another. Reference count
+ * of the destination object is preserved.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_simple_object (
+ union acpi_operand_object *source_desc,
+ union acpi_operand_object *dest_desc)
+{
+ u16 reference_count;
+ union acpi_operand_object *next_object;
+
+
+ /* Save fields from destination that we don't want to overwrite */
+
+ reference_count = dest_desc->common.reference_count;
+ next_object = dest_desc->common.next_object;
+
+ /* Copy the entire source object over the destination object*/
+
+ ACPI_MEMCPY ((char *) dest_desc, (char *) source_desc,
+ sizeof (union acpi_operand_object));
+
+ /* Restore the saved fields */
+
+ dest_desc->common.reference_count = reference_count;
+ dest_desc->common.next_object = next_object;
+
+ /* Handle the objects with extra data */
+
+ switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
+ case ACPI_TYPE_BUFFER:
+
+ dest_desc->buffer.node = NULL;
+ dest_desc->common.flags = source_desc->common.flags;
+
+ /*
+ * Allocate and copy the actual buffer if and only if:
+ * 1) There is a valid buffer pointer
+ * 2) The buffer is not static (not in an ACPI table) (in this case,
+ * the actual pointer was already copied above)
+ */
+ if ((source_desc->buffer.pointer) &&
+ (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+ dest_desc->buffer.pointer = NULL;
+
+ /* Create an actual buffer only if length > 0 */
+
+ if (source_desc->buffer.length) {
+ dest_desc->buffer.pointer =
+ ACPI_MEM_ALLOCATE (source_desc->buffer.length);
+ if (!dest_desc->buffer.pointer) {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Copy the actual buffer data */
+
+ ACPI_MEMCPY (dest_desc->buffer.pointer,
+ source_desc->buffer.pointer,
+ source_desc->buffer.length);
+ }
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ /*
+ * Allocate and copy the actual string if and only if:
+ * 1) There is a valid string pointer
+ * 2) The string is not static (not in an ACPI table) (in this case,
+ * the actual pointer was already copied above)
+ */
+ if ((source_desc->string.pointer) &&
+ (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+ dest_desc->string.pointer =
+ ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
+ if (!dest_desc->string.pointer) {
+ return (AE_NO_MEMORY);
+ }
+
+ ACPI_MEMCPY (dest_desc->string.pointer, source_desc->string.pointer,
+ (acpi_size) source_desc->string.length + 1);
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+ /*
+ * We copied the reference object, so we now must add a reference
+ * to the object pointed to by the reference
+ */
+ acpi_ut_add_reference (source_desc->reference.object);
+ break;
+
+ default:
+ /* Nothing to do for other simple objects */
+ break;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_ielement_to_ielement
+ *
+ * PARAMETERS: acpi_pkg_callback
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy one package element to another package element
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_ielement_to_ielement (
+ u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context)
+{
+ acpi_status status = AE_OK;
+ u32 this_index;
+ union acpi_operand_object **this_target_ptr;
+ union acpi_operand_object *target_object;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ this_index = state->pkg.index;
+ this_target_ptr = (union acpi_operand_object **)
+ &state->pkg.dest_object->package.elements[this_index];
+
+ switch (object_type) {
+ case ACPI_COPY_TYPE_SIMPLE:
+
+ /* A null source object indicates a (legal) null package element */
+
+ if (source_object) {
+ /*
+ * This is a simple object, just copy it
+ */
+ target_object = acpi_ut_create_internal_object (
+ ACPI_GET_OBJECT_TYPE (source_object));
+ if (!target_object) {
+ return (AE_NO_MEMORY);
+ }
+
+ status = acpi_ut_copy_simple_object (source_object, target_object);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+
+ *this_target_ptr = target_object;
+ }
+ else {
+ /* Pass through a null element */
+
+ *this_target_ptr = NULL;
+ }
+ break;
+
+
+ case ACPI_COPY_TYPE_PACKAGE:
+
+ /*
+ * This object is a package - go down another nesting level
+ * Create and build the package object
+ */
+ target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
+ if (!target_object) {
+ return (AE_NO_MEMORY);
+ }
+
+ target_object->package.count = source_object->package.count;
+ target_object->common.flags = source_object->common.flags;
+
+ /*
+ * Create the object array
+ */
+ target_object->package.elements =
+ ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) *
+ sizeof (void *));
+ if (!target_object->package.elements) {
+ status = AE_NO_MEMORY;
+ goto error_exit;
+ }
+
+ /*
+ * Pass the new package object back to the package walk routine
+ */
+ state->pkg.this_target_obj = target_object;
+
+ /*
+ * Store the object pointer in the parent package object
+ */
+ *this_target_ptr = target_object;
+ break;
+
+
+ default:
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (status);
+
+error_exit:
+ acpi_ut_remove_reference (target_object);
+ return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_ipackage_to_ipackage
+ *
+ * PARAMETERS: *source_obj - Pointer to the source package object
+ * *dest_obj - Where the internal object is returned
+ *
+ * RETURN: Status - the status of the call
+ *
+ * DESCRIPTION: This function is called to copy an internal package object
+ * into another internal package object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_ipackage_to_ipackage (
+ union acpi_operand_object *source_obj,
+ union acpi_operand_object *dest_obj,
+ struct acpi_walk_state *walk_state)
+{
+ acpi_status status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_ipackage");
+
+
+ dest_obj->common.type = ACPI_GET_OBJECT_TYPE (source_obj);
+ dest_obj->common.flags = source_obj->common.flags;
+ dest_obj->package.count = source_obj->package.count;
+
+ /*
+ * Create the object array and walk the source package tree
+ */
+ dest_obj->package.elements = ACPI_MEM_CALLOCATE (
+ ((acpi_size) source_obj->package.count + 1) *
+ sizeof (void *));
+ if (!dest_obj->package.elements) {
+ ACPI_REPORT_ERROR (
+ ("aml_build_copy_internal_package_object: Package allocation failure\n"));
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /*
+ * Copy the package element-by-element by walking the package "tree".
+ * This handles nested packages of arbitrary depth.
+ */
+ status = acpi_ut_walk_package_tree (source_obj, dest_obj,
+ acpi_ut_copy_ielement_to_ielement, walk_state);
+ if (ACPI_FAILURE (status)) {
+ /* On failure, delete the destination package object */
+
+ acpi_ut_remove_reference (dest_obj);
+ }
+
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_iobject_to_iobject
+ *
+ * PARAMETERS: walk_state - Current walk state
+ * source_desc - The internal object to be copied
+ * dest_desc - Where the copied object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy an internal object to a new internal object
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_iobject_to_iobject (
+ union acpi_operand_object *source_desc,
+ union acpi_operand_object **dest_desc,
+ struct acpi_walk_state *walk_state)
+{
+ acpi_status status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_iobject");
+
+
+ /* Create the top level object */
+
+ *dest_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (source_desc));
+ if (!*dest_desc) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Copy the object and possible subobjects */
+
+ if (ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_PACKAGE) {
+ status = acpi_ut_copy_ipackage_to_ipackage (source_desc, *dest_desc,
+ walk_state);
+ }
+ else {
+ status = acpi_ut_copy_simple_object (source_desc, *dest_desc);
+ }
+
+ return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
new file mode 100644
index 000000000000..985c5d045b78
--- /dev/null
+++ b/drivers/acpi/utilities/utdebug.c
@@ -0,0 +1,624 @@
+/******************************************************************************
+ *
+ * Module Name: utdebug - Debug print routines
+ *
+ *****************************************************************************/
+
+/*
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utdebug")
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+static u32 acpi_gbl_prev_thread_id = 0xFFFFFFFF;
+static char *acpi_gbl_fn_entry_str = "----Entry";
+static char *acpi_gbl_fn_exit_str = "----Exit-";
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_init_stack_ptr_trace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Save the current stack pointer
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_init_stack_ptr_trace (
+ void)
+{
+ u32 current_sp;
+
+
+ acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF (&current_sp, NULL);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_track_stack_ptr
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Save the current stack pointer
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_track_stack_ptr (
+ void)
+{
+ acpi_size current_sp;
+
+
+ current_sp = ACPI_PTR_DIFF (&current_sp, NULL);
+
+ if (current_sp < acpi_gbl_lowest_stack_pointer) {
+ acpi_gbl_lowest_stack_pointer = current_sp;
+ }
+
+ if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) {
+ acpi_gbl_deepest_nesting = acpi_gbl_nesting_level;
+ }
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_debug_print
+ *
+ * PARAMETERS: debug_level - Requested debug print level
+ * proc_name - Caller's procedure name
+ * 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)
+ *
+ * Format - Printf format field
+ * ... - Optional printf arguments
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print error message with prefix consisting of the module name,
+ * line number, and component ID.
+ *
+ ****************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_debug_print (
+ u32 requested_debug_level,
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info,
+ char *format,
+ ...)
+{
+ u32 thread_id;
+ va_list args;
+
+
+ /*
+ * Stay silent if the debug level or component ID is disabled
+ */
+ if (!(requested_debug_level & acpi_dbg_level) ||
+ !(dbg_info->component_id & acpi_dbg_layer)) {
+ return;
+ }
+
+ /*
+ * Thread tracking and context switch notification
+ */
+ thread_id = acpi_os_get_thread_id ();
+
+ if (thread_id != acpi_gbl_prev_thread_id) {
+ if (ACPI_LV_THREADS & acpi_dbg_level) {
+ acpi_os_printf ("\n**** Context Switch from TID %X to TID %X ****\n\n",
+ acpi_gbl_prev_thread_id, thread_id);
+ }
+
+ acpi_gbl_prev_thread_id = thread_id;
+ }
+
+ /*
+ * Display the module name, current line number, thread ID (if requested),
+ * current procedure nesting level, and the current procedure name
+ */
+ acpi_os_printf ("%8s-%04ld ", dbg_info->module_name, line_number);
+
+ if (ACPI_LV_THREADS & acpi_dbg_level) {
+ acpi_os_printf ("[%04lX] ", thread_id);
+ }
+
+ acpi_os_printf ("[%02ld] %-22.22s: ", acpi_gbl_nesting_level, dbg_info->proc_name);
+
+ va_start (args, format);
+ acpi_os_vprintf (format, args);
+}
+EXPORT_SYMBOL(acpi_ut_debug_print);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_debug_print_raw
+ *
+ * PARAMETERS: requested_debug_level - Requested debug print level
+ * line_number - Caller's line number
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
+ * Format - Printf format field
+ * ... - Optional printf arguments
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print message with no headers. Has same interface as
+ * debug_print so that the same macros can be used.
+ *
+ ****************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_debug_print_raw (
+ u32 requested_debug_level,
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info,
+ char *format,
+ ...)
+{
+ va_list args;
+
+
+ if (!(requested_debug_level & acpi_dbg_level) ||
+ !(dbg_info->component_id & acpi_dbg_layer)) {
+ return;
+ }
+
+ va_start (args, format);
+ acpi_os_vprintf (format, args);
+}
+EXPORT_SYMBOL(acpi_ut_debug_print_raw);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_trace
+ *
+ * PARAMETERS: line_number - Caller's line number
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
+ * set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_trace (
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info)
+{
+
+ acpi_gbl_nesting_level++;
+ acpi_ut_track_stack_ptr ();
+
+ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+ "%s\n", acpi_gbl_fn_entry_str);
+}
+EXPORT_SYMBOL(acpi_ut_trace);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_trace_ptr
+ *
+ * PARAMETERS: line_number - Caller's line number
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
+ * Pointer - Pointer to display
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
+ * set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_trace_ptr (
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info,
+ void *pointer)
+{
+ acpi_gbl_nesting_level++;
+ acpi_ut_track_stack_ptr ();
+
+ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+ "%s %p\n", acpi_gbl_fn_entry_str, pointer);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_trace_str
+ *
+ * PARAMETERS: line_number - Caller's line number
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
+ * String - Additional string to display
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
+ * set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_trace_str (
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info,
+ char *string)
+{
+
+ acpi_gbl_nesting_level++;
+ acpi_ut_track_stack_ptr ();
+
+ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+ "%s %s\n", acpi_gbl_fn_entry_str, string);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_trace_u32
+ *
+ * PARAMETERS: line_number - Caller's line number
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
+ * Integer - Integer to display
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
+ * set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_trace_u32 (
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info,
+ u32 integer)
+{
+
+ acpi_gbl_nesting_level++;
+ acpi_ut_track_stack_ptr ();
+
+ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+ "%s %08X\n", acpi_gbl_fn_entry_str, integer);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_exit
+ *
+ * PARAMETERS: line_number - Caller's line number
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
+ * set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_exit (
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info)
+{
+
+ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+ "%s\n", acpi_gbl_fn_exit_str);
+
+ acpi_gbl_nesting_level--;
+}
+EXPORT_SYMBOL(acpi_ut_exit);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_status_exit
+ *
+ * PARAMETERS: line_number - Caller's line number
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
+ * Status - Exit status code
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
+ * set in debug_level. Prints exit status also.
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_status_exit (
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info,
+ acpi_status status)
+{
+
+ if (ACPI_SUCCESS (status)) {
+ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+ "%s %s\n", acpi_gbl_fn_exit_str,
+ acpi_format_exception (status));
+ }
+ else {
+ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+ "%s ****Exception****: %s\n", acpi_gbl_fn_exit_str,
+ acpi_format_exception (status));
+ }
+
+ acpi_gbl_nesting_level--;
+}
+EXPORT_SYMBOL(acpi_ut_status_exit);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_value_exit
+ *
+ * PARAMETERS: line_number - Caller's line number
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
+ * Value - Value to be printed with exit msg
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
+ * set in debug_level. Prints exit value also.
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_value_exit (
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info,
+ acpi_integer value)
+{
+
+ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+ "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str,
+ ACPI_FORMAT_UINT64 (value));
+
+ acpi_gbl_nesting_level--;
+}
+EXPORT_SYMBOL(acpi_ut_value_exit);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_ptr_exit
+ *
+ * PARAMETERS: line_number - Caller's line number
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
+ * Value - Value to be printed with exit msg
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
+ * set in debug_level. Prints exit value also.
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_ptr_exit (
+ u32 line_number,
+ struct acpi_debug_print_info *dbg_info,
+ u8 *ptr)
+{
+
+ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+ "%s %p\n", acpi_gbl_fn_exit_str, ptr);
+
+ acpi_gbl_nesting_level--;
+}
+
+#endif
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_dump_buffer
+ *
+ * PARAMETERS: Buffer - Buffer to dump
+ * Count - Amount to dump, in bytes
+ * Display - BYTE, WORD, DWORD, or QWORD display
+ * component_iD - Caller's component ID
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Generic dump buffer in both hex and ascii.
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_dump_buffer (
+ u8 *buffer,
+ u32 count,
+ u32 display,
+ u32 component_id)
+{
+ acpi_native_uint i = 0;
+ acpi_native_uint j;
+ u32 temp32;
+ u8 buf_char;
+
+
+ /* Only dump the buffer if tracing is enabled */
+
+ if (!((ACPI_LV_TABLES & acpi_dbg_level) &&
+ (component_id & acpi_dbg_layer))) {
+ return;
+ }
+
+ if ((count < 4) || (count & 0x01)) {
+ display = DB_BYTE_DISPLAY;
+ }
+
+ acpi_os_printf ("\nOffset Value\n");
+
+ /*
+ * Nasty little dump buffer routine!
+ */
+ while (i < count) {
+ /* Print current offset */
+
+ acpi_os_printf ("%05X ", (u32) i);
+
+ /* Print 16 hex chars */
+
+ for (j = 0; j < 16;) {
+ if (i + j >= count) {
+ acpi_os_printf ("\n");
+ return;
+ }
+
+ /* Make sure that the s8 doesn't get sign-extended! */
+
+ switch (display) {
+ /* Default is BYTE display */
+
+ default:
+
+ acpi_os_printf ("%02X ",
+ *((u8 *) &buffer[i + j]));
+ j += 1;
+ break;
+
+
+ case DB_WORD_DISPLAY:
+
+ ACPI_MOVE_16_TO_32 (&temp32, &buffer[i + j]);
+ acpi_os_printf ("%04X ", temp32);
+ j += 2;
+ break;
+
+
+ case DB_DWORD_DISPLAY:
+
+ ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]);
+ acpi_os_printf ("%08X ", temp32);
+ j += 4;
+ break;
+
+
+ case DB_QWORD_DISPLAY:
+
+ ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]);
+ acpi_os_printf ("%08X", temp32);
+
+ ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j + 4]);
+ acpi_os_printf ("%08X ", temp32);
+ j += 8;
+ break;
+ }
+ }
+
+ /*
+ * Print the ASCII equivalent characters
+ * But watch out for the bad unprintable ones...
+ */
+ for (j = 0; j < 16; j++) {
+ if (i + j >= count) {
+ acpi_os_printf ("\n");
+ return;
+ }
+
+ buf_char = buffer[i + j];
+ if ((buf_char > 0x1F && buf_char < 0x2E) ||
+ (buf_char > 0x2F && buf_char < 0x61) ||
+ (buf_char > 0x60 && buf_char < 0x7F)) {
+ acpi_os_printf ("%c", buf_char);
+ }
+ else {
+ acpi_os_printf (".");
+ }
+ }
+
+ /* Done with that line. */
+
+ acpi_os_printf ("\n");
+ i += 16;
+ }
+
+ return;
+}
+
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
new file mode 100644
index 000000000000..9a52ad52a23a
--- /dev/null
+++ b/drivers/acpi/utilities/utdelete.c
@@ -0,0 +1,700 @@
+/*******************************************************************************
+ *
+ * Module Name: utdelete - object deletion and reference count utilities
+ *
+ ******************************************************************************/
+
+/*
+ * 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/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/amlcode.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utdelete")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_internal_obj
+ *
+ * PARAMETERS: *Object - Pointer to the list to be deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Low level object deletion, after reference counts have been
+ * updated (All reference counts, including sub-objects!)
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_internal_obj (
+ union acpi_operand_object *object)
+{
+ void *obj_pointer = NULL;
+ union acpi_operand_object *handler_desc;
+ union acpi_operand_object *second_desc;
+ union acpi_operand_object *next_desc;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object);
+
+
+ if (!object) {
+ return_VOID;
+ }
+
+ /*
+ * Must delete or free any pointers within the object that are not
+ * actual ACPI objects (for example, a raw buffer pointer).
+ */
+ switch (ACPI_GET_OBJECT_TYPE (object)) {
+ case ACPI_TYPE_STRING:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
+ object, object->string.pointer));
+
+ /* Free the actual string buffer */
+
+ if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
+ /* But only if it is NOT a pointer into an ACPI table */
+
+ obj_pointer = object->string.pointer;
+ }
+ break;
+
+
+ case ACPI_TYPE_BUFFER:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
+ object, object->buffer.pointer));
+
+ /* Free the actual buffer */
+
+ if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
+ /* But only if it is NOT a pointer into an ACPI table */
+
+ obj_pointer = object->buffer.pointer;
+ }
+ break;
+
+
+ case ACPI_TYPE_PACKAGE:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
+ object->package.count));
+
+ /*
+ * Elements of the package are not handled here, they are deleted
+ * separately
+ */
+
+ /* Free the (variable length) element pointer array */
+
+ obj_pointer = object->package.elements;
+ break;
+
+
+ case ACPI_TYPE_DEVICE:
+
+ if (object->device.gpe_block) {
+ (void) acpi_ev_delete_gpe_block (object->device.gpe_block);
+ }
+
+ /* Walk the handler list for this device */
+
+ handler_desc = object->device.handler;
+ while (handler_desc) {
+ next_desc = handler_desc->address_space.next;
+ acpi_ut_remove_reference (handler_desc);
+ handler_desc = next_desc;
+ }
+ break;
+
+
+ case ACPI_TYPE_MUTEX:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Mutex %p, Semaphore %p\n",
+ object, object->mutex.semaphore));
+
+ acpi_ex_unlink_mutex (object);
+ (void) acpi_os_delete_semaphore (object->mutex.semaphore);
+ break;
+
+
+ case ACPI_TYPE_EVENT:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Event %p, Semaphore %p\n",
+ object, object->event.semaphore));
+
+ (void) acpi_os_delete_semaphore (object->event.semaphore);
+ object->event.semaphore = NULL;
+ break;
+
+
+ case ACPI_TYPE_METHOD:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Method %p\n", object));
+
+ /* Delete the method semaphore if it exists */
+
+ if (object->method.semaphore) {
+ (void) acpi_os_delete_semaphore (object->method.semaphore);
+ object->method.semaphore = NULL;
+ }
+ break;
+
+
+ case ACPI_TYPE_REGION:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Region %p\n", object));
+
+ second_desc = acpi_ns_get_secondary_object (object);
+ if (second_desc) {
+ /*
+ * Free the region_context if and only if the handler is one of the
+ * default handlers -- and therefore, we created the context object
+ * locally, it was not created by an external caller.
+ */
+ handler_desc = object->region.handler;
+ if (handler_desc) {
+ if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+ obj_pointer = second_desc->extra.region_context;
+ }
+
+ acpi_ut_remove_reference (handler_desc);
+ }
+
+ /* Now we can free the Extra object */
+
+ acpi_ut_delete_object_desc (second_desc);
+ }
+ break;
+
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Buffer Field %p\n", object));
+
+ second_desc = acpi_ns_get_secondary_object (object);
+ if (second_desc) {
+ acpi_ut_delete_object_desc (second_desc);
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+ /* Free any allocated memory (pointer within the object) found above */
+
+ if (obj_pointer) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
+ obj_pointer));
+ ACPI_MEM_FREE (obj_pointer);
+ }
+
+ /* Now the object can be safely deleted */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
+ object, acpi_ut_get_object_type_name (object)));
+
+ acpi_ut_delete_object_desc (object);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_internal_object_list
+ *
+ * PARAMETERS: *obj_list - Pointer to the list to be deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: This function deletes an internal object list, including both
+ * simple objects and package objects
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_internal_object_list (
+ union acpi_operand_object **obj_list)
+{
+ union acpi_operand_object **internal_obj;
+
+
+ ACPI_FUNCTION_TRACE ("ut_delete_internal_object_list");
+
+
+ /* Walk the null-terminated internal list */
+
+ for (internal_obj = obj_list; *internal_obj; internal_obj++) {
+ acpi_ut_remove_reference (*internal_obj);
+ }
+
+ /* Free the combined parameter pointer list and object array */
+
+ ACPI_MEM_FREE (obj_list);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_update_ref_count
+ *
+ * PARAMETERS: *Object - Object whose ref count is to be updated
+ * Action - What to do
+ *
+ * RETURN: New ref count
+ *
+ * DESCRIPTION: Modify the ref count and return it.
+ *
+ ******************************************************************************/
+
+static void
+acpi_ut_update_ref_count (
+ union acpi_operand_object *object,
+ u32 action)
+{
+ u16 count;
+ u16 new_count;
+
+
+ ACPI_FUNCTION_NAME ("ut_update_ref_count");
+
+
+ if (!object) {
+ return;
+ }
+
+ count = object->common.reference_count;
+ new_count = count;
+
+ /*
+ * Perform the reference count action (increment, decrement, or force delete)
+ */
+ switch (action) {
+
+ case REF_INCREMENT:
+
+ new_count++;
+ object->common.reference_count = new_count;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Incremented]\n",
+ object, new_count));
+ break;
+
+
+ case REF_DECREMENT:
+
+ if (count < 1) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
+ object, new_count));
+
+ new_count = 0;
+ }
+ else {
+ new_count--;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Decremented]\n",
+ object, new_count));
+ }
+
+ if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n",
+ object, new_count));
+ }
+
+ object->common.reference_count = new_count;
+ if (new_count == 0) {
+ acpi_ut_delete_internal_obj (object);
+ }
+
+ break;
+
+
+ case REF_FORCE_DELETE:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, Force delete! (Set to 0)\n",
+ object, count));
+
+ new_count = 0;
+ object->common.reference_count = new_count;
+ acpi_ut_delete_internal_obj (object);
+ break;
+
+
+ default:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown action (%X)\n", action));
+ break;
+ }
+
+ /*
+ * Sanity check the reference count, for debug purposes only.
+ * (A deleted object will have a huge reference count)
+ */
+ if (count > ACPI_MAX_REFERENCE_COUNT) {
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
+ "**** Warning **** Large Reference Count (%X) in object %p\n\n",
+ count, object));
+ }
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_update_object_reference
+ *
+ * PARAMETERS: *Object - Increment ref count for this object
+ * and all sub-objects
+ * Action - Either REF_INCREMENT or REF_DECREMENT or
+ * REF_FORCE_DELETE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Increment the object reference count
+ *
+ * Object references are incremented when:
+ * 1) An object is attached to a Node (namespace object)
+ * 2) An object is copied (all subobjects must be incremented)
+ *
+ * Object references are decremented when:
+ * 1) An object is detached from an Node
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_update_object_reference (
+ union acpi_operand_object *object,
+ u16 action)
+{
+ acpi_status status;
+ u32 i;
+ union acpi_generic_state *state_list = NULL;
+ union acpi_generic_state *state;
+ union acpi_operand_object *tmp;
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object);
+
+
+ /* Ignore a null object ptr */
+
+ if (!object) {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Make sure that this isn't a namespace handle */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object));
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ state = acpi_ut_create_update_state (object, action);
+
+ while (state) {
+ object = state->update.object;
+ action = state->update.value;
+ acpi_ut_delete_generic_state (state);
+
+ /*
+ * All sub-objects must have their reference count incremented also.
+ * Different object types have different subobjects.
+ */
+ switch (ACPI_GET_OBJECT_TYPE (object)) {
+ case ACPI_TYPE_DEVICE:
+
+ tmp = object->device.system_notify;
+ if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+ object->device.system_notify = NULL;
+ acpi_ut_update_ref_count (tmp, action);
+
+ tmp = object->device.device_notify;
+ if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+ object->device.device_notify = NULL;
+ acpi_ut_update_ref_count (tmp, action);
+
+ break;
+
+
+ case ACPI_TYPE_PACKAGE:
+
+ /*
+ * We must update all the sub-objects of the package
+ * (Each of whom may have their own sub-objects, etc.
+ */
+ for (i = 0; i < object->package.count; i++) {
+ /*
+ * Push each element onto the stack for later processing.
+ * Note: There can be null elements within the package,
+ * these are simply ignored
+ */
+ status = acpi_ut_create_update_state_and_push (
+ object->package.elements[i], action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+
+ tmp = object->package.elements[i];
+ if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+ object->package.elements[i] = NULL;
+ }
+ break;
+
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ status = acpi_ut_create_update_state_and_push (
+ object->buffer_field.buffer_obj, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+
+ tmp = object->buffer_field.buffer_obj;
+ if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+ object->buffer_field.buffer_obj = NULL;
+ break;
+
+
+ case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+ status = acpi_ut_create_update_state_and_push (
+ object->field.region_obj, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+
+ tmp = object->field.region_obj;
+ if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+ object->field.region_obj = NULL;
+ break;
+
+
+ case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+ status = acpi_ut_create_update_state_and_push (
+ object->bank_field.bank_obj, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+
+ tmp = object->bank_field.bank_obj;
+ if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+ object->bank_field.bank_obj = NULL;
+
+ status = acpi_ut_create_update_state_and_push (
+ object->bank_field.region_obj, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+
+ tmp = object->bank_field.region_obj;
+ if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+ object->bank_field.region_obj = NULL;
+ break;
+
+
+ case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+ status = acpi_ut_create_update_state_and_push (
+ object->index_field.index_obj, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+
+ tmp = object->index_field.index_obj;
+ if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+ object->index_field.index_obj = NULL;
+
+ status = acpi_ut_create_update_state_and_push (
+ object->index_field.data_obj, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+
+ tmp = object->index_field.data_obj;
+ if ( tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+ object->index_field.data_obj = NULL;
+ break;
+
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ /*
+ * The target of an Index (a package, string, or buffer) must track
+ * changes to the ref count of the index.
+ */
+ if (object->reference.opcode == AML_INDEX_OP) {
+ status = acpi_ut_create_update_state_and_push (
+ object->reference.object, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+ }
+ break;
+
+
+ case ACPI_TYPE_REGION:
+ default:
+
+ /* No subobjects */
+ break;
+ }
+
+ /*
+ * Now we can update the count in the main object. This can only
+ * happen after we update the sub-objects in case this causes the
+ * main object to be deleted.
+ */
+ acpi_ut_update_ref_count (object, action);
+
+ /* Move on to the next object to be updated */
+
+ state = acpi_ut_pop_generic_state (&state_list);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+
+
+error_exit:
+
+ ACPI_REPORT_ERROR (("Could not update object reference count, %s\n",
+ acpi_format_exception (status)));
+
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_add_reference
+ *
+ * PARAMETERS: *Object - Object whose reference count is to be
+ * incremented
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add one reference to an ACPI object
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_add_reference (
+ union acpi_operand_object *object)
+{
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object);
+
+
+ /* Ensure that we have a valid object */
+
+ if (!acpi_ut_valid_internal_object (object)) {
+ return_VOID;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Current Refs=%X [To Be Incremented]\n",
+ object, object->common.reference_count));
+
+ /* Increment the reference count */
+
+ (void) acpi_ut_update_object_reference (object, REF_INCREMENT);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_remove_reference
+ *
+ * PARAMETERS: *Object - Object whose ref count will be decremented
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decrement the reference count of an ACPI internal object
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_remove_reference (
+ union acpi_operand_object *object)
+{
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object);
+
+
+ /*
+ * Allow a NULL pointer to be passed in, just ignore it. This saves
+ * each caller from having to check. Also, ignore NS nodes.
+ *
+ */
+ if (!object ||
+ (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED)) {
+ return_VOID;
+ }
+
+ /* Ensure that we have a valid object */
+
+ if (!acpi_ut_valid_internal_object (object)) {
+ return_VOID;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Current Refs=%X [To Be Decremented]\n",
+ object, object->common.reference_count));
+
+ /*
+ * Decrement the reference count, and only actually delete the object
+ * if the reference count becomes 0. (Must also decrement the ref count
+ * of all subobjects!)
+ */
+ (void) acpi_ut_update_object_reference (object, REF_DECREMENT);
+ return_VOID;
+}
+
+
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
new file mode 100644
index 000000000000..ead27d2c4d18
--- /dev/null
+++ b/drivers/acpi/utilities/uteval.c
@@ -0,0 +1,696 @@
+/******************************************************************************
+ *
+ * Module Name: uteval - Object evaluation
+ *
+ *****************************************************************************/
+
+/*
+ * 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>
+#include <acpi/acinterp.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("uteval")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_osi_implementation
+ *
+ * PARAMETERS: walk_state - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Implementation of _OSI predefined control method
+ * Supported = _OSI (String)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_osi_implementation (
+ struct acpi_walk_state *walk_state)
+{
+ union acpi_operand_object *string_desc;
+ union acpi_operand_object *return_desc;
+ acpi_native_uint i;
+
+
+ ACPI_FUNCTION_TRACE ("ut_osi_implementation");
+
+
+ /* Validate the string input argument */
+
+ string_desc = walk_state->arguments[0].object;
+ if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Create a return object (Default value = 0) */
+
+ return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ if (!return_desc) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Compare input string to table of supported strings */
+
+ for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) {
+ if (!ACPI_STRCMP (string_desc->string.pointer,
+ (char *) acpi_gbl_valid_osi_strings[i])) {
+ /* This string is supported */
+
+ return_desc->integer.value = 0xFFFFFFFF;
+ break;
+ }
+ }
+
+ walk_state->return_desc = return_desc;
+ return_ACPI_STATUS (AE_CTRL_TERMINATE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_evaluate_object
+ *
+ * PARAMETERS: prefix_node - Starting node
+ * Path - Path to object from starting node
+ * expected_return_types - Bitmap of allowed return types
+ * return_desc - Where a return value is stored
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Evaluates a namespace object and verifies the type of the
+ * return object. Common code that simplifies accessing objects
+ * that have required return objects of fixed types.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_evaluate_object (
+ struct acpi_namespace_node *prefix_node,
+ char *path,
+ u32 expected_return_btypes,
+ union acpi_operand_object **return_desc)
+{
+ struct acpi_parameter_info info;
+ acpi_status status;
+ u32 return_btype;
+
+
+ ACPI_FUNCTION_TRACE ("ut_evaluate_object");
+
+
+ info.node = prefix_node;
+ info.parameters = NULL;
+ info.parameter_type = ACPI_PARAM_ARGS;
+
+ /* Evaluate the object/method */
+
+ status = acpi_ns_evaluate_relative (path, &info);
+ if (ACPI_FAILURE (status)) {
+ if (status == AE_NOT_FOUND) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
+ acpi_ut_get_node_name (prefix_node), path));
+ }
+ else {
+ ACPI_REPORT_METHOD_ERROR ("Method execution failed",
+ prefix_node, path, status);
+ }
+
+ return_ACPI_STATUS (status);
+ }
+
+ /* Did we get a return object? */
+
+ if (!info.return_object) {
+ if (expected_return_btypes) {
+ ACPI_REPORT_METHOD_ERROR ("No object was returned from",
+ prefix_node, path, AE_NOT_EXIST);
+
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Map the return object type to the bitmapped type */
+
+ switch (ACPI_GET_OBJECT_TYPE (info.return_object)) {
+ case ACPI_TYPE_INTEGER:
+ return_btype = ACPI_BTYPE_INTEGER;
+ break;
+
+ case ACPI_TYPE_BUFFER:
+ return_btype = ACPI_BTYPE_BUFFER;
+ break;
+
+ case ACPI_TYPE_STRING:
+ return_btype = ACPI_BTYPE_STRING;
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+ return_btype = ACPI_BTYPE_PACKAGE;
+ break;
+
+ default:
+ return_btype = 0;
+ break;
+ }
+
+ if ((acpi_gbl_enable_interpreter_slack) &&
+ (!expected_return_btypes)) {
+ /*
+ * We received a return object, but one was not expected. This can
+ * happen frequently if the "implicit return" feature is enabled.
+ * Just delete the return object and return AE_OK.
+ */
+ acpi_ut_remove_reference (info.return_object);
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Is the return object one of the expected types? */
+
+ if (!(expected_return_btypes & return_btype)) {
+ ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect",
+ prefix_node, path, AE_TYPE);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Type returned from %s was incorrect: %s, expected Btypes: %X\n",
+ path, acpi_ut_get_object_type_name (info.return_object),
+ expected_return_btypes));
+
+ /* On error exit, we must delete the return object */
+
+ acpi_ut_remove_reference (info.return_object);
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Object type is OK, return it */
+
+ *return_desc = info.return_object;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_evaluate_numeric_object
+ *
+ * PARAMETERS: *object_name - Object name to be evaluated
+ * device_node - Node for the device
+ * *Address - Where the value is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Evaluates a numeric namespace object for a selected device
+ * and stores result in *Address.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_evaluate_numeric_object (
+ char *object_name,
+ struct acpi_namespace_node *device_node,
+ acpi_integer *address)
+{
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ut_evaluate_numeric_object");
+
+
+ status = acpi_ut_evaluate_object (device_node, object_name,
+ ACPI_BTYPE_INTEGER, &obj_desc);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /* Get the returned Integer */
+
+ *address = obj_desc->integer.value;
+
+ /* On exit, we must delete the return object */
+
+ acpi_ut_remove_reference (obj_desc);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_copy_id_string
+ *
+ * PARAMETERS: Destination - Where to copy the string
+ * Source - Source string
+ * max_length - Length of the destination buffer
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
+ * Performs removal of a leading asterisk if present -- workaround
+ * for a known issue on a bunch of machines.
+ *
+ ******************************************************************************/
+
+static void
+acpi_ut_copy_id_string (
+ char *destination,
+ char *source,
+ acpi_size max_length)
+{
+
+
+ /*
+ * Workaround for ID strings that have a leading asterisk. This construct
+ * is not allowed by the ACPI specification (ID strings must be
+ * alphanumeric), but enough existing machines have this embedded in their
+ * ID strings that the following code is useful.
+ */
+ if (*source == '*') {
+ source++;
+ }
+
+ /* Do the actual copy */
+
+ ACPI_STRNCPY (destination, source, max_length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_execute_HID
+ *
+ * PARAMETERS: device_node - Node for the device
+ * *Hid - Where the HID is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes the _HID control method that returns the hardware
+ * ID of the device.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_HID (
+ struct acpi_namespace_node *device_node,
+ struct acpi_device_id *hid)
+{
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ut_execute_HID");
+
+
+ status = acpi_ut_evaluate_object (device_node, METHOD_NAME__HID,
+ ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ /* Convert the Numeric HID to string */
+
+ acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value);
+ }
+ else {
+ /* Copy the String HID from the returned object */
+
+ acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer,
+ sizeof (hid->value));
+ }
+
+ /* On exit, we must delete the return object */
+
+ acpi_ut_remove_reference (obj_desc);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_translate_one_cid
+ *
+ * PARAMETERS: obj_desc - _CID object, must be integer or string
+ * one_cid - Where the CID string is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Return a numeric or string _CID value as a string.
+ * (Compatible ID)
+ *
+ * NOTE: Assumes a maximum _CID string length of
+ * ACPI_MAX_CID_LENGTH.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_translate_one_cid (
+ union acpi_operand_object *obj_desc,
+ struct acpi_compatible_id *one_cid)
+{
+
+
+ switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ case ACPI_TYPE_INTEGER:
+
+ /* Convert the Numeric CID to string */
+
+ acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value);
+ return (AE_OK);
+
+ case ACPI_TYPE_STRING:
+
+ if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
+ return (AE_AML_STRING_LIMIT);
+ }
+
+ /* Copy the String CID from the returned object */
+
+ acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer,
+ ACPI_MAX_CID_LENGTH);
+ return (AE_OK);
+
+ default:
+
+ return (AE_TYPE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_execute_CID
+ *
+ * PARAMETERS: device_node - Node for the device
+ * *Cid - Where the CID is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes the _CID control method that returns one or more
+ * compatible hardware IDs for the device.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_CID (
+ struct acpi_namespace_node *device_node,
+ struct acpi_compatible_id_list **return_cid_list)
+{
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ u32 count;
+ u32 size;
+ struct acpi_compatible_id_list *cid_list;
+ acpi_native_uint i;
+
+
+ ACPI_FUNCTION_TRACE ("ut_execute_CID");
+
+
+ /* Evaluate the _CID method for this device */
+
+ status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID,
+ ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
+ &obj_desc);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /* Get the number of _CIDs returned */
+
+ count = 1;
+ if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+ count = obj_desc->package.count;
+ }
+
+ /* Allocate a worst-case buffer for the _CIDs */
+
+ size = (((count - 1) * sizeof (struct acpi_compatible_id)) +
+ sizeof (struct acpi_compatible_id_list));
+
+ cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size);
+ if (!cid_list) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Init CID list */
+
+ cid_list->count = count;
+ cid_list->size = size;
+
+ /*
+ * A _CID can return either a single compatible ID or a package of compatible
+ * IDs. Each compatible ID can be one of the following:
+ * -- Number (32 bit compressed EISA ID) or
+ * -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
+ */
+
+ /* The _CID object can be either a single CID or a package (list) of CIDs */
+
+ if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+ /* Translate each package element */
+
+ for (i = 0; i < count; i++) {
+ status = acpi_ut_translate_one_cid (obj_desc->package.elements[i],
+ &cid_list->id[i]);
+ if (ACPI_FAILURE (status)) {
+ break;
+ }
+ }
+ }
+ else {
+ /* Only one CID, translate to a string */
+
+ status = acpi_ut_translate_one_cid (obj_desc, cid_list->id);
+ }
+
+ /* Cleanup on error */
+
+ if (ACPI_FAILURE (status)) {
+ ACPI_MEM_FREE (cid_list);
+ }
+ else {
+ *return_cid_list = cid_list;
+ }
+
+ /* On exit, we must delete the _CID return object */
+
+ acpi_ut_remove_reference (obj_desc);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_execute_UID
+ *
+ * PARAMETERS: device_node - Node for the device
+ * *Uid - Where the UID is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes the _UID control method that returns the hardware
+ * ID of the device.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_UID (
+ struct acpi_namespace_node *device_node,
+ struct acpi_device_id *uid)
+{
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ut_execute_UID");
+
+
+ status = acpi_ut_evaluate_object (device_node, METHOD_NAME__UID,
+ ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+ /* Convert the Numeric UID to string */
+
+ acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value);
+ }
+ else {
+ /* Copy the String UID from the returned object */
+
+ acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer,
+ sizeof (uid->value));
+ }
+
+ /* On exit, we must delete the return object */
+
+ acpi_ut_remove_reference (obj_desc);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_execute_STA
+ *
+ * PARAMETERS: device_node - Node for the device
+ * *Flags - Where the status flags are returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes _STA for selected device and stores results in
+ * *Flags.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_STA (
+ struct acpi_namespace_node *device_node,
+ u32 *flags)
+{
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ut_execute_STA");
+
+
+ status = acpi_ut_evaluate_object (device_node, METHOD_NAME__STA,
+ ACPI_BTYPE_INTEGER, &obj_desc);
+ if (ACPI_FAILURE (status)) {
+ if (AE_NOT_FOUND == status) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "_STA on %4.4s was not found, assuming device is present\n",
+ acpi_ut_get_node_name (device_node)));
+
+ *flags = 0x0F;
+ status = AE_OK;
+ }
+
+ return_ACPI_STATUS (status);
+ }
+
+ /* Extract the status flags */
+
+ *flags = (u32) obj_desc->integer.value;
+
+ /* On exit, we must delete the return object */
+
+ acpi_ut_remove_reference (obj_desc);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_execute_Sxds
+ *
+ * PARAMETERS: device_node - Node for the device
+ * *Flags - Where the status flags are returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Executes _STA for selected device and stores results in
+ * *Flags.
+ *
+ * NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_sxds (
+ struct acpi_namespace_node *device_node,
+ u8 *highest)
+{
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ u32 i;
+
+
+ ACPI_FUNCTION_TRACE ("ut_execute_Sxds");
+
+
+ for (i = 0; i < 4; i++) {
+ highest[i] = 0xFF;
+ status = acpi_ut_evaluate_object (device_node,
+ (char *) acpi_gbl_highest_dstate_names[i],
+ ACPI_BTYPE_INTEGER, &obj_desc);
+ if (ACPI_FAILURE (status)) {
+ if (status != AE_NOT_FOUND) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "%s on Device %4.4s, %s\n",
+ (char *) acpi_gbl_highest_dstate_names[i],
+ acpi_ut_get_node_name (device_node),
+ acpi_format_exception (status)));
+
+ return_ACPI_STATUS (status);
+ }
+ }
+ else {
+ /* Extract the Dstate value */
+
+ highest[i] = (u8) obj_desc->integer.value;
+
+ /* Delete the return object */
+
+ acpi_ut_remove_reference (obj_desc);
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
new file mode 100644
index 000000000000..25b0f8ae1bc6
--- /dev/null
+++ b/drivers/acpi/utilities/utglobal.c
@@ -0,0 +1,935 @@
+/******************************************************************************
+ *
+ * Module Name: utglobal - Global variables for the ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ * 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.
+ */
+
+#define DEFINE_ACPI_GLOBALS
+
+#include <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utglobal")
+
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_format_exception
+ *
+ * PARAMETERS: Status - The acpi_status code to be formatted
+ *
+ * RETURN: A string containing the exception text
+ *
+ * DESCRIPTION: This function translates an ACPI exception into an ASCII string.
+ *
+ ******************************************************************************/
+
+const char *
+acpi_format_exception (
+ acpi_status status)
+{
+ const char *exception = "UNKNOWN_STATUS_CODE";
+ acpi_status sub_status;
+
+
+ ACPI_FUNCTION_NAME ("format_exception");
+
+
+ sub_status = (status & ~AE_CODE_MASK);
+
+ switch (status & AE_CODE_MASK) {
+ case AE_CODE_ENVIRONMENTAL:
+
+ if (sub_status <= AE_CODE_ENV_MAX) {
+ exception = acpi_gbl_exception_names_env [sub_status];
+ break;
+ }
+ goto unknown;
+
+ case AE_CODE_PROGRAMMER:
+
+ if (sub_status <= AE_CODE_PGM_MAX) {
+ exception = acpi_gbl_exception_names_pgm [sub_status -1];
+ break;
+ }
+ goto unknown;
+
+ case AE_CODE_ACPI_TABLES:
+
+ if (sub_status <= AE_CODE_TBL_MAX) {
+ exception = acpi_gbl_exception_names_tbl [sub_status -1];
+ break;
+ }
+ goto unknown;
+
+ case AE_CODE_AML:
+
+ if (sub_status <= AE_CODE_AML_MAX) {
+ exception = acpi_gbl_exception_names_aml [sub_status -1];
+ break;
+ }
+ goto unknown;
+
+ case AE_CODE_CONTROL:
+
+ if (sub_status <= AE_CODE_CTRL_MAX) {
+ exception = acpi_gbl_exception_names_ctrl [sub_status -1];
+ break;
+ }
+ goto unknown;
+
+ default:
+ goto unknown;
+ }
+
+
+ return ((const char *) exception);
+
+unknown:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown exception code: 0x%8.8X\n", status));
+ return ((const char *) exception);
+}
+
+
+/******************************************************************************
+ *
+ * Static global variable initialization.
+ *
+ ******************************************************************************/
+
+/*
+ * We want the debug switches statically initialized so they
+ * are already set when the debugger is entered.
+ */
+
+/* Debug switch - level and trace mask */
+u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT;
+EXPORT_SYMBOL(acpi_dbg_level);
+
+/* Debug switch - layer (component) mask */
+
+u32 acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
+EXPORT_SYMBOL(acpi_dbg_layer);
+u32 acpi_gbl_nesting_level = 0;
+
+
+/* Debugger globals */
+
+u8 acpi_gbl_db_terminate_threads = FALSE;
+u8 acpi_gbl_abort_method = FALSE;
+u8 acpi_gbl_method_executing = FALSE;
+
+/* System flags */
+
+u32 acpi_gbl_startup_flags = 0;
+
+/* System starts uninitialized */
+
+u8 acpi_gbl_shutdown = TRUE;
+
+const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
+
+const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] =
+{
+ "\\_S0_",
+ "\\_S1_",
+ "\\_S2_",
+ "\\_S3_",
+ "\\_S4_",
+ "\\_S5_"
+};
+
+const char *acpi_gbl_highest_dstate_names[4] =
+{
+ "_S1D",
+ "_S2D",
+ "_S3D",
+ "_S4D"
+};
+
+/*
+ * Strings supported by the _OSI predefined (internal) method.
+ * When adding strings, be sure to update ACPI_NUM_OSI_STRINGS.
+ */
+const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] =
+{
+ /* Operating System Vendor Strings */
+
+ "Linux",
+ "Windows 2000",
+ "Windows 2001",
+ "Windows 2001.1",
+ "Windows 2001 SP0",
+ "Windows 2001 SP1",
+ "Windows 2001 SP2",
+ "Windows 2001 SP3",
+ "Windows 2001 SP4",
+
+ /* Feature Group Strings */
+
+ "Extended Address Space Descriptor"
+};
+
+
+/******************************************************************************
+ *
+ * Namespace globals
+ *
+ ******************************************************************************/
+
+
+/*
+ * Predefined ACPI Names (Built-in to the Interpreter)
+ *
+ * NOTES:
+ * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
+ * during the initialization sequence.
+ * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to
+ * perform a Notify() operation on it.
+ */
+const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
+{ {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
+ {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
+ {"_SB_", ACPI_TYPE_DEVICE, NULL},
+ {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
+ {"_TZ_", ACPI_TYPE_THERMAL, NULL},
+ {"_REV", ACPI_TYPE_INTEGER, (char *) ACPI_CA_SUPPORT_LEVEL},
+ {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
+ {"_GL_", ACPI_TYPE_MUTEX, (char *) 1},
+
+#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
+ {"_OSI", ACPI_TYPE_METHOD, (char *) 1},
+#endif
+ {NULL, ACPI_TYPE_ANY, NULL} /* Table terminator */
+};
+
+
+/*
+ * Properties of the ACPI Object Types, both internal and external.
+ * The table is indexed by values of acpi_object_type
+ */
+const u8 acpi_gbl_ns_properties[] =
+{
+ ACPI_NS_NORMAL, /* 00 Any */
+ ACPI_NS_NORMAL, /* 01 Number */
+ ACPI_NS_NORMAL, /* 02 String */
+ ACPI_NS_NORMAL, /* 03 Buffer */
+ ACPI_NS_NORMAL, /* 04 Package */
+ ACPI_NS_NORMAL, /* 05 field_unit */
+ ACPI_NS_NEWSCOPE, /* 06 Device */
+ ACPI_NS_NORMAL, /* 07 Event */
+ ACPI_NS_NEWSCOPE, /* 08 Method */
+ ACPI_NS_NORMAL, /* 09 Mutex */
+ ACPI_NS_NORMAL, /* 10 Region */
+ ACPI_NS_NEWSCOPE, /* 11 Power */
+ ACPI_NS_NEWSCOPE, /* 12 Processor */
+ ACPI_NS_NEWSCOPE, /* 13 Thermal */
+ ACPI_NS_NORMAL, /* 14 buffer_field */
+ ACPI_NS_NORMAL, /* 15 ddb_handle */
+ ACPI_NS_NORMAL, /* 16 Debug Object */
+ ACPI_NS_NORMAL, /* 17 def_field */
+ ACPI_NS_NORMAL, /* 18 bank_field */
+ ACPI_NS_NORMAL, /* 19 index_field */
+ ACPI_NS_NORMAL, /* 20 Reference */
+ ACPI_NS_NORMAL, /* 21 Alias */
+ ACPI_NS_NORMAL, /* 22 method_alias */
+ ACPI_NS_NORMAL, /* 23 Notify */
+ ACPI_NS_NORMAL, /* 24 Address Handler */
+ ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */
+ ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */
+ ACPI_NS_NEWSCOPE, /* 27 Scope */
+ ACPI_NS_NORMAL, /* 28 Extra */
+ ACPI_NS_NORMAL, /* 29 Data */
+ ACPI_NS_NORMAL /* 30 Invalid */
+};
+
+
+/* Hex to ASCII conversion table */
+
+static const char acpi_gbl_hex_to_ascii[] =
+ {'0','1','2','3','4','5','6','7',
+ '8','9','A','B','C','D','E','F'};
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_hex_to_ascii_char
+ *
+ * PARAMETERS: Integer - Contains the hex digit
+ * Position - bit position of the digit within the
+ * integer
+ *
+ * RETURN: Ascii character
+ *
+ * DESCRIPTION: Convert a hex digit to an ascii character
+ *
+ ****************************************************************************/
+
+char
+acpi_ut_hex_to_ascii_char (
+ acpi_integer integer,
+ u32 position)
+{
+
+ return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
+}
+
+
+/******************************************************************************
+ *
+ * Table name globals
+ *
+ * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes.
+ * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables
+ * that are not used by the subsystem are simply ignored.
+ *
+ * Do NOT add any table to this list that is not consumed directly by this
+ * subsystem.
+ *
+ ******************************************************************************/
+
+struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
+
+struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] =
+{
+ /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */
+
+ /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE},
+ /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE},
+ /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE},
+ /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE},
+ /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
+ /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
+ /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof (RSDT_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE},
+};
+
+
+/******************************************************************************
+ *
+ * Event and Hardware globals
+ *
+ ******************************************************************************/
+
+struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] =
+{
+ /* Name Parent Register Register Bit Position Register Bit Mask */
+
+ /* ACPI_BITREG_TIMER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_TIMER_STATUS, ACPI_BITMASK_TIMER_STATUS},
+ /* ACPI_BITREG_BUS_MASTER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_BUS_MASTER_STATUS, ACPI_BITMASK_BUS_MASTER_STATUS},
+ /* ACPI_BITREG_GLOBAL_LOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_STATUS},
+ /* ACPI_BITREG_POWER_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_STATUS},
+ /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_STATUS},
+ /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_STATUS},
+ /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_WAKE_STATUS, ACPI_BITMASK_WAKE_STATUS},
+ /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_PCIEXP_WAKE_STATUS, ACPI_BITMASK_PCIEXP_WAKE_STATUS},
+
+ /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_TIMER_ENABLE, ACPI_BITMASK_TIMER_ENABLE},
+ /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
+ /* ACPI_BITREG_POWER_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_ENABLE},
+ /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
+ /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_ENABLE},
+ /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0},
+ /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
+
+ /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SCI_ENABLE, ACPI_BITMASK_SCI_ENABLE},
+ /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_BUS_MASTER_RLD, ACPI_BITMASK_BUS_MASTER_RLD},
+ /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE, ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
+ /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_TYPE_X, ACPI_BITMASK_SLEEP_TYPE_X},
+ /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_TYPE_X, ACPI_BITMASK_SLEEP_TYPE_X},
+ /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_ENABLE, ACPI_BITMASK_SLEEP_ENABLE},
+
+ /* ACPI_BITREG_ARB_DIS */ {ACPI_REGISTER_PM2_CONTROL, ACPI_BITPOSITION_ARB_DISABLE, ACPI_BITMASK_ARB_DISABLE}
+};
+
+
+struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
+{
+ /* ACPI_EVENT_PMTIMER */ {ACPI_BITREG_TIMER_STATUS, ACPI_BITREG_TIMER_ENABLE, ACPI_BITMASK_TIMER_STATUS, ACPI_BITMASK_TIMER_ENABLE},
+ /* ACPI_EVENT_GLOBAL */ {ACPI_BITREG_GLOBAL_LOCK_STATUS, ACPI_BITREG_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
+ /* ACPI_EVENT_POWER_BUTTON */ {ACPI_BITREG_POWER_BUTTON_STATUS, ACPI_BITREG_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_ENABLE},
+ /* ACPI_EVENT_SLEEP_BUTTON */ {ACPI_BITREG_SLEEP_BUTTON_STATUS, ACPI_BITREG_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
+ /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS, ACPI_BITREG_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_ENABLE},
+};
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_region_name
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a Space ID into a name string (Debug only)
+ *
+ ****************************************************************************/
+
+/* Region type decoding */
+
+const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] =
+{
+/*! [Begin] no source code translation (keep these ASL Keywords as-is) */
+ "SystemMemory",
+ "SystemIO",
+ "PCI_Config",
+ "EmbeddedControl",
+ "SMBus",
+ "CMOS",
+ "PCIBARTarget",
+ "DataTable"
+/*! [End] no source code translation !*/
+};
+
+
+char *
+acpi_ut_get_region_name (
+ u8 space_id)
+{
+
+ if (space_id >= ACPI_USER_REGION_BEGIN)
+ {
+ return ("user_defined_region");
+ }
+
+ else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS)
+ {
+ return ("invalid_space_id");
+ }
+
+ return ((char *) acpi_gbl_region_types[space_id]);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_event_name
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a Event ID into a name string (Debug only)
+ *
+ ****************************************************************************/
+
+/* Event type decoding */
+
+static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] =
+{
+ "PM_Timer",
+ "global_lock",
+ "power_button",
+ "sleep_button",
+ "real_time_clock",
+};
+
+
+char *
+acpi_ut_get_event_name (
+ u32 event_id)
+{
+
+ if (event_id > ACPI_EVENT_MAX)
+ {
+ return ("invalid_event_iD");
+ }
+
+ return ((char *) acpi_gbl_event_types[event_id]);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_type_name
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a Type ID into a name string (Debug only)
+ *
+ ****************************************************************************/
+
+/*
+ * Elements of acpi_gbl_ns_type_names below must match
+ * one-to-one with values of acpi_object_type
+ *
+ * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when
+ * stored in a table it really means that we have thus far seen no evidence to
+ * indicate what type is actually going to be stored for this entry.
+ */
+static const char acpi_gbl_bad_type[] = "UNDEFINED";
+#define TYPE_NAME_LENGTH 12 /* Maximum length of each string */
+
+static const char *acpi_gbl_ns_type_names[] = /* printable names of ACPI types */
+{
+ /* 00 */ "Untyped",
+ /* 01 */ "Integer",
+ /* 02 */ "String",
+ /* 03 */ "Buffer",
+ /* 04 */ "Package",
+ /* 05 */ "field_unit",
+ /* 06 */ "Device",
+ /* 07 */ "Event",
+ /* 08 */ "Method",
+ /* 09 */ "Mutex",
+ /* 10 */ "Region",
+ /* 11 */ "Power",
+ /* 12 */ "Processor",
+ /* 13 */ "Thermal",
+ /* 14 */ "buffer_field",
+ /* 15 */ "ddb_handle",
+ /* 16 */ "debug_object",
+ /* 17 */ "region_field",
+ /* 18 */ "bank_field",
+ /* 19 */ "index_field",
+ /* 20 */ "Reference",
+ /* 21 */ "Alias",
+ /* 22 */ "method_alias",
+ /* 23 */ "Notify",
+ /* 24 */ "addr_handler",
+ /* 25 */ "resource_desc",
+ /* 26 */ "resource_fld",
+ /* 27 */ "Scope",
+ /* 28 */ "Extra",
+ /* 29 */ "Data",
+ /* 30 */ "Invalid"
+};
+
+
+char *
+acpi_ut_get_type_name (
+ acpi_object_type type)
+{
+
+ if (type > ACPI_TYPE_INVALID)
+ {
+ return ((char *) acpi_gbl_bad_type);
+ }
+
+ return ((char *) acpi_gbl_ns_type_names[type]);
+}
+
+
+char *
+acpi_ut_get_object_type_name (
+ union acpi_operand_object *obj_desc)
+{
+
+ if (!obj_desc)
+ {
+ return ("[NULL Object Descriptor]");
+ }
+
+ return (acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)));
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_node_name
+ *
+ * PARAMETERS: Object - A namespace node
+ *
+ * RETURN: Pointer to a string
+ *
+ * DESCRIPTION: Validate the node and return the node's ACPI name.
+ *
+ ****************************************************************************/
+
+char *
+acpi_ut_get_node_name (
+ void *object)
+{
+ struct acpi_namespace_node *node = (struct acpi_namespace_node *) object;
+
+
+ /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
+
+ if (!object)
+ {
+ return ("NULL");
+ }
+
+ /* Check for Root node */
+
+ if ((object == ACPI_ROOT_OBJECT) ||
+ (object == acpi_gbl_root_node))
+ {
+ return ("\"\\\" ");
+ }
+
+ /* Descriptor must be a namespace node */
+
+ if (node->descriptor != ACPI_DESC_TYPE_NAMED)
+ {
+ return ("####");
+ }
+
+ /* Name must be a valid ACPI name */
+
+ if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii))
+ {
+ return ("????");
+ }
+
+ /* Return the name */
+
+ return (node->name.ascii);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_descriptor_name
+ *
+ * PARAMETERS: Object - An ACPI object
+ *
+ * RETURN: Pointer to a string
+ *
+ * DESCRIPTION: Validate object and return the descriptor type
+ *
+ ****************************************************************************/
+
+static const char *acpi_gbl_desc_type_names[] = /* printable names of descriptor types */
+{
+ /* 00 */ "Invalid",
+ /* 01 */ "Cached",
+ /* 02 */ "State-Generic",
+ /* 03 */ "State-Update",
+ /* 04 */ "State-Package",
+ /* 05 */ "State-Control",
+ /* 06 */ "State-root_parse_scope",
+ /* 07 */ "State-parse_scope",
+ /* 08 */ "State-walk_scope",
+ /* 09 */ "State-Result",
+ /* 10 */ "State-Notify",
+ /* 11 */ "State-Thread",
+ /* 12 */ "Walk",
+ /* 13 */ "Parser",
+ /* 14 */ "Operand",
+ /* 15 */ "Node"
+};
+
+
+char *
+acpi_ut_get_descriptor_name (
+ void *object)
+{
+
+ if (!object)
+ {
+ return ("NULL OBJECT");
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (object) > ACPI_DESC_TYPE_MAX)
+ {
+ return ((char *) acpi_gbl_bad_type);
+ }
+
+ return ((char *) acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE (object)]);
+
+}
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+/*
+ * Strings and procedures used for debug only
+ */
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_mutex_name
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
+ *
+ ****************************************************************************/
+
+char *
+acpi_ut_get_mutex_name (
+ u32 mutex_id)
+{
+
+ if (mutex_id > MAX_MUTEX)
+ {
+ return ("Invalid Mutex ID");
+ }
+
+ return (acpi_gbl_mutex_names[mutex_id]);
+}
+
+#endif
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_valid_object_type
+ *
+ * PARAMETERS: Type - Object type to be validated
+ *
+ * RETURN: TRUE if valid object type
+ *
+ * DESCRIPTION: Validate an object type
+ *
+ ****************************************************************************/
+
+u8
+acpi_ut_valid_object_type (
+ acpi_object_type type)
+{
+
+ if (type > ACPI_TYPE_LOCAL_MAX)
+ {
+ /* Note: Assumes all TYPEs are contiguous (external/local) */
+
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION: acpi_ut_allocate_owner_id
+ *
+ * PARAMETERS: id_type - Type of ID (method or table)
+ *
+ * DESCRIPTION: Allocate a table or method owner id
+ *
+ ***************************************************************************/
+
+acpi_owner_id
+acpi_ut_allocate_owner_id (
+ u32 id_type)
+{
+ acpi_owner_id owner_id = 0xFFFF;
+
+
+ ACPI_FUNCTION_TRACE ("ut_allocate_owner_id");
+
+
+ if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES)))
+ {
+ return (0);
+ }
+
+ switch (id_type)
+ {
+ case ACPI_OWNER_TYPE_TABLE:
+
+ owner_id = acpi_gbl_next_table_owner_id;
+ acpi_gbl_next_table_owner_id++;
+
+ /* Check for wraparound */
+
+ if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID)
+ {
+ acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID;
+ ACPI_REPORT_WARNING (("Table owner ID wraparound\n"));
+ }
+ break;
+
+
+ case ACPI_OWNER_TYPE_METHOD:
+
+ owner_id = acpi_gbl_next_method_owner_id;
+ acpi_gbl_next_method_owner_id++;
+
+ if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID)
+ {
+ /* Check for wraparound */
+
+ acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ (void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
+ return_VALUE (owner_id);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION: acpi_ut_init_globals
+ *
+ * PARAMETERS: none
+ *
+ * DESCRIPTION: Init library globals. All globals that require specific
+ * initialization should be initialized here!
+ *
+ ***************************************************************************/
+
+void
+acpi_ut_init_globals (
+ void)
+{
+ u32 i;
+
+
+ ACPI_FUNCTION_TRACE ("ut_init_globals");
+
+
+ /* Memory allocation and cache lists */
+
+ ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS);
+
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_generic_state *) NULL)->common.next), NULL);
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL);
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL);
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_operand_object *) NULL)->cache.next), NULL);
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].link_offset = (u16) ACPI_PTR_DIFF (&(((struct acpi_walk_state *) NULL)->next), NULL);
+
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].object_size = sizeof (struct acpi_namespace_node);
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].object_size = sizeof (union acpi_generic_state);
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].object_size = sizeof (struct acpi_parse_obj_common);
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].object_size = sizeof (struct acpi_parse_obj_named);
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].object_size = sizeof (union acpi_operand_object);
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].object_size = sizeof (struct acpi_walk_state);
+
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].max_cache_depth = ACPI_MAX_STATE_CACHE_DEPTH;
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].max_cache_depth = ACPI_MAX_PARSE_CACHE_DEPTH;
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].max_cache_depth = ACPI_MAX_EXTPARSE_CACHE_DEPTH;
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].max_cache_depth = ACPI_MAX_OBJECT_CACHE_DEPTH;
+ acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].max_cache_depth = ACPI_MAX_WALK_CACHE_DEPTH;
+
+ ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].list_name = "Global Memory Allocation");
+ ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].list_name = "Namespace Nodes");
+ ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].list_name = "State Object Cache");
+ ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].list_name = "Parse Node Cache");
+ ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].list_name = "Extended Parse Node Cache");
+ ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].list_name = "Operand Object Cache");
+ ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].list_name = "Tree Walk Node Cache");
+
+ /* ACPI table structure */
+
+ for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
+ {
+ acpi_gbl_table_lists[i].next = NULL;
+ acpi_gbl_table_lists[i].count = 0;
+ }
+
+ /* Mutex locked flags */
+
+ for (i = 0; i < NUM_MUTEX; i++)
+ {
+ acpi_gbl_mutex_info[i].mutex = NULL;
+ acpi_gbl_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+ acpi_gbl_mutex_info[i].use_count = 0;
+ }
+
+ /* GPE support */
+
+ acpi_gbl_gpe_xrupt_list_head = NULL;
+ acpi_gbl_gpe_fadt_blocks[0] = NULL;
+ acpi_gbl_gpe_fadt_blocks[1] = NULL;
+
+ /* Global notify handlers */
+
+ acpi_gbl_system_notify.handler = NULL;
+ acpi_gbl_device_notify.handler = NULL;
+ acpi_gbl_exception_handler = NULL;
+ acpi_gbl_init_handler = NULL;
+
+ /* Global "typed" ACPI table pointers */
+
+ acpi_gbl_RSDP = NULL;
+ acpi_gbl_XSDT = NULL;
+ acpi_gbl_FACS = NULL;
+ acpi_gbl_FADT = NULL;
+ acpi_gbl_DSDT = NULL;
+
+ /* Global Lock support */
+
+ acpi_gbl_global_lock_acquired = FALSE;
+ acpi_gbl_global_lock_thread_count = 0;
+ acpi_gbl_global_lock_handle = 0;
+
+ /* Miscellaneous variables */
+
+ acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER;
+ acpi_gbl_rsdp_original_location = 0;
+ acpi_gbl_cm_single_step = FALSE;
+ acpi_gbl_db_terminate_threads = FALSE;
+ acpi_gbl_shutdown = FALSE;
+ acpi_gbl_ns_lookup_count = 0;
+ acpi_gbl_ps_find_count = 0;
+ acpi_gbl_acpi_hardware_present = TRUE;
+ acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID;
+ acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID;
+ acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
+ acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+
+ /* Hardware oriented */
+
+ acpi_gbl_events_initialized = FALSE;
+ acpi_gbl_system_awake_and_running = TRUE;
+
+ /* Namespace */
+
+ acpi_gbl_root_node = NULL;
+
+ acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
+ acpi_gbl_root_node_struct.descriptor = ACPI_DESC_TYPE_NAMED;
+ acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
+ acpi_gbl_root_node_struct.child = NULL;
+ acpi_gbl_root_node_struct.peer = NULL;
+ acpi_gbl_root_node_struct.object = NULL;
+ acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST;
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+ acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX;
+#endif
+
+ return_VOID;
+}
+
+
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
new file mode 100644
index 000000000000..bdbadaf48d29
--- /dev/null
+++ b/drivers/acpi/utilities/utinit.c
@@ -0,0 +1,266 @@
+/******************************************************************************
+ *
+ * Module Name: utinit - Common ACPI subsystem initialization
+ *
+ *****************************************************************************/
+
+/*
+ * 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>
+#include <acpi/acevents.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utinit")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_fadt_register_error
+ *
+ * PARAMETERS: *register_name - Pointer to string identifying register
+ * Value - Actual register contents value
+ * acpi_test_spec_section - TDS section containing assertion
+ * acpi_assertion - Assertion number being tested
+ *
+ * RETURN: AE_BAD_VALUE
+ *
+ * DESCRIPTION: Display failure message and link failure to TDS assertion
+ *
+ ******************************************************************************/
+
+static void
+acpi_ut_fadt_register_error (
+ char *register_name,
+ u32 value,
+ acpi_size offset)
+{
+
+ ACPI_REPORT_WARNING (
+ ("Invalid FADT value %s=%X at offset %X FADT=%p\n",
+ register_name, value, (u32) offset, acpi_gbl_FADT));
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_ut_validate_fadt
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validate various ACPI registers in the FADT
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_validate_fadt (
+ void)
+{
+
+ /*
+ * Verify Fixed ACPI Description Table fields,
+ * but don't abort on any problems, just display error
+ */
+ if (acpi_gbl_FADT->pm1_evt_len < 4) {
+ acpi_ut_fadt_register_error ("PM1_EVT_LEN",
+ (u32) acpi_gbl_FADT->pm1_evt_len,
+ ACPI_FADT_OFFSET (pm1_evt_len));
+ }
+
+ if (!acpi_gbl_FADT->pm1_cnt_len) {
+ acpi_ut_fadt_register_error ("PM1_CNT_LEN", 0,
+ ACPI_FADT_OFFSET (pm1_cnt_len));
+ }
+
+ if (!acpi_gbl_FADT->xpm1a_evt_blk.address) {
+ acpi_ut_fadt_register_error ("X_PM1a_EVT_BLK", 0,
+ ACPI_FADT_OFFSET (xpm1a_evt_blk.address));
+ }
+
+ if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) {
+ acpi_ut_fadt_register_error ("X_PM1a_CNT_BLK", 0,
+ ACPI_FADT_OFFSET (xpm1a_cnt_blk.address));
+ }
+
+ if (!acpi_gbl_FADT->xpm_tmr_blk.address) {
+ acpi_ut_fadt_register_error ("X_PM_TMR_BLK", 0,
+ ACPI_FADT_OFFSET (xpm_tmr_blk.address));
+ }
+
+ if ((acpi_gbl_FADT->xpm2_cnt_blk.address &&
+ !acpi_gbl_FADT->pm2_cnt_len)) {
+ acpi_ut_fadt_register_error ("PM2_CNT_LEN",
+ (u32) acpi_gbl_FADT->pm2_cnt_len,
+ ACPI_FADT_OFFSET (pm2_cnt_len));
+ }
+
+ if (acpi_gbl_FADT->pm_tm_len < 4) {
+ acpi_ut_fadt_register_error ("PM_TM_LEN",
+ (u32) acpi_gbl_FADT->pm_tm_len,
+ ACPI_FADT_OFFSET (pm_tm_len));
+ }
+
+ /* Length of GPE blocks must be a multiple of 2 */
+
+ if (acpi_gbl_FADT->xgpe0_blk.address &&
+ (acpi_gbl_FADT->gpe0_blk_len & 1)) {
+ acpi_ut_fadt_register_error ("(x)GPE0_BLK_LEN",
+ (u32) acpi_gbl_FADT->gpe0_blk_len,
+ ACPI_FADT_OFFSET (gpe0_blk_len));
+ }
+
+ if (acpi_gbl_FADT->xgpe1_blk.address &&
+ (acpi_gbl_FADT->gpe1_blk_len & 1)) {
+ acpi_ut_fadt_register_error ("(x)GPE1_BLK_LEN",
+ (u32) acpi_gbl_FADT->gpe1_blk_len,
+ ACPI_FADT_OFFSET (gpe1_blk_len));
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_ut_terminate
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: free global memory
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_terminate (void)
+{
+ struct acpi_gpe_block_info *gpe_block;
+ struct acpi_gpe_block_info *next_gpe_block;
+ struct acpi_gpe_xrupt_info *gpe_xrupt_info;
+ struct acpi_gpe_xrupt_info *next_gpe_xrupt_info;
+
+
+ ACPI_FUNCTION_TRACE ("ut_terminate");
+
+
+ /* Free global tables, etc. */
+
+
+ /* Free global GPE blocks and related info structures */
+
+ gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
+ while (gpe_xrupt_info) {
+ gpe_block = gpe_xrupt_info->gpe_block_list_head;
+ while (gpe_block) {
+ next_gpe_block = gpe_block->next;
+ ACPI_MEM_FREE (gpe_block->event_info);
+ ACPI_MEM_FREE (gpe_block->register_info);
+ ACPI_MEM_FREE (gpe_block);
+
+ gpe_block = next_gpe_block;
+ }
+ next_gpe_xrupt_info = gpe_xrupt_info->next;
+ ACPI_MEM_FREE (gpe_xrupt_info);
+ gpe_xrupt_info = next_gpe_xrupt_info;
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_subsystem_shutdown
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Shutdown the various subsystems. Don't delete the mutex
+ * objects here -- because the AML debugger may be still running.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_subsystem_shutdown (void)
+{
+
+ ACPI_FUNCTION_TRACE ("ut_subsystem_shutdown");
+
+ /* Just exit if subsystem is already shutdown */
+
+ if (acpi_gbl_shutdown) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "ACPI Subsystem is already terminated\n"));
+ return_VOID;
+ }
+
+ /* Subsystem appears active, go ahead and shut it down */
+
+ acpi_gbl_shutdown = TRUE;
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem...\n"));
+
+ /* Close the acpi_event Handling */
+
+ acpi_ev_terminate ();
+
+ /* Close the Namespace */
+
+ acpi_ns_terminate ();
+
+ /* Close the globals */
+
+ acpi_ut_terminate ();
+
+ /* Purge the local caches */
+
+ (void) acpi_purge_cached_objects ();
+
+ /* Debug only - display leftover memory allocation, if any */
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ acpi_ut_dump_allocations (ACPI_UINT32_MAX, NULL);
+#endif
+
+ return_VOID;
+}
+
+
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
new file mode 100644
index 000000000000..2525c1a93547
--- /dev/null
+++ b/drivers/acpi/utilities/utmath.c
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ *
+ * Module Name: utmath - Integer math support routines
+ *
+ ******************************************************************************/
+
+/*
+ * 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>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utmath")
+
+/*
+ * Support for double-precision integer divide. This code is included here
+ * in order to support kernel environments where the double-precision math
+ * library is not available.
+ */
+
+#ifndef ACPI_USE_NATIVE_DIVIDE
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_short_divide
+ *
+ * PARAMETERS: Dividend - 64-bit dividend
+ * Divisor - 32-bit divisor
+ * out_quotient - Pointer to where the quotient is returned
+ * out_remainder - Pointer to where the remainder is returned
+ *
+ * RETURN: Status (Checks for divide-by-zero)
+ *
+ * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits)
+ * divide and modulo. The result is a 64-bit quotient and a
+ * 32-bit remainder.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_short_divide (
+ acpi_integer dividend,
+ u32 divisor,
+ acpi_integer *out_quotient,
+ u32 *out_remainder)
+{
+ union uint64_overlay dividend_ovl;
+ union uint64_overlay quotient;
+ u32 remainder32;
+
+
+ ACPI_FUNCTION_TRACE ("ut_short_divide");
+
+
+ /* Always check for a zero divisor */
+
+ if (divisor == 0) {
+ ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n"));
+ return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+ }
+
+ dividend_ovl.full = dividend;
+
+ /*
+ * The quotient is 64 bits, the remainder is always 32 bits,
+ * and is generated by the second divide.
+ */
+ ACPI_DIV_64_BY_32 (0, dividend_ovl.part.hi, divisor,
+ quotient.part.hi, remainder32);
+ ACPI_DIV_64_BY_32 (remainder32, dividend_ovl.part.lo, divisor,
+ quotient.part.lo, remainder32);
+
+ /* Return only what was requested */
+
+ if (out_quotient) {
+ *out_quotient = quotient.full;
+ }
+ if (out_remainder) {
+ *out_remainder = remainder32;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_divide
+ *
+ * PARAMETERS: in_dividend - Dividend
+ * in_divisor - Divisor
+ * out_quotient - Pointer to where the quotient is returned
+ * out_remainder - Pointer to where the remainder is returned
+ *
+ * RETURN: Status (Checks for divide-by-zero)
+ *
+ * DESCRIPTION: Perform a divide and modulo.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_divide (
+ acpi_integer in_dividend,
+ acpi_integer in_divisor,
+ acpi_integer *out_quotient,
+ acpi_integer *out_remainder)
+{
+ union uint64_overlay dividend;
+ union uint64_overlay divisor;
+ union uint64_overlay quotient;
+ union uint64_overlay remainder;
+ union uint64_overlay normalized_dividend;
+ union uint64_overlay normalized_divisor;
+ u32 partial1;
+ union uint64_overlay partial2;
+ union uint64_overlay partial3;
+
+
+ ACPI_FUNCTION_TRACE ("ut_divide");
+
+
+ /* Always check for a zero divisor */
+
+ if (in_divisor == 0) {
+ ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n"));
+ return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+ }
+
+ divisor.full = in_divisor;
+ dividend.full = in_dividend;
+ if (divisor.part.hi == 0) {
+ /*
+ * 1) Simplest case is where the divisor is 32 bits, we can
+ * just do two divides
+ */
+ remainder.part.hi = 0;
+
+ /*
+ * The quotient is 64 bits, the remainder is always 32 bits,
+ * and is generated by the second divide.
+ */
+ ACPI_DIV_64_BY_32 (0, dividend.part.hi, divisor.part.lo,
+ quotient.part.hi, partial1);
+ ACPI_DIV_64_BY_32 (partial1, dividend.part.lo, divisor.part.lo,
+ quotient.part.lo, remainder.part.lo);
+ }
+
+ else {
+ /*
+ * 2) The general case where the divisor is a full 64 bits
+ * is more difficult
+ */
+ quotient.part.hi = 0;
+ normalized_dividend = dividend;
+ normalized_divisor = divisor;
+
+ /* Normalize the operands (shift until the divisor is < 32 bits) */
+
+ do {
+ ACPI_SHIFT_RIGHT_64 (normalized_divisor.part.hi,
+ normalized_divisor.part.lo);
+ ACPI_SHIFT_RIGHT_64 (normalized_dividend.part.hi,
+ normalized_dividend.part.lo);
+
+ } while (normalized_divisor.part.hi != 0);
+
+ /* Partial divide */
+
+ ACPI_DIV_64_BY_32 (normalized_dividend.part.hi,
+ normalized_dividend.part.lo,
+ normalized_divisor.part.lo,
+ quotient.part.lo, partial1);
+
+ /*
+ * The quotient is always 32 bits, and simply requires adjustment.
+ * The 64-bit remainder must be generated.
+ */
+ partial1 = quotient.part.lo * divisor.part.hi;
+ partial2.full = (acpi_integer) quotient.part.lo * divisor.part.lo;
+ partial3.full = (acpi_integer) partial2.part.hi + partial1;
+
+ remainder.part.hi = partial3.part.lo;
+ remainder.part.lo = partial2.part.lo;
+
+ if (partial3.part.hi == 0) {
+ if (partial3.part.lo >= dividend.part.hi) {
+ if (partial3.part.lo == dividend.part.hi) {
+ if (partial2.part.lo > dividend.part.lo) {
+ quotient.part.lo--;
+ remainder.full -= divisor.full;
+ }
+ }
+ else {
+ quotient.part.lo--;
+ remainder.full -= divisor.full;
+ }
+ }
+
+ remainder.full = remainder.full - dividend.full;
+ remainder.part.hi = (u32) -((s32) remainder.part.hi);
+ remainder.part.lo = (u32) -((s32) remainder.part.lo);
+
+ if (remainder.part.lo) {
+ remainder.part.hi--;
+ }
+ }
+ }
+
+ /* Return only what was requested */
+
+ if (out_quotient) {
+ *out_quotient = quotient.full;
+ }
+ if (out_remainder) {
+ *out_remainder = remainder.full;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+#else
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_short_divide, acpi_ut_divide
+ *
+ * DESCRIPTION: Native versions of the ut_divide functions. Use these if either
+ * 1) The target is a 64-bit platform and therefore 64-bit
+ * integer math is supported directly by the machine.
+ * 2) The target is a 32-bit or 16-bit platform, and the
+ * double-precision integer math library is available to
+ * perform the divide.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_short_divide (
+ acpi_integer in_dividend,
+ u32 divisor,
+ acpi_integer *out_quotient,
+ u32 *out_remainder)
+{
+
+ ACPI_FUNCTION_TRACE ("ut_short_divide");
+
+
+ /* Always check for a zero divisor */
+
+ if (divisor == 0) {
+ ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n"));
+ return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+ }
+
+ /* Return only what was requested */
+
+ if (out_quotient) {
+ *out_quotient = in_dividend / divisor;
+ }
+ if (out_remainder) {
+ *out_remainder = (u32) in_dividend % divisor;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+acpi_status
+acpi_ut_divide (
+ acpi_integer in_dividend,
+ acpi_integer in_divisor,
+ acpi_integer *out_quotient,
+ acpi_integer *out_remainder)
+{
+ ACPI_FUNCTION_TRACE ("ut_divide");
+
+
+ /* Always check for a zero divisor */
+
+ if (in_divisor == 0) {
+ ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n"));
+ return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+ }
+
+
+ /* Return only what was requested */
+
+ if (out_quotient) {
+ *out_quotient = in_dividend / in_divisor;
+ }
+ if (out_remainder) {
+ *out_remainder = in_dividend % in_divisor;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+#endif
+
+
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
new file mode 100644
index 000000000000..f6598547389b
--- /dev/null
+++ b/drivers/acpi/utilities/utmisc.c
@@ -0,0 +1,1516 @@
+/*******************************************************************************
+ *
+ * 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_UTILITIES
+ ACPI_MODULE_NAME ("utmisc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_print_string
+ *
+ * PARAMETERS: String - Null terminated ASCII string
+ *
+ * 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
+ *
+ * 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: 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
+ *
+ ******************************************************************************/
+
+void
+acpi_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: Character - The character to be examined
+ *
+ * RETURN: 1 if Character may appear in a name, else 0
+ *
+ * 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);
+ }
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_valid_acpi_character
+ *
+ * PARAMETERS: Character - The character to be examined
+ *
+ * RETURN: 1 if Character may appear in a name, else 0
+ *
+ * DESCRIPTION: Check for a printable character
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_valid_acpi_character (
+ char character)
+{
+
+ ACPI_FUNCTION_ENTRY ();
+
+ return ((u8) ((character == '_') ||
+ (character >= 'A' && character <= 'Z') ||
+ (character >= '0' && character <= '9')));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strtoul64
+ *
+ * PARAMETERS: String - Null terminated string
+ * Base - Radix of the string: 10, 16, or ACPI_ANY_BASE
+ * ret_integer - Where the converted integer is returned
+ *
+ * RETURN: Status and Converted value
+ *
+ * DESCRIPTION: Convert a string into an unsigned value.
+ * NOTE: Does not support Octal strings, not needed.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_strtoul64 (
+ char *string,
+ u32 base,
+ acpi_integer *ret_integer)
+{
+ u32 this_digit = 0;
+ acpi_integer return_value = 0;
+ acpi_integer quotient;
+
+
+ ACPI_FUNCTION_TRACE ("ut_stroul64");
+
+
+ if ((!string) || !(*string)) {
+ goto error_exit;
+ }
+
+ switch (base) {
+ case ACPI_ANY_BASE:
+ case 10:
+ case 16:
+ break;
+
+ default:
+ /* Invalid Base */
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Skip over any white space in the buffer */
+
+ while (ACPI_IS_SPACE (*string) || *string == '\t') {
+ string++;
+ }
+
+ /*
+ * If the input parameter Base is zero, then we need to
+ * determine if it is decimal or hexadecimal:
+ */
+ if (base == 0) {
+ if ((*string == '0') &&
+ (ACPI_TOLOWER (*(string + 1)) == 'x')) {
+ base = 16;
+ string += 2;
+ }
+ else {
+ base = 10;
+ }
+ }
+
+ /*
+ * For hexadecimal base, skip over the leading
+ * 0 or 0x, if they are present.
+ */
+ if ((base == 16) &&
+ (*string == '0') &&
+ (ACPI_TOLOWER (*(string + 1)) == 'x')) {
+ string += 2;
+ }
+
+ /* Any string left? */
+
+ if (!(*string)) {
+ goto error_exit;
+ }
+
+ /* Main loop: convert the string to a 64-bit integer */
+
+ while (*string) {
+ if (ACPI_IS_DIGIT (*string)) {
+ /* Convert ASCII 0-9 to Decimal value */
+
+ this_digit = ((u8) *string) - '0';
+ }
+ else {
+ if (base == 10) {
+ /* Digit is out of range */
+
+ goto error_exit;
+ }
+
+ this_digit = (u8) ACPI_TOUPPER (*string);
+ if (ACPI_IS_XDIGIT ((char) this_digit)) {
+ /* Convert ASCII Hex char to value */
+
+ this_digit = this_digit - 'A' + 10;
+ }
+ else {
+ /*
+ * We allow non-hex chars, just stop now, same as end-of-string.
+ * See ACPI spec, string-to-integer conversion.
+ */
+ break;
+ }
+ }
+
+ /* Divide the digit into the correct position */
+
+ (void) acpi_ut_short_divide ((ACPI_INTEGER_MAX - (acpi_integer) this_digit),
+ base, &quotient, NULL);
+ if (return_value > quotient) {
+ goto error_exit;
+ }
+
+ return_value *= base;
+ return_value += this_digit;
+ string++;
+ }
+
+ /* All done, normal exit */
+
+ *ret_integer = return_value;
+ return_ACPI_STATUS (AE_OK);
+
+
+error_exit:
+ /* Base was set/validated above */
+
+ if (base == 10) {
+ return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
+ }
+ else {
+ return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strupr
+ *
+ * PARAMETERS: src_string - The source string to convert to
+ *
+ * RETURN: src_string
+ *
+ * DESCRIPTION: Convert string to uppercase
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+char *
+acpi_ut_strupr (
+ char *src_string)
+{
+ char *string;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Walk entire string, uppercasing the letters */
+
+ for (string = src_string; *string; ) {
+ *string = (char) ACPI_TOUPPER (*string);
+ string++;
+ }
+
+ return (src_string);
+}
+#endif /* ACPI_FUTURE_USAGE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_mutex_initialize
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create the system mutex objects.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_mutex_initialize (
+ void)
+{
+ u32 i;
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ut_mutex_initialize");
+
+
+ /*
+ * Create each of the predefined mutex objects
+ */
+ for (i = 0; i < NUM_MUTEX; i++) {
+ status = acpi_ut_create_mutex (i);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_mutex_terminate
+ *
+ * PARAMETERS: None.
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Delete all of the system mutex objects.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_mutex_terminate (
+ void)
+{
+ u32 i;
+
+
+ ACPI_FUNCTION_TRACE ("ut_mutex_terminate");
+
+
+ /*
+ * Delete each predefined mutex object
+ */
+ for (i = 0; i < NUM_MUTEX; i++) {
+ (void) acpi_ut_delete_mutex (i);
+ }
+
+ acpi_os_delete_lock (acpi_gbl_gpe_lock);
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_mutex
+ *
+ * PARAMETERS: mutex_iD - ID of the mutex to be created
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_create_mutex (
+ acpi_mutex_handle mutex_id)
+{
+ acpi_status status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id);
+
+
+ if (mutex_id > MAX_MUTEX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (!acpi_gbl_mutex_info[mutex_id].mutex) {
+ status = acpi_os_create_semaphore (1, 1,
+ &acpi_gbl_mutex_info[mutex_id].mutex);
+ acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+ acpi_gbl_mutex_info[mutex_id].use_count = 0;
+ }
+
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_mutex
+ *
+ * PARAMETERS: mutex_iD - ID of the mutex to be deleted
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_delete_mutex (
+ acpi_mutex_handle mutex_id)
+{
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id);
+
+
+ if (mutex_id > MAX_MUTEX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex);
+
+ acpi_gbl_mutex_info[mutex_id].mutex = NULL;
+ acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_acquire_mutex
+ *
+ * PARAMETERS: mutex_iD - ID of the mutex to be acquired
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Acquire a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_acquire_mutex (
+ acpi_mutex_handle mutex_id)
+{
+ acpi_status status;
+ u32 this_thread_id;
+
+
+ ACPI_FUNCTION_NAME ("ut_acquire_mutex");
+
+
+ if (mutex_id > MAX_MUTEX) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ this_thread_id = acpi_os_get_thread_id ();
+
+#ifdef ACPI_MUTEX_DEBUG
+ {
+ u32 i;
+ /*
+ * Mutex debug code, for internal debugging only.
+ *
+ * Deadlock prevention. Check if this thread owns any mutexes of value
+ * greater than or equal to this one. If so, the thread has violated
+ * the mutex ordering rule. This indicates a coding error somewhere in
+ * the ACPI subsystem code.
+ */
+ for (i = mutex_id; i < MAX_MUTEX; i++) {
+ if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+ if (i == mutex_id) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Mutex [%s] already acquired by this thread [%X]\n",
+ acpi_ut_get_mutex_name (mutex_id), this_thread_id));
+
+ return (AE_ALREADY_ACQUIRED);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
+ this_thread_id, acpi_ut_get_mutex_name (i),
+ acpi_ut_get_mutex_name (mutex_id)));
+
+ return (AE_ACQUIRE_DEADLOCK);
+ }
+ }
+ }
+#endif
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
+ "Thread %X attempting to acquire Mutex [%s]\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+
+ status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex,
+ 1, ACPI_WAIT_FOREVER);
+ if (ACPI_SUCCESS (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+
+ acpi_gbl_mutex_info[mutex_id].use_count++;
+ acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id;
+ }
+ else {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id),
+ acpi_format_exception (status)));
+ }
+
+ return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_release_mutex
+ *
+ * PARAMETERS: mutex_iD - ID of the mutex to be released
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_release_mutex (
+ acpi_mutex_handle mutex_id)
+{
+ acpi_status status;
+ u32 i;
+ u32 this_thread_id;
+
+
+ ACPI_FUNCTION_NAME ("ut_release_mutex");
+
+
+ this_thread_id = acpi_os_get_thread_id ();
+ ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
+ "Thread %X releasing Mutex [%s]\n", this_thread_id,
+ acpi_ut_get_mutex_name (mutex_id)));
+
+ if (mutex_id > MAX_MUTEX) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Mutex must be acquired in order to release it!
+ */
+ if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Mutex [%s] is not acquired, cannot release\n",
+ acpi_ut_get_mutex_name (mutex_id)));
+
+ return (AE_NOT_ACQUIRED);
+ }
+
+ /*
+ * Deadlock prevention. Check if this thread owns any mutexes of value
+ * greater than this one. If so, the thread has violated the mutex
+ * ordering rule. This indicates a coding error somewhere in
+ * the ACPI subsystem code.
+ */
+ for (i = mutex_id; i < MAX_MUTEX; i++) {
+ if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+ if (i == mutex_id) {
+ continue;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Invalid release order: owns [%s], releasing [%s]\n",
+ acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id)));
+
+ return (AE_RELEASE_DEADLOCK);
+ }
+ }
+
+ /* Mark unlocked FIRST */
+
+ acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+ status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);
+
+ if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id),
+ acpi_format_exception (status)));
+ }
+ else {
+ ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+ }
+
+ return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_update_state_and_push
+ *
+ * PARAMETERS: *Object - Object to be added to the new state
+ * Action - Increment/Decrement
+ * state_list - List the state will be added to
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create a new state and push it
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_create_update_state_and_push (
+ union acpi_operand_object *object,
+ u16 action,
+ union acpi_generic_state **state_list)
+{
+ union acpi_generic_state *state;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Ignore null objects; these are expected */
+
+ if (!object) {
+ return (AE_OK);
+ }
+
+ state = acpi_ut_create_update_state (object, action);
+ if (!state) {
+ return (AE_NO_MEMORY);
+ }
+
+ acpi_ut_push_generic_state (state_list, state);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_pkg_state_and_push
+ *
+ * PARAMETERS: *Object - Object to be added to the new state
+ * Action - Increment/Decrement
+ * state_list - List the state will be added to
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create a new state and push it
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_ut_create_pkg_state_and_push (
+ void *internal_object,
+ void *external_object,
+ u16 index,
+ union acpi_generic_state **state_list)
+{
+ union acpi_generic_state *state;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ state = acpi_ut_create_pkg_state (internal_object, external_object, index);
+ if (!state) {
+ return (AE_NO_MEMORY);
+ }
+
+ acpi_ut_push_generic_state (state_list, state);
+ return (AE_OK);
+}
+#endif /* ACPI_FUTURE_USAGE */
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_push_generic_state
+ *
+ * PARAMETERS: list_head - Head of the state stack
+ * State - State object to push
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Push a state object onto a state stack
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_push_generic_state (
+ union acpi_generic_state **list_head,
+ union acpi_generic_state *state)
+{
+ ACPI_FUNCTION_TRACE ("ut_push_generic_state");
+
+
+ /* Push the state object onto the front of the list (stack) */
+
+ state->common.next = *list_head;
+ *list_head = state;
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_pop_generic_state
+ *
+ * PARAMETERS: list_head - Head of the state stack
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop a state object from a state stack
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_pop_generic_state (
+ union acpi_generic_state **list_head)
+{
+ union acpi_generic_state *state;
+
+
+ ACPI_FUNCTION_TRACE ("ut_pop_generic_state");
+
+
+ /* Remove the state object at the head of the list (stack) */
+
+ state = *list_head;
+ if (state) {
+ /* Update the list head */
+
+ *list_head = state->common.next;
+ }
+
+ return_PTR (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_generic_state
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a generic state object. Attempt to obtain one from
+ * the global state cache; If none available, create a new one.
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_create_generic_state (void)
+{
+ union acpi_generic_state *state;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_STATE);
+
+ /* Initialize */
+
+ if (state) {
+ state->common.data_type = ACPI_DESC_TYPE_STATE;
+ }
+
+ return (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_thread_state
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Thread State
+ *
+ * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
+ * to track per-thread info during method execution
+ *
+ ******************************************************************************/
+
+struct acpi_thread_state *
+acpi_ut_create_thread_state (
+ void)
+{
+ union acpi_generic_state *state;
+
+
+ ACPI_FUNCTION_TRACE ("ut_create_thread_state");
+
+
+ /* Create the generic state object */
+
+ state = acpi_ut_create_generic_state ();
+ if (!state) {
+ return_PTR (NULL);
+ }
+
+ /* Init fields specific to the update struct */
+
+ state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD;
+ state->thread.thread_id = acpi_os_get_thread_id ();
+
+ return_PTR ((struct acpi_thread_state *) state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_update_state
+ *
+ * PARAMETERS: Object - Initial Object to be installed in the
+ * state
+ * Action - Update action to be performed
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
+ * to update reference counts and delete complex objects such
+ * as packages.
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_create_update_state (
+ union acpi_operand_object *object,
+ u16 action)
+{
+ union acpi_generic_state *state;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_create_update_state", object);
+
+
+ /* Create the generic state object */
+
+ state = acpi_ut_create_generic_state ();
+ if (!state) {
+ return_PTR (NULL);
+ }
+
+ /* Init fields specific to the update struct */
+
+ state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE;
+ state->update.object = object;
+ state->update.value = action;
+
+ return_PTR (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_pkg_state
+ *
+ * PARAMETERS: Object - Initial Object to be installed in the
+ * state
+ * Action - Update action to be performed
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a "Package State"
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_create_pkg_state (
+ void *internal_object,
+ void *external_object,
+ u16 index)
+{
+ union acpi_generic_state *state;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_create_pkg_state", internal_object);
+
+
+ /* Create the generic state object */
+
+ state = acpi_ut_create_generic_state ();
+ if (!state) {
+ return_PTR (NULL);
+ }
+
+ /* Init fields specific to the update struct */
+
+ state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE;
+ state->pkg.source_object = (union acpi_operand_object *) internal_object;
+ state->pkg.dest_object = external_object;
+ state->pkg.index = index;
+ state->pkg.num_packages = 1;
+
+ return_PTR (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_control_state
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
+ * to support nested IF/WHILE constructs in the AML.
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_create_control_state (
+ void)
+{
+ union acpi_generic_state *state;
+
+
+ ACPI_FUNCTION_TRACE ("ut_create_control_state");
+
+
+ /* Create the generic state object */
+
+ state = acpi_ut_create_generic_state ();
+ if (!state) {
+ return_PTR (NULL);
+ }
+
+ /* Init fields specific to the control struct */
+
+ state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL;
+ state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING;
+
+ return_PTR (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_generic_state
+ *
+ * PARAMETERS: State - The state object to be deleted
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Put a state object back into the global state cache. The object
+ * is not actually freed at this time.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_generic_state (
+ union acpi_generic_state *state)
+{
+ ACPI_FUNCTION_TRACE ("ut_delete_generic_state");
+
+
+ acpi_ut_release_to_cache (ACPI_MEM_LIST_STATE, state);
+ return_VOID;
+}
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_generic_state_cache
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Purge the global state object cache. Used during subsystem
+ * termination.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_generic_state_cache (
+ void)
+{
+ ACPI_FUNCTION_TRACE ("ut_delete_generic_state_cache");
+
+
+ acpi_ut_delete_generic_cache (ACPI_MEM_LIST_STATE);
+ return_VOID;
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_walk_package_tree
+ *
+ * PARAMETERS: obj_desc - The Package object on which to resolve refs
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk through a package
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_walk_package_tree (
+ union acpi_operand_object *source_object,
+ void *target_object,
+ acpi_pkg_callback walk_callback,
+ void *context)
+{
+ acpi_status status = AE_OK;
+ union acpi_generic_state *state_list = NULL;
+ union acpi_generic_state *state;
+ u32 this_index;
+ union acpi_operand_object *this_source_obj;
+
+
+ ACPI_FUNCTION_TRACE ("ut_walk_package_tree");
+
+
+ state = acpi_ut_create_pkg_state (source_object, target_object, 0);
+ if (!state) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ while (state) {
+ /* Get one element of the package */
+
+ this_index = state->pkg.index;
+ this_source_obj = (union acpi_operand_object *)
+ state->pkg.source_object->package.elements[this_index];
+
+ /*
+ * Check for:
+ * 1) An uninitialized package element. It is completely
+ * legal to declare a package and leave it uninitialized
+ * 2) Not an internal object - can be a namespace node instead
+ * 3) Any type other than a package. Packages are handled in else
+ * case below.
+ */
+ if ((!this_source_obj) ||
+ (ACPI_GET_DESCRIPTOR_TYPE (this_source_obj) != ACPI_DESC_TYPE_OPERAND) ||
+ (ACPI_GET_OBJECT_TYPE (this_source_obj) != ACPI_TYPE_PACKAGE)) {
+ status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj,
+ state, context);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ state->pkg.index++;
+ while (state->pkg.index >= state->pkg.source_object->package.count) {
+ /*
+ * We've handled all of the objects at this level, This means
+ * that we have just completed a package. That package may
+ * have contained one or more packages itself.
+ *
+ * Delete this state and pop the previous state (package).
+ */
+ acpi_ut_delete_generic_state (state);
+ state = acpi_ut_pop_generic_state (&state_list);
+
+ /* Finished when there are no more states */
+
+ if (!state) {
+ /*
+ * We have handled all of the objects in the top level
+ * package just add the length of the package objects
+ * and exit
+ */
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Go back up a level and move the index past the just
+ * completed package object.
+ */
+ state->pkg.index++;
+ }
+ }
+ else {
+ /* This is a subobject of type package */
+
+ status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj,
+ state, context);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /*
+ * Push the current state and create a new one
+ * The callback above returned a new target package object.
+ */
+ acpi_ut_push_generic_state (&state_list, state);
+ state = acpi_ut_create_pkg_state (this_source_obj,
+ state->pkg.this_target_obj, 0);
+ if (!state) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ }
+ }
+
+ /* We should never get here */
+
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_generate_checksum
+ *
+ * PARAMETERS: Buffer - Buffer to be scanned
+ * Length - number of bytes to examine
+ *
+ * RETURN: checksum
+ *
+ * DESCRIPTION: Generate a checksum on a raw buffer
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_generate_checksum (
+ u8 *buffer,
+ u32 length)
+{
+ u32 i;
+ signed char sum = 0;
+
+
+ for (i = 0; i < length; i++) {
+ sum = (signed char) (sum + buffer[i]);
+ }
+
+ return ((u8) (0 - sum));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_resource_end_tag
+ *
+ * PARAMETERS: obj_desc - The resource template buffer object
+ *
+ * RETURN: Pointer to the end tag
+ *
+ * DESCRIPTION: Find the END_TAG resource descriptor in a resource template
+ *
+ ******************************************************************************/
+
+
+u8 *
+acpi_ut_get_resource_end_tag (
+ union acpi_operand_object *obj_desc)
+{
+ u8 buffer_byte;
+ u8 *buffer;
+ u8 *end_buffer;
+
+
+ buffer = obj_desc->buffer.pointer;
+ end_buffer = buffer + obj_desc->buffer.length;
+
+ while (buffer < end_buffer) {
+ buffer_byte = *buffer;
+ if (buffer_byte & ACPI_RDESC_TYPE_MASK) {
+ /* Large Descriptor - Length is next 2 bytes */
+
+ buffer += ((*(buffer+1) | (*(buffer+2) << 8)) + 3);
+ }
+ else {
+ /* Small Descriptor. End Tag will be found here */
+
+ if ((buffer_byte & ACPI_RDESC_SMALL_MASK) == ACPI_RDESC_TYPE_END_TAG) {
+ /* Found the end tag descriptor, all done. */
+
+ return (buffer);
+ }
+
+ /* Length is in the header */
+
+ buffer += ((buffer_byte & 0x07) + 1);
+ }
+ }
+
+ /* End tag not found */
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_report_error
+ *
+ * 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)
+ * Message - Error message to use on failure
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print error message
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_report_error (
+ char *module_name,
+ u32 line_number,
+ u32 component_id)
+{
+
+
+ acpi_os_printf ("%8s-%04d: *** Error: ", 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)
+ * Message - Error message to use on failure
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print warning message
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_report_warning (
+ char *module_name,
+ u32 line_number,
+ u32 component_id)
+{
+
+ acpi_os_printf ("%8s-%04d: *** Warning: ", 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)
+ * Message - Error message to use on failure
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print information message
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_report_info (
+ char *module_name,
+ u32 line_number,
+ u32 component_id)
+{
+
+ acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number);
+}
+
+
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
new file mode 100644
index 000000000000..9ee40a484e07
--- /dev/null
+++ b/drivers/acpi/utilities/utobject.c
@@ -0,0 +1,671 @@
+/******************************************************************************
+ *
+ * Module Name: utobject - ACPI object create/delete/size/cache routines
+ *
+ *****************************************************************************/
+
+/*
+ * 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>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utobject")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_internal_object_dbg
+ *
+ * PARAMETERS: module_name - Source file name of caller
+ * line_number - Line number of caller
+ * component_id - Component type of caller
+ * Type - ACPI Type of the new object
+ *
+ * RETURN: Object - The new object. Null on failure
+ *
+ * DESCRIPTION: Create and initialize a new internal object.
+ *
+ * NOTE: We always allocate the worst-case object descriptor because
+ * these objects are cached, and we want them to be
+ * one-size-satisifies-any-request. This in itself may not be
+ * the most memory efficient, but the efficiency of the object
+ * cache should more than make up for this!
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *
+acpi_ut_create_internal_object_dbg (
+ char *module_name,
+ u32 line_number,
+ u32 component_id,
+ acpi_object_type type)
+{
+ union acpi_operand_object *object;
+ union acpi_operand_object *second_object;
+
+
+ ACPI_FUNCTION_TRACE_STR ("ut_create_internal_object_dbg", acpi_ut_get_type_name (type));
+
+
+ /* Allocate the raw object descriptor */
+
+ object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id);
+ if (!object) {
+ return_PTR (NULL);
+ }
+
+ switch (type) {
+ case ACPI_TYPE_REGION:
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ /* These types require a secondary object */
+
+ second_object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id);
+ if (!second_object) {
+ acpi_ut_delete_object_desc (object);
+ return_PTR (NULL);
+ }
+
+ second_object->common.type = ACPI_TYPE_LOCAL_EXTRA;
+ second_object->common.reference_count = 1;
+
+ /* Link the second object to the first */
+
+ object->common.next_object = second_object;
+ break;
+
+ default:
+ /* All others have no secondary object */
+ break;
+ }
+
+ /* Save the object type in the object descriptor */
+
+ object->common.type = (u8) type;
+
+ /* Init the reference count */
+
+ object->common.reference_count = 1;
+
+ /* Any per-type initialization should go here */
+
+ return_PTR (object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_buffer_object
+ *
+ * PARAMETERS: buffer_size - Size of buffer to be created
+ *
+ * RETURN: Pointer to a new Buffer object
+ *
+ * DESCRIPTION: Create a fully initialized buffer object
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *
+acpi_ut_create_buffer_object (
+ acpi_size buffer_size)
+{
+ union acpi_operand_object *buffer_desc;
+ u8 *buffer = NULL;
+
+
+ ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size);
+
+
+ /* Create a new Buffer object */
+
+ buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+ if (!buffer_desc) {
+ return_PTR (NULL);
+ }
+
+ /* Create an actual buffer only if size > 0 */
+
+ if (buffer_size > 0) {
+ /* Allocate the actual buffer */
+
+ buffer = ACPI_MEM_CALLOCATE (buffer_size);
+ if (!buffer) {
+ ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n",
+ (u32) buffer_size));
+ acpi_ut_remove_reference (buffer_desc);
+ return_PTR (NULL);
+ }
+ }
+
+ /* Complete buffer object initialization */
+
+ buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
+ buffer_desc->buffer.pointer = buffer;
+ buffer_desc->buffer.length = (u32) buffer_size;
+
+ /* Return the new buffer descriptor */
+
+ return_PTR (buffer_desc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_string_object
+ *
+ * PARAMETERS: string_size - Size of string to be created. Does not
+ * include NULL terminator, this is added
+ * automatically.
+ *
+ * RETURN: Pointer to a new String object
+ *
+ * DESCRIPTION: Create a fully initialized string object
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *
+acpi_ut_create_string_object (
+ acpi_size string_size)
+{
+ union acpi_operand_object *string_desc;
+ char *string;
+
+
+ ACPI_FUNCTION_TRACE_U32 ("ut_create_string_object", string_size);
+
+
+ /* Create a new String object */
+
+ string_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+ if (!string_desc) {
+ return_PTR (NULL);
+ }
+
+ /*
+ * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
+ * NOTE: Zero-length strings are NULL terminated
+ */
+ string = ACPI_MEM_CALLOCATE (string_size + 1);
+ if (!string) {
+ ACPI_REPORT_ERROR (("create_string: could not allocate size %X\n",
+ (u32) string_size));
+ acpi_ut_remove_reference (string_desc);
+ return_PTR (NULL);
+ }
+
+ /* Complete string object initialization */
+
+ string_desc->string.pointer = string;
+ string_desc->string.length = (u32) string_size;
+
+ /* Return the new string descriptor */
+
+ return_PTR (string_desc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_valid_internal_object
+ *
+ * PARAMETERS: Object - Object to be validated
+ *
+ * RETURN: Validate a pointer to be an union acpi_operand_object
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_valid_internal_object (
+ void *object)
+{
+
+ ACPI_FUNCTION_NAME ("ut_valid_internal_object");
+
+
+ /* Check for a null pointer */
+
+ if (!object) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Null Object Ptr\n"));
+ return (FALSE);
+ }
+
+ /* Check the descriptor type field */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (object)) {
+ case ACPI_DESC_TYPE_OPERAND:
+
+ /* The object appears to be a valid union acpi_operand_object */
+
+ return (TRUE);
+
+ default:
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "%p is not not an ACPI operand obj [%s]\n",
+ object, acpi_ut_get_descriptor_name (object)));
+ break;
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_allocate_object_desc_dbg
+ *
+ * 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: Pointer to newly allocated object descriptor. Null on error
+ *
+ * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
+ * error conditions.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_allocate_object_desc_dbg (
+ char *module_name,
+ u32 line_number,
+ u32 component_id)
+{
+ union acpi_operand_object *object;
+
+
+ ACPI_FUNCTION_TRACE ("ut_allocate_object_desc_dbg");
+
+
+ object = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_OPERAND);
+ if (!object) {
+ _ACPI_REPORT_ERROR (module_name, line_number, component_id,
+ ("Could not allocate an object descriptor\n"));
+
+ return_PTR (NULL);
+ }
+
+ /* Mark the descriptor type */
+
+ ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_OPERAND);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
+ object, (u32) sizeof (union acpi_operand_object)));
+
+ return_PTR (object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_object_desc
+ *
+ * PARAMETERS: Object - An Acpi internal object to be deleted
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_object_desc (
+ union acpi_operand_object *object)
+{
+ ACPI_FUNCTION_TRACE_PTR ("ut_delete_object_desc", object);
+
+
+ /* Object must be an union acpi_operand_object */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "%p is not an ACPI Operand object [%s]\n", object,
+ acpi_ut_get_descriptor_name (object)));
+ return_VOID;
+ }
+
+ acpi_ut_release_to_cache (ACPI_MEM_LIST_OPERAND, object);
+
+ return_VOID;
+}
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_delete_object_cache
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Purge the global state object cache. Used during subsystem
+ * termination.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_object_cache (
+ void)
+{
+ ACPI_FUNCTION_TRACE ("ut_delete_object_cache");
+
+
+ acpi_ut_delete_generic_cache (ACPI_MEM_LIST_OPERAND);
+ return_VOID;
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_simple_object_size
+ *
+ * PARAMETERS: *internal_object - Pointer to the object we are examining
+ * *obj_length - Where the length is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ * contain a simple object for return to an external user.
+ *
+ * The length includes the object structure plus any additional
+ * needed space.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_get_simple_object_size (
+ union acpi_operand_object *internal_object,
+ acpi_size *obj_length)
+{
+ acpi_size length;
+ acpi_status status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_get_simple_object_size", internal_object);
+
+
+ /* Handle a null object (Could be a uninitialized package element -- which is legal) */
+
+ if (!internal_object) {
+ *obj_length = 0;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Start with the length of the Acpi object */
+
+ length = sizeof (union acpi_object);
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_NAMED) {
+ /* Object is a named object (reference), just return the length */
+
+ *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length);
+ return_ACPI_STATUS (status);
+ }
+
+ /*
+ * The final length depends on the object type
+ * Strings and Buffers are packed right up against the parent object and
+ * must be accessed bytewise or there may be alignment problems on
+ * certain processors
+ */
+ switch (ACPI_GET_OBJECT_TYPE (internal_object)) {
+ case ACPI_TYPE_STRING:
+
+ length += (acpi_size) internal_object->string.length + 1;
+ break;
+
+
+ case ACPI_TYPE_BUFFER:
+
+ length += (acpi_size) internal_object->buffer.length;
+ break;
+
+
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_POWER:
+
+ /*
+ * No extra data for these types
+ */
+ break;
+
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ switch (internal_object->reference.opcode) {
+ case AML_INT_NAMEPATH_OP:
+
+ /*
+ * Get the actual length of the full pathname to this object.
+ * The reference will be converted to the pathname to the object
+ */
+ length += ACPI_ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node));
+ break;
+
+ default:
+
+ /*
+ * No other reference opcodes are supported.
+ * Notably, Locals and Args are not supported, but this may be
+ * required eventually.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Unsupported Reference opcode=%X in object %p\n",
+ internal_object->reference.opcode, internal_object));
+ status = AE_TYPE;
+ break;
+ }
+ break;
+
+
+ default:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n",
+ ACPI_GET_OBJECT_TYPE (internal_object), internal_object));
+ status = AE_TYPE;
+ break;
+ }
+
+ /*
+ * Account for the space required by the object rounded up to the next
+ * multiple of the machine word size. This keeps each object aligned
+ * on a machine word boundary. (preventing alignment faults on some
+ * machines.)
+ */
+ *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_element_length
+ *
+ * PARAMETERS: acpi_pkg_callback
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the length of one package element.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_get_element_length (
+ u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context)
+{
+ acpi_status status = AE_OK;
+ struct acpi_pkg_info *info = (struct acpi_pkg_info *) context;
+ acpi_size object_space;
+
+
+ switch (object_type) {
+ case ACPI_COPY_TYPE_SIMPLE:
+
+ /*
+ * Simple object - just get the size (Null object/entry is handled
+ * here also) and sum it into the running package length
+ */
+ status = acpi_ut_get_simple_object_size (source_object, &object_space);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+
+ info->length += object_space;
+ break;
+
+
+ case ACPI_COPY_TYPE_PACKAGE:
+
+ /* Package object - nothing much to do here, let the walk handle it */
+
+ info->num_packages++;
+ state->pkg.this_target_obj = NULL;
+ break;
+
+
+ default:
+
+ /* No other types allowed */
+
+ return (AE_BAD_PARAMETER);
+ }
+
+ return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_package_object_size
+ *
+ * PARAMETERS: *internal_object - Pointer to the object we are examining
+ * *obj_length - Where the length is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ * contain a package object for return to an external user.
+ *
+ * This is moderately complex since a package contains other
+ * objects including packages.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_get_package_object_size (
+ union acpi_operand_object *internal_object,
+ acpi_size *obj_length)
+{
+ acpi_status status;
+ struct acpi_pkg_info info;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_get_package_object_size", internal_object);
+
+
+ info.length = 0;
+ info.object_space = 0;
+ info.num_packages = 1;
+
+ status = acpi_ut_walk_package_tree (internal_object, NULL,
+ acpi_ut_get_element_length, &info);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /*
+ * We have handled all of the objects in all levels of the package.
+ * just add the length of the package objects themselves.
+ * Round up to the next machine word.
+ */
+ info.length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)) *
+ (acpi_size) info.num_packages;
+
+ /* Return the total package length */
+
+ *obj_length = info.length;
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_object_size
+ *
+ * PARAMETERS: *internal_object - Pointer to the object we are examining
+ * *obj_length - Where the length will be returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ * contain an object for return to an API user.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_get_object_size(
+ union acpi_operand_object *internal_object,
+ acpi_size *obj_length)
+{
+ acpi_status status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ if ((ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_OPERAND) &&
+ (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE)) {
+ status = acpi_ut_get_package_object_size (internal_object, obj_length);
+ }
+ else {
+ status = acpi_ut_get_simple_object_size (internal_object, obj_length);
+ }
+
+ return (status);
+}
+
+
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
new file mode 100644
index 000000000000..97a91f3f06f0
--- /dev/null
+++ b/drivers/acpi/utilities/utxface.c
@@ -0,0 +1,525 @@
+/******************************************************************************
+ *
+ * Module Name: utxface - External interfaces for "global" ACPI functions
+ *
+ *****************************************************************************/
+
+/*
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/acdebug.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_initialize_subsystem
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initializes all global variables. This is the first function
+ * called, so any early initialization belongs here.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_initialize_subsystem (
+ void)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE ("acpi_initialize_subsystem");
+
+
+ ACPI_DEBUG_EXEC (acpi_ut_init_stack_ptr_trace ());
+
+
+ /* Initialize all globals used by the subsystem */
+
+ acpi_ut_init_globals ();
+
+ /* Initialize the OS-Dependent layer */
+
+ status = acpi_os_initialize ();
+ if (ACPI_FAILURE (status)) {
+ ACPI_REPORT_ERROR (("OSD failed to initialize, %s\n",
+ acpi_format_exception (status)));
+ return_ACPI_STATUS (status);
+ }
+
+ /* Create the default mutex objects */
+
+ status = acpi_ut_mutex_initialize ();
+ if (ACPI_FAILURE (status)) {
+ ACPI_REPORT_ERROR (("Global mutex creation failure, %s\n",
+ acpi_format_exception (status)));
+ return_ACPI_STATUS (status);
+ }
+
+ /*
+ * Initialize the namespace manager and
+ * the root of the namespace tree
+ */
+
+ status = acpi_ns_root_initialize ();
+ if (ACPI_FAILURE (status)) {
+ ACPI_REPORT_ERROR (("Namespace initialization failure, %s\n",
+ acpi_format_exception (status)));
+ return_ACPI_STATUS (status);
+ }
+
+
+ /* If configured, initialize the AML debugger */
+
+ ACPI_DEBUGGER_EXEC (status = acpi_db_initialize ());
+
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_enable_subsystem
+ *
+ * PARAMETERS: Flags - Init/enable Options
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Completes the subsystem initialization including hardware.
+ * Puts system into ACPI mode if it isn't already.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enable_subsystem (
+ u32 flags)
+{
+ acpi_status status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE ("acpi_enable_subsystem");
+
+
+ /*
+ * We must initialize the hardware before we can enable ACPI.
+ * The values from the FADT are validated here.
+ */
+ if (!(flags & ACPI_NO_HARDWARE_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n"));
+
+ status = acpi_hw_initialize ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ /* Enable ACPI mode */
+
+ if (!(flags & ACPI_NO_ACPI_ENABLE)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
+
+ acpi_gbl_original_mode = acpi_hw_get_mode();
+
+ status = acpi_enable ();
+ if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "acpi_enable failed.\n"));
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ /*
+ * Install the default op_region handlers. These are installed unless
+ * other handlers have already been installed via the
+ * install_address_space_handler interface.
+ */
+ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+
+ status = acpi_ev_install_region_handlers ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ /*
+ * Initialize ACPI Event handling (Fixed and General Purpose)
+ *
+ * NOTE: We must have the hardware AND events initialized before we can execute
+ * ANY control methods SAFELY. Any control method can require ACPI hardware
+ * support, so the hardware MUST be initialized before execution!
+ */
+ if (!(flags & ACPI_NO_EVENT_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI events\n"));
+
+ status = acpi_ev_initialize_events ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ /* Install the SCI handler and Global Lock handler */
+
+ if (!(flags & ACPI_NO_HANDLER_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n"));
+
+ status = acpi_ev_install_xrupt_handlers ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ return_ACPI_STATUS (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_initialize_objects
+ *
+ * PARAMETERS: Flags - Init/enable Options
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Completes namespace initialization by initializing device
+ * objects and executing AML code for Regions, buffers, etc.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_initialize_objects (
+ u32 flags)
+{
+ acpi_status status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE ("acpi_initialize_objects");
+
+
+ /*
+ * Run all _REG methods
+ *
+ * NOTE: Any objects accessed
+ * by the _REG methods will be automatically initialized, even if they
+ * contain executable AML (see call to acpi_ns_initialize_objects below).
+ */
+ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Executing _REG op_region methods\n"));
+
+ status = acpi_ev_initialize_op_regions ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ /*
+ * Initialize the objects that remain uninitialized. This
+ * runs the executable AML that may be part of the declaration of these
+ * objects: operation_regions, buffer_fields, Buffers, and Packages.
+ */
+ if (!(flags & ACPI_NO_OBJECT_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Completing Initialization of ACPI Objects\n"));
+
+ status = acpi_ns_initialize_objects ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ /*
+ * Initialize all device objects in the namespace
+ * This runs the _STA and _INI methods.
+ */
+ if (!(flags & ACPI_NO_DEVICE_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
+
+ status = acpi_ns_initialize_devices ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ /*
+ * Empty the caches (delete the cached objects) on the assumption that
+ * the table load filled them up more than they will be at runtime --
+ * thus wasting non-paged memory.
+ */
+ status = acpi_purge_cached_objects ();
+
+ acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_terminate
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_terminate (void)
+{
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("acpi_terminate");
+
+
+ /* Terminate the AML Debugger if present */
+
+ ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
+
+ /* Shutdown and free all resources */
+
+ acpi_ut_subsystem_shutdown ();
+
+
+ /* Free the mutex objects */
+
+ acpi_ut_mutex_terminate ();
+
+
+#ifdef ACPI_DEBUGGER
+
+ /* Shut down the debugger */
+
+ acpi_db_terminate ();
+#endif
+
+ /* Now we can shutdown the OS-dependent layer */
+
+ status = acpi_os_terminate ();
+ return_ACPI_STATUS (status);
+}
+
+
+#ifdef ACPI_FUTURE_USAGE
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_subsystem_status
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status of the ACPI subsystem
+ *
+ * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
+ * before making any other calls, to ensure the subsystem initial-
+ * ized successfully.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_subsystem_status (void)
+{
+ if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) {
+ return (AE_OK);
+ }
+ else {
+ return (AE_ERROR);
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_get_system_info
+ *
+ * PARAMETERS: out_buffer - a pointer to a buffer to receive the
+ * resources for the device
+ * buffer_length - the number of bytes available in the buffer
+ *
+ * RETURN: Status - the status of the call
+ *
+ * DESCRIPTION: This function is called to get information about the current
+ * state of the ACPI subsystem. It will return system information
+ * in the out_buffer.
+ *
+ * If the function fails an appropriate status will be returned
+ * and the value of out_buffer is undefined.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_system_info (
+ struct acpi_buffer *out_buffer)
+{
+ struct acpi_system_info *info_ptr;
+ u32 i;
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("acpi_get_system_info");
+
+
+ /* Parameter validation */
+
+ status = acpi_ut_validate_buffer (out_buffer);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /* Validate/Allocate/Clear caller buffer */
+
+ status = acpi_ut_initialize_buffer (out_buffer, sizeof (struct acpi_system_info));
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /*
+ * Populate the return buffer
+ */
+ info_ptr = (struct acpi_system_info *) out_buffer->pointer;
+
+ info_ptr->acpi_ca_version = ACPI_CA_VERSION;
+
+ /* System flags (ACPI capabilities) */
+
+ info_ptr->flags = ACPI_SYS_MODE_ACPI;
+
+ /* Timer resolution - 24 or 32 bits */
+
+ if (!acpi_gbl_FADT) {
+ info_ptr->timer_resolution = 0;
+ }
+ else if (acpi_gbl_FADT->tmr_val_ext == 0) {
+ info_ptr->timer_resolution = 24;
+ }
+ else {
+ info_ptr->timer_resolution = 32;
+ }
+
+ /* Clear the reserved fields */
+
+ info_ptr->reserved1 = 0;
+ info_ptr->reserved2 = 0;
+
+ /* Current debug levels */
+
+ info_ptr->debug_layer = acpi_dbg_layer;
+ info_ptr->debug_level = acpi_dbg_level;
+
+ /* Current status of the ACPI tables, per table type */
+
+ info_ptr->num_table_types = NUM_ACPI_TABLE_TYPES;
+ for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
+ info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+EXPORT_SYMBOL(acpi_get_system_info);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_install_initialization_handler
+ *
+ * PARAMETERS: Handler - Callback procedure
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install an initialization handler
+ *
+ * TBD: When a second function is added, must save the Function also.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_install_initialization_handler (
+ acpi_init_handler handler,
+ u32 function)
+{
+
+ if (!handler) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ if (acpi_gbl_init_handler) {
+ return (AE_ALREADY_EXISTS);
+ }
+
+ acpi_gbl_init_handler = handler;
+ return AE_OK;
+}
+
+#endif /* ACPI_FUTURE_USAGE */
+
+
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_purge_cached_objects
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Empty all caches (delete the cached objects)
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_purge_cached_objects (void)
+{
+ ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects");
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+ acpi_ut_delete_generic_state_cache ();
+ acpi_ut_delete_object_cache ();
+ acpi_ds_delete_walk_state_cache ();
+ acpi_ps_delete_parse_cache ();
+#endif
+
+ return_ACPI_STATUS (AE_OK);
+}