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