1/******************************************************************************* 2 * 3 * Module Name: utstate - state object support procedures 4 * 5 ******************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2013, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44#include <acpi/acpi.h> 45#include "accommon.h" 46 47#define _COMPONENT ACPI_UTILITIES 48ACPI_MODULE_NAME("utstate") 49 50/******************************************************************************* 51 * 52 * FUNCTION: acpi_ut_create_pkg_state_and_push 53 * 54 * PARAMETERS: object - Object to be added to the new state 55 * action - Increment/Decrement 56 * state_list - List the state will be added to 57 * 58 * RETURN: Status 59 * 60 * DESCRIPTION: Create a new state and push it 61 * 62 ******************************************************************************/ 63acpi_status 64acpi_ut_create_pkg_state_and_push(void *internal_object, 65 void *external_object, 66 u16 index, 67 union acpi_generic_state **state_list) 68{ 69 union acpi_generic_state *state; 70 71 ACPI_FUNCTION_ENTRY(); 72 73 state = 74 acpi_ut_create_pkg_state(internal_object, external_object, index); 75 if (!state) { 76 return (AE_NO_MEMORY); 77 } 78 79 acpi_ut_push_generic_state(state_list, state); 80 return (AE_OK); 81} 82 83/******************************************************************************* 84 * 85 * FUNCTION: acpi_ut_push_generic_state 86 * 87 * PARAMETERS: list_head - Head of the state stack 88 * state - State object to push 89 * 90 * RETURN: None 91 * 92 * DESCRIPTION: Push a state object onto a state stack 93 * 94 ******************************************************************************/ 95 96void 97acpi_ut_push_generic_state(union acpi_generic_state **list_head, 98 union acpi_generic_state *state) 99{ 100 ACPI_FUNCTION_ENTRY(); 101 102 /* Push the state object onto the front of the list (stack) */ 103 104 state->common.next = *list_head; 105 *list_head = state; 106 return; 107} 108 109/******************************************************************************* 110 * 111 * FUNCTION: acpi_ut_pop_generic_state 112 * 113 * PARAMETERS: list_head - Head of the state stack 114 * 115 * RETURN: The popped state object 116 * 117 * DESCRIPTION: Pop a state object from a state stack 118 * 119 ******************************************************************************/ 120 121union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state 122 **list_head) 123{ 124 union acpi_generic_state *state; 125 126 ACPI_FUNCTION_ENTRY(); 127 128 /* Remove the state object at the head of the list (stack) */ 129 130 state = *list_head; 131 if (state) { 132 133 /* Update the list head */ 134 135 *list_head = state->common.next; 136 } 137 138 return (state); 139} 140 141/******************************************************************************* 142 * 143 * FUNCTION: acpi_ut_create_generic_state 144 * 145 * PARAMETERS: None 146 * 147 * RETURN: The new state object. NULL on failure. 148 * 149 * DESCRIPTION: Create a generic state object. Attempt to obtain one from 150 * the global state cache; If none available, create a new one. 151 * 152 ******************************************************************************/ 153 154union acpi_generic_state *acpi_ut_create_generic_state(void) 155{ 156 union acpi_generic_state *state; 157 158 ACPI_FUNCTION_ENTRY(); 159 160 state = acpi_os_acquire_object(acpi_gbl_state_cache); 161 if (state) { 162 163 /* Initialize */ 164 memset(state, 0, sizeof(union acpi_generic_state)); 165 state->common.descriptor_type = ACPI_DESC_TYPE_STATE; 166 } 167 168 return (state); 169} 170 171/******************************************************************************* 172 * 173 * FUNCTION: acpi_ut_create_thread_state 174 * 175 * PARAMETERS: None 176 * 177 * RETURN: New Thread State. NULL on failure 178 * 179 * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used 180 * to track per-thread info during method execution 181 * 182 ******************************************************************************/ 183 184struct acpi_thread_state *acpi_ut_create_thread_state(void) 185{ 186 union acpi_generic_state *state; 187 188 ACPI_FUNCTION_ENTRY(); 189 190 /* Create the generic state object */ 191 192 state = acpi_ut_create_generic_state(); 193 if (!state) { 194 return (NULL); 195 } 196 197 /* Init fields specific to the update struct */ 198 199 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD; 200 state->thread.thread_id = acpi_os_get_thread_id(); 201 202 /* Check for invalid thread ID - zero is very bad, it will break things */ 203 204 if (!state->thread.thread_id) { 205 ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId")); 206 state->thread.thread_id = (acpi_thread_id) 1; 207 } 208 209 return ((struct acpi_thread_state *)state); 210} 211 212/******************************************************************************* 213 * 214 * FUNCTION: acpi_ut_create_update_state 215 * 216 * PARAMETERS: object - Initial Object to be installed in the state 217 * action - Update action to be performed 218 * 219 * RETURN: New state object, null on failure 220 * 221 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 222 * to update reference counts and delete complex objects such 223 * as packages. 224 * 225 ******************************************************************************/ 226 227union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object 228 *object, u16 action) 229{ 230 union acpi_generic_state *state; 231 232 ACPI_FUNCTION_ENTRY(); 233 234 /* Create the generic state object */ 235 236 state = acpi_ut_create_generic_state(); 237 if (!state) { 238 return (NULL); 239 } 240 241 /* Init fields specific to the update struct */ 242 243 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE; 244 state->update.object = object; 245 state->update.value = action; 246 return (state); 247} 248 249/******************************************************************************* 250 * 251 * FUNCTION: acpi_ut_create_pkg_state 252 * 253 * PARAMETERS: object - Initial Object to be installed in the state 254 * action - Update action to be performed 255 * 256 * RETURN: New state object, null on failure 257 * 258 * DESCRIPTION: Create a "Package State" 259 * 260 ******************************************************************************/ 261 262union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object, 263 void *external_object, 264 u16 index) 265{ 266 union acpi_generic_state *state; 267 268 ACPI_FUNCTION_ENTRY(); 269 270 /* Create the generic state object */ 271 272 state = acpi_ut_create_generic_state(); 273 if (!state) { 274 return (NULL); 275 } 276 277 /* Init fields specific to the update struct */ 278 279 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE; 280 state->pkg.source_object = (union acpi_operand_object *)internal_object; 281 state->pkg.dest_object = external_object; 282 state->pkg.index = index; 283 state->pkg.num_packages = 1; 284 return (state); 285} 286 287/******************************************************************************* 288 * 289 * FUNCTION: acpi_ut_create_control_state 290 * 291 * PARAMETERS: None 292 * 293 * RETURN: New state object, null on failure 294 * 295 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 296 * to support nested IF/WHILE constructs in the AML. 297 * 298 ******************************************************************************/ 299 300union acpi_generic_state *acpi_ut_create_control_state(void) 301{ 302 union acpi_generic_state *state; 303 304 ACPI_FUNCTION_ENTRY(); 305 306 /* Create the generic state object */ 307 308 state = acpi_ut_create_generic_state(); 309 if (!state) { 310 return (NULL); 311 } 312 313 /* Init fields specific to the control struct */ 314 315 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL; 316 state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; 317 return (state); 318} 319 320/******************************************************************************* 321 * 322 * FUNCTION: acpi_ut_delete_generic_state 323 * 324 * PARAMETERS: state - The state object to be deleted 325 * 326 * RETURN: None 327 * 328 * DESCRIPTION: Release a state object to the state cache. NULL state objects 329 * are ignored. 330 * 331 ******************************************************************************/ 332 333void acpi_ut_delete_generic_state(union acpi_generic_state *state) 334{ 335 ACPI_FUNCTION_ENTRY(); 336 337 /* Ignore null state */ 338 339 if (state) { 340 (void)acpi_os_release_object(acpi_gbl_state_cache, state); 341 } 342 return; 343} 344