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 <contrib/dev/acpica/include/acpi.h>
48#include <contrib/dev/acpica/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
68ACPI_STATUS
69AcpiUtCreatePkgStateAndPush (
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
105void
106AcpiUtPushGenericState (
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
134ACPI_GENERIC_STATE *
135AcpiUtPopGenericState (
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
171ACPI_GENERIC_STATE *
172AcpiUtCreateGenericState (
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
205ACPI_THREAD_STATE *
206AcpiUtCreateThreadState (
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
255ACPI_GENERIC_STATE *
256AcpiUtCreateUpdateState (
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
297ACPI_GENERIC_STATE *
298AcpiUtCreatePkgState (
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
342ACPI_GENERIC_STATE *
343AcpiUtCreateControlState (
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
382void
383AcpiUtDeleteGenericState (
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
399