1 /******************************************************************************* 2 * 3 * Module Name: utstate - state object support procedures 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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_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 121 union 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 154 union 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 state->common.descriptor_type = ACPI_DESC_TYPE_STATE; 165 } 166 167 return (state); 168 } 169 170 /******************************************************************************* 171 * 172 * FUNCTION: acpi_ut_create_thread_state 173 * 174 * PARAMETERS: None 175 * 176 * RETURN: New Thread State. NULL on failure 177 * 178 * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used 179 * to track per-thread info during method execution 180 * 181 ******************************************************************************/ 182 183 struct acpi_thread_state *acpi_ut_create_thread_state(void) 184 { 185 union acpi_generic_state *state; 186 187 ACPI_FUNCTION_ENTRY(); 188 189 /* Create the generic state object */ 190 191 state = acpi_ut_create_generic_state(); 192 if (!state) { 193 return (NULL); 194 } 195 196 /* Init fields specific to the update struct */ 197 198 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD; 199 state->thread.thread_id = acpi_os_get_thread_id(); 200 201 /* Check for invalid thread ID - zero is very bad, it will break things */ 202 203 if (!state->thread.thread_id) { 204 ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId")); 205 state->thread.thread_id = (acpi_thread_id) 1; 206 } 207 208 return ((struct acpi_thread_state *)state); 209 } 210 211 /******************************************************************************* 212 * 213 * FUNCTION: acpi_ut_create_update_state 214 * 215 * PARAMETERS: object - Initial Object to be installed in the state 216 * action - Update action to be performed 217 * 218 * RETURN: New state object, null on failure 219 * 220 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 221 * to update reference counts and delete complex objects such 222 * as packages. 223 * 224 ******************************************************************************/ 225 226 union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object 227 *object, u16 action) 228 { 229 union acpi_generic_state *state; 230 231 ACPI_FUNCTION_ENTRY(); 232 233 /* Create the generic state object */ 234 235 state = acpi_ut_create_generic_state(); 236 if (!state) { 237 return (NULL); 238 } 239 240 /* Init fields specific to the update struct */ 241 242 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE; 243 state->update.object = object; 244 state->update.value = action; 245 return (state); 246 } 247 248 /******************************************************************************* 249 * 250 * FUNCTION: acpi_ut_create_pkg_state 251 * 252 * PARAMETERS: object - Initial Object to be installed in the state 253 * action - Update action to be performed 254 * 255 * RETURN: New state object, null on failure 256 * 257 * DESCRIPTION: Create a "Package State" 258 * 259 ******************************************************************************/ 260 261 union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object, 262 void *external_object, 263 u16 index) 264 { 265 union acpi_generic_state *state; 266 267 ACPI_FUNCTION_ENTRY(); 268 269 /* Create the generic state object */ 270 271 state = acpi_ut_create_generic_state(); 272 if (!state) { 273 return (NULL); 274 } 275 276 /* Init fields specific to the update struct */ 277 278 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE; 279 state->pkg.source_object = (union acpi_operand_object *)internal_object; 280 state->pkg.dest_object = external_object; 281 state->pkg.index = index; 282 state->pkg.num_packages = 1; 283 return (state); 284 } 285 286 /******************************************************************************* 287 * 288 * FUNCTION: acpi_ut_create_control_state 289 * 290 * PARAMETERS: None 291 * 292 * RETURN: New state object, null on failure 293 * 294 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 295 * to support nested IF/WHILE constructs in the AML. 296 * 297 ******************************************************************************/ 298 299 union acpi_generic_state *acpi_ut_create_control_state(void) 300 { 301 union acpi_generic_state *state; 302 303 ACPI_FUNCTION_ENTRY(); 304 305 /* Create the generic state object */ 306 307 state = acpi_ut_create_generic_state(); 308 if (!state) { 309 return (NULL); 310 } 311 312 /* Init fields specific to the control struct */ 313 314 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL; 315 state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; 316 return (state); 317 } 318 319 /******************************************************************************* 320 * 321 * FUNCTION: acpi_ut_delete_generic_state 322 * 323 * PARAMETERS: state - The state object to be deleted 324 * 325 * RETURN: None 326 * 327 * DESCRIPTION: Release a state object to the state cache. NULL state objects 328 * are ignored. 329 * 330 ******************************************************************************/ 331 332 void acpi_ut_delete_generic_state(union acpi_generic_state *state) 333 { 334 ACPI_FUNCTION_ENTRY(); 335 336 /* Ignore null state */ 337 338 if (state) { 339 (void)acpi_os_release_object(acpi_gbl_state_cache, state); 340 } 341 return; 342 } 343