1/*******************************************************************************
2 *
3 * Module Name: utstate - state object support procedures
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2013, 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_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
133ACPI_GENERIC_STATE *
134AcpiUtPopGenericState (
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
170ACPI_GENERIC_STATE *
171AcpiUtCreateGenericState (
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
204ACPI_THREAD_STATE *
205AcpiUtCreateThreadState (
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
254ACPI_GENERIC_STATE *
255AcpiUtCreateUpdateState (
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
295ACPI_GENERIC_STATE *
296AcpiUtCreatePkgState (
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
339ACPI_GENERIC_STATE *
340AcpiUtCreateControlState (
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
378void
379AcpiUtDeleteGenericState (
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}
393