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 
  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_ENTRY ();
 111 
 112 
 113     /* Push the state object onto the front of the list (stack) */
 114 
 115     State->Common.Next = *ListHead;
 116     *ListHead = State;
 117     return;
 118 }
 119 
 120 
 121 /*******************************************************************************
 122  *
 123  * FUNCTION:    AcpiUtPopGenericState
 124  *
 125  * PARAMETERS:  ListHead            - Head of the state stack
 126  *
 127  * RETURN:      The popped state object
 128  *
 129  * DESCRIPTION: Pop a state object from a state stack
 130  *
 131  ******************************************************************************/
 132 
 133 ACPI_GENERIC_STATE *
 134 AcpiUtPopGenericState (
 135     ACPI_GENERIC_STATE      **ListHead)
 136 {
 137     ACPI_GENERIC_STATE      *State;
 138 
 139 
 140     ACPI_FUNCTION_ENTRY ();
 141 
 142 
 143     /* Remove the state object at the head of the list (stack) */
 144 
 145     State = *ListHead;
 146     if (State)
 147     {
 148         /* Update the list head */
 149 
 150         *ListHead = State->Common.Next;
 151     }
 152 
 153     return (State);
 154 }
 155 
 156 
 157 /*******************************************************************************
 158  *
 159  * FUNCTION:    AcpiUtCreateGenericState
 160  *
 161  * PARAMETERS:  None
 162  *
 163  * RETURN:      The new state object. NULL on failure.
 164  *
 165  * DESCRIPTION: Create a generic state object. Attempt to obtain one from
 166  *              the global state cache;  If none available, create a new one.
 167  *
 168  ******************************************************************************/
 169 
 170 ACPI_GENERIC_STATE *
 171 AcpiUtCreateGenericState (
 172     void)
 173 {
 174     ACPI_GENERIC_STATE      *State;
 175 
 176 
 177     ACPI_FUNCTION_ENTRY ();
 178 
 179 
 180     State = AcpiOsAcquireObject (AcpiGbl_StateCache);
 181     if (State)
 182     {
 183         /* Initialize */
 184         State->Common.DescriptorType = ACPI_DESC_TYPE_STATE;
 185     }
 186 
 187     return (State);
 188 }
 189 
 190 
 191 /*******************************************************************************
 192  *
 193  * FUNCTION:    AcpiUtCreateThreadState
 194  *
 195  * PARAMETERS:  None
 196  *
 197  * RETURN:      New Thread State. NULL on failure
 198  *
 199  * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
 200  *              to track per-thread info during method execution
 201  *
 202  ******************************************************************************/
 203 
 204 ACPI_THREAD_STATE *
 205 AcpiUtCreateThreadState (
 206     void)
 207 {
 208     ACPI_GENERIC_STATE      *State;
 209 
 210 
 211     ACPI_FUNCTION_ENTRY ();
 212 
 213 
 214     /* Create the generic state object */
 215 
 216     State = AcpiUtCreateGenericState ();
 217     if (!State)
 218     {
 219         return (NULL);
 220     }
 221 
 222     /* Init fields specific to the update struct */
 223 
 224     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_THREAD;
 225     State->Thread.ThreadId = AcpiOsGetThreadId ();
 226 
 227     /* Check for invalid thread ID - zero is very bad, it will break things */
 228 
 229     if (!State->Thread.ThreadId)
 230     {
 231         ACPI_ERROR ((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
 232         State->Thread.ThreadId = (ACPI_THREAD_ID) 1;
 233     }
 234 
 235     return ((ACPI_THREAD_STATE *) State);
 236 }
 237 
 238 
 239 /*******************************************************************************
 240  *
 241  * FUNCTION:    AcpiUtCreateUpdateState
 242  *
 243  * PARAMETERS:  Object          - Initial Object to be installed in the state
 244  *              Action          - Update action to be performed
 245  *
 246  * RETURN:      New state object, null on failure
 247  *
 248  * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
 249  *              to update reference counts and delete complex objects such
 250  *              as packages.
 251  *
 252  ******************************************************************************/
 253 
 254 ACPI_GENERIC_STATE *
 255 AcpiUtCreateUpdateState (
 256     ACPI_OPERAND_OBJECT     *Object,
 257     UINT16                  Action)
 258 {
 259     ACPI_GENERIC_STATE      *State;
 260 
 261 
 262     ACPI_FUNCTION_ENTRY ();
 263 
 264 
 265     /* Create the generic state object */
 266 
 267     State = AcpiUtCreateGenericState ();
 268     if (!State)
 269     {
 270         return (NULL);
 271     }
 272 
 273     /* Init fields specific to the update struct */
 274 
 275     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_UPDATE;
 276     State->Update.Object = Object;
 277     State->Update.Value = Action;
 278     return (State);
 279 }
 280 
 281 
 282 /*******************************************************************************
 283  *
 284  * FUNCTION:    AcpiUtCreatePkgState
 285  *
 286  * PARAMETERS:  Object          - Initial Object to be installed in the state
 287  *              Action          - Update action to be performed
 288  *
 289  * RETURN:      New state object, null on failure
 290  *
 291  * DESCRIPTION: Create a "Package State"
 292  *
 293  ******************************************************************************/
 294 
 295 ACPI_GENERIC_STATE *
 296 AcpiUtCreatePkgState (
 297     void                    *InternalObject,
 298     void                    *ExternalObject,
 299     UINT16                  Index)
 300 {
 301     ACPI_GENERIC_STATE      *State;
 302 
 303 
 304     ACPI_FUNCTION_ENTRY ();
 305 
 306 
 307     /* Create the generic state object */
 308 
 309     State = AcpiUtCreateGenericState ();
 310     if (!State)
 311     {
 312         return (NULL);
 313     }
 314 
 315     /* Init fields specific to the update struct */
 316 
 317     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_PACKAGE;
 318     State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject;
 319     State->Pkg.DestObject = ExternalObject;
 320     State->Pkg.Index= Index;
 321     State->Pkg.NumPackages = 1;
 322     return (State);
 323 }
 324 
 325 
 326 /*******************************************************************************
 327  *
 328  * FUNCTION:    AcpiUtCreateControlState
 329  *
 330  * PARAMETERS:  None
 331  *
 332  * RETURN:      New state object, null on failure
 333  *
 334  * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
 335  *              to support nested IF/WHILE constructs in the AML.
 336  *
 337  ******************************************************************************/
 338 
 339 ACPI_GENERIC_STATE *
 340 AcpiUtCreateControlState (
 341     void)
 342 {
 343     ACPI_GENERIC_STATE      *State;
 344 
 345 
 346     ACPI_FUNCTION_ENTRY ();
 347 
 348 
 349     /* Create the generic state object */
 350 
 351     State = AcpiUtCreateGenericState ();
 352     if (!State)
 353     {
 354         return (NULL);
 355     }
 356 
 357     /* Init fields specific to the control struct */
 358 
 359     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_CONTROL;
 360     State->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING;
 361     return (State);
 362 }
 363 
 364 
 365 /*******************************************************************************
 366  *
 367  * FUNCTION:    AcpiUtDeleteGenericState
 368  *
 369  * PARAMETERS:  State               - The state object to be deleted
 370  *
 371  * RETURN:      None
 372  *
 373  * DESCRIPTION: Release a state object to the state cache. NULL state objects
 374  *              are ignored.
 375  *
 376  ******************************************************************************/
 377 
 378 void
 379 AcpiUtDeleteGenericState (
 380     ACPI_GENERIC_STATE      *State)
 381 {
 382     ACPI_FUNCTION_ENTRY ();
 383 
 384 
 385     /* Ignore null state */
 386 
 387     if (State)
 388     {
 389         (void) AcpiOsReleaseObject (AcpiGbl_StateCache, State);
 390     }
 391     return;
 392 }