utmisc.c revision 87031
1/*******************************************************************************
2 *
3 * Module Name: utmisc - common utility procedures
4 *              $Revision: 56 $
5 *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights.  You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code.  No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision.  In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change.  Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee.  Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution.  In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117
118#define __UTMISC_C__
119
120#include "acpi.h"
121#include "acevents.h"
122#include "achware.h"
123#include "acnamesp.h"
124#include "acinterp.h"
125#include "amlcode.h"
126#include "acdebug.h"
127
128
129#define _COMPONENT          ACPI_UTILITIES
130        MODULE_NAME         ("utmisc")
131
132
133/*******************************************************************************
134 *
135 * FUNCTION:    AcpiUtValidAcpiName
136 *
137 * PARAMETERS:  Character           - The character to be examined
138 *
139 * RETURN:      1 if Character may appear in a name, else 0
140 *
141 * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
142 *              1) Upper case alpha
143 *              2) numeric
144 *              3) underscore
145 *
146 ******************************************************************************/
147
148BOOLEAN
149AcpiUtValidAcpiName (
150    UINT32                  Name)
151{
152    NATIVE_CHAR             *NamePtr = (NATIVE_CHAR *) &Name;
153    UINT32                  i;
154
155
156    FUNCTION_ENTRY ();
157
158
159    for (i = 0; i < ACPI_NAME_SIZE; i++)
160    {
161        if (!((NamePtr[i] == '_') ||
162              (NamePtr[i] >= 'A' && NamePtr[i] <= 'Z') ||
163              (NamePtr[i] >= '0' && NamePtr[i] <= '9')))
164        {
165            return (FALSE);
166        }
167    }
168
169    return (TRUE);
170}
171
172
173/*******************************************************************************
174 *
175 * FUNCTION:    AcpiUtValidAcpiCharacter
176 *
177 * PARAMETERS:  Character           - The character to be examined
178 *
179 * RETURN:      1 if Character may appear in a name, else 0
180 *
181 * DESCRIPTION: Check for a printable character
182 *
183 ******************************************************************************/
184
185BOOLEAN
186AcpiUtValidAcpiCharacter (
187    NATIVE_CHAR             Character)
188{
189
190    FUNCTION_ENTRY ();
191
192    return ((BOOLEAN)   ((Character == '_') ||
193                        (Character >= 'A' && Character <= 'Z') ||
194                        (Character >= '0' && Character <= '9')));
195}
196
197
198/*******************************************************************************
199 *
200 * FUNCTION:    AcpiUtStrupr
201 *
202 * PARAMETERS:  SrcString       - The source string to convert to
203 *
204 * RETURN:      SrcString
205 *
206 * DESCRIPTION: Convert string to uppercase
207 *
208 ******************************************************************************/
209
210NATIVE_CHAR *
211AcpiUtStrupr (
212    NATIVE_CHAR             *SrcString)
213{
214    NATIVE_CHAR             *String;
215
216
217    FUNCTION_ENTRY ();
218
219
220    /* Walk entire string, uppercasing the letters */
221
222    for (String = SrcString; *String; )
223    {
224        *String = (char) TOUPPER (*String);
225        String++;
226    }
227
228
229    return (SrcString);
230}
231
232/*******************************************************************************
233 *
234 * FUNCTION:    AcpiUtMutexInitialize
235 *
236 * PARAMETERS:  None.
237 *
238 * RETURN:      Status
239 *
240 * DESCRIPTION: Create the system mutex objects.
241 *
242 ******************************************************************************/
243
244ACPI_STATUS
245AcpiUtMutexInitialize (
246    void)
247{
248    UINT32                  i;
249    ACPI_STATUS             Status;
250
251
252    FUNCTION_TRACE ("UtMutexInitialize");
253
254
255    /*
256     * Create each of the predefined mutex objects
257     */
258    for (i = 0; i < NUM_MTX; i++)
259    {
260        Status = AcpiUtCreateMutex (i);
261        if (ACPI_FAILURE (Status))
262        {
263            return_ACPI_STATUS (Status);
264        }
265    }
266
267    return_ACPI_STATUS (AE_OK);
268}
269
270
271/*******************************************************************************
272 *
273 * FUNCTION:    AcpiUtMutexTerminate
274 *
275 * PARAMETERS:  None.
276 *
277 * RETURN:      None.
278 *
279 * DESCRIPTION: Delete all of the system mutex objects.
280 *
281 ******************************************************************************/
282
283void
284AcpiUtMutexTerminate (
285    void)
286{
287    UINT32                  i;
288
289
290    FUNCTION_TRACE ("UtMutexTerminate");
291
292
293    /*
294     * Delete each predefined mutex object
295     */
296    for (i = 0; i < NUM_MTX; i++)
297    {
298        AcpiUtDeleteMutex (i);
299    }
300
301    return_VOID;
302}
303
304
305/*******************************************************************************
306 *
307 * FUNCTION:    AcpiUtCreateMutex
308 *
309 * PARAMETERS:  MutexID         - ID of the mutex to be created
310 *
311 * RETURN:      Status
312 *
313 * DESCRIPTION: Create a mutex object.
314 *
315 ******************************************************************************/
316
317ACPI_STATUS
318AcpiUtCreateMutex (
319    ACPI_MUTEX_HANDLE       MutexId)
320{
321    ACPI_STATUS             Status = AE_OK;
322
323
324    FUNCTION_TRACE_U32 ("UtCreateMutex", MutexId);
325
326
327    if (MutexId > MAX_MTX)
328    {
329        return_ACPI_STATUS (AE_BAD_PARAMETER);
330    }
331
332
333    if (!AcpiGbl_AcpiMutexInfo[MutexId].Mutex)
334    {
335        Status = AcpiOsCreateSemaphore (1, 1,
336                        &AcpiGbl_AcpiMutexInfo[MutexId].Mutex);
337        AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED;
338        AcpiGbl_AcpiMutexInfo[MutexId].UseCount = 0;
339    }
340
341    return_ACPI_STATUS (Status);
342}
343
344
345/*******************************************************************************
346 *
347 * FUNCTION:    AcpiUtDeleteMutex
348 *
349 * PARAMETERS:  MutexID         - ID of the mutex to be deleted
350 *
351 * RETURN:      Status
352 *
353 * DESCRIPTION: Delete a mutex object.
354 *
355 ******************************************************************************/
356
357ACPI_STATUS
358AcpiUtDeleteMutex (
359    ACPI_MUTEX_HANDLE       MutexId)
360{
361    ACPI_STATUS             Status;
362
363
364    FUNCTION_TRACE_U32 ("UtDeleteMutex", MutexId);
365
366
367    if (MutexId > MAX_MTX)
368    {
369        return_ACPI_STATUS (AE_BAD_PARAMETER);
370    }
371
372
373    Status = AcpiOsDeleteSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex);
374
375    AcpiGbl_AcpiMutexInfo[MutexId].Mutex = NULL;
376    AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED;
377
378    return_ACPI_STATUS (Status);
379}
380
381
382/*******************************************************************************
383 *
384 * FUNCTION:    AcpiUtAcquireMutex
385 *
386 * PARAMETERS:  MutexID         - ID of the mutex to be acquired
387 *
388 * RETURN:      Status
389 *
390 * DESCRIPTION: Acquire a mutex object.
391 *
392 ******************************************************************************/
393
394ACPI_STATUS
395AcpiUtAcquireMutex (
396    ACPI_MUTEX_HANDLE       MutexId)
397{
398    ACPI_STATUS             Status;
399    UINT32                  i;
400    UINT32                  ThisThreadId;
401
402
403    PROC_NAME ("UtAcquireMutex");
404
405
406    if (MutexId > MAX_MTX)
407    {
408        return (AE_BAD_PARAMETER);
409    }
410
411
412    ThisThreadId = AcpiOsGetThreadId ();
413
414    /*
415     * Deadlock prevention.  Check if this thread owns any mutexes of value
416     * greater than or equal to this one.  If so, the thread has violated
417     * the mutex ordering rule.  This indicates a coding error somewhere in
418     * the ACPI subsystem code.
419     */
420    for (i = MutexId; i < MAX_MTX; i++)
421    {
422        if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId)
423        {
424            if (i == MutexId)
425            {
426                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
427                        "Mutex [%s] already acquired by this thread [%X]\n",
428                        AcpiUtGetMutexName (MutexId), ThisThreadId));
429
430                return (AE_ALREADY_ACQUIRED);
431            }
432
433            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
434                    "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
435                    ThisThreadId, AcpiUtGetMutexName (i),
436                    AcpiUtGetMutexName (MutexId)));
437
438            return (AE_ACQUIRE_DEADLOCK);
439        }
440    }
441
442
443    ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
444                "Thread %X attempting to acquire Mutex [%s]\n",
445                ThisThreadId, AcpiUtGetMutexName (MutexId)));
446
447    Status = AcpiOsWaitSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex,
448                                    1, WAIT_FOREVER);
449
450    if (ACPI_SUCCESS (Status))
451    {
452        ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
453                    ThisThreadId, AcpiUtGetMutexName (MutexId)));
454
455        AcpiGbl_AcpiMutexInfo[MutexId].UseCount++;
456        AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ThisThreadId;
457    }
458
459    else
460    {
461        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
462                    ThisThreadId, AcpiUtGetMutexName (MutexId),
463                    AcpiFormatException (Status)));
464    }
465
466    return (Status);
467}
468
469
470/*******************************************************************************
471 *
472 * FUNCTION:    AcpiUtReleaseMutex
473 *
474 * PARAMETERS:  MutexID         - ID of the mutex to be released
475 *
476 * RETURN:      Status
477 *
478 * DESCRIPTION: Release a mutex object.
479 *
480 ******************************************************************************/
481
482ACPI_STATUS
483AcpiUtReleaseMutex (
484    ACPI_MUTEX_HANDLE       MutexId)
485{
486    ACPI_STATUS             Status;
487    UINT32                  i;
488    UINT32                  ThisThreadId;
489
490
491    PROC_NAME ("UtReleaseMutex");
492
493
494    ThisThreadId = AcpiOsGetThreadId ();
495    ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
496        "Thread %X releasing Mutex [%s]\n", ThisThreadId,
497        AcpiUtGetMutexName (MutexId)));
498
499    if (MutexId > MAX_MTX)
500    {
501        return (AE_BAD_PARAMETER);
502    }
503
504
505    /*
506     * Mutex must be acquired in order to release it!
507     */
508    if (AcpiGbl_AcpiMutexInfo[MutexId].OwnerId == ACPI_MUTEX_NOT_ACQUIRED)
509    {
510        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
511                "Mutex [%s] is not acquired, cannot release\n",
512                AcpiUtGetMutexName (MutexId)));
513
514        return (AE_NOT_ACQUIRED);
515    }
516
517
518    /*
519     * Deadlock prevention.  Check if this thread owns any mutexes of value
520     * greater than this one.  If so, the thread has violated the mutex
521     * ordering rule.  This indicates a coding error somewhere in
522     * the ACPI subsystem code.
523     */
524    for (i = MutexId; i < MAX_MTX; i++)
525    {
526        if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId)
527        {
528            if (i == MutexId)
529            {
530                continue;
531            }
532
533            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
534                    "Invalid release order: owns [%s], releasing [%s]\n",
535                    AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId)));
536
537            return (AE_RELEASE_DEADLOCK);
538        }
539    }
540
541
542    /* Mark unlocked FIRST */
543
544    AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED;
545
546    Status = AcpiOsSignalSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 1);
547
548    if (ACPI_FAILURE (Status))
549    {
550        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
551                    ThisThreadId, AcpiUtGetMutexName (MutexId),
552                    AcpiFormatException (Status)));
553    }
554    else
555    {
556        ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
557                    ThisThreadId, AcpiUtGetMutexName (MutexId)));
558    }
559
560    return (Status);
561}
562
563
564/*******************************************************************************
565 *
566 * FUNCTION:    AcpiUtCreateUpdateStateAndPush
567 *
568 * PARAMETERS:  *Object         - Object to be added to the new state
569 *              Action          - Increment/Decrement
570 *              StateList       - List the state will be added to
571 *
572 * RETURN:      None
573 *
574 * DESCRIPTION: Create a new state and push it
575 *
576 ******************************************************************************/
577
578ACPI_STATUS
579AcpiUtCreateUpdateStateAndPush (
580    ACPI_OPERAND_OBJECT     *Object,
581    UINT16                  Action,
582    ACPI_GENERIC_STATE      **StateList)
583{
584    ACPI_GENERIC_STATE       *State;
585
586
587    FUNCTION_ENTRY ();
588
589
590    /* Ignore null objects; these are expected */
591
592    if (!Object)
593    {
594        return (AE_OK);
595    }
596
597    State = AcpiUtCreateUpdateState (Object, Action);
598    if (!State)
599    {
600        return (AE_NO_MEMORY);
601    }
602
603
604    AcpiUtPushGenericState (StateList, State);
605    return (AE_OK);
606}
607
608
609/*******************************************************************************
610 *
611 * FUNCTION:    AcpiUtCreatePkgStateAndPush
612 *
613 * PARAMETERS:  *Object         - Object to be added to the new state
614 *              Action          - Increment/Decrement
615 *              StateList       - List the state will be added to
616 *
617 * RETURN:      None
618 *
619 * DESCRIPTION: Create a new state and push it
620 *
621 ******************************************************************************/
622
623ACPI_STATUS
624AcpiUtCreatePkgStateAndPush (
625    void                    *InternalObject,
626    void                    *ExternalObject,
627    UINT16                  Index,
628    ACPI_GENERIC_STATE      **StateList)
629{
630    ACPI_GENERIC_STATE       *State;
631
632
633    FUNCTION_ENTRY ();
634
635
636    State = AcpiUtCreatePkgState (InternalObject, ExternalObject, Index);
637    if (!State)
638    {
639        return (AE_NO_MEMORY);
640    }
641
642
643    AcpiUtPushGenericState (StateList, State);
644    return (AE_OK);
645}
646
647
648/*******************************************************************************
649 *
650 * FUNCTION:    AcpiUtPushGenericState
651 *
652 * PARAMETERS:  ListHead            - Head of the state stack
653 *              State               - State object to push
654 *
655 * RETURN:      Status
656 *
657 * DESCRIPTION: Push a state object onto a state stack
658 *
659 ******************************************************************************/
660
661void
662AcpiUtPushGenericState (
663    ACPI_GENERIC_STATE      **ListHead,
664    ACPI_GENERIC_STATE      *State)
665{
666    FUNCTION_TRACE ("UtPushGenericState");
667
668
669    /* Push the state object onto the front of the list (stack) */
670
671    State->Common.Next = *ListHead;
672    *ListHead = State;
673
674    return_VOID;
675}
676
677
678/*******************************************************************************
679 *
680 * FUNCTION:    AcpiUtPopGenericState
681 *
682 * PARAMETERS:  ListHead            - Head of the state stack
683 *
684 * RETURN:      Status
685 *
686 * DESCRIPTION: Pop a state object from a state stack
687 *
688 ******************************************************************************/
689
690ACPI_GENERIC_STATE *
691AcpiUtPopGenericState (
692    ACPI_GENERIC_STATE      **ListHead)
693{
694    ACPI_GENERIC_STATE      *State;
695
696
697    FUNCTION_TRACE ("UtPopGenericState");
698
699
700    /* Remove the state object at the head of the list (stack) */
701
702    State = *ListHead;
703    if (State)
704    {
705        /* Update the list head */
706
707        *ListHead = State->Common.Next;
708    }
709
710    return_PTR (State);
711}
712
713
714/*******************************************************************************
715 *
716 * FUNCTION:    AcpiUtCreateGenericState
717 *
718 * PARAMETERS:  None
719 *
720 * RETURN:      Status
721 *
722 * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
723 *              the global state cache;  If none available, create a new one.
724 *
725 ******************************************************************************/
726
727ACPI_GENERIC_STATE *
728AcpiUtCreateGenericState (void)
729{
730    ACPI_GENERIC_STATE      *State;
731
732
733    FUNCTION_ENTRY ();
734
735
736    State = AcpiUtAcquireFromCache (ACPI_MEM_LIST_STATE);
737
738    /* Initialize */
739
740    if (State)
741    {
742        State->Common.DataType = ACPI_DESC_TYPE_STATE;
743    }
744
745    return (State);
746}
747
748
749/*******************************************************************************
750 *
751 * FUNCTION:    AcpiUtCreateThreadState
752 *
753 * PARAMETERS:  None
754 *
755 * RETURN:      Thread State
756 *
757 * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
758 *              to track per-thread info during method execution
759 *
760 ******************************************************************************/
761
762ACPI_THREAD_STATE *
763AcpiUtCreateThreadState (
764    void)
765{
766    ACPI_GENERIC_STATE      *State;
767
768
769    FUNCTION_TRACE ("UtCreateThreadState");
770
771
772    /* Create the generic state object */
773
774    State = AcpiUtCreateGenericState ();
775    if (!State)
776    {
777        return_PTR (NULL);
778    }
779
780    /* Init fields specific to the update struct */
781
782    State->Common.DataType = ACPI_DESC_TYPE_STATE_THREAD;
783    State->Thread.ThreadId = AcpiOsGetThreadId ();
784
785    return_PTR ((ACPI_THREAD_STATE *) State);
786}
787
788
789/*******************************************************************************
790 *
791 * FUNCTION:    AcpiUtCreateUpdateState
792 *
793 * PARAMETERS:  Object              - Initial Object to be installed in the
794 *                                    state
795 *              Action              - Update action to be performed
796 *
797 * RETURN:      Status
798 *
799 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
800 *              to update reference counts and delete complex objects such
801 *              as packages.
802 *
803 ******************************************************************************/
804
805ACPI_GENERIC_STATE *
806AcpiUtCreateUpdateState (
807    ACPI_OPERAND_OBJECT     *Object,
808    UINT16                  Action)
809{
810    ACPI_GENERIC_STATE      *State;
811
812
813    FUNCTION_TRACE_PTR ("UtCreateUpdateState", Object);
814
815
816    /* Create the generic state object */
817
818    State = AcpiUtCreateGenericState ();
819    if (!State)
820    {
821        return_PTR (NULL);
822    }
823
824    /* Init fields specific to the update struct */
825
826    State->Common.DataType = ACPI_DESC_TYPE_STATE_UPDATE;
827    State->Update.Object = Object;
828    State->Update.Value  = Action;
829
830    return_PTR (State);
831}
832
833
834/*******************************************************************************
835 *
836 * FUNCTION:    AcpiUtCreatePkgState
837 *
838 * PARAMETERS:  Object              - Initial Object to be installed in the
839 *                                    state
840 *              Action              - Update action to be performed
841 *
842 * RETURN:      Status
843 *
844 * DESCRIPTION: Create a "Package State"
845 *
846 ******************************************************************************/
847
848ACPI_GENERIC_STATE *
849AcpiUtCreatePkgState (
850    void                    *InternalObject,
851    void                    *ExternalObject,
852    UINT16                  Index)
853{
854    ACPI_GENERIC_STATE      *State;
855
856
857    FUNCTION_TRACE_PTR ("UtCreatePkgState", InternalObject);
858
859
860    /* Create the generic state object */
861
862    State = AcpiUtCreateGenericState ();
863    if (!State)
864    {
865        return_PTR (NULL);
866    }
867
868    /* Init fields specific to the update struct */
869
870    State->Common.DataType  = ACPI_DESC_TYPE_STATE_PACKAGE;
871    State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject;
872    State->Pkg.DestObject   = ExternalObject;
873    State->Pkg.Index        = Index;
874    State->Pkg.NumPackages  = 1;
875
876    return_PTR (State);
877}
878
879
880/*******************************************************************************
881 *
882 * FUNCTION:    AcpiUtCreateControlState
883 *
884 * PARAMETERS:  None
885 *
886 * RETURN:      Status
887 *
888 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
889 *              to support nested IF/WHILE constructs in the AML.
890 *
891 ******************************************************************************/
892
893ACPI_GENERIC_STATE *
894AcpiUtCreateControlState (
895    void)
896{
897    ACPI_GENERIC_STATE      *State;
898
899
900    FUNCTION_TRACE ("UtCreateControlState");
901
902
903    /* Create the generic state object */
904
905    State = AcpiUtCreateGenericState ();
906    if (!State)
907    {
908        return_PTR (NULL);
909    }
910
911
912    /* Init fields specific to the control struct */
913
914    State->Common.DataType  = ACPI_DESC_TYPE_STATE_CONTROL;
915    State->Common.State     = CONTROL_CONDITIONAL_EXECUTING;
916
917    return_PTR (State);
918}
919
920
921/*******************************************************************************
922 *
923 * FUNCTION:    AcpiUtDeleteGenericState
924 *
925 * PARAMETERS:  State               - The state object to be deleted
926 *
927 * RETURN:      Status
928 *
929 * DESCRIPTION: Put a state object back into the global state cache.  The object
930 *              is not actually freed at this time.
931 *
932 ******************************************************************************/
933
934void
935AcpiUtDeleteGenericState (
936    ACPI_GENERIC_STATE      *State)
937{
938    FUNCTION_TRACE ("UtDeleteGenericState");
939
940
941    AcpiUtReleaseToCache (ACPI_MEM_LIST_STATE, State);
942    return_VOID;
943}
944
945
946/*******************************************************************************
947 *
948 * FUNCTION:    AcpiUtDeleteGenericStateCache
949 *
950 * PARAMETERS:  None
951 *
952 * RETURN:      Status
953 *
954 * DESCRIPTION: Purge the global state object cache.  Used during subsystem
955 *              termination.
956 *
957 ******************************************************************************/
958
959void
960AcpiUtDeleteGenericStateCache (
961    void)
962{
963    FUNCTION_TRACE ("UtDeleteGenericStateCache");
964
965
966    AcpiUtDeleteGenericCache (ACPI_MEM_LIST_STATE);
967    return_VOID;
968}
969
970
971/*******************************************************************************
972 *
973 * FUNCTION:    AcpiUtResolvePackageReferences
974 *
975 * PARAMETERS:  ObjDesc         - The Package object on which to resolve refs
976 *
977 * RETURN:      Status
978 *
979 * DESCRIPTION: Walk through a package and turn internal references into values
980 *
981 ******************************************************************************/
982
983ACPI_STATUS
984AcpiUtResolvePackageReferences (
985    ACPI_OPERAND_OBJECT     *ObjDesc)
986{
987    UINT32                  Count;
988    ACPI_OPERAND_OBJECT     *SubObject;
989
990
991    FUNCTION_TRACE ("UtResolvePackageReferences");
992
993
994    if (ObjDesc->Common.Type != ACPI_TYPE_PACKAGE)
995    {
996        /* The object must be a package */
997
998        REPORT_ERROR (("Must resolve Package Refs on a Package\n"));
999        return_ACPI_STATUS(AE_ERROR);
1000    }
1001
1002    /*
1003     * TBD: what about nested packages? */
1004
1005    for (Count = 0; Count < ObjDesc->Package.Count; Count++)
1006    {
1007        SubObject = ObjDesc->Package.Elements[Count];
1008
1009        if (SubObject->Common.Type == INTERNAL_TYPE_REFERENCE)
1010        {
1011            if (SubObject->Reference.Opcode == AML_ZERO_OP)
1012            {
1013                SubObject->Common.Type  = ACPI_TYPE_INTEGER;
1014                SubObject->Integer.Value = 0;
1015            }
1016
1017            else if (SubObject->Reference.Opcode == AML_ONE_OP)
1018            {
1019                SubObject->Common.Type  = ACPI_TYPE_INTEGER;
1020                SubObject->Integer.Value = 1;
1021            }
1022
1023            else if (SubObject->Reference.Opcode == AML_ONES_OP)
1024            {
1025                SubObject->Common.Type  = ACPI_TYPE_INTEGER;
1026                SubObject->Integer.Value = ACPI_INTEGER_MAX;
1027            }
1028        }
1029    }
1030
1031    return_ACPI_STATUS(AE_OK);
1032}
1033
1034#ifdef ACPI_DEBUG
1035
1036/*******************************************************************************
1037 *
1038 * FUNCTION:    AcpiUtDisplayInitPathname
1039 *
1040 * PARAMETERS:  ObjHandle           - Handle whose pathname will be displayed
1041 *              Path                - Additional path string to be appended
1042 *
1043 * RETURN:      ACPI_STATUS
1044 *
1045 * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY
1046 *
1047 ******************************************************************************/
1048
1049void
1050AcpiUtDisplayInitPathname (
1051    ACPI_HANDLE             ObjHandle,
1052    char                    *Path)
1053{
1054    ACPI_STATUS             Status;
1055    UINT32                  Length = 128;
1056    char                    Buffer[128];
1057
1058
1059    PROC_NAME ("UtDisplayInitPathname");
1060
1061
1062    Status = AcpiNsHandleToPathname (ObjHandle, &Length, Buffer);
1063    if (ACPI_SUCCESS (Status))
1064    {
1065        if (Path)
1066        {
1067            ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s.%s\n", Buffer, Path));
1068        }
1069        else
1070        {
1071            ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s\n", Buffer));
1072        }
1073    }
1074}
1075#endif
1076
1077/*******************************************************************************
1078 *
1079 * FUNCTION:    AcpiUtWalkPackageTree
1080 *
1081 * PARAMETERS:  ObjDesc         - The Package object on which to resolve refs
1082 *
1083 * RETURN:      Status
1084 *
1085 * DESCRIPTION: Walk through a package
1086 *
1087 ******************************************************************************/
1088
1089ACPI_STATUS
1090AcpiUtWalkPackageTree (
1091    ACPI_OPERAND_OBJECT     *SourceObject,
1092    void                    *TargetObject,
1093    ACPI_PKG_CALLBACK       WalkCallback,
1094    void                    *Context)
1095{
1096    ACPI_STATUS             Status = AE_OK;
1097    ACPI_GENERIC_STATE      *StateList = NULL;
1098    ACPI_GENERIC_STATE      *State;
1099    UINT32                  ThisIndex;
1100    ACPI_OPERAND_OBJECT     *ThisSourceObj;
1101
1102
1103    FUNCTION_TRACE ("UtWalkPackageTree");
1104
1105
1106    State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
1107    if (!State)
1108    {
1109        return_ACPI_STATUS (AE_NO_MEMORY);
1110    }
1111
1112    while (State)
1113    {
1114        ThisIndex     = State->Pkg.Index;
1115        ThisSourceObj = (ACPI_OPERAND_OBJECT *)
1116                        State->Pkg.SourceObject->Package.Elements[ThisIndex];
1117
1118        /*
1119         * Check for:
1120         * 1) An uninitialized package element.  It is completely
1121         *      legal to declare a package and leave it uninitialized
1122         * 2) Not an internal object - can be a namespace node instead
1123         * 3) Any type other than a package.  Packages are handled in else
1124         *      case below.
1125         */
1126        if ((!ThisSourceObj) ||
1127            (!VALID_DESCRIPTOR_TYPE (
1128                    ThisSourceObj, ACPI_DESC_TYPE_INTERNAL)) ||
1129            (!IS_THIS_OBJECT_TYPE (
1130                    ThisSourceObj, ACPI_TYPE_PACKAGE)))
1131        {
1132
1133            Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
1134                                    State, Context);
1135            if (ACPI_FAILURE (Status))
1136            {
1137                return_ACPI_STATUS (Status);
1138            }
1139
1140            State->Pkg.Index++;
1141            while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
1142            {
1143                /*
1144                 * We've handled all of the objects at this level,  This means
1145                 * that we have just completed a package.  That package may
1146                 * have contained one or more packages itself.
1147                 *
1148                 * Delete this state and pop the previous state (package).
1149                 */
1150                AcpiUtDeleteGenericState (State);
1151                State = AcpiUtPopGenericState (&StateList);
1152
1153                /* Finished when there are no more states */
1154
1155                if (!State)
1156                {
1157                    /*
1158                     * We have handled all of the objects in the top level
1159                     * package just add the length of the package objects
1160                     * and exit
1161                     */
1162                    return_ACPI_STATUS (AE_OK);
1163                }
1164
1165                /*
1166                 * Go back up a level and move the index past the just
1167                 * completed package object.
1168                 */
1169                State->Pkg.Index++;
1170            }
1171        }
1172        else
1173        {
1174            /* This is a subobject of type package */
1175
1176            Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
1177                                        State, Context);
1178            if (ACPI_FAILURE (Status))
1179            {
1180                return_ACPI_STATUS (Status);
1181            }
1182
1183            /*
1184             * Push the current state and create a new one
1185             * The callback above returned a new target package object.
1186             */
1187            AcpiUtPushGenericState (&StateList, State);
1188            State = AcpiUtCreatePkgState (ThisSourceObj,
1189                                            State->Pkg.ThisTargetObj, 0);
1190            if (!State)
1191            {
1192                return_ACPI_STATUS (AE_NO_MEMORY);
1193            }
1194        }
1195    }
1196
1197    /* We should never get here */
1198
1199    return_ACPI_STATUS (AE_AML_INTERNAL);
1200}
1201
1202
1203/*******************************************************************************
1204 *
1205 * FUNCTION:    AcpiUtReportError
1206 *
1207 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1208 *              LineNumber          - Caller's line number (for error output)
1209 *              ComponentId         - Caller's component ID (for error output)
1210 *              Message             - Error message to use on failure
1211 *
1212 * RETURN:      None
1213 *
1214 * DESCRIPTION: Print error message
1215 *
1216 ******************************************************************************/
1217
1218void
1219AcpiUtReportError (
1220    NATIVE_CHAR             *ModuleName,
1221    UINT32                  LineNumber,
1222    UINT32                  ComponentId)
1223{
1224
1225
1226    AcpiOsPrintf ("%8s-%04d: *** Error: ", ModuleName, LineNumber);
1227}
1228
1229
1230/*******************************************************************************
1231 *
1232 * FUNCTION:    AcpiUtReportWarning
1233 *
1234 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1235 *              LineNumber          - Caller's line number (for error output)
1236 *              ComponentId         - Caller's component ID (for error output)
1237 *              Message             - Error message to use on failure
1238 *
1239 * RETURN:      None
1240 *
1241 * DESCRIPTION: Print warning message
1242 *
1243 ******************************************************************************/
1244
1245void
1246AcpiUtReportWarning (
1247    NATIVE_CHAR             *ModuleName,
1248    UINT32                  LineNumber,
1249    UINT32                  ComponentId)
1250{
1251
1252    AcpiOsPrintf ("%8s-%04d: *** Warning: ", ModuleName, LineNumber);
1253}
1254
1255
1256/*******************************************************************************
1257 *
1258 * FUNCTION:    AcpiUtReportInfo
1259 *
1260 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1261 *              LineNumber          - Caller's line number (for error output)
1262 *              ComponentId         - Caller's component ID (for error output)
1263 *              Message             - Error message to use on failure
1264 *
1265 * RETURN:      None
1266 *
1267 * DESCRIPTION: Print information message
1268 *
1269 ******************************************************************************/
1270
1271void
1272AcpiUtReportInfo (
1273    NATIVE_CHAR             *ModuleName,
1274    UINT32                  LineNumber,
1275    UINT32                  ComponentId)
1276{
1277
1278    AcpiOsPrintf ("%8s-%04d: *** Info: ", ModuleName, LineNumber);
1279}
1280
1281
1282