1 /******************************************************************************* 2 * 3 * Module Name: utstate - state object support procedures 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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_push_generic_state 53 * 54 * PARAMETERS: list_head - Head of the state stack 55 * state - State object to push 56 * 57 * RETURN: None 58 * 59 * DESCRIPTION: Push a state object onto a state stack 60 * 61 ******************************************************************************/ 62 void 63 acpi_ut_push_generic_state(union acpi_generic_state **list_head, 64 union acpi_generic_state *state) 65 { 66 ACPI_FUNCTION_ENTRY(); 67 68 /* Push the state object onto the front of the list (stack) */ 69 70 state->common.next = *list_head; 71 *list_head = state; 72 return; 73 } 74 75 /******************************************************************************* 76 * 77 * FUNCTION: acpi_ut_pop_generic_state 78 * 79 * PARAMETERS: list_head - Head of the state stack 80 * 81 * RETURN: The popped state object 82 * 83 * DESCRIPTION: Pop a state object from a state stack 84 * 85 ******************************************************************************/ 86 87 union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state 88 **list_head) 89 { 90 union acpi_generic_state *state; 91 92 ACPI_FUNCTION_ENTRY(); 93 94 /* Remove the state object at the head of the list (stack) */ 95 96 state = *list_head; 97 if (state) { 98 99 /* Update the list head */ 100 101 *list_head = state->common.next; 102 } 103 104 return (state); 105 } 106 107 /******************************************************************************* 108 * 109 * FUNCTION: acpi_ut_create_generic_state 110 * 111 * PARAMETERS: None 112 * 113 * RETURN: The new state object. NULL on failure. 114 * 115 * DESCRIPTION: Create a generic state object. Attempt to obtain one from 116 * the global state cache; If none available, create a new one. 117 * 118 ******************************************************************************/ 119 120 union acpi_generic_state *acpi_ut_create_generic_state(void) 121 { 122 union acpi_generic_state *state; 123 124 ACPI_FUNCTION_ENTRY(); 125 126 state = acpi_os_acquire_object(acpi_gbl_state_cache); 127 if (state) { 128 129 /* Initialize */ 130 state->common.descriptor_type = ACPI_DESC_TYPE_STATE; 131 } 132 133 return (state); 134 } 135 136 /******************************************************************************* 137 * 138 * FUNCTION: acpi_ut_create_thread_state 139 * 140 * PARAMETERS: None 141 * 142 * RETURN: New Thread State. NULL on failure 143 * 144 * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used 145 * to track per-thread info during method execution 146 * 147 ******************************************************************************/ 148 149 struct acpi_thread_state *acpi_ut_create_thread_state(void) 150 { 151 union acpi_generic_state *state; 152 153 ACPI_FUNCTION_ENTRY(); 154 155 /* Create the generic state object */ 156 157 state = acpi_ut_create_generic_state(); 158 if (!state) { 159 return (NULL); 160 } 161 162 /* Init fields specific to the update struct */ 163 164 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD; 165 state->thread.thread_id = acpi_os_get_thread_id(); 166 167 /* Check for invalid thread ID - zero is very bad, it will break things */ 168 169 if (!state->thread.thread_id) { 170 ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId")); 171 state->thread.thread_id = (acpi_thread_id) 1; 172 } 173 174 return ((struct acpi_thread_state *)state); 175 } 176 177 /******************************************************************************* 178 * 179 * FUNCTION: acpi_ut_create_update_state 180 * 181 * PARAMETERS: object - Initial Object to be installed in the state 182 * action - Update action to be performed 183 * 184 * RETURN: New state object, null on failure 185 * 186 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 187 * to update reference counts and delete complex objects such 188 * as packages. 189 * 190 ******************************************************************************/ 191 192 union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object 193 *object, u16 action) 194 { 195 union acpi_generic_state *state; 196 197 ACPI_FUNCTION_ENTRY(); 198 199 /* Create the generic state object */ 200 201 state = acpi_ut_create_generic_state(); 202 if (!state) { 203 return (NULL); 204 } 205 206 /* Init fields specific to the update struct */ 207 208 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE; 209 state->update.object = object; 210 state->update.value = action; 211 return (state); 212 } 213 214 /******************************************************************************* 215 * 216 * FUNCTION: acpi_ut_create_pkg_state 217 * 218 * PARAMETERS: object - Initial Object to be installed in the state 219 * action - Update action to be performed 220 * 221 * RETURN: New state object, null on failure 222 * 223 * DESCRIPTION: Create a "Package State" 224 * 225 ******************************************************************************/ 226 227 union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object, 228 void *external_object, 229 u32 index) 230 { 231 union acpi_generic_state *state; 232 233 ACPI_FUNCTION_ENTRY(); 234 235 /* Create the generic state object */ 236 237 state = acpi_ut_create_generic_state(); 238 if (!state) { 239 return (NULL); 240 } 241 242 /* Init fields specific to the update struct */ 243 244 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE; 245 state->pkg.source_object = (union acpi_operand_object *)internal_object; 246 state->pkg.dest_object = external_object; 247 state->pkg.index = index; 248 state->pkg.num_packages = 1; 249 250 return (state); 251 } 252 253 /******************************************************************************* 254 * 255 * FUNCTION: acpi_ut_create_control_state 256 * 257 * PARAMETERS: None 258 * 259 * RETURN: New state object, null on failure 260 * 261 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 262 * to support nested IF/WHILE constructs in the AML. 263 * 264 ******************************************************************************/ 265 266 union acpi_generic_state *acpi_ut_create_control_state(void) 267 { 268 union acpi_generic_state *state; 269 270 ACPI_FUNCTION_ENTRY(); 271 272 /* Create the generic state object */ 273 274 state = acpi_ut_create_generic_state(); 275 if (!state) { 276 return (NULL); 277 } 278 279 /* Init fields specific to the control struct */ 280 281 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL; 282 state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; 283 284 return (state); 285 } 286 287 /******************************************************************************* 288 * 289 * FUNCTION: acpi_ut_delete_generic_state 290 * 291 * PARAMETERS: state - The state object to be deleted 292 * 293 * RETURN: None 294 * 295 * DESCRIPTION: Release a state object to the state cache. NULL state objects 296 * are ignored. 297 * 298 ******************************************************************************/ 299 300 void acpi_ut_delete_generic_state(union acpi_generic_state *state) 301 { 302 ACPI_FUNCTION_ENTRY(); 303 304 /* Ignore null state */ 305 306 if (state) { 307 (void)acpi_os_release_object(acpi_gbl_state_cache, state); 308 } 309 310 return; 311 } 312