195b482a8SLen Brown /******************************************************************************* 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: utstate - state object support procedures 495b482a8SLen Brown * 595b482a8SLen Brown ******************************************************************************/ 695b482a8SLen Brown 795b482a8SLen Brown /* 895b482a8SLen Brown * Copyright (C) 2000 - 2008, Intel Corp. 995b482a8SLen Brown * All rights reserved. 1095b482a8SLen Brown * 1195b482a8SLen Brown * Redistribution and use in source and binary forms, with or without 1295b482a8SLen Brown * modification, are permitted provided that the following conditions 1395b482a8SLen Brown * are met: 1495b482a8SLen Brown * 1. Redistributions of source code must retain the above copyright 1595b482a8SLen Brown * notice, this list of conditions, and the following disclaimer, 1695b482a8SLen Brown * without modification. 1795b482a8SLen Brown * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1895b482a8SLen Brown * substantially similar to the "NO WARRANTY" disclaimer below 1995b482a8SLen Brown * ("Disclaimer") and any redistribution must be conditioned upon 2095b482a8SLen Brown * including a substantially similar Disclaimer requirement for further 2195b482a8SLen Brown * binary redistribution. 2295b482a8SLen Brown * 3. Neither the names of the above-listed copyright holders nor the names 2395b482a8SLen Brown * of any contributors may be used to endorse or promote products derived 2495b482a8SLen Brown * from this software without specific prior written permission. 2595b482a8SLen Brown * 2695b482a8SLen Brown * Alternatively, this software may be distributed under the terms of the 2795b482a8SLen Brown * GNU General Public License ("GPL") version 2 as published by the Free 2895b482a8SLen Brown * Software Foundation. 2995b482a8SLen Brown * 3095b482a8SLen Brown * NO WARRANTY 3195b482a8SLen Brown * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3295b482a8SLen Brown * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3395b482a8SLen Brown * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3495b482a8SLen Brown * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3595b482a8SLen Brown * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3695b482a8SLen Brown * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3795b482a8SLen Brown * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3895b482a8SLen Brown * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3995b482a8SLen Brown * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4095b482a8SLen Brown * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4195b482a8SLen Brown * POSSIBILITY OF SUCH DAMAGES. 4295b482a8SLen Brown */ 4395b482a8SLen Brown 4495b482a8SLen Brown #include <acpi/acpi.h> 45*e2f7a777SLen Brown #include "accommon.h" 4695b482a8SLen Brown 4795b482a8SLen Brown #define _COMPONENT ACPI_UTILITIES 4895b482a8SLen Brown ACPI_MODULE_NAME("utstate") 4995b482a8SLen Brown 5095b482a8SLen Brown /******************************************************************************* 5195b482a8SLen Brown * 5295b482a8SLen Brown * FUNCTION: acpi_ut_create_pkg_state_and_push 5395b482a8SLen Brown * 5495b482a8SLen Brown * PARAMETERS: Object - Object to be added to the new state 5595b482a8SLen Brown * Action - Increment/Decrement 5695b482a8SLen Brown * state_list - List the state will be added to 5795b482a8SLen Brown * 5895b482a8SLen Brown * RETURN: Status 5995b482a8SLen Brown * 6095b482a8SLen Brown * DESCRIPTION: Create a new state and push it 6195b482a8SLen Brown * 6295b482a8SLen Brown ******************************************************************************/ 6395b482a8SLen Brown acpi_status 6495b482a8SLen Brown acpi_ut_create_pkg_state_and_push(void *internal_object, 6595b482a8SLen Brown void *external_object, 6695b482a8SLen Brown u16 index, 6795b482a8SLen Brown union acpi_generic_state **state_list) 6895b482a8SLen Brown { 6995b482a8SLen Brown union acpi_generic_state *state; 7095b482a8SLen Brown 7195b482a8SLen Brown ACPI_FUNCTION_ENTRY(); 7295b482a8SLen Brown 7395b482a8SLen Brown state = 7495b482a8SLen Brown acpi_ut_create_pkg_state(internal_object, external_object, index); 7595b482a8SLen Brown if (!state) { 7695b482a8SLen Brown return (AE_NO_MEMORY); 7795b482a8SLen Brown } 7895b482a8SLen Brown 7995b482a8SLen Brown acpi_ut_push_generic_state(state_list, state); 8095b482a8SLen Brown return (AE_OK); 8195b482a8SLen Brown } 8295b482a8SLen Brown 8395b482a8SLen Brown /******************************************************************************* 8495b482a8SLen Brown * 8595b482a8SLen Brown * FUNCTION: acpi_ut_push_generic_state 8695b482a8SLen Brown * 8795b482a8SLen Brown * PARAMETERS: list_head - Head of the state stack 8895b482a8SLen Brown * State - State object to push 8995b482a8SLen Brown * 9095b482a8SLen Brown * RETURN: None 9195b482a8SLen Brown * 9295b482a8SLen Brown * DESCRIPTION: Push a state object onto a state stack 9395b482a8SLen Brown * 9495b482a8SLen Brown ******************************************************************************/ 9595b482a8SLen Brown 9695b482a8SLen Brown void 9795b482a8SLen Brown acpi_ut_push_generic_state(union acpi_generic_state **list_head, 9895b482a8SLen Brown union acpi_generic_state *state) 9995b482a8SLen Brown { 10095b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_push_generic_state); 10195b482a8SLen Brown 10295b482a8SLen Brown /* Push the state object onto the front of the list (stack) */ 10395b482a8SLen Brown 10495b482a8SLen Brown state->common.next = *list_head; 10595b482a8SLen Brown *list_head = state; 10695b482a8SLen Brown 10795b482a8SLen Brown return_VOID; 10895b482a8SLen Brown } 10995b482a8SLen Brown 11095b482a8SLen Brown /******************************************************************************* 11195b482a8SLen Brown * 11295b482a8SLen Brown * FUNCTION: acpi_ut_pop_generic_state 11395b482a8SLen Brown * 11495b482a8SLen Brown * PARAMETERS: list_head - Head of the state stack 11595b482a8SLen Brown * 11695b482a8SLen Brown * RETURN: The popped state object 11795b482a8SLen Brown * 11895b482a8SLen Brown * DESCRIPTION: Pop a state object from a state stack 11995b482a8SLen Brown * 12095b482a8SLen Brown ******************************************************************************/ 12195b482a8SLen Brown 12295b482a8SLen Brown union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state 12395b482a8SLen Brown **list_head) 12495b482a8SLen Brown { 12595b482a8SLen Brown union acpi_generic_state *state; 12695b482a8SLen Brown 12795b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_pop_generic_state); 12895b482a8SLen Brown 12995b482a8SLen Brown /* Remove the state object at the head of the list (stack) */ 13095b482a8SLen Brown 13195b482a8SLen Brown state = *list_head; 13295b482a8SLen Brown if (state) { 13395b482a8SLen Brown 13495b482a8SLen Brown /* Update the list head */ 13595b482a8SLen Brown 13695b482a8SLen Brown *list_head = state->common.next; 13795b482a8SLen Brown } 13895b482a8SLen Brown 13995b482a8SLen Brown return_PTR(state); 14095b482a8SLen Brown } 14195b482a8SLen Brown 14295b482a8SLen Brown /******************************************************************************* 14395b482a8SLen Brown * 14495b482a8SLen Brown * FUNCTION: acpi_ut_create_generic_state 14595b482a8SLen Brown * 14695b482a8SLen Brown * PARAMETERS: None 14795b482a8SLen Brown * 14895b482a8SLen Brown * RETURN: The new state object. NULL on failure. 14995b482a8SLen Brown * 15095b482a8SLen Brown * DESCRIPTION: Create a generic state object. Attempt to obtain one from 15195b482a8SLen Brown * the global state cache; If none available, create a new one. 15295b482a8SLen Brown * 15395b482a8SLen Brown ******************************************************************************/ 15495b482a8SLen Brown 15595b482a8SLen Brown union acpi_generic_state *acpi_ut_create_generic_state(void) 15695b482a8SLen Brown { 15795b482a8SLen Brown union acpi_generic_state *state; 15895b482a8SLen Brown 15995b482a8SLen Brown ACPI_FUNCTION_ENTRY(); 16095b482a8SLen Brown 16195b482a8SLen Brown state = acpi_os_acquire_object(acpi_gbl_state_cache); 16295b482a8SLen Brown if (state) { 16395b482a8SLen Brown 16495b482a8SLen Brown /* Initialize */ 16595b482a8SLen Brown memset(state, 0, sizeof(union acpi_generic_state)); 16695b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE; 16795b482a8SLen Brown } 16895b482a8SLen Brown 16995b482a8SLen Brown return (state); 17095b482a8SLen Brown } 17195b482a8SLen Brown 17295b482a8SLen Brown /******************************************************************************* 17395b482a8SLen Brown * 17495b482a8SLen Brown * FUNCTION: acpi_ut_create_thread_state 17595b482a8SLen Brown * 17695b482a8SLen Brown * PARAMETERS: None 17795b482a8SLen Brown * 17895b482a8SLen Brown * RETURN: New Thread State. NULL on failure 17995b482a8SLen Brown * 18095b482a8SLen Brown * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used 18195b482a8SLen Brown * to track per-thread info during method execution 18295b482a8SLen Brown * 18395b482a8SLen Brown ******************************************************************************/ 18495b482a8SLen Brown 18595b482a8SLen Brown struct acpi_thread_state *acpi_ut_create_thread_state(void) 18695b482a8SLen Brown { 18795b482a8SLen Brown union acpi_generic_state *state; 18895b482a8SLen Brown 18995b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_create_thread_state); 19095b482a8SLen Brown 19195b482a8SLen Brown /* Create the generic state object */ 19295b482a8SLen Brown 19395b482a8SLen Brown state = acpi_ut_create_generic_state(); 19495b482a8SLen Brown if (!state) { 19595b482a8SLen Brown return_PTR(NULL); 19695b482a8SLen Brown } 19795b482a8SLen Brown 19895b482a8SLen Brown /* Init fields specific to the update struct */ 19995b482a8SLen Brown 20095b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD; 20195b482a8SLen Brown state->thread.thread_id = acpi_os_get_thread_id(); 20295b482a8SLen Brown 20395b482a8SLen Brown /* Check for invalid thread ID - zero is very bad, it will break things */ 20495b482a8SLen Brown 20595b482a8SLen Brown if (!state->thread.thread_id) { 20695b482a8SLen Brown ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId")); 20795b482a8SLen Brown state->thread.thread_id = (acpi_thread_id) 1; 20895b482a8SLen Brown } 20995b482a8SLen Brown 21095b482a8SLen Brown return_PTR((struct acpi_thread_state *)state); 21195b482a8SLen Brown } 21295b482a8SLen Brown 21395b482a8SLen Brown /******************************************************************************* 21495b482a8SLen Brown * 21595b482a8SLen Brown * FUNCTION: acpi_ut_create_update_state 21695b482a8SLen Brown * 21795b482a8SLen Brown * PARAMETERS: Object - Initial Object to be installed in the state 21895b482a8SLen Brown * Action - Update action to be performed 21995b482a8SLen Brown * 22095b482a8SLen Brown * RETURN: New state object, null on failure 22195b482a8SLen Brown * 22295b482a8SLen Brown * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 22395b482a8SLen Brown * to update reference counts and delete complex objects such 22495b482a8SLen Brown * as packages. 22595b482a8SLen Brown * 22695b482a8SLen Brown ******************************************************************************/ 22795b482a8SLen Brown 22895b482a8SLen Brown union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object 22995b482a8SLen Brown *object, u16 action) 23095b482a8SLen Brown { 23195b482a8SLen Brown union acpi_generic_state *state; 23295b482a8SLen Brown 23395b482a8SLen Brown ACPI_FUNCTION_TRACE_PTR(ut_create_update_state, object); 23495b482a8SLen Brown 23595b482a8SLen Brown /* Create the generic state object */ 23695b482a8SLen Brown 23795b482a8SLen Brown state = acpi_ut_create_generic_state(); 23895b482a8SLen Brown if (!state) { 23995b482a8SLen Brown return_PTR(NULL); 24095b482a8SLen Brown } 24195b482a8SLen Brown 24295b482a8SLen Brown /* Init fields specific to the update struct */ 24395b482a8SLen Brown 24495b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE; 24595b482a8SLen Brown state->update.object = object; 24695b482a8SLen Brown state->update.value = action; 24795b482a8SLen Brown 24895b482a8SLen Brown return_PTR(state); 24995b482a8SLen Brown } 25095b482a8SLen Brown 25195b482a8SLen Brown /******************************************************************************* 25295b482a8SLen Brown * 25395b482a8SLen Brown * FUNCTION: acpi_ut_create_pkg_state 25495b482a8SLen Brown * 25595b482a8SLen Brown * PARAMETERS: Object - Initial Object to be installed in the state 25695b482a8SLen Brown * Action - Update action to be performed 25795b482a8SLen Brown * 25895b482a8SLen Brown * RETURN: New state object, null on failure 25995b482a8SLen Brown * 26095b482a8SLen Brown * DESCRIPTION: Create a "Package State" 26195b482a8SLen Brown * 26295b482a8SLen Brown ******************************************************************************/ 26395b482a8SLen Brown 26495b482a8SLen Brown union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object, 26595b482a8SLen Brown void *external_object, 26695b482a8SLen Brown u16 index) 26795b482a8SLen Brown { 26895b482a8SLen Brown union acpi_generic_state *state; 26995b482a8SLen Brown 27095b482a8SLen Brown ACPI_FUNCTION_TRACE_PTR(ut_create_pkg_state, internal_object); 27195b482a8SLen Brown 27295b482a8SLen Brown /* Create the generic state object */ 27395b482a8SLen Brown 27495b482a8SLen Brown state = acpi_ut_create_generic_state(); 27595b482a8SLen Brown if (!state) { 27695b482a8SLen Brown return_PTR(NULL); 27795b482a8SLen Brown } 27895b482a8SLen Brown 27995b482a8SLen Brown /* Init fields specific to the update struct */ 28095b482a8SLen Brown 28195b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE; 28295b482a8SLen Brown state->pkg.source_object = (union acpi_operand_object *)internal_object; 28395b482a8SLen Brown state->pkg.dest_object = external_object; 28495b482a8SLen Brown state->pkg.index = index; 28595b482a8SLen Brown state->pkg.num_packages = 1; 28695b482a8SLen Brown 28795b482a8SLen Brown return_PTR(state); 28895b482a8SLen Brown } 28995b482a8SLen Brown 29095b482a8SLen Brown /******************************************************************************* 29195b482a8SLen Brown * 29295b482a8SLen Brown * FUNCTION: acpi_ut_create_control_state 29395b482a8SLen Brown * 29495b482a8SLen Brown * PARAMETERS: None 29595b482a8SLen Brown * 29695b482a8SLen Brown * RETURN: New state object, null on failure 29795b482a8SLen Brown * 29895b482a8SLen Brown * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 29995b482a8SLen Brown * to support nested IF/WHILE constructs in the AML. 30095b482a8SLen Brown * 30195b482a8SLen Brown ******************************************************************************/ 30295b482a8SLen Brown 30395b482a8SLen Brown union acpi_generic_state *acpi_ut_create_control_state(void) 30495b482a8SLen Brown { 30595b482a8SLen Brown union acpi_generic_state *state; 30695b482a8SLen Brown 30795b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_create_control_state); 30895b482a8SLen Brown 30995b482a8SLen Brown /* Create the generic state object */ 31095b482a8SLen Brown 31195b482a8SLen Brown state = acpi_ut_create_generic_state(); 31295b482a8SLen Brown if (!state) { 31395b482a8SLen Brown return_PTR(NULL); 31495b482a8SLen Brown } 31595b482a8SLen Brown 31695b482a8SLen Brown /* Init fields specific to the control struct */ 31795b482a8SLen Brown 31895b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL; 31995b482a8SLen Brown state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; 32095b482a8SLen Brown 32195b482a8SLen Brown return_PTR(state); 32295b482a8SLen Brown } 32395b482a8SLen Brown 32495b482a8SLen Brown /******************************************************************************* 32595b482a8SLen Brown * 32695b482a8SLen Brown * FUNCTION: acpi_ut_delete_generic_state 32795b482a8SLen Brown * 32895b482a8SLen Brown * PARAMETERS: State - The state object to be deleted 32995b482a8SLen Brown * 33095b482a8SLen Brown * RETURN: None 33195b482a8SLen Brown * 33295b482a8SLen Brown * DESCRIPTION: Release a state object to the state cache. NULL state objects 33395b482a8SLen Brown * are ignored. 33495b482a8SLen Brown * 33595b482a8SLen Brown ******************************************************************************/ 33695b482a8SLen Brown 33795b482a8SLen Brown void acpi_ut_delete_generic_state(union acpi_generic_state *state) 33895b482a8SLen Brown { 33995b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_delete_generic_state); 34095b482a8SLen Brown 34195b482a8SLen Brown /* Ignore null state */ 34295b482a8SLen Brown 34395b482a8SLen Brown if (state) { 34495b482a8SLen Brown (void)acpi_os_release_object(acpi_gbl_state_cache, state); 34595b482a8SLen Brown } 34695b482a8SLen Brown return_VOID; 34795b482a8SLen Brown } 348