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