1 /******************************************************************************* 2 * 3 * Module Name: utstate - state object support procedures 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 48 ACPI_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 ******************************************************************************/ 63 acpi_status 64 acpi_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 96 void 97 acpi_ut_push_generic_state(union acpi_generic_state **list_head, 98 union acpi_generic_state *state) 99 { 100 ACPI_FUNCTION_TRACE(ut_push_generic_state); 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 107 return_VOID; 108 } 109 110 /******************************************************************************* 111 * 112 * FUNCTION: acpi_ut_pop_generic_state 113 * 114 * PARAMETERS: list_head - Head of the state stack 115 * 116 * RETURN: The popped state object 117 * 118 * DESCRIPTION: Pop a state object from a state stack 119 * 120 ******************************************************************************/ 121 122 union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state 123 **list_head) 124 { 125 union acpi_generic_state *state; 126 127 ACPI_FUNCTION_TRACE(ut_pop_generic_state); 128 129 /* Remove the state object at the head of the list (stack) */ 130 131 state = *list_head; 132 if (state) { 133 134 /* Update the list head */ 135 136 *list_head = state->common.next; 137 } 138 139 return_PTR(state); 140 } 141 142 /******************************************************************************* 143 * 144 * FUNCTION: acpi_ut_create_generic_state 145 * 146 * PARAMETERS: None 147 * 148 * RETURN: The new state object. NULL on failure. 149 * 150 * DESCRIPTION: Create a generic state object. Attempt to obtain one from 151 * the global state cache; If none available, create a new one. 152 * 153 ******************************************************************************/ 154 155 union acpi_generic_state *acpi_ut_create_generic_state(void) 156 { 157 union acpi_generic_state *state; 158 159 ACPI_FUNCTION_ENTRY(); 160 161 state = acpi_os_acquire_object(acpi_gbl_state_cache); 162 if (state) { 163 164 /* Initialize */ 165 memset(state, 0, sizeof(union acpi_generic_state)); 166 state->common.descriptor_type = ACPI_DESC_TYPE_STATE; 167 } 168 169 return (state); 170 } 171 172 /******************************************************************************* 173 * 174 * FUNCTION: acpi_ut_create_thread_state 175 * 176 * PARAMETERS: None 177 * 178 * RETURN: New Thread State. NULL on failure 179 * 180 * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used 181 * to track per-thread info during method execution 182 * 183 ******************************************************************************/ 184 185 struct acpi_thread_state *acpi_ut_create_thread_state(void) 186 { 187 union acpi_generic_state *state; 188 189 ACPI_FUNCTION_TRACE(ut_create_thread_state); 190 191 /* Create the generic state object */ 192 193 state = acpi_ut_create_generic_state(); 194 if (!state) { 195 return_PTR(NULL); 196 } 197 198 /* Init fields specific to the update struct */ 199 200 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD; 201 state->thread.thread_id = acpi_os_get_thread_id(); 202 203 /* Check for invalid thread ID - zero is very bad, it will break things */ 204 205 if (!state->thread.thread_id) { 206 ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId")); 207 state->thread.thread_id = (acpi_thread_id) 1; 208 } 209 210 return_PTR((struct acpi_thread_state *)state); 211 } 212 213 /******************************************************************************* 214 * 215 * FUNCTION: acpi_ut_create_update_state 216 * 217 * PARAMETERS: object - Initial Object to be installed in the state 218 * action - Update action to be performed 219 * 220 * RETURN: New state object, null on failure 221 * 222 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 223 * to update reference counts and delete complex objects such 224 * as packages. 225 * 226 ******************************************************************************/ 227 228 union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object 229 *object, u16 action) 230 { 231 union acpi_generic_state *state; 232 233 ACPI_FUNCTION_TRACE_PTR(ut_create_update_state, object); 234 235 /* Create the generic state object */ 236 237 state = acpi_ut_create_generic_state(); 238 if (!state) { 239 return_PTR(NULL); 240 } 241 242 /* Init fields specific to the update struct */ 243 244 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE; 245 state->update.object = object; 246 state->update.value = action; 247 248 return_PTR(state); 249 } 250 251 /******************************************************************************* 252 * 253 * FUNCTION: acpi_ut_create_pkg_state 254 * 255 * PARAMETERS: object - Initial Object to be installed in the state 256 * action - Update action to be performed 257 * 258 * RETURN: New state object, null on failure 259 * 260 * DESCRIPTION: Create a "Package State" 261 * 262 ******************************************************************************/ 263 264 union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object, 265 void *external_object, 266 u16 index) 267 { 268 union acpi_generic_state *state; 269 270 ACPI_FUNCTION_TRACE_PTR(ut_create_pkg_state, internal_object); 271 272 /* Create the generic state object */ 273 274 state = acpi_ut_create_generic_state(); 275 if (!state) { 276 return_PTR(NULL); 277 } 278 279 /* Init fields specific to the update struct */ 280 281 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE; 282 state->pkg.source_object = (union acpi_operand_object *)internal_object; 283 state->pkg.dest_object = external_object; 284 state->pkg.index = index; 285 state->pkg.num_packages = 1; 286 287 return_PTR(state); 288 } 289 290 /******************************************************************************* 291 * 292 * FUNCTION: acpi_ut_create_control_state 293 * 294 * PARAMETERS: None 295 * 296 * RETURN: New state object, null on failure 297 * 298 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 299 * to support nested IF/WHILE constructs in the AML. 300 * 301 ******************************************************************************/ 302 303 union acpi_generic_state *acpi_ut_create_control_state(void) 304 { 305 union acpi_generic_state *state; 306 307 ACPI_FUNCTION_TRACE(ut_create_control_state); 308 309 /* Create the generic state object */ 310 311 state = acpi_ut_create_generic_state(); 312 if (!state) { 313 return_PTR(NULL); 314 } 315 316 /* Init fields specific to the control struct */ 317 318 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL; 319 state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; 320 321 return_PTR(state); 322 } 323 324 /******************************************************************************* 325 * 326 * FUNCTION: acpi_ut_delete_generic_state 327 * 328 * PARAMETERS: state - The state object to be deleted 329 * 330 * RETURN: None 331 * 332 * DESCRIPTION: Release a state object to the state cache. NULL state objects 333 * are ignored. 334 * 335 ******************************************************************************/ 336 337 void acpi_ut_delete_generic_state(union acpi_generic_state *state) 338 { 339 ACPI_FUNCTION_TRACE(ut_delete_generic_state); 340 341 /* Ignore null state */ 342 343 if (state) { 344 (void)acpi_os_release_object(acpi_gbl_state_cache, state); 345 } 346 return_VOID; 347 } 348