1 /*******************************************************************************
   2  *
   3  * Module Name: utstate - state object support procedures
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 
  45 #define __UTSTATE_C__
  46 
  47 #include "acpi.h"
  48 #include "accommon.h"
  49 
  50 #define _COMPONENT          ACPI_UTILITIES
  51         ACPI_MODULE_NAME    ("utstate")
  52 
  53 
  54 /*******************************************************************************
  55  *
  56  * FUNCTION:    AcpiUtCreatePkgStateAndPush
  57  *
  58  * PARAMETERS:  Object          - Object to be added to the new state
  59  *              Action          - Increment/Decrement
  60  *              StateList       - List the state will be added to
  61  *
  62  * RETURN:      Status
  63  *
  64  * DESCRIPTION: Create a new state and push it
  65  *
  66  ******************************************************************************/
  67 
  68 ACPI_STATUS
  69 AcpiUtCreatePkgStateAndPush (
  70     void                    *InternalObject,
  71     void                    *ExternalObject,
  72     UINT16                  Index,
  73     ACPI_GENERIC_STATE      **StateList)
  74 {
  75     ACPI_GENERIC_STATE       *State;
  76 
  77 
  78     ACPI_FUNCTION_ENTRY ();
  79 
  80 
  81     State = AcpiUtCreatePkgState (InternalObject, ExternalObject, Index);
  82     if (!State)
  83     {
  84         return (AE_NO_MEMORY);
  85     }
  86 
  87     AcpiUtPushGenericState (StateList, State);
  88     return (AE_OK);
  89 }
  90 
  91 
  92 /*******************************************************************************
  93  *
  94  * FUNCTION:    AcpiUtPushGenericState
  95  *
  96  * PARAMETERS:  ListHead            - Head of the state stack
  97  *              State               - State object to push
  98  *
  99  * RETURN:      None
 100  *
 101  * DESCRIPTION: Push a state object onto a state stack
 102  *
 103  ******************************************************************************/
 104 
 105 void
 106 AcpiUtPushGenericState (
 107     ACPI_GENERIC_STATE      **ListHead,
 108     ACPI_GENERIC_STATE      *State)
 109 {
 110     ACPI_FUNCTION_TRACE (UtPushGenericState);
 111 
 112 
 113     /* Push the state object onto the front of the list (stack) */
 114 
 115     State->Common.Next = *ListHead;
 116     *ListHead = State;
 117 
 118     return_VOID;
 119 }
 120 
 121 
 122 /*******************************************************************************
 123  *
 124  * FUNCTION:    AcpiUtPopGenericState
 125  *
 126  * PARAMETERS:  ListHead            - Head of the state stack
 127  *
 128  * RETURN:      The popped state object
 129  *
 130  * DESCRIPTION: Pop a state object from a state stack
 131  *
 132  ******************************************************************************/
 133 
 134 ACPI_GENERIC_STATE *
 135 AcpiUtPopGenericState (
 136     ACPI_GENERIC_STATE      **ListHead)
 137 {
 138     ACPI_GENERIC_STATE      *State;
 139 
 140 
 141     ACPI_FUNCTION_TRACE (UtPopGenericState);
 142 
 143 
 144     /* Remove the state object at the head of the list (stack) */
 145 
 146     State = *ListHead;
 147     if (State)
 148     {
 149         /* Update the list head */
 150 
 151         *ListHead = State->Common.Next;
 152     }
 153 
 154     return_PTR (State);
 155 }
 156 
 157 
 158 /*******************************************************************************
 159  *
 160  * FUNCTION:    AcpiUtCreateGenericState
 161  *
 162  * PARAMETERS:  None
 163  *
 164  * RETURN:      The new state object. NULL on failure.
 165  *
 166  * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
 167  *              the global state cache;  If none available, create a new one.
 168  *
 169  ******************************************************************************/
 170 
 171 ACPI_GENERIC_STATE *
 172 AcpiUtCreateGenericState (
 173     void)
 174 {
 175     ACPI_GENERIC_STATE      *State;
 176 
 177 
 178     ACPI_FUNCTION_ENTRY ();
 179 
 180 
 181     State = AcpiOsAcquireObject (AcpiGbl_StateCache);
 182     if (State)
 183     {
 184         /* Initialize */
 185         State->Common.DescriptorType = ACPI_DESC_TYPE_STATE;
 186     }
 187 
 188     return (State);
 189 }
 190 
 191 
 192 /*******************************************************************************
 193  *
 194  * FUNCTION:    AcpiUtCreateThreadState
 195  *
 196  * PARAMETERS:  None
 197  *
 198  * RETURN:      New Thread State. NULL on failure
 199  *
 200  * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
 201  *              to track per-thread info during method execution
 202  *
 203  ******************************************************************************/
 204 
 205 ACPI_THREAD_STATE *
 206 AcpiUtCreateThreadState (
 207     void)
 208 {
 209     ACPI_GENERIC_STATE      *State;
 210 
 211 
 212     ACPI_FUNCTION_TRACE (UtCreateThreadState);
 213 
 214 
 215     /* Create the generic state object */
 216 
 217     State = AcpiUtCreateGenericState ();
 218     if (!State)
 219     {
 220         return_PTR (NULL);
 221     }
 222 
 223     /* Init fields specific to the update struct */
 224 
 225     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_THREAD;
 226     State->Thread.ThreadId = AcpiOsGetThreadId ();
 227 
 228     /* Check for invalid thread ID - zero is very bad, it will break things */
 229 
 230     if (!State->Thread.ThreadId)
 231     {
 232         ACPI_ERROR ((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
 233         State->Thread.ThreadId = (ACPI_THREAD_ID) 1;
 234     }
 235 
 236     return_PTR ((ACPI_THREAD_STATE *) State);
 237 }
 238 
 239 
 240 /*******************************************************************************
 241  *
 242  * FUNCTION:    AcpiUtCreateUpdateState
 243  *
 244  * PARAMETERS:  Object          - Initial Object to be installed in the state
 245  *              Action          - Update action to be performed
 246  *
 247  * RETURN:      New state object, null on failure
 248  *
 249  * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
 250  *              to update reference counts and delete complex objects such
 251  *              as packages.
 252  *
 253  ******************************************************************************/
 254 
 255 ACPI_GENERIC_STATE *
 256 AcpiUtCreateUpdateState (
 257     ACPI_OPERAND_OBJECT     *Object,
 258     UINT16                  Action)
 259 {
 260     ACPI_GENERIC_STATE      *State;
 261 
 262 
 263     ACPI_FUNCTION_TRACE_PTR (UtCreateUpdateState, Object);
 264 
 265 
 266     /* Create the generic state object */
 267 
 268     State = AcpiUtCreateGenericState ();
 269     if (!State)
 270     {
 271         return_PTR (NULL);
 272     }
 273 
 274     /* Init fields specific to the update struct */
 275 
 276     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_UPDATE;
 277     State->Update.Object = Object;
 278     State->Update.Value = Action;
 279 
 280     return_PTR (State);
 281 }
 282 
 283 
 284 /*******************************************************************************
 285  *
 286  * FUNCTION:    AcpiUtCreatePkgState
 287  *
 288  * PARAMETERS:  Object          - Initial Object to be installed in the state
 289  *              Action          - Update action to be performed
 290  *
 291  * RETURN:      New state object, null on failure
 292  *
 293  * DESCRIPTION: Create a "Package State"
 294  *
 295  ******************************************************************************/
 296 
 297 ACPI_GENERIC_STATE *
 298 AcpiUtCreatePkgState (
 299     void                    *InternalObject,
 300     void                    *ExternalObject,
 301     UINT16                  Index)
 302 {
 303     ACPI_GENERIC_STATE      *State;
 304 
 305 
 306     ACPI_FUNCTION_TRACE_PTR (UtCreatePkgState, InternalObject);
 307 
 308 
 309     /* Create the generic state object */
 310 
 311     State = AcpiUtCreateGenericState ();
 312     if (!State)
 313     {
 314         return_PTR (NULL);
 315     }
 316 
 317     /* Init fields specific to the update struct */
 318 
 319     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_PACKAGE;
 320     State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject;
 321     State->Pkg.DestObject = ExternalObject;
 322     State->Pkg.Index= Index;
 323     State->Pkg.NumPackages = 1;
 324 
 325     return_PTR (State);
 326 }
 327 
 328 
 329 /*******************************************************************************
 330  *
 331  * FUNCTION:    AcpiUtCreateControlState
 332  *
 333  * PARAMETERS:  None
 334  *
 335  * RETURN:      New state object, null on failure
 336  *
 337  * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
 338  *              to support nested IF/WHILE constructs in the AML.
 339  *
 340  ******************************************************************************/
 341 
 342 ACPI_GENERIC_STATE *
 343 AcpiUtCreateControlState (
 344     void)
 345 {
 346     ACPI_GENERIC_STATE      *State;
 347 
 348 
 349     ACPI_FUNCTION_TRACE (UtCreateControlState);
 350 
 351 
 352     /* Create the generic state object */
 353 
 354     State = AcpiUtCreateGenericState ();
 355     if (!State)
 356     {
 357         return_PTR (NULL);
 358     }
 359 
 360     /* Init fields specific to the control struct */
 361 
 362     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_CONTROL;
 363     State->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING;
 364 
 365     return_PTR (State);
 366 }
 367 
 368 
 369 /*******************************************************************************
 370  *
 371  * FUNCTION:    AcpiUtDeleteGenericState
 372  *
 373  * PARAMETERS:  State               - The state object to be deleted
 374  *
 375  * RETURN:      None
 376  *
 377  * DESCRIPTION: Release a state object to the state cache. NULL state objects
 378  *              are ignored.
 379  *
 380  ******************************************************************************/
 381 
 382 void
 383 AcpiUtDeleteGenericState (
 384     ACPI_GENERIC_STATE      *State)
 385 {
 386     ACPI_FUNCTION_TRACE (UtDeleteGenericState);
 387 
 388 
 389     /* Ignore null state */
 390 
 391     if (State)
 392     {
 393         (void) AcpiOsReleaseObject (AcpiGbl_StateCache, State);
 394     }
 395     return_VOID;
 396 }
 397 
 398