1*95857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 295b482a8SLen Brown /******************************************************************************* 395b482a8SLen Brown * 495b482a8SLen Brown * Module Name: utstate - state object support procedures 595b482a8SLen Brown * 695b482a8SLen Brown ******************************************************************************/ 795b482a8SLen Brown 895b482a8SLen Brown #include <acpi/acpi.h> 9e2f7a777SLen Brown #include "accommon.h" 1095b482a8SLen Brown 1195b482a8SLen Brown #define _COMPONENT ACPI_UTILITIES 1295b482a8SLen Brown ACPI_MODULE_NAME("utstate") 1395b482a8SLen Brown 1495b482a8SLen Brown /******************************************************************************* 1595b482a8SLen Brown * 1695b482a8SLen Brown * FUNCTION: acpi_ut_push_generic_state 1795b482a8SLen Brown * 1895b482a8SLen Brown * PARAMETERS: list_head - Head of the state stack 19ba494beeSBob Moore * state - State object to push 2095b482a8SLen Brown * 2195b482a8SLen Brown * RETURN: None 2295b482a8SLen Brown * 2395b482a8SLen Brown * DESCRIPTION: Push a state object onto a state stack 2495b482a8SLen Brown * 2595b482a8SLen Brown ******************************************************************************/ 2695b482a8SLen Brown void 2795b482a8SLen Brown acpi_ut_push_generic_state(union acpi_generic_state **list_head, 2895b482a8SLen Brown union acpi_generic_state *state) 2995b482a8SLen Brown { 300e770b32SBob Moore ACPI_FUNCTION_ENTRY(); 3195b482a8SLen Brown 3295b482a8SLen Brown /* Push the state object onto the front of the list (stack) */ 3395b482a8SLen Brown 3495b482a8SLen Brown state->common.next = *list_head; 3595b482a8SLen Brown *list_head = state; 360e770b32SBob Moore return; 3795b482a8SLen Brown } 3895b482a8SLen Brown 3995b482a8SLen Brown /******************************************************************************* 4095b482a8SLen Brown * 4195b482a8SLen Brown * FUNCTION: acpi_ut_pop_generic_state 4295b482a8SLen Brown * 4395b482a8SLen Brown * PARAMETERS: list_head - Head of the state stack 4495b482a8SLen Brown * 4595b482a8SLen Brown * RETURN: The popped state object 4695b482a8SLen Brown * 4795b482a8SLen Brown * DESCRIPTION: Pop a state object from a state stack 4895b482a8SLen Brown * 4995b482a8SLen Brown ******************************************************************************/ 5095b482a8SLen Brown 5195b482a8SLen Brown union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state 5295b482a8SLen Brown **list_head) 5395b482a8SLen Brown { 5495b482a8SLen Brown union acpi_generic_state *state; 5595b482a8SLen Brown 560e770b32SBob Moore ACPI_FUNCTION_ENTRY(); 5795b482a8SLen Brown 5895b482a8SLen Brown /* Remove the state object at the head of the list (stack) */ 5995b482a8SLen Brown 6095b482a8SLen Brown state = *list_head; 6195b482a8SLen Brown if (state) { 6295b482a8SLen Brown 6395b482a8SLen Brown /* Update the list head */ 6495b482a8SLen Brown 6595b482a8SLen Brown *list_head = state->common.next; 6695b482a8SLen Brown } 6795b482a8SLen Brown 680e770b32SBob Moore return (state); 6995b482a8SLen Brown } 7095b482a8SLen Brown 7195b482a8SLen Brown /******************************************************************************* 7295b482a8SLen Brown * 7395b482a8SLen Brown * FUNCTION: acpi_ut_create_generic_state 7495b482a8SLen Brown * 7595b482a8SLen Brown * PARAMETERS: None 7695b482a8SLen Brown * 7795b482a8SLen Brown * RETURN: The new state object. NULL on failure. 7895b482a8SLen Brown * 7995b482a8SLen Brown * DESCRIPTION: Create a generic state object. Attempt to obtain one from 8095b482a8SLen Brown * the global state cache; If none available, create a new one. 8195b482a8SLen Brown * 8295b482a8SLen Brown ******************************************************************************/ 8395b482a8SLen Brown 8495b482a8SLen Brown union acpi_generic_state *acpi_ut_create_generic_state(void) 8595b482a8SLen Brown { 8695b482a8SLen Brown union acpi_generic_state *state; 8795b482a8SLen Brown 8895b482a8SLen Brown ACPI_FUNCTION_ENTRY(); 8995b482a8SLen Brown 9095b482a8SLen Brown state = acpi_os_acquire_object(acpi_gbl_state_cache); 9195b482a8SLen Brown if (state) { 9295b482a8SLen Brown 9395b482a8SLen Brown /* Initialize */ 9495b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE; 9595b482a8SLen Brown } 9695b482a8SLen Brown 9795b482a8SLen Brown return (state); 9895b482a8SLen Brown } 9995b482a8SLen Brown 10095b482a8SLen Brown /******************************************************************************* 10195b482a8SLen Brown * 10295b482a8SLen Brown * FUNCTION: acpi_ut_create_thread_state 10395b482a8SLen Brown * 10495b482a8SLen Brown * PARAMETERS: None 10595b482a8SLen Brown * 10695b482a8SLen Brown * RETURN: New Thread State. NULL on failure 10795b482a8SLen Brown * 10895b482a8SLen Brown * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used 10995b482a8SLen Brown * to track per-thread info during method execution 11095b482a8SLen Brown * 11195b482a8SLen Brown ******************************************************************************/ 11295b482a8SLen Brown 11395b482a8SLen Brown struct acpi_thread_state *acpi_ut_create_thread_state(void) 11495b482a8SLen Brown { 11595b482a8SLen Brown union acpi_generic_state *state; 11695b482a8SLen Brown 1170e770b32SBob Moore ACPI_FUNCTION_ENTRY(); 11895b482a8SLen Brown 11995b482a8SLen Brown /* Create the generic state object */ 12095b482a8SLen Brown 12195b482a8SLen Brown state = acpi_ut_create_generic_state(); 12295b482a8SLen Brown if (!state) { 1230e770b32SBob Moore return (NULL); 12495b482a8SLen Brown } 12595b482a8SLen Brown 12695b482a8SLen Brown /* Init fields specific to the update struct */ 12795b482a8SLen Brown 12895b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD; 12995b482a8SLen Brown state->thread.thread_id = acpi_os_get_thread_id(); 13095b482a8SLen Brown 13195b482a8SLen Brown /* Check for invalid thread ID - zero is very bad, it will break things */ 13295b482a8SLen Brown 13395b482a8SLen Brown if (!state->thread.thread_id) { 13495b482a8SLen Brown ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId")); 13595b482a8SLen Brown state->thread.thread_id = (acpi_thread_id) 1; 13695b482a8SLen Brown } 13795b482a8SLen Brown 1380e770b32SBob Moore return ((struct acpi_thread_state *)state); 13995b482a8SLen Brown } 14095b482a8SLen Brown 14195b482a8SLen Brown /******************************************************************************* 14295b482a8SLen Brown * 14395b482a8SLen Brown * FUNCTION: acpi_ut_create_update_state 14495b482a8SLen Brown * 145ba494beeSBob Moore * PARAMETERS: object - Initial Object to be installed in the state 146ba494beeSBob Moore * action - Update action to be performed 14795b482a8SLen Brown * 14895b482a8SLen Brown * RETURN: New state object, null on failure 14995b482a8SLen Brown * 15095b482a8SLen Brown * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 15195b482a8SLen Brown * to update reference counts and delete complex objects such 15295b482a8SLen Brown * as packages. 15395b482a8SLen Brown * 15495b482a8SLen Brown ******************************************************************************/ 15595b482a8SLen Brown 15695b482a8SLen Brown union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object 15795b482a8SLen Brown *object, u16 action) 15895b482a8SLen Brown { 15995b482a8SLen Brown union acpi_generic_state *state; 16095b482a8SLen Brown 1610e770b32SBob Moore ACPI_FUNCTION_ENTRY(); 16295b482a8SLen Brown 16395b482a8SLen Brown /* Create the generic state object */ 16495b482a8SLen Brown 16595b482a8SLen Brown state = acpi_ut_create_generic_state(); 16695b482a8SLen Brown if (!state) { 1670e770b32SBob Moore return (NULL); 16895b482a8SLen Brown } 16995b482a8SLen Brown 17095b482a8SLen Brown /* Init fields specific to the update struct */ 17195b482a8SLen Brown 17295b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE; 17395b482a8SLen Brown state->update.object = object; 17495b482a8SLen Brown state->update.value = action; 1750e770b32SBob Moore return (state); 17695b482a8SLen Brown } 17795b482a8SLen Brown 17895b482a8SLen Brown /******************************************************************************* 17995b482a8SLen Brown * 18095b482a8SLen Brown * FUNCTION: acpi_ut_create_pkg_state 18195b482a8SLen Brown * 182ba494beeSBob Moore * PARAMETERS: object - Initial Object to be installed in the state 183ba494beeSBob Moore * action - Update action to be performed 18495b482a8SLen Brown * 18595b482a8SLen Brown * RETURN: New state object, null on failure 18695b482a8SLen Brown * 18795b482a8SLen Brown * DESCRIPTION: Create a "Package State" 18895b482a8SLen Brown * 18995b482a8SLen Brown ******************************************************************************/ 19095b482a8SLen Brown 19195b482a8SLen Brown union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object, 19295b482a8SLen Brown void *external_object, 193a62a7117SBob Moore u32 index) 19495b482a8SLen Brown { 19595b482a8SLen Brown union acpi_generic_state *state; 19695b482a8SLen Brown 1970e770b32SBob Moore ACPI_FUNCTION_ENTRY(); 19895b482a8SLen Brown 19995b482a8SLen Brown /* Create the generic state object */ 20095b482a8SLen Brown 20195b482a8SLen Brown state = acpi_ut_create_generic_state(); 20295b482a8SLen Brown if (!state) { 2030e770b32SBob Moore return (NULL); 20495b482a8SLen Brown } 20595b482a8SLen Brown 20695b482a8SLen Brown /* Init fields specific to the update struct */ 20795b482a8SLen Brown 20895b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE; 20995b482a8SLen Brown state->pkg.source_object = (union acpi_operand_object *)internal_object; 21095b482a8SLen Brown state->pkg.dest_object = external_object; 21195b482a8SLen Brown state->pkg.index = index; 21295b482a8SLen Brown state->pkg.num_packages = 1; 2131fad8738SBob Moore 2140e770b32SBob Moore return (state); 21595b482a8SLen Brown } 21695b482a8SLen Brown 21795b482a8SLen Brown /******************************************************************************* 21895b482a8SLen Brown * 21995b482a8SLen Brown * FUNCTION: acpi_ut_create_control_state 22095b482a8SLen Brown * 22195b482a8SLen Brown * PARAMETERS: None 22295b482a8SLen Brown * 22395b482a8SLen Brown * RETURN: New state object, null on failure 22495b482a8SLen Brown * 22595b482a8SLen Brown * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 22695b482a8SLen Brown * to support nested IF/WHILE constructs in the AML. 22795b482a8SLen Brown * 22895b482a8SLen Brown ******************************************************************************/ 22995b482a8SLen Brown 23095b482a8SLen Brown union acpi_generic_state *acpi_ut_create_control_state(void) 23195b482a8SLen Brown { 23295b482a8SLen Brown union acpi_generic_state *state; 23395b482a8SLen Brown 2340e770b32SBob Moore ACPI_FUNCTION_ENTRY(); 23595b482a8SLen Brown 23695b482a8SLen Brown /* Create the generic state object */ 23795b482a8SLen Brown 23895b482a8SLen Brown state = acpi_ut_create_generic_state(); 23995b482a8SLen Brown if (!state) { 2400e770b32SBob Moore return (NULL); 24195b482a8SLen Brown } 24295b482a8SLen Brown 24395b482a8SLen Brown /* Init fields specific to the control struct */ 24495b482a8SLen Brown 24595b482a8SLen Brown state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL; 24695b482a8SLen Brown state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; 2471fad8738SBob Moore 2480e770b32SBob Moore return (state); 24995b482a8SLen Brown } 25095b482a8SLen Brown 25195b482a8SLen Brown /******************************************************************************* 25295b482a8SLen Brown * 25395b482a8SLen Brown * FUNCTION: acpi_ut_delete_generic_state 25495b482a8SLen Brown * 255ba494beeSBob Moore * PARAMETERS: state - The state object to be deleted 25695b482a8SLen Brown * 25795b482a8SLen Brown * RETURN: None 25895b482a8SLen Brown * 25995b482a8SLen Brown * DESCRIPTION: Release a state object to the state cache. NULL state objects 26095b482a8SLen Brown * are ignored. 26195b482a8SLen Brown * 26295b482a8SLen Brown ******************************************************************************/ 26395b482a8SLen Brown 26495b482a8SLen Brown void acpi_ut_delete_generic_state(union acpi_generic_state *state) 26595b482a8SLen Brown { 2660e770b32SBob Moore ACPI_FUNCTION_ENTRY(); 26795b482a8SLen Brown 26895b482a8SLen Brown /* Ignore null state */ 26995b482a8SLen Brown 27095b482a8SLen Brown if (state) { 27195b482a8SLen Brown (void)acpi_os_release_object(acpi_gbl_state_cache, state); 27295b482a8SLen Brown } 2731fad8738SBob Moore 2740e770b32SBob Moore return; 27595b482a8SLen Brown } 276