utmisc.c revision 82367
1/*******************************************************************************
2 *
3 * Module Name: utmisc - common utility procedures
4 *              $Revision: 46 $
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    for (i = 0; i < ACPI_NAME_SIZE; i++)
157    {
158        if (!((NamePtr[i] == '_') ||
159              (NamePtr[i] >= 'A' && NamePtr[i] <= 'Z') ||
160              (NamePtr[i] >= '0' && NamePtr[i] <= '9')))
161        {
162            return (FALSE);
163        }
164    }
165
166
167    return (TRUE);
168}
169
170
171/*******************************************************************************
172 *
173 * FUNCTION:    AcpiUtValidAcpiCharacter
174 *
175 * PARAMETERS:  Character           - The character to be examined
176 *
177 * RETURN:      1 if Character may appear in a name, else 0
178 *
179 * DESCRIPTION: Check for a printable character
180 *
181 ******************************************************************************/
182
183BOOLEAN
184AcpiUtValidAcpiCharacter (
185    NATIVE_CHAR             Character)
186{
187
188    return ((BOOLEAN)   ((Character == '_') ||
189                        (Character >= 'A' && Character <= 'Z') ||
190                        (Character >= '0' && Character <= '9')));
191}
192
193/*******************************************************************************
194 *
195 * FUNCTION:    AcpiUtStrupr
196 *
197 * PARAMETERS:  SrcString       - The source string to convert to
198 *
199 * RETURN:      SrcString
200 *
201 * DESCRIPTION: Convert string to uppercase
202 *
203 ******************************************************************************/
204
205NATIVE_CHAR *
206AcpiUtStrupr (
207    NATIVE_CHAR             *SrcString)
208{
209    NATIVE_CHAR             *String;
210
211
212    /* Walk entire string, uppercasing the letters */
213
214    for (String = SrcString; *String; )
215    {
216        *String = (char) TOUPPER (*String);
217        String++;
218    }
219
220
221    return (SrcString);
222}
223
224/*******************************************************************************
225 *
226 * FUNCTION:    AcpiUtMutexInitialize
227 *
228 * PARAMETERS:  None.
229 *
230 * RETURN:      Status
231 *
232 * DESCRIPTION: Create the system mutex objects.
233 *
234 ******************************************************************************/
235
236ACPI_STATUS
237AcpiUtMutexInitialize (
238    void)
239{
240    UINT32                  i;
241    ACPI_STATUS             Status;
242
243
244    FUNCTION_TRACE ("UtMutexInitialize");
245
246
247    /*
248     * Create each of the predefined mutex objects
249     */
250    for (i = 0; i < NUM_MTX; i++)
251    {
252        Status = AcpiUtCreateMutex (i);
253        if (ACPI_FAILURE (Status))
254        {
255            return_ACPI_STATUS (Status);
256        }
257    }
258
259    return_ACPI_STATUS (AE_OK);
260}
261
262
263/*******************************************************************************
264 *
265 * FUNCTION:    AcpiUtMutexTerminate
266 *
267 * PARAMETERS:  None.
268 *
269 * RETURN:      None.
270 *
271 * DESCRIPTION: Delete all of the system mutex objects.
272 *
273 ******************************************************************************/
274
275void
276AcpiUtMutexTerminate (
277    void)
278{
279    UINT32                  i;
280
281
282    FUNCTION_TRACE ("UtMutexTerminate");
283
284
285    /*
286     * Delete each predefined mutex object
287     */
288    for (i = 0; i < NUM_MTX; i++)
289    {
290        AcpiUtDeleteMutex (i);
291    }
292
293    return_VOID;
294}
295
296
297/*******************************************************************************
298 *
299 * FUNCTION:    AcpiUtCreateMutex
300 *
301 * PARAMETERS:  MutexID         - ID of the mutex to be created
302 *
303 * RETURN:      Status
304 *
305 * DESCRIPTION: Create a mutex object.
306 *
307 ******************************************************************************/
308
309ACPI_STATUS
310AcpiUtCreateMutex (
311    ACPI_MUTEX_HANDLE       MutexId)
312{
313    ACPI_STATUS             Status = AE_OK;
314
315
316    FUNCTION_TRACE_U32 ("UtCreateMutex", MutexId);
317
318
319    if (MutexId > MAX_MTX)
320    {
321        return_ACPI_STATUS (AE_BAD_PARAMETER);
322    }
323
324
325    if (!AcpiGbl_AcpiMutexInfo[MutexId].Mutex)
326    {
327        Status = AcpiOsCreateSemaphore (1, 1,
328                        &AcpiGbl_AcpiMutexInfo[MutexId].Mutex);
329        AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED;
330        AcpiGbl_AcpiMutexInfo[MutexId].UseCount = 0;
331    }
332
333    return_ACPI_STATUS (Status);
334}
335
336
337/*******************************************************************************
338 *
339 * FUNCTION:    AcpiUtDeleteMutex
340 *
341 * PARAMETERS:  MutexID         - ID of the mutex to be deleted
342 *
343 * RETURN:      Status
344 *
345 * DESCRIPTION: Delete a mutex object.
346 *
347 ******************************************************************************/
348
349ACPI_STATUS
350AcpiUtDeleteMutex (
351    ACPI_MUTEX_HANDLE       MutexId)
352{
353    ACPI_STATUS             Status;
354
355
356    FUNCTION_TRACE_U32 ("UtDeleteMutex", MutexId);
357
358
359    if (MutexId > MAX_MTX)
360    {
361        return_ACPI_STATUS (AE_BAD_PARAMETER);
362    }
363
364
365    Status = AcpiOsDeleteSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex);
366
367    AcpiGbl_AcpiMutexInfo[MutexId].Mutex = NULL;
368    AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED;
369
370    return_ACPI_STATUS (Status);
371}
372
373
374/*******************************************************************************
375 *
376 * FUNCTION:    AcpiUtAcquireMutex
377 *
378 * PARAMETERS:  MutexID         - ID of the mutex to be acquired
379 *
380 * RETURN:      Status
381 *
382 * DESCRIPTION: Acquire a mutex object.
383 *
384 ******************************************************************************/
385
386ACPI_STATUS
387AcpiUtAcquireMutex (
388    ACPI_MUTEX_HANDLE       MutexId)
389{
390    ACPI_STATUS             Status;
391    UINT32                  i;
392    UINT32                  ThisThreadId;
393
394
395    PROC_NAME ("UtAcquireMutex");
396
397
398    if (MutexId > MAX_MTX)
399    {
400        return (AE_BAD_PARAMETER);
401    }
402
403
404    ThisThreadId = AcpiOsGetThreadId ();
405
406    /*
407     * Deadlock prevention.  Check if this thread owns any mutexes of value
408     * greater than or equal to this one.  If so, the thread has violated
409     * the mutex ordering rule.  This indicates a coding error somewhere in
410     * the ACPI subsystem code.
411     */
412    for (i = MutexId; i < MAX_MTX; i++)
413    {
414        if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId)
415        {
416            if (i == MutexId)
417            {
418                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
419                        "Mutex [%s] already acquired by this thread [%X]\n",
420                        AcpiUtGetMutexName (MutexId), ThisThreadId));
421
422                return (AE_ALREADY_ACQUIRED);
423            }
424
425            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
426                    "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
427                    ThisThreadId, AcpiUtGetMutexName (i),
428                    AcpiUtGetMutexName (MutexId)));
429
430            return (AE_ACQUIRE_DEADLOCK);
431        }
432    }
433
434
435    ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
436                "Thread %X attempting to acquire Mutex [%s]\n",
437                ThisThreadId, AcpiUtGetMutexName (MutexId)));
438
439    Status = AcpiOsWaitSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex,
440                                    1, WAIT_FOREVER);
441
442    if (ACPI_SUCCESS (Status))
443    {
444        ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
445                    ThisThreadId, AcpiUtGetMutexName (MutexId)));
446
447        AcpiGbl_AcpiMutexInfo[MutexId].UseCount++;
448        AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ThisThreadId;
449    }
450
451    else
452    {
453        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
454                    ThisThreadId, AcpiUtGetMutexName (MutexId),
455                    AcpiFormatException (Status)));
456    }
457
458    return (Status);
459}
460
461
462/*******************************************************************************
463 *
464 * FUNCTION:    AcpiUtReleaseMutex
465 *
466 * PARAMETERS:  MutexID         - ID of the mutex to be released
467 *
468 * RETURN:      Status
469 *
470 * DESCRIPTION: Release a mutex object.
471 *
472 ******************************************************************************/
473
474ACPI_STATUS
475AcpiUtReleaseMutex (
476    ACPI_MUTEX_HANDLE       MutexId)
477{
478    ACPI_STATUS             Status;
479    UINT32                  i;
480    UINT32                  ThisThreadId;
481
482
483    PROC_NAME ("UtReleaseMutex");
484
485
486    ThisThreadId = AcpiOsGetThreadId ();
487    ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
488        "Thread %X releasing Mutex [%s]\n", ThisThreadId,
489        AcpiUtGetMutexName (MutexId)));
490
491    if (MutexId > MAX_MTX)
492    {
493        return (AE_BAD_PARAMETER);
494    }
495
496
497    /*
498     * Mutex must be acquired in order to release it!
499     */
500    if (AcpiGbl_AcpiMutexInfo[MutexId].OwnerId == ACPI_MUTEX_NOT_ACQUIRED)
501    {
502        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
503                "Mutex [%s] is not acquired, cannot release\n",
504                AcpiUtGetMutexName (MutexId)));
505
506        return (AE_NOT_ACQUIRED);
507    }
508
509
510    /*
511     * Deadlock prevention.  Check if this thread owns any mutexes of value
512     * greater than this one.  If so, the thread has violated the mutex
513     * ordering rule.  This indicates a coding error somewhere in
514     * the ACPI subsystem code.
515     */
516    for (i = MutexId; i < MAX_MTX; i++)
517    {
518        if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId)
519        {
520            if (i == MutexId)
521            {
522                continue;
523            }
524
525            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
526                    "Invalid release order: owns [%s], releasing [%s]\n",
527                    AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId)));
528
529            return (AE_RELEASE_DEADLOCK);
530        }
531    }
532
533
534    /* Mark unlocked FIRST */
535
536    AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED;
537
538    Status = AcpiOsSignalSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 1);
539
540    if (ACPI_FAILURE (Status))
541    {
542        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
543                    ThisThreadId, AcpiUtGetMutexName (MutexId),
544                    AcpiFormatException (Status)));
545    }
546    else
547    {
548        ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
549                    ThisThreadId, AcpiUtGetMutexName (MutexId)));
550    }
551
552    return (Status);
553}
554
555
556/*******************************************************************************
557 *
558 * FUNCTION:    AcpiUtCreateUpdateStateAndPush
559 *
560 * PARAMETERS:  *Object         - Object to be added to the new state
561 *              Action          - Increment/Decrement
562 *              StateList       - List the state will be added to
563 *
564 * RETURN:      None
565 *
566 * DESCRIPTION: Create a new state and push it
567 *
568 ******************************************************************************/
569
570ACPI_STATUS
571AcpiUtCreateUpdateStateAndPush (
572    ACPI_OPERAND_OBJECT     *Object,
573    UINT16                  Action,
574    ACPI_GENERIC_STATE      **StateList)
575{
576    ACPI_GENERIC_STATE       *State;
577
578
579    /* Ignore null objects; these are expected */
580
581    if (!Object)
582    {
583        return (AE_OK);
584    }
585
586    State = AcpiUtCreateUpdateState (Object, Action);
587    if (!State)
588    {
589        return (AE_NO_MEMORY);
590    }
591
592
593    AcpiUtPushGenericState (StateList, State);
594    return (AE_OK);
595}
596
597
598/*******************************************************************************
599 *
600 * FUNCTION:    AcpiUtCreatePkgStateAndPush
601 *
602 * PARAMETERS:  *Object         - Object to be added to the new state
603 *              Action          - Increment/Decrement
604 *              StateList       - List the state will be added to
605 *
606 * RETURN:      None
607 *
608 * DESCRIPTION: Create a new state and push it
609 *
610 ******************************************************************************/
611
612ACPI_STATUS
613AcpiUtCreatePkgStateAndPush (
614    void                    *InternalObject,
615    void                    *ExternalObject,
616    UINT16                  Index,
617    ACPI_GENERIC_STATE      **StateList)
618{
619    ACPI_GENERIC_STATE       *State;
620
621
622    State = AcpiUtCreatePkgState (InternalObject, ExternalObject, Index);
623    if (!State)
624    {
625        return (AE_NO_MEMORY);
626    }
627
628
629    AcpiUtPushGenericState (StateList, State);
630    return (AE_OK);
631}
632
633
634/*******************************************************************************
635 *
636 * FUNCTION:    AcpiUtPushGenericState
637 *
638 * PARAMETERS:  ListHead            - Head of the state stack
639 *              State               - State object to push
640 *
641 * RETURN:      Status
642 *
643 * DESCRIPTION: Push a state object onto a state stack
644 *
645 ******************************************************************************/
646
647void
648AcpiUtPushGenericState (
649    ACPI_GENERIC_STATE      **ListHead,
650    ACPI_GENERIC_STATE      *State)
651{
652    FUNCTION_TRACE ("UtPushGenericState");
653
654    /* Push the state object onto the front of the list (stack) */
655
656    State->Common.Next = *ListHead;
657    *ListHead = State;
658
659    return_VOID;
660}
661
662
663/*******************************************************************************
664 *
665 * FUNCTION:    AcpiUtPopGenericState
666 *
667 * PARAMETERS:  ListHead            - Head of the state stack
668 *
669 * RETURN:      Status
670 *
671 * DESCRIPTION: Pop a state object from a state stack
672 *
673 ******************************************************************************/
674
675ACPI_GENERIC_STATE *
676AcpiUtPopGenericState (
677    ACPI_GENERIC_STATE      **ListHead)
678{
679    ACPI_GENERIC_STATE      *State;
680
681
682    FUNCTION_TRACE ("DsPopGenericState");
683
684
685    /* Remove the state object at the head of the list (stack) */
686
687    State = *ListHead;
688    if (State)
689    {
690        /* Update the list head */
691
692        *ListHead = State->Common.Next;
693    }
694
695    return_PTR (State);
696}
697
698
699/*******************************************************************************
700 *
701 * FUNCTION:    AcpiUtCreateGenericState
702 *
703 * PARAMETERS:  None
704 *
705 * RETURN:      Status
706 *
707 * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
708 *              the global state cache;  If none available, create a new one.
709 *
710 ******************************************************************************/
711
712ACPI_GENERIC_STATE *
713AcpiUtCreateGenericState (void)
714{
715    ACPI_GENERIC_STATE      *State;
716
717
718    State = AcpiUtAcquireFromCache (ACPI_MEM_LIST_STATE);
719
720    /* Initialize */
721
722    if (State)
723    {
724        State->Common.DataType = ACPI_DESC_TYPE_STATE;
725    }
726
727    return (State);
728}
729
730
731/*******************************************************************************
732 *
733 * FUNCTION:    AcpiUtCreateUpdateState
734 *
735 * PARAMETERS:  Object              - Initial Object to be installed in the
736 *                                    state
737 *              Action              - Update action to be performed
738 *
739 * RETURN:      Status
740 *
741 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
742 *              to update reference counts and delete complex objects such
743 *              as packages.
744 *
745 ******************************************************************************/
746
747ACPI_GENERIC_STATE *
748AcpiUtCreateUpdateState (
749    ACPI_OPERAND_OBJECT     *Object,
750    UINT16                  Action)
751{
752    ACPI_GENERIC_STATE      *State;
753
754
755    FUNCTION_TRACE_PTR ("UtCreateUpdateState", Object);
756
757
758    /* Create the generic state object */
759
760    State = AcpiUtCreateGenericState ();
761    if (!State)
762    {
763        return (NULL);
764    }
765
766    /* Init fields specific to the update struct */
767
768    State->Update.Object = Object;
769    State->Update.Value  = Action;
770
771    return_PTR (State);
772}
773
774
775/*******************************************************************************
776 *
777 * FUNCTION:    AcpiUtCreatePkgState
778 *
779 * PARAMETERS:  Object              - Initial Object to be installed in the
780 *                                    state
781 *              Action              - Update action to be performed
782 *
783 * RETURN:      Status
784 *
785 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
786 *              to update reference counts and delete complex objects such
787 *              as packages.
788 *
789 ******************************************************************************/
790
791ACPI_GENERIC_STATE *
792AcpiUtCreatePkgState (
793    void                    *InternalObject,
794    void                    *ExternalObject,
795    UINT16                  Index)
796{
797    ACPI_GENERIC_STATE      *State;
798
799
800    FUNCTION_TRACE_PTR ("UtCreatePkgState", InternalObject);
801
802
803    /* Create the generic state object */
804
805    State = AcpiUtCreateGenericState ();
806    if (!State)
807    {
808        return (NULL);
809    }
810
811    /* Init fields specific to the update struct */
812
813    State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject;
814    State->Pkg.DestObject   = ExternalObject;
815    State->Pkg.Index        = Index;
816    State->Pkg.NumPackages  = 1;
817
818    return_PTR (State);
819}
820
821
822/*******************************************************************************
823 *
824 * FUNCTION:    AcpiUtCreateControlState
825 *
826 * PARAMETERS:  None
827 *
828 * RETURN:      Status
829 *
830 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
831 *              to support nested IF/WHILE constructs in the AML.
832 *
833 ******************************************************************************/
834
835ACPI_GENERIC_STATE *
836AcpiUtCreateControlState (
837    void)
838{
839    ACPI_GENERIC_STATE      *State;
840
841
842    FUNCTION_TRACE ("UtCreateControlState");
843
844    /* Create the generic state object */
845
846    State = AcpiUtCreateGenericState ();
847    if (!State)
848    {
849        return (NULL);
850    }
851
852
853    /* Init fields specific to the control struct */
854
855    State->Common.State = CONTROL_CONDITIONAL_EXECUTING;
856
857    return_PTR (State);
858}
859
860
861/*******************************************************************************
862 *
863 * FUNCTION:    AcpiUtDeleteGenericState
864 *
865 * PARAMETERS:  State               - The state object to be deleted
866 *
867 * RETURN:      Status
868 *
869 * DESCRIPTION: Put a state object back into the global state cache.  The object
870 *              is not actually freed at this time.
871 *
872 ******************************************************************************/
873
874void
875AcpiUtDeleteGenericState (
876    ACPI_GENERIC_STATE      *State)
877{
878    FUNCTION_TRACE ("UtDeleteGenericState");
879
880
881    AcpiUtReleaseToCache (ACPI_MEM_LIST_STATE, State);
882    return_VOID;
883}
884
885
886/*******************************************************************************
887 *
888 * FUNCTION:    AcpiUtDeleteGenericStateCache
889 *
890 * PARAMETERS:  None
891 *
892 * RETURN:      Status
893 *
894 * DESCRIPTION: Purge the global state object cache.  Used during subsystem
895 *              termination.
896 *
897 ******************************************************************************/
898
899void
900AcpiUtDeleteGenericStateCache (
901    void)
902{
903    FUNCTION_TRACE ("UtDeleteGenericStateCache");
904
905
906    AcpiUtDeleteGenericCache (ACPI_MEM_LIST_STATE);
907    return_VOID;
908}
909
910
911/*******************************************************************************
912 *
913 * FUNCTION:    AcpiUtResolvePackageReferences
914 *
915 * PARAMETERS:  ObjDesc         - The Package object on which to resolve refs
916 *
917 * RETURN:      Status
918 *
919 * DESCRIPTION: Walk through a package and turn internal references into values
920 *
921 ******************************************************************************/
922
923ACPI_STATUS
924AcpiUtResolvePackageReferences (
925    ACPI_OPERAND_OBJECT     *ObjDesc)
926{
927    UINT32                  Count;
928    ACPI_OPERAND_OBJECT     *SubObject;
929
930
931    FUNCTION_TRACE ("AcpiUtResolvePackageReferences");
932
933
934    if (ObjDesc->Common.Type != ACPI_TYPE_PACKAGE)
935    {
936        /* The object must be a package */
937
938        REPORT_ERROR (("Must resolve Package Refs on a Package\n"));
939        return_ACPI_STATUS(AE_ERROR);
940    }
941
942    /*
943     * TBD: what about nested packages? */
944
945    for (Count = 0; Count < ObjDesc->Package.Count; Count++)
946    {
947        SubObject = ObjDesc->Package.Elements[Count];
948
949        if (SubObject->Common.Type == INTERNAL_TYPE_REFERENCE)
950        {
951            if (SubObject->Reference.Opcode == AML_ZERO_OP)
952            {
953                SubObject->Common.Type  = ACPI_TYPE_INTEGER;
954                SubObject->Integer.Value = 0;
955            }
956
957            else if (SubObject->Reference.Opcode == AML_ONE_OP)
958            {
959                SubObject->Common.Type  = ACPI_TYPE_INTEGER;
960                SubObject->Integer.Value = 1;
961            }
962
963            else if (SubObject->Reference.Opcode == AML_ONES_OP)
964            {
965                SubObject->Common.Type  = ACPI_TYPE_INTEGER;
966                SubObject->Integer.Value = ACPI_INTEGER_MAX;
967            }
968        }
969    }
970
971    return_ACPI_STATUS(AE_OK);
972}
973
974#ifdef ACPI_DEBUG
975
976/*******************************************************************************
977 *
978 * FUNCTION:    AcpiUtDisplayInitPathname
979 *
980 * PARAMETERS:  ObjHandle           - Handle whose pathname will be displayed
981 *              Path                - Additional path string to be appended
982 *
983 * RETURN:      ACPI_STATUS
984 *
985 * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY
986 *
987 ******************************************************************************/
988
989void
990AcpiUtDisplayInitPathname (
991    ACPI_HANDLE             ObjHandle,
992    char                    *Path)
993{
994    ACPI_STATUS             Status;
995    UINT32                  Length = 128;
996    char                    Buffer[128];
997
998
999    PROC_NAME ("AcpiUtDisplayInitPathname");
1000
1001
1002    Status = AcpiNsHandleToPathname (ObjHandle, &Length, Buffer);
1003    if (ACPI_SUCCESS (Status))
1004    {
1005        if (Path)
1006        {
1007            ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s.%s\n", Buffer, Path));
1008        }
1009        else
1010        {
1011            ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s\n", Buffer));
1012        }
1013    }
1014}
1015#endif
1016
1017/*******************************************************************************
1018 *
1019 * FUNCTION:    AcpiUtWalkPackageTree
1020 *
1021 * PARAMETERS:  ObjDesc         - The Package object on which to resolve refs
1022 *
1023 * RETURN:      Status
1024 *
1025 * DESCRIPTION: Walk through a package
1026 *
1027 ******************************************************************************/
1028
1029ACPI_STATUS
1030AcpiUtWalkPackageTree (
1031    ACPI_OPERAND_OBJECT     *SourceObject,
1032    void                    *TargetObject,
1033    ACPI_PKG_CALLBACK       WalkCallback,
1034    void                    *Context)
1035{
1036    ACPI_STATUS             Status = AE_OK;
1037    ACPI_GENERIC_STATE      *StateList = NULL;
1038    ACPI_GENERIC_STATE      *State;
1039    UINT32                  ThisIndex;
1040    ACPI_OPERAND_OBJECT     *ThisSourceObj;
1041
1042
1043    FUNCTION_TRACE ("AcpiUtWalkPackageTree");
1044
1045
1046    State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
1047    if (!State)
1048    {
1049        return_ACPI_STATUS (AE_NO_MEMORY);
1050    }
1051
1052    while (State)
1053    {
1054        ThisIndex     = State->Pkg.Index;
1055        ThisSourceObj = (ACPI_OPERAND_OBJECT *)
1056                        State->Pkg.SourceObject->Package.Elements[ThisIndex];
1057
1058        /*
1059         * Check for
1060         * 1) An uninitialized package element.  It is completely
1061         *      legal to declare a package and leave it uninitialized
1062         * 2) Not an internal object - can be a namespace node instead
1063         * 3) Any type other than a package.  Packages are handled in else
1064         *      case below.
1065         */
1066        if ((!ThisSourceObj) ||
1067            (!VALID_DESCRIPTOR_TYPE (
1068                    ThisSourceObj, ACPI_DESC_TYPE_INTERNAL)) ||
1069            (!IS_THIS_OBJECT_TYPE (
1070                    ThisSourceObj, ACPI_TYPE_PACKAGE)))
1071        {
1072
1073            Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
1074                                    State, Context);
1075            if (ACPI_FAILURE (Status))
1076            {
1077                /* TBD: must delete package created up to this point */
1078
1079                return_ACPI_STATUS (Status);
1080            }
1081
1082            State->Pkg.Index++;
1083            while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
1084            {
1085                /*
1086                 * We've handled all of the objects at this level,  This means
1087                 * that we have just completed a package.  That package may
1088                 * have contained one or more packages itself.
1089                 *
1090                 * Delete this state and pop the previous state (package).
1091                 */
1092                AcpiUtDeleteGenericState (State);
1093                State = AcpiUtPopGenericState (&StateList);
1094
1095
1096                /* Finished when there are no more states */
1097
1098                if (!State)
1099                {
1100                    /*
1101                     * We have handled all of the objects in the top level
1102                     * package just add the length of the package objects
1103                     * and exit
1104                     */
1105                    return_ACPI_STATUS (AE_OK);
1106                }
1107
1108                /*
1109                 * Go back up a level and move the index past the just
1110                 * completed package object.
1111                 */
1112                State->Pkg.Index++;
1113            }
1114        }
1115
1116        else
1117        {
1118            /* This is a sub-object of type package */
1119
1120            Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
1121                                        State, Context);
1122            if (ACPI_FAILURE (Status))
1123            {
1124                /* TBD: must delete package created up to this point */
1125
1126                return_ACPI_STATUS (Status);
1127            }
1128
1129
1130            /*
1131             * The callback above returned a new target package object.
1132             */
1133
1134            /*
1135             * Push the current state and create a new one
1136             */
1137            AcpiUtPushGenericState (&StateList, State);
1138            State = AcpiUtCreatePkgState (ThisSourceObj,
1139                                            State->Pkg.ThisTargetObj, 0);
1140            if (!State)
1141            {
1142                /* TBD: must delete package created up to this point */
1143
1144                return_ACPI_STATUS (AE_NO_MEMORY);
1145            }
1146        }
1147    }
1148
1149    /* We should never get here */
1150
1151    return (AE_AML_INTERNAL);
1152
1153}
1154
1155
1156/*******************************************************************************
1157 *
1158 * FUNCTION:    _ReportError
1159 *
1160 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1161 *              LineNumber          - Caller's line number (for error output)
1162 *              ComponentId         - Caller's component ID (for error output)
1163 *              Message             - Error message to use on failure
1164 *
1165 * RETURN:      None
1166 *
1167 * DESCRIPTION: Print error message
1168 *
1169 ******************************************************************************/
1170
1171void
1172_ReportError (
1173    NATIVE_CHAR             *ModuleName,
1174    UINT32                  LineNumber,
1175    UINT32                  ComponentId)
1176{
1177
1178
1179    AcpiOsPrintf ("%8s-%04d: *** Error: ", ModuleName, LineNumber);
1180}
1181
1182
1183/*******************************************************************************
1184 *
1185 * FUNCTION:    _ReportWarning
1186 *
1187 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1188 *              LineNumber          - Caller's line number (for error output)
1189 *              ComponentId         - Caller's component ID (for error output)
1190 *              Message             - Error message to use on failure
1191 *
1192 * RETURN:      None
1193 *
1194 * DESCRIPTION: Print warning message
1195 *
1196 ******************************************************************************/
1197
1198void
1199_ReportWarning (
1200    NATIVE_CHAR             *ModuleName,
1201    UINT32                  LineNumber,
1202    UINT32                  ComponentId)
1203{
1204
1205    AcpiOsPrintf ("%8s-%04d: *** Warning: ", ModuleName, LineNumber);
1206}
1207
1208
1209/*******************************************************************************
1210 *
1211 * FUNCTION:    _ReportInfo
1212 *
1213 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1214 *              LineNumber          - Caller's line number (for error output)
1215 *              ComponentId         - Caller's component ID (for error output)
1216 *              Message             - Error message to use on failure
1217 *
1218 * RETURN:      None
1219 *
1220 * DESCRIPTION: Print information message
1221 *
1222 ******************************************************************************/
1223
1224void
1225_ReportInfo (
1226    NATIVE_CHAR             *ModuleName,
1227    UINT32                  LineNumber,
1228    UINT32                  ComponentId)
1229{
1230
1231    AcpiOsPrintf ("%8s-%04d: *** Info: ", ModuleName, LineNumber);
1232}
1233
1234
1235