utmisc.c revision 99679
1/*******************************************************************************
2 *
3 * Module Name: utmisc - common utility procedures
4 *              $Revision: 78 $
5 *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2002, 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 "acnamesp.h"
122#include "amlcode.h"
123#include "acinterp.h"
124
125
126#define _COMPONENT          ACPI_UTILITIES
127        ACPI_MODULE_NAME    ("utmisc")
128
129
130/*******************************************************************************
131 *
132 * FUNCTION:    AcpiUtDwordByteSwap
133 *
134 * PARAMETERS:  Value           - Value to be converted
135 *
136 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
137 *
138 ******************************************************************************/
139
140UINT32
141AcpiUtDwordByteSwap (
142    UINT32                  Value)
143{
144    union
145    {
146        UINT32              Value;
147        UINT8               Bytes[4];
148    } Out;
149
150    union
151    {
152        UINT32              Value;
153        UINT8               Bytes[4];
154    } In;
155
156
157    ACPI_FUNCTION_ENTRY ();
158
159
160    In.Value = Value;
161
162    Out.Bytes[0] = In.Bytes[3];
163    Out.Bytes[1] = In.Bytes[2];
164    Out.Bytes[2] = In.Bytes[1];
165    Out.Bytes[3] = In.Bytes[0];
166
167    return (Out.Value);
168}
169
170
171/*******************************************************************************
172 *
173 * FUNCTION:    AcpiUtSetIntegerWidth
174 *
175 * PARAMETERS:  Revision            From DSDT header
176 *
177 * RETURN:      None
178 *
179 * DESCRIPTION: Set the global integer bit width based upon the revision
180 *              of the DSDT.  For Revision 1 and 0, Integers are 32 bits.
181 *              For Revision 2 and above, Integers are 64 bits.  Yes, this
182 *              makes a difference.
183 *
184 ******************************************************************************/
185
186void
187AcpiUtSetIntegerWidth (
188    UINT8                   Revision)
189{
190
191    if (Revision <= 1)
192    {
193        AcpiGbl_IntegerBitWidth  = 32;
194        AcpiGbl_IntegerByteWidth = 4;
195    }
196    else
197    {
198        AcpiGbl_IntegerBitWidth  = 64;
199        AcpiGbl_IntegerByteWidth = 8;
200    }
201}
202
203
204
205#ifdef ACPI_DEBUG
206/*******************************************************************************
207 *
208 * FUNCTION:    AcpiUtDisplayInitPathname
209 *
210 * PARAMETERS:  ObjHandle           - Handle whose pathname will be displayed
211 *              Path                - Additional path string to be appended
212 *
213 * RETURN:      ACPI_STATUS
214 *
215 * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY
216 *
217 ******************************************************************************/
218
219void
220AcpiUtDisplayInitPathname (
221    ACPI_HANDLE             ObjHandle,
222    char                    *Path)
223{
224    ACPI_STATUS             Status;
225    ACPI_BUFFER             Buffer;
226
227
228    ACPI_FUNCTION_NAME ("UtDisplayInitPathname");
229
230
231    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
232
233    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
234    if (ACPI_SUCCESS (Status))
235    {
236        if (Path)
237        {
238            ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s.%s\n", (char *) Buffer.Pointer, Path));
239        }
240        else
241        {
242            ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s\n", (char *) Buffer.Pointer));
243        }
244
245        ACPI_MEM_FREE (Buffer.Pointer);
246    }
247}
248#endif
249
250
251/*******************************************************************************
252 *
253 * FUNCTION:    AcpiUtValidAcpiName
254 *
255 * PARAMETERS:  Character           - The character to be examined
256 *
257 * RETURN:      1 if Character may appear in a name, else 0
258 *
259 * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
260 *              1) Upper case alpha
261 *              2) numeric
262 *              3) underscore
263 *
264 ******************************************************************************/
265
266BOOLEAN
267AcpiUtValidAcpiName (
268    UINT32                  Name)
269{
270    NATIVE_CHAR             *NamePtr = (NATIVE_CHAR *) &Name;
271    UINT32                  i;
272
273
274    ACPI_FUNCTION_ENTRY ();
275
276
277    for (i = 0; i < ACPI_NAME_SIZE; i++)
278    {
279        if (!((NamePtr[i] == '_') ||
280              (NamePtr[i] >= 'A' && NamePtr[i] <= 'Z') ||
281              (NamePtr[i] >= '0' && NamePtr[i] <= '9')))
282        {
283            return (FALSE);
284        }
285    }
286
287    return (TRUE);
288}
289
290
291/*******************************************************************************
292 *
293 * FUNCTION:    AcpiUtValidAcpiCharacter
294 *
295 * PARAMETERS:  Character           - The character to be examined
296 *
297 * RETURN:      1 if Character may appear in a name, else 0
298 *
299 * DESCRIPTION: Check for a printable character
300 *
301 ******************************************************************************/
302
303BOOLEAN
304AcpiUtValidAcpiCharacter (
305    NATIVE_CHAR             Character)
306{
307
308    ACPI_FUNCTION_ENTRY ();
309
310    return ((BOOLEAN)   ((Character == '_') ||
311                        (Character >= 'A' && Character <= 'Z') ||
312                        (Character >= '0' && Character <= '9')));
313}
314
315
316/*******************************************************************************
317 *
318 * FUNCTION:    AcpiUtStrtoul64
319 *
320 * PARAMETERS:  String          - Null terminated string
321 *              Terminater      - Where a pointer to the terminating byte is returned
322 *              Base            - Radix of the string
323 *
324 * RETURN:      Converted value
325 *
326 * DESCRIPTION: Convert a string into an unsigned value.
327 *
328 ******************************************************************************/
329#define NEGATIVE    1
330#define POSITIVE    0
331
332ACPI_STATUS
333AcpiUtStrtoul64 (
334    NATIVE_CHAR             *String,
335    UINT32                  Base,
336    ACPI_INTEGER            *RetInteger)
337{
338    UINT32                  Index;
339    ACPI_INTEGER            ReturnValue = 0;
340    ACPI_STATUS             Status = AE_OK;
341    ACPI_INTEGER            Dividend;
342    ACPI_INTEGER            Quotient;
343
344
345    *RetInteger = 0;
346
347    switch (Base)
348    {
349    case 0:
350    case 8:
351    case 10:
352    case 16:
353        break;
354
355    default:
356        /*
357         * The specified Base parameter is not in the domain of
358         * this function:
359         */
360        return (AE_BAD_PARAMETER);
361    }
362
363    /*
364     * skip over any white space in the buffer:
365     */
366    while (ACPI_IS_SPACE (*String) || *String == '\t')
367    {
368        ++String;
369    }
370
371    /*
372     * If the input parameter Base is zero, then we need to
373     * determine if it is octal, decimal, or hexadecimal:
374     */
375    if (Base == 0)
376    {
377        if (*String == '0')
378        {
379            if (ACPI_TOLOWER (*(++String)) == 'x')
380            {
381                Base = 16;
382                ++String;
383            }
384            else
385            {
386                Base = 8;
387            }
388        }
389        else
390        {
391            Base = 10;
392        }
393    }
394
395    /*
396     * For octal and hexadecimal bases, skip over the leading
397     * 0 or 0x, if they are present.
398     */
399    if (Base == 8 && *String == '0')
400    {
401        String++;
402    }
403
404    if (Base == 16 &&
405        *String == '0' &&
406        ACPI_TOLOWER (*(++String)) == 'x')
407    {
408        String++;
409    }
410
411    /* Main loop: convert the string to an unsigned long */
412
413    while (*String)
414    {
415        if (ACPI_IS_DIGIT (*String))
416        {
417            Index = ((UINT8) *String) - '0';
418        }
419        else
420        {
421            Index = (UINT8) ACPI_TOUPPER (*String);
422            if (ACPI_IS_UPPER ((char) Index))
423            {
424                Index = Index - 'A' + 10;
425            }
426            else
427            {
428                goto ErrorExit;
429            }
430        }
431
432        if (Index >= Base)
433        {
434            goto ErrorExit;
435        }
436
437        /* Check to see if value is out of range: */
438
439        Dividend = ACPI_INTEGER_MAX - (ACPI_INTEGER) Index;
440        (void) AcpiUtShortDivide (&Dividend, Base, &Quotient, NULL);
441        if (ReturnValue > Quotient)
442        {
443            goto ErrorExit;
444        }
445
446        ReturnValue *= Base;
447        ReturnValue += Index;
448        ++String;
449    }
450
451    *RetInteger = ReturnValue;
452    return (Status);
453
454
455ErrorExit:
456    switch (Base)
457    {
458    case 8:
459        Status = AE_BAD_OCTAL_CONSTANT;
460        break;
461
462    case 10:
463        Status = AE_BAD_DECIMAL_CONSTANT;
464        break;
465
466    case 16:
467        Status = AE_BAD_HEX_CONSTANT;
468        break;
469
470    default:
471        /* Base validated above */
472        break;
473    }
474
475    return (Status);
476}
477
478
479/*******************************************************************************
480 *
481 * FUNCTION:    AcpiUtStrupr
482 *
483 * PARAMETERS:  SrcString       - The source string to convert to
484 *
485 * RETURN:      SrcString
486 *
487 * DESCRIPTION: Convert string to uppercase
488 *
489 ******************************************************************************/
490
491NATIVE_CHAR *
492AcpiUtStrupr (
493    NATIVE_CHAR             *SrcString)
494{
495    NATIVE_CHAR             *String;
496
497
498    ACPI_FUNCTION_ENTRY ();
499
500
501    /* Walk entire string, uppercasing the letters */
502
503    for (String = SrcString; *String; )
504    {
505        *String = (char) ACPI_TOUPPER (*String);
506        String++;
507    }
508
509
510    return (SrcString);
511}
512
513/*******************************************************************************
514 *
515 * FUNCTION:    AcpiUtMutexInitialize
516 *
517 * PARAMETERS:  None.
518 *
519 * RETURN:      Status
520 *
521 * DESCRIPTION: Create the system mutex objects.
522 *
523 ******************************************************************************/
524
525ACPI_STATUS
526AcpiUtMutexInitialize (
527    void)
528{
529    UINT32                  i;
530    ACPI_STATUS             Status;
531
532
533    ACPI_FUNCTION_TRACE ("UtMutexInitialize");
534
535
536    /*
537     * Create each of the predefined mutex objects
538     */
539    for (i = 0; i < NUM_MTX; i++)
540    {
541        Status = AcpiUtCreateMutex (i);
542        if (ACPI_FAILURE (Status))
543        {
544            return_ACPI_STATUS (Status);
545        }
546    }
547
548    return_ACPI_STATUS (AE_OK);
549}
550
551
552/*******************************************************************************
553 *
554 * FUNCTION:    AcpiUtMutexTerminate
555 *
556 * PARAMETERS:  None.
557 *
558 * RETURN:      None.
559 *
560 * DESCRIPTION: Delete all of the system mutex objects.
561 *
562 ******************************************************************************/
563
564void
565AcpiUtMutexTerminate (
566    void)
567{
568    UINT32                  i;
569
570
571    ACPI_FUNCTION_TRACE ("UtMutexTerminate");
572
573
574    /*
575     * Delete each predefined mutex object
576     */
577    for (i = 0; i < NUM_MTX; i++)
578    {
579        (void) AcpiUtDeleteMutex (i);
580    }
581
582    return_VOID;
583}
584
585
586/*******************************************************************************
587 *
588 * FUNCTION:    AcpiUtCreateMutex
589 *
590 * PARAMETERS:  MutexID         - ID of the mutex to be created
591 *
592 * RETURN:      Status
593 *
594 * DESCRIPTION: Create a mutex object.
595 *
596 ******************************************************************************/
597
598ACPI_STATUS
599AcpiUtCreateMutex (
600    ACPI_MUTEX_HANDLE       MutexId)
601{
602    ACPI_STATUS             Status = AE_OK;
603
604
605    ACPI_FUNCTION_TRACE_U32 ("UtCreateMutex", MutexId);
606
607
608    if (MutexId > MAX_MTX)
609    {
610        return_ACPI_STATUS (AE_BAD_PARAMETER);
611    }
612
613
614    if (!AcpiGbl_AcpiMutexInfo[MutexId].Mutex)
615    {
616        Status = AcpiOsCreateSemaphore (1, 1,
617                        &AcpiGbl_AcpiMutexInfo[MutexId].Mutex);
618        AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED;
619        AcpiGbl_AcpiMutexInfo[MutexId].UseCount = 0;
620    }
621
622    return_ACPI_STATUS (Status);
623}
624
625
626/*******************************************************************************
627 *
628 * FUNCTION:    AcpiUtDeleteMutex
629 *
630 * PARAMETERS:  MutexID         - ID of the mutex to be deleted
631 *
632 * RETURN:      Status
633 *
634 * DESCRIPTION: Delete a mutex object.
635 *
636 ******************************************************************************/
637
638ACPI_STATUS
639AcpiUtDeleteMutex (
640    ACPI_MUTEX_HANDLE       MutexId)
641{
642    ACPI_STATUS             Status;
643
644
645    ACPI_FUNCTION_TRACE_U32 ("UtDeleteMutex", MutexId);
646
647
648    if (MutexId > MAX_MTX)
649    {
650        return_ACPI_STATUS (AE_BAD_PARAMETER);
651    }
652
653
654    Status = AcpiOsDeleteSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex);
655
656    AcpiGbl_AcpiMutexInfo[MutexId].Mutex = NULL;
657    AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED;
658
659    return_ACPI_STATUS (Status);
660}
661
662
663/*******************************************************************************
664 *
665 * FUNCTION:    AcpiUtAcquireMutex
666 *
667 * PARAMETERS:  MutexID         - ID of the mutex to be acquired
668 *
669 * RETURN:      Status
670 *
671 * DESCRIPTION: Acquire a mutex object.
672 *
673 ******************************************************************************/
674
675ACPI_STATUS
676AcpiUtAcquireMutex (
677    ACPI_MUTEX_HANDLE       MutexId)
678{
679    ACPI_STATUS             Status;
680    UINT32                  i;
681    UINT32                  ThisThreadId;
682
683
684    ACPI_FUNCTION_NAME ("UtAcquireMutex");
685
686
687    if (MutexId > MAX_MTX)
688    {
689        return (AE_BAD_PARAMETER);
690    }
691
692
693    ThisThreadId = AcpiOsGetThreadId ();
694
695    /*
696     * Deadlock prevention.  Check if this thread owns any mutexes of value
697     * greater than or equal to this one.  If so, the thread has violated
698     * the mutex ordering rule.  This indicates a coding error somewhere in
699     * the ACPI subsystem code.
700     */
701    for (i = MutexId; i < MAX_MTX; i++)
702    {
703        if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId)
704        {
705            if (i == MutexId)
706            {
707                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
708                        "Mutex [%s] already acquired by this thread [%X]\n",
709                        AcpiUtGetMutexName (MutexId), ThisThreadId));
710
711                return (AE_ALREADY_ACQUIRED);
712            }
713
714            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
715                    "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
716                    ThisThreadId, AcpiUtGetMutexName (i),
717                    AcpiUtGetMutexName (MutexId)));
718
719            return (AE_ACQUIRE_DEADLOCK);
720        }
721    }
722
723
724    ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
725                "Thread %X attempting to acquire Mutex [%s]\n",
726                ThisThreadId, AcpiUtGetMutexName (MutexId)));
727
728    Status = AcpiOsWaitSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex,
729                                    1, WAIT_FOREVER);
730    if (ACPI_SUCCESS (Status))
731    {
732        ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
733                    ThisThreadId, AcpiUtGetMutexName (MutexId)));
734
735        AcpiGbl_AcpiMutexInfo[MutexId].UseCount++;
736        AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ThisThreadId;
737    }
738
739    else
740    {
741        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
742                    ThisThreadId, AcpiUtGetMutexName (MutexId),
743                    AcpiFormatException (Status)));
744    }
745
746    return (Status);
747}
748
749
750/*******************************************************************************
751 *
752 * FUNCTION:    AcpiUtReleaseMutex
753 *
754 * PARAMETERS:  MutexID         - ID of the mutex to be released
755 *
756 * RETURN:      Status
757 *
758 * DESCRIPTION: Release a mutex object.
759 *
760 ******************************************************************************/
761
762ACPI_STATUS
763AcpiUtReleaseMutex (
764    ACPI_MUTEX_HANDLE       MutexId)
765{
766    ACPI_STATUS             Status;
767    UINT32                  i;
768    UINT32                  ThisThreadId;
769
770
771    ACPI_FUNCTION_NAME ("UtReleaseMutex");
772
773
774    ThisThreadId = AcpiOsGetThreadId ();
775    ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
776        "Thread %X releasing Mutex [%s]\n", ThisThreadId,
777        AcpiUtGetMutexName (MutexId)));
778
779    if (MutexId > MAX_MTX)
780    {
781        return (AE_BAD_PARAMETER);
782    }
783
784
785    /*
786     * Mutex must be acquired in order to release it!
787     */
788    if (AcpiGbl_AcpiMutexInfo[MutexId].OwnerId == ACPI_MUTEX_NOT_ACQUIRED)
789    {
790        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
791                "Mutex [%s] is not acquired, cannot release\n",
792                AcpiUtGetMutexName (MutexId)));
793
794        return (AE_NOT_ACQUIRED);
795    }
796
797
798    /*
799     * Deadlock prevention.  Check if this thread owns any mutexes of value
800     * greater than this one.  If so, the thread has violated the mutex
801     * ordering rule.  This indicates a coding error somewhere in
802     * the ACPI subsystem code.
803     */
804    for (i = MutexId; i < MAX_MTX; i++)
805    {
806        if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId)
807        {
808            if (i == MutexId)
809            {
810                continue;
811            }
812
813            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
814                    "Invalid release order: owns [%s], releasing [%s]\n",
815                    AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId)));
816
817            return (AE_RELEASE_DEADLOCK);
818        }
819    }
820
821
822    /* Mark unlocked FIRST */
823
824    AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED;
825
826    Status = AcpiOsSignalSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 1);
827
828    if (ACPI_FAILURE (Status))
829    {
830        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
831                    ThisThreadId, AcpiUtGetMutexName (MutexId),
832                    AcpiFormatException (Status)));
833    }
834    else
835    {
836        ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
837                    ThisThreadId, AcpiUtGetMutexName (MutexId)));
838    }
839
840    return (Status);
841}
842
843
844/*******************************************************************************
845 *
846 * FUNCTION:    AcpiUtCreateUpdateStateAndPush
847 *
848 * PARAMETERS:  *Object         - Object to be added to the new state
849 *              Action          - Increment/Decrement
850 *              StateList       - List the state will be added to
851 *
852 * RETURN:      None
853 *
854 * DESCRIPTION: Create a new state and push it
855 *
856 ******************************************************************************/
857
858ACPI_STATUS
859AcpiUtCreateUpdateStateAndPush (
860    ACPI_OPERAND_OBJECT     *Object,
861    UINT16                  Action,
862    ACPI_GENERIC_STATE      **StateList)
863{
864    ACPI_GENERIC_STATE       *State;
865
866
867    ACPI_FUNCTION_ENTRY ();
868
869
870    /* Ignore null objects; these are expected */
871
872    if (!Object)
873    {
874        return (AE_OK);
875    }
876
877    State = AcpiUtCreateUpdateState (Object, Action);
878    if (!State)
879    {
880        return (AE_NO_MEMORY);
881    }
882
883
884    AcpiUtPushGenericState (StateList, State);
885    return (AE_OK);
886}
887
888
889/*******************************************************************************
890 *
891 * FUNCTION:    AcpiUtCreatePkgStateAndPush
892 *
893 * PARAMETERS:  *Object         - Object to be added to the new state
894 *              Action          - Increment/Decrement
895 *              StateList       - List the state will be added to
896 *
897 * RETURN:      None
898 *
899 * DESCRIPTION: Create a new state and push it
900 *
901 ******************************************************************************/
902
903ACPI_STATUS
904AcpiUtCreatePkgStateAndPush (
905    void                    *InternalObject,
906    void                    *ExternalObject,
907    UINT16                  Index,
908    ACPI_GENERIC_STATE      **StateList)
909{
910    ACPI_GENERIC_STATE       *State;
911
912
913    ACPI_FUNCTION_ENTRY ();
914
915
916    State = AcpiUtCreatePkgState (InternalObject, ExternalObject, Index);
917    if (!State)
918    {
919        return (AE_NO_MEMORY);
920    }
921
922
923    AcpiUtPushGenericState (StateList, State);
924    return (AE_OK);
925}
926
927
928/*******************************************************************************
929 *
930 * FUNCTION:    AcpiUtPushGenericState
931 *
932 * PARAMETERS:  ListHead            - Head of the state stack
933 *              State               - State object to push
934 *
935 * RETURN:      Status
936 *
937 * DESCRIPTION: Push a state object onto a state stack
938 *
939 ******************************************************************************/
940
941void
942AcpiUtPushGenericState (
943    ACPI_GENERIC_STATE      **ListHead,
944    ACPI_GENERIC_STATE      *State)
945{
946    ACPI_FUNCTION_TRACE ("UtPushGenericState");
947
948
949    /* Push the state object onto the front of the list (stack) */
950
951    State->Common.Next = *ListHead;
952    *ListHead = State;
953
954    return_VOID;
955}
956
957
958/*******************************************************************************
959 *
960 * FUNCTION:    AcpiUtPopGenericState
961 *
962 * PARAMETERS:  ListHead            - Head of the state stack
963 *
964 * RETURN:      Status
965 *
966 * DESCRIPTION: Pop a state object from a state stack
967 *
968 ******************************************************************************/
969
970ACPI_GENERIC_STATE *
971AcpiUtPopGenericState (
972    ACPI_GENERIC_STATE      **ListHead)
973{
974    ACPI_GENERIC_STATE      *State;
975
976
977    ACPI_FUNCTION_TRACE ("UtPopGenericState");
978
979
980    /* Remove the state object at the head of the list (stack) */
981
982    State = *ListHead;
983    if (State)
984    {
985        /* Update the list head */
986
987        *ListHead = State->Common.Next;
988    }
989
990    return_PTR (State);
991}
992
993
994/*******************************************************************************
995 *
996 * FUNCTION:    AcpiUtCreateGenericState
997 *
998 * PARAMETERS:  None
999 *
1000 * RETURN:      Status
1001 *
1002 * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
1003 *              the global state cache;  If none available, create a new one.
1004 *
1005 ******************************************************************************/
1006
1007ACPI_GENERIC_STATE *
1008AcpiUtCreateGenericState (void)
1009{
1010    ACPI_GENERIC_STATE      *State;
1011
1012
1013    ACPI_FUNCTION_ENTRY ();
1014
1015
1016    State = AcpiUtAcquireFromCache (ACPI_MEM_LIST_STATE);
1017
1018    /* Initialize */
1019
1020    if (State)
1021    {
1022        State->Common.DataType = ACPI_DESC_TYPE_STATE;
1023    }
1024
1025    return (State);
1026}
1027
1028
1029/*******************************************************************************
1030 *
1031 * FUNCTION:    AcpiUtCreateThreadState
1032 *
1033 * PARAMETERS:  None
1034 *
1035 * RETURN:      Thread State
1036 *
1037 * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
1038 *              to track per-thread info during method execution
1039 *
1040 ******************************************************************************/
1041
1042ACPI_THREAD_STATE *
1043AcpiUtCreateThreadState (
1044    void)
1045{
1046    ACPI_GENERIC_STATE      *State;
1047
1048
1049    ACPI_FUNCTION_TRACE ("UtCreateThreadState");
1050
1051
1052    /* Create the generic state object */
1053
1054    State = AcpiUtCreateGenericState ();
1055    if (!State)
1056    {
1057        return_PTR (NULL);
1058    }
1059
1060    /* Init fields specific to the update struct */
1061
1062    State->Common.DataType = ACPI_DESC_TYPE_STATE_THREAD;
1063    State->Thread.ThreadId = AcpiOsGetThreadId ();
1064
1065    return_PTR ((ACPI_THREAD_STATE *) State);
1066}
1067
1068
1069/*******************************************************************************
1070 *
1071 * FUNCTION:    AcpiUtCreateUpdateState
1072 *
1073 * PARAMETERS:  Object              - Initial Object to be installed in the
1074 *                                    state
1075 *              Action              - Update action to be performed
1076 *
1077 * RETURN:      Status
1078 *
1079 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
1080 *              to update reference counts and delete complex objects such
1081 *              as packages.
1082 *
1083 ******************************************************************************/
1084
1085ACPI_GENERIC_STATE *
1086AcpiUtCreateUpdateState (
1087    ACPI_OPERAND_OBJECT     *Object,
1088    UINT16                  Action)
1089{
1090    ACPI_GENERIC_STATE      *State;
1091
1092
1093    ACPI_FUNCTION_TRACE_PTR ("UtCreateUpdateState", Object);
1094
1095
1096    /* Create the generic state object */
1097
1098    State = AcpiUtCreateGenericState ();
1099    if (!State)
1100    {
1101        return_PTR (NULL);
1102    }
1103
1104    /* Init fields specific to the update struct */
1105
1106    State->Common.DataType = ACPI_DESC_TYPE_STATE_UPDATE;
1107    State->Update.Object = Object;
1108    State->Update.Value  = Action;
1109
1110    return_PTR (State);
1111}
1112
1113
1114/*******************************************************************************
1115 *
1116 * FUNCTION:    AcpiUtCreatePkgState
1117 *
1118 * PARAMETERS:  Object              - Initial Object to be installed in the
1119 *                                    state
1120 *              Action              - Update action to be performed
1121 *
1122 * RETURN:      Status
1123 *
1124 * DESCRIPTION: Create a "Package State"
1125 *
1126 ******************************************************************************/
1127
1128ACPI_GENERIC_STATE *
1129AcpiUtCreatePkgState (
1130    void                    *InternalObject,
1131    void                    *ExternalObject,
1132    UINT16                  Index)
1133{
1134    ACPI_GENERIC_STATE      *State;
1135
1136
1137    ACPI_FUNCTION_TRACE_PTR ("UtCreatePkgState", InternalObject);
1138
1139
1140    /* Create the generic state object */
1141
1142    State = AcpiUtCreateGenericState ();
1143    if (!State)
1144    {
1145        return_PTR (NULL);
1146    }
1147
1148    /* Init fields specific to the update struct */
1149
1150    State->Common.DataType  = ACPI_DESC_TYPE_STATE_PACKAGE;
1151    State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject;
1152    State->Pkg.DestObject   = ExternalObject;
1153    State->Pkg.Index        = Index;
1154    State->Pkg.NumPackages  = 1;
1155
1156    return_PTR (State);
1157}
1158
1159
1160/*******************************************************************************
1161 *
1162 * FUNCTION:    AcpiUtCreateControlState
1163 *
1164 * PARAMETERS:  None
1165 *
1166 * RETURN:      Status
1167 *
1168 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
1169 *              to support nested IF/WHILE constructs in the AML.
1170 *
1171 ******************************************************************************/
1172
1173ACPI_GENERIC_STATE *
1174AcpiUtCreateControlState (
1175    void)
1176{
1177    ACPI_GENERIC_STATE      *State;
1178
1179
1180    ACPI_FUNCTION_TRACE ("UtCreateControlState");
1181
1182
1183    /* Create the generic state object */
1184
1185    State = AcpiUtCreateGenericState ();
1186    if (!State)
1187    {
1188        return_PTR (NULL);
1189    }
1190
1191
1192    /* Init fields specific to the control struct */
1193
1194    State->Common.DataType  = ACPI_DESC_TYPE_STATE_CONTROL;
1195    State->Common.State     = ACPI_CONTROL_CONDITIONAL_EXECUTING;
1196
1197    return_PTR (State);
1198}
1199
1200
1201/*******************************************************************************
1202 *
1203 * FUNCTION:    AcpiUtDeleteGenericState
1204 *
1205 * PARAMETERS:  State               - The state object to be deleted
1206 *
1207 * RETURN:      Status
1208 *
1209 * DESCRIPTION: Put a state object back into the global state cache.  The object
1210 *              is not actually freed at this time.
1211 *
1212 ******************************************************************************/
1213
1214void
1215AcpiUtDeleteGenericState (
1216    ACPI_GENERIC_STATE      *State)
1217{
1218    ACPI_FUNCTION_TRACE ("UtDeleteGenericState");
1219
1220
1221    AcpiUtReleaseToCache (ACPI_MEM_LIST_STATE, State);
1222    return_VOID;
1223}
1224
1225
1226/*******************************************************************************
1227 *
1228 * FUNCTION:    AcpiUtDeleteGenericStateCache
1229 *
1230 * PARAMETERS:  None
1231 *
1232 * RETURN:      Status
1233 *
1234 * DESCRIPTION: Purge the global state object cache.  Used during subsystem
1235 *              termination.
1236 *
1237 ******************************************************************************/
1238
1239void
1240AcpiUtDeleteGenericStateCache (
1241    void)
1242{
1243    ACPI_FUNCTION_TRACE ("UtDeleteGenericStateCache");
1244
1245
1246    AcpiUtDeleteGenericCache (ACPI_MEM_LIST_STATE);
1247    return_VOID;
1248}
1249
1250
1251/*******************************************************************************
1252 *
1253 * FUNCTION:    AcpiUtWalkPackageTree
1254 *
1255 * PARAMETERS:  ObjDesc         - The Package object on which to resolve refs
1256 *
1257 * RETURN:      Status
1258 *
1259 * DESCRIPTION: Walk through a package
1260 *
1261 ******************************************************************************/
1262
1263ACPI_STATUS
1264AcpiUtWalkPackageTree (
1265    ACPI_OPERAND_OBJECT     *SourceObject,
1266    void                    *TargetObject,
1267    ACPI_PKG_CALLBACK       WalkCallback,
1268    void                    *Context)
1269{
1270    ACPI_STATUS             Status = AE_OK;
1271    ACPI_GENERIC_STATE      *StateList = NULL;
1272    ACPI_GENERIC_STATE      *State;
1273    UINT32                  ThisIndex;
1274    ACPI_OPERAND_OBJECT     *ThisSourceObj;
1275
1276
1277    ACPI_FUNCTION_TRACE ("UtWalkPackageTree");
1278
1279
1280    State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
1281    if (!State)
1282    {
1283        return_ACPI_STATUS (AE_NO_MEMORY);
1284    }
1285
1286    while (State)
1287    {
1288        ThisIndex     = State->Pkg.Index;
1289        ThisSourceObj = (ACPI_OPERAND_OBJECT *)
1290                        State->Pkg.SourceObject->Package.Elements[ThisIndex];
1291
1292        /*
1293         * Check for:
1294         * 1) An uninitialized package element.  It is completely
1295         *    legal to declare a package and leave it uninitialized
1296         * 2) Not an internal object - can be a namespace node instead
1297         * 3) Any type other than a package.  Packages are handled in else
1298         *    case below.
1299         */
1300        if ((!ThisSourceObj) ||
1301            (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
1302            (ACPI_GET_OBJECT_TYPE (ThisSourceObj) != ACPI_TYPE_PACKAGE))
1303        {
1304            Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
1305                                    State, Context);
1306            if (ACPI_FAILURE (Status))
1307            {
1308                return_ACPI_STATUS (Status);
1309            }
1310
1311            State->Pkg.Index++;
1312            while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
1313            {
1314                /*
1315                 * We've handled all of the objects at this level,  This means
1316                 * that we have just completed a package.  That package may
1317                 * have contained one or more packages itself.
1318                 *
1319                 * Delete this state and pop the previous state (package).
1320                 */
1321                AcpiUtDeleteGenericState (State);
1322                State = AcpiUtPopGenericState (&StateList);
1323
1324                /* Finished when there are no more states */
1325
1326                if (!State)
1327                {
1328                    /*
1329                     * We have handled all of the objects in the top level
1330                     * package just add the length of the package objects
1331                     * and exit
1332                     */
1333                    return_ACPI_STATUS (AE_OK);
1334                }
1335
1336                /*
1337                 * Go back up a level and move the index past the just
1338                 * completed package object.
1339                 */
1340                State->Pkg.Index++;
1341            }
1342        }
1343        else
1344        {
1345            /* This is a subobject of type package */
1346
1347            Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
1348                                        State, Context);
1349            if (ACPI_FAILURE (Status))
1350            {
1351                return_ACPI_STATUS (Status);
1352            }
1353
1354            /*
1355             * Push the current state and create a new one
1356             * The callback above returned a new target package object.
1357             */
1358            AcpiUtPushGenericState (&StateList, State);
1359            State = AcpiUtCreatePkgState (ThisSourceObj,
1360                                            State->Pkg.ThisTargetObj, 0);
1361            if (!State)
1362            {
1363                return_ACPI_STATUS (AE_NO_MEMORY);
1364            }
1365        }
1366    }
1367
1368    /* We should never get here */
1369
1370    return_ACPI_STATUS (AE_AML_INTERNAL);
1371}
1372
1373
1374/*******************************************************************************
1375 *
1376 * FUNCTION:    AcpiUtGenerateChecksum
1377 *
1378 * PARAMETERS:  Buffer          - Buffer to be scanned
1379 *              Length          - number of bytes to examine
1380 *
1381 * RETURN:      checksum
1382 *
1383 * DESCRIPTION: Generate a checksum on a raw buffer
1384 *
1385 ******************************************************************************/
1386
1387UINT8
1388AcpiUtGenerateChecksum (
1389    UINT8                   *Buffer,
1390    UINT32                  Length)
1391{
1392    UINT32                  i;
1393    signed char             Sum = 0;
1394
1395    for (i = 0; i < Length; i++)
1396    {
1397        Sum = (signed char) (Sum + Buffer[i]);
1398    }
1399
1400    return ((UINT8) (0 - Sum));
1401}
1402
1403
1404/*******************************************************************************
1405 *
1406 * FUNCTION:    AcpiUtGetResourceEndTag
1407 *
1408 * PARAMETERS:  ObjDesc         - The resource template buffer object
1409 *
1410 * RETURN:      Pointer to the end tag
1411 *
1412 * DESCRIPTION: Find the END_TAG resource descriptor in a resource template
1413 *
1414 ******************************************************************************/
1415
1416
1417UINT8 *
1418AcpiUtGetResourceEndTag (
1419    ACPI_OPERAND_OBJECT     *ObjDesc)
1420{
1421    UINT8                   BufferByte;
1422    UINT8                   *Buffer;
1423    UINT8                   *EndBuffer;
1424
1425
1426    Buffer    = ObjDesc->Buffer.Pointer;
1427    EndBuffer = Buffer + ObjDesc->Buffer.Length;
1428
1429    while (Buffer < EndBuffer)
1430    {
1431        BufferByte = *Buffer;
1432        if (BufferByte & ACPI_RDESC_TYPE_MASK)
1433        {
1434            /* Large Descriptor - Length is next 2 bytes */
1435
1436            Buffer += ((*(Buffer+1) | (*(Buffer+2) << 8)) + 3);
1437        }
1438        else
1439        {
1440            /* Small Descriptor.  End Tag will be found here */
1441
1442            if ((BufferByte & ACPI_RDESC_SMALL_MASK) == ACPI_RDESC_TYPE_END_TAG)
1443            {
1444                /* Found the end tag descriptor, all done. */
1445
1446                return (Buffer);
1447            }
1448
1449            /* Length is in the header */
1450
1451            Buffer += ((BufferByte & 0x07) + 1);
1452        }
1453    }
1454
1455    /* End tag not found */
1456
1457    return (NULL);
1458}
1459
1460
1461/*******************************************************************************
1462 *
1463 * FUNCTION:    AcpiUtReportError
1464 *
1465 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1466 *              LineNumber          - Caller's line number (for error output)
1467 *              ComponentId         - Caller's component ID (for error output)
1468 *              Message             - Error message to use on failure
1469 *
1470 * RETURN:      None
1471 *
1472 * DESCRIPTION: Print error message
1473 *
1474 ******************************************************************************/
1475
1476void
1477AcpiUtReportError (
1478    NATIVE_CHAR             *ModuleName,
1479    UINT32                  LineNumber,
1480    UINT32                  ComponentId)
1481{
1482
1483
1484    AcpiOsPrintf ("%8s-%04d: *** Error: ", ModuleName, LineNumber);
1485}
1486
1487
1488/*******************************************************************************
1489 *
1490 * FUNCTION:    AcpiUtReportWarning
1491 *
1492 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1493 *              LineNumber          - Caller's line number (for error output)
1494 *              ComponentId         - Caller's component ID (for error output)
1495 *              Message             - Error message to use on failure
1496 *
1497 * RETURN:      None
1498 *
1499 * DESCRIPTION: Print warning message
1500 *
1501 ******************************************************************************/
1502
1503void
1504AcpiUtReportWarning (
1505    NATIVE_CHAR             *ModuleName,
1506    UINT32                  LineNumber,
1507    UINT32                  ComponentId)
1508{
1509
1510    AcpiOsPrintf ("%8s-%04d: *** Warning: ", ModuleName, LineNumber);
1511}
1512
1513
1514/*******************************************************************************
1515 *
1516 * FUNCTION:    AcpiUtReportInfo
1517 *
1518 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1519 *              LineNumber          - Caller's line number (for error output)
1520 *              ComponentId         - Caller's component ID (for error output)
1521 *              Message             - Error message to use on failure
1522 *
1523 * RETURN:      None
1524 *
1525 * DESCRIPTION: Print information message
1526 *
1527 ******************************************************************************/
1528
1529void
1530AcpiUtReportInfo (
1531    NATIVE_CHAR             *ModuleName,
1532    UINT32                  LineNumber,
1533    UINT32                  ComponentId)
1534{
1535
1536    AcpiOsPrintf ("%8s-%04d: *** Info: ", ModuleName, LineNumber);
1537}
1538
1539
1540