Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
This commit is contained in:
8
drivers/acpi/utilities/Makefile
Normal file
8
drivers/acpi/utilities/Makefile
Normal file
@@ -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)
|
988
drivers/acpi/utilities/utalloc.c
Normal file
988
drivers/acpi/utilities/utalloc.c
Normal file
@@ -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 */
|
||||
|
930
drivers/acpi/utilities/utcopy.c
Normal file
930
drivers/acpi/utilities/utcopy.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
|
624
drivers/acpi/utilities/utdebug.c
Normal file
624
drivers/acpi/utilities/utdebug.c
Normal file
@@ -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 (¤t_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 (¤t_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;
|
||||
}
|
||||
|
700
drivers/acpi/utilities/utdelete.c
Normal file
700
drivers/acpi/utilities/utdelete.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
|
696
drivers/acpi/utilities/uteval.c
Normal file
696
drivers/acpi/utilities/uteval.c
Normal file
@@ -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);
|
||||
}
|
935
drivers/acpi/utilities/utglobal.c
Normal file
935
drivers/acpi/utilities/utglobal.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
|
266
drivers/acpi/utilities/utinit.c
Normal file
266
drivers/acpi/utilities/utinit.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
|
333
drivers/acpi/utilities/utmath.c
Normal file
333
drivers/acpi/utilities/utmath.c
Normal file
@@ -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
|
||||
|
||||
|
1516
drivers/acpi/utilities/utmisc.c
Normal file
1516
drivers/acpi/utilities/utmisc.c
Normal file
File diff suppressed because it is too large
Load Diff
671
drivers/acpi/utilities/utobject.c
Normal file
671
drivers/acpi/utilities/utobject.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
|
525
drivers/acpi/utilities/utxface.c
Normal file
525
drivers/acpi/utilities/utxface.c
Normal file
@@ -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);
|
||||
}
|
Reference in New Issue
Block a user