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