Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: utmisc - common utility procedures
4
 *
5
 ******************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
11
 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12
 * All rights reserved.
13
 *
14
 * 2. License
15
 *
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
17
 * rights.  You may have additional license terms from the party that provided
18
 * you this software, covering your right to use that party's intellectual
19
 * property rights.
20
 *
21
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
 * copy of the source code appearing in this file ("Covered Code") an
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * make derivatives, distribute, use and display any portion of the Covered
26
 * Code in any form, with the right to sublicense such rights; and
27
 *
28
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
 * license (with the right to sublicense), under only those claims of Intel
30
 * patents that are infringed by the Original Intel Code, to make, use, sell,
31
 * offer to sell, and import the Covered Code and derivative works thereof
32
 * solely to the minimum extent necessary to exercise the above copyright
33
 * license, and in no event shall the patent license extend to any additions
34
 * to or modifications of the Original Intel Code.  No other license or right
35
 * is granted directly or by implication, estoppel or otherwise;
36
 *
37
 * The above copyright and patent license is granted only if the following
38
 * conditions are met:
39
 *
40
 * 3. Conditions
41
 *
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * Redistribution of source code of any substantial portion of the Covered
44
 * Code or modification with rights to further distribute source must include
45
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * Licensee must cause all Covered Code to which Licensee contributes to
48
 * contain a file documenting the changes Licensee made to create that Covered
49
 * Code and the date of any change.  Licensee must include in that file the
50
 * documentation of any changes made by any predecessor Licensee.  Licensee
51
 * must include a prominent statement that the modification is derived,
52
 * directly or indirectly, from Original Intel Code.
53
 *
54
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
 * Redistribution of source code of any substantial portion of the Covered
56
 * Code or modification without rights to further distribute source must
57
 * include the following Disclaimer and Export Compliance provision in the
58
 * documentation and/or other materials provided with distribution.  In
59
 * addition, Licensee may not authorize further sublicense of source of any
60
 * portion of the Covered Code, and must include terms to the effect that the
61
 * license from Licensee to its licensee is limited to the intellectual
62
 * property embodied in the software Licensee provides to its licensee, and
63
 * not to intellectual property embodied in modifications its licensee may
64
 * make.
65
 *
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * substantial portion of the Covered Code or modification must reproduce the
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * provision in the documentation and/or other materials provided with the
70
 * distribution.
71
 *
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * Intel Code.
74
 *
75
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
 * Intel shall be used in advertising or otherwise to promote the sale, use or
77
 * other dealings in products derived from or relating to the Covered Code
78
 * without prior written authorization from Intel.
79
 *
80
 * 4. Disclaimer and Export Compliance
81
 *
82
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * PARTICULAR PURPOSE.
89
 *
90
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * LIMITED REMEDY.
98
 *
99
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100
 * software or system incorporating such software without first obtaining any
101
 * required license or other approval from the U. S. Department of Commerce or
102
 * any other agency or department of the United States Government.  In the
103
 * event Licensee exports any such software from the United States or
104
 * re-exports any such software from a foreign destination, Licensee shall
105
 * ensure that the distribution and export/re-export of the software is in
106
 * compliance with all laws, regulations, orders, or other restrictions of the
107
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
 * any of its subsidiaries will export/re-export any technical data, process,
109
 * software, or service, directly or indirectly, to any country for which the
110
 * United States government or any agency thereof requires an export license,
111
 * other governmental approval, or letter of assurance, without first obtaining
112
 * such license, approval or letter.
113
 *
114
 *****************************************************************************/
115
 
116
 
117
#define __UTMISC_C__
118
 
119
#include "acpi.h"
120
#include "accommon.h"
121
#include "acnamesp.h"
122
 
123
 
124
#define _COMPONENT          ACPI_UTILITIES
125
        ACPI_MODULE_NAME    ("utmisc")
126
 
127
/*
128
 * Common suffix for messages
129
 */
130
#define ACPI_COMMON_MSG_SUFFIX \
131
    AcpiOsPrintf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, ModuleName, LineNumber)
132
 
133
 
134
/*******************************************************************************
135
 *
136
 * FUNCTION:    AcpiUtValidateException
137
 *
138
 * PARAMETERS:  Status       - The ACPI_STATUS code to be formatted
139
 *
140
 * RETURN:      A string containing the exception text. NULL if exception is
141
 *              not valid.
142
 *
143
 * DESCRIPTION: This function validates and translates an ACPI exception into
144
 *              an ASCII string.
145
 *
146
 ******************************************************************************/
147
 
148
const char *
149
AcpiUtValidateException (
150
    ACPI_STATUS             Status)
151
{
152
    UINT32                  SubStatus;
153
    const char              *Exception = NULL;
154
 
155
 
156
    ACPI_FUNCTION_ENTRY ();
157
 
158
 
159
    /*
160
     * Status is composed of two parts, a "type" and an actual code
161
     */
162
    SubStatus = (Status & ~AE_CODE_MASK);
163
 
164
    switch (Status & AE_CODE_MASK)
165
    {
166
    case AE_CODE_ENVIRONMENTAL:
167
 
168
        if (SubStatus <= AE_CODE_ENV_MAX)
169
        {
170
            Exception = AcpiGbl_ExceptionNames_Env [SubStatus];
171
        }
172
        break;
173
 
174
    case AE_CODE_PROGRAMMER:
175
 
176
        if (SubStatus <= AE_CODE_PGM_MAX)
177
        {
178
            Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus];
179
        }
180
        break;
181
 
182
    case AE_CODE_ACPI_TABLES:
183
 
184
        if (SubStatus <= AE_CODE_TBL_MAX)
185
        {
186
            Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus];
187
        }
188
        break;
189
 
190
    case AE_CODE_AML:
191
 
192
        if (SubStatus <= AE_CODE_AML_MAX)
193
        {
194
            Exception = AcpiGbl_ExceptionNames_Aml [SubStatus];
195
        }
196
        break;
197
 
198
    case AE_CODE_CONTROL:
199
 
200
        if (SubStatus <= AE_CODE_CTRL_MAX)
201
        {
202
            Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus];
203
        }
204
        break;
205
 
206
    default:
207
        break;
208
    }
209
 
210
    return (ACPI_CAST_PTR (const char, Exception));
211
}
212
 
213
 
214
/*******************************************************************************
215
 *
216
 * FUNCTION:    AcpiUtIsPciRootBridge
217
 *
218
 * PARAMETERS:  Id              - The HID/CID in string format
219
 *
220
 * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
221
 *
222
 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
223
 *
224
 ******************************************************************************/
225
 
226
BOOLEAN
227
AcpiUtIsPciRootBridge (
228
    char                    *Id)
229
{
230
 
231
    /*
232
     * Check if this is a PCI root bridge.
233
     * ACPI 3.0+: check for a PCI Express root also.
234
     */
235
    if (!(ACPI_STRCMP (Id,
236
            PCI_ROOT_HID_STRING)) ||
237
 
238
        !(ACPI_STRCMP (Id,
239
            PCI_EXPRESS_ROOT_HID_STRING)))
240
    {
241
        return (TRUE);
242
    }
243
 
244
    return (FALSE);
245
}
246
 
247
 
248
/*******************************************************************************
249
 *
250
 * FUNCTION:    AcpiUtIsAmlTable
251
 *
252
 * PARAMETERS:  Table               - An ACPI table
253
 *
254
 * RETURN:      TRUE if table contains executable AML; FALSE otherwise
255
 *
256
 * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
257
 *              Currently, these are DSDT,SSDT,PSDT. All other table types are
258
 *              data tables that do not contain AML code.
259
 *
260
 ******************************************************************************/
261
 
262
BOOLEAN
263
AcpiUtIsAmlTable (
264
    ACPI_TABLE_HEADER       *Table)
265
{
266
 
267
    /* These are the only tables that contain executable AML */
268
 
269
    if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
270
        ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
271
        ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
272
    {
273
        return (TRUE);
274
    }
275
 
276
    return (FALSE);
277
}
278
 
279
 
280
/*******************************************************************************
281
 *
282
 * FUNCTION:    AcpiUtAllocateOwnerId
283
 *
284
 * PARAMETERS:  OwnerId         - Where the new owner ID is returned
285
 *
286
 * RETURN:      Status
287
 *
288
 * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
289
 *              track objects created by the table or method, to be deleted
290
 *              when the method exits or the table is unloaded.
291
 *
292
 ******************************************************************************/
293
 
294
ACPI_STATUS
295
AcpiUtAllocateOwnerId (
296
    ACPI_OWNER_ID           *OwnerId)
297
{
298
    UINT32                  i;
299
    UINT32                  j;
300
    UINT32                  k;
301
    ACPI_STATUS             Status;
302
 
303
 
304
    ACPI_FUNCTION_TRACE (UtAllocateOwnerId);
305
 
306
 
307
    /* Guard against multiple allocations of ID to the same location */
308
 
309
    if (*OwnerId)
310
    {
311
        ACPI_ERROR ((AE_INFO, "Owner ID [0x%2.2X] already exists", *OwnerId));
312
        return_ACPI_STATUS (AE_ALREADY_EXISTS);
313
    }
314
 
315
    /* Mutex for the global ID mask */
316
 
317
    Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
318
    if (ACPI_FAILURE (Status))
319
    {
320
        return_ACPI_STATUS (Status);
321
    }
322
 
323
    /*
324
     * Find a free owner ID, cycle through all possible IDs on repeated
325
     * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
326
     * to be scanned twice.
327
     */
328
    for (i = 0, j = AcpiGbl_LastOwnerIdIndex;
329
         i < (ACPI_NUM_OWNERID_MASKS + 1);
330
         i++, j++)
331
    {
332
        if (j >= ACPI_NUM_OWNERID_MASKS)
333
        {
334
            j = 0;  /* Wraparound to start of mask array */
335
        }
336
 
337
        for (k = AcpiGbl_NextOwnerIdOffset; k < 32; k++)
338
        {
339
            if (AcpiGbl_OwnerIdMask[j] == ACPI_UINT32_MAX)
340
            {
341
                /* There are no free IDs in this mask */
342
 
343
                break;
344
            }
345
 
346
            if (!(AcpiGbl_OwnerIdMask[j] & (1 << k)))
347
            {
348
                /*
349
                 * Found a free ID. The actual ID is the bit index plus one,
350
                 * making zero an invalid Owner ID. Save this as the last ID
351
                 * allocated and update the global ID mask.
352
                 */
353
                AcpiGbl_OwnerIdMask[j] |= (1 << k);
354
 
355
                AcpiGbl_LastOwnerIdIndex = (UINT8) j;
356
                AcpiGbl_NextOwnerIdOffset = (UINT8) (k + 1);
357
 
358
                /*
359
                 * Construct encoded ID from the index and bit position
360
                 *
361
                 * Note: Last [j].k (bit 255) is never used and is marked
362
                 * permanently allocated (prevents +1 overflow)
363
                 */
364
                *OwnerId = (ACPI_OWNER_ID) ((k + 1) + ACPI_MUL_32 (j));
365
 
366
                ACPI_DEBUG_PRINT ((ACPI_DB_VALUES,
367
                    "Allocated OwnerId: %2.2X\n", (unsigned int) *OwnerId));
368
                goto Exit;
369
            }
370
        }
371
 
372
        AcpiGbl_NextOwnerIdOffset = 0;
373
    }
374
 
375
    /*
376
     * All OwnerIds have been allocated. This typically should
377
     * not happen since the IDs are reused after deallocation. The IDs are
378
     * allocated upon table load (one per table) and method execution, and
379
     * they are released when a table is unloaded or a method completes
380
     * execution.
381
     *
382
     * If this error happens, there may be very deep nesting of invoked control
383
     * methods, or there may be a bug where the IDs are not released.
384
     */
385
    Status = AE_OWNER_ID_LIMIT;
386
    ACPI_ERROR ((AE_INFO,
387
        "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
388
 
389
Exit:
390
    (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
391
    return_ACPI_STATUS (Status);
392
}
393
 
394
 
395
/*******************************************************************************
396
 *
397
 * FUNCTION:    AcpiUtReleaseOwnerId
398
 *
399
 * PARAMETERS:  OwnerIdPtr          - Pointer to a previously allocated OwnerID
400
 *
401
 * RETURN:      None. No error is returned because we are either exiting a
402
 *              control method or unloading a table. Either way, we would
403
 *              ignore any error anyway.
404
 *
405
 * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 255
406
 *
407
 ******************************************************************************/
408
 
409
void
410
AcpiUtReleaseOwnerId (
411
    ACPI_OWNER_ID           *OwnerIdPtr)
412
{
413
    ACPI_OWNER_ID           OwnerId = *OwnerIdPtr;
414
    ACPI_STATUS             Status;
415
    UINT32                  Index;
416
    UINT32                  Bit;
417
 
418
 
419
    ACPI_FUNCTION_TRACE_U32 (UtReleaseOwnerId, OwnerId);
420
 
421
 
422
    /* Always clear the input OwnerId (zero is an invalid ID) */
423
 
424
    *OwnerIdPtr = 0;
425
 
426
    /* Zero is not a valid OwnerID */
427
 
428
    if (OwnerId == 0)
429
    {
430
        ACPI_ERROR ((AE_INFO, "Invalid OwnerId: 0x%2.2X", OwnerId));
431
        return_VOID;
432
    }
433
 
434
    /* Mutex for the global ID mask */
435
 
436
    Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
437
    if (ACPI_FAILURE (Status))
438
    {
439
        return_VOID;
440
    }
441
 
442
    /* Normalize the ID to zero */
443
 
444
    OwnerId--;
445
 
446
    /* Decode ID to index/offset pair */
447
 
448
    Index = ACPI_DIV_32 (OwnerId);
449
    Bit = 1 << ACPI_MOD_32 (OwnerId);
450
 
451
    /* Free the owner ID only if it is valid */
452
 
453
    if (AcpiGbl_OwnerIdMask[Index] & Bit)
454
    {
455
        AcpiGbl_OwnerIdMask[Index] ^= Bit;
456
    }
457
    else
458
    {
459
        ACPI_ERROR ((AE_INFO,
460
            "Release of non-allocated OwnerId: 0x%2.2X", OwnerId + 1));
461
    }
462
 
463
    (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
464
    return_VOID;
465
}
466
 
467
 
468
/*******************************************************************************
469
 *
470
 * FUNCTION:    AcpiUtStrupr (strupr)
471
 *
472
 * PARAMETERS:  SrcString       - The source string to convert
473
 *
474
 * RETURN:      None
475
 *
476
 * DESCRIPTION: Convert string to uppercase
477
 *
478
 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
479
 *
480
 ******************************************************************************/
481
 
482
void
483
AcpiUtStrupr (
484
    char                    *SrcString)
485
{
486
    char                    *String;
487
 
488
 
489
    ACPI_FUNCTION_ENTRY ();
490
 
491
 
492
    if (!SrcString)
493
    {
494
        return;
495
    }
496
 
497
    /* Walk entire string, uppercasing the letters */
498
 
499
    for (String = SrcString; *String; String++)
500
    {
501
        *String = (char) ACPI_TOUPPER (*String);
502
    }
503
 
504
    return;
505
}
506
 
507
 
508
/*******************************************************************************
509
 *
510
 * FUNCTION:    AcpiUtPrintString
511
 *
512
 * PARAMETERS:  String          - Null terminated ASCII string
513
 *              MaxLength       - Maximum output length
514
 *
515
 * RETURN:      None
516
 *
517
 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
518
 *              sequences.
519
 *
520
 ******************************************************************************/
521
 
522
void
523
AcpiUtPrintString (
524
    char                    *String,
525
    UINT8                   MaxLength)
526
{
527
    UINT32                  i;
528
 
529
 
530
    if (!String)
531
    {
532
        AcpiOsPrintf ("<\"NULL STRING PTR\">");
533
        return;
534
    }
535
 
536
    AcpiOsPrintf ("\"");
537
    for (i = 0; String[i] && (i < MaxLength); i++)
538
    {
539
        /* Escape sequences */
540
 
541
        switch (String[i])
542
        {
543
        case 0x07:
544
            AcpiOsPrintf ("\\a");       /* BELL */
545
            break;
546
 
547
        case 0x08:
548
            AcpiOsPrintf ("\\b");       /* BACKSPACE */
549
            break;
550
 
551
        case 0x0C:
552
            AcpiOsPrintf ("\\f");       /* FORMFEED */
553
            break;
554
 
555
        case 0x0A:
556
            AcpiOsPrintf ("\\n");       /* LINEFEED */
557
            break;
558
 
559
        case 0x0D:
560
            AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
561
            break;
562
 
563
        case 0x09:
564
            AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
565
            break;
566
 
567
        case 0x0B:
568
            AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
569
            break;
570
 
571
        case '\'':                      /* Single Quote */
572
        case '\"':                      /* Double Quote */
573
        case '\\':                      /* Backslash */
574
            AcpiOsPrintf ("\\%c", (int) String[i]);
575
            break;
576
 
577
        default:
578
 
579
            /* Check for printable character or hex escape */
580
 
581
            if (ACPI_IS_PRINT (String[i]))
582
            {
583
                /* This is a normal character */
584
 
585
                AcpiOsPrintf ("%c", (int) String[i]);
586
            }
587
            else
588
            {
589
                /* All others will be Hex escapes */
590
 
591
                AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
592
            }
593
            break;
594
        }
595
    }
596
    AcpiOsPrintf ("\"");
597
 
598
    if (i == MaxLength && String[i])
599
    {
600
        AcpiOsPrintf ("...");
601
    }
602
}
603
 
604
 
605
/*******************************************************************************
606
 *
607
 * FUNCTION:    AcpiUtDwordByteSwap
608
 *
609
 * PARAMETERS:  Value           - Value to be converted
610
 *
611
 * RETURN:      UINT32 integer with bytes swapped
612
 *
613
 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
614
 *
615
 ******************************************************************************/
616
 
617
UINT32
618
AcpiUtDwordByteSwap (
619
    UINT32                  Value)
620
{
621
    union
622
    {
623
        UINT32              Value;
624
        UINT8               Bytes[4];
625
    } Out;
626
    union
627
    {
628
        UINT32              Value;
629
        UINT8               Bytes[4];
630
    } In;
631
 
632
 
633
    ACPI_FUNCTION_ENTRY ();
634
 
635
 
636
    In.Value = Value;
637
 
638
    Out.Bytes[0] = In.Bytes[3];
639
    Out.Bytes[1] = In.Bytes[2];
640
    Out.Bytes[2] = In.Bytes[1];
641
    Out.Bytes[3] = In.Bytes[0];
642
 
643
    return (Out.Value);
644
}
645
 
646
 
647
/*******************************************************************************
648
 *
649
 * FUNCTION:    AcpiUtSetIntegerWidth
650
 *
651
 * PARAMETERS:  Revision            From DSDT header
652
 *
653
 * RETURN:      None
654
 *
655
 * DESCRIPTION: Set the global integer bit width based upon the revision
656
 *              of the DSDT.  For Revision 1 and 0, Integers are 32 bits.
657
 *              For Revision 2 and above, Integers are 64 bits.  Yes, this
658
 *              makes a difference.
659
 *
660
 ******************************************************************************/
661
 
662
void
663
AcpiUtSetIntegerWidth (
664
    UINT8                   Revision)
665
{
666
 
667
    if (Revision < 2)
668
    {
669
        /* 32-bit case */
670
 
671
        AcpiGbl_IntegerBitWidth    = 32;
672
        AcpiGbl_IntegerNybbleWidth = 8;
673
        AcpiGbl_IntegerByteWidth   = 4;
674
    }
675
    else
676
    {
677
        /* 64-bit case (ACPI 2.0+) */
678
 
679
        AcpiGbl_IntegerBitWidth    = 64;
680
        AcpiGbl_IntegerNybbleWidth = 16;
681
        AcpiGbl_IntegerByteWidth   = 8;
682
    }
683
}
684
 
685
 
686
#ifdef ACPI_DEBUG_OUTPUT
687
/*******************************************************************************
688
 *
689
 * FUNCTION:    AcpiUtDisplayInitPathname
690
 *
691
 * PARAMETERS:  Type                - Object type of the node
692
 *              ObjHandle           - Handle whose pathname will be displayed
693
 *              Path                - Additional path string to be appended.
694
 *                                      (NULL if no extra path)
695
 *
696
 * RETURN:      ACPI_STATUS
697
 *
698
 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
699
 *
700
 ******************************************************************************/
701
 
702
void
703
AcpiUtDisplayInitPathname (
704
    UINT8                   Type,
705
    ACPI_NAMESPACE_NODE     *ObjHandle,
706
    char                    *Path)
707
{
708
    ACPI_STATUS             Status;
709
    ACPI_BUFFER             Buffer;
710
 
711
 
712
    ACPI_FUNCTION_ENTRY ();
713
 
714
 
715
    /* Only print the path if the appropriate debug level is enabled */
716
 
717
    if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
718
    {
719
        return;
720
    }
721
 
722
    /* Get the full pathname to the node */
723
 
724
    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
725
    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
726
    if (ACPI_FAILURE (Status))
727
    {
728
        return;
729
    }
730
 
731
    /* Print what we're doing */
732
 
733
    switch (Type)
734
    {
735
    case ACPI_TYPE_METHOD:
736
        AcpiOsPrintf ("Executing    ");
737
        break;
738
 
739
    default:
740
        AcpiOsPrintf ("Initializing ");
741
        break;
742
    }
743
 
744
    /* Print the object type and pathname */
745
 
746
    AcpiOsPrintf ("%-12s  %s",
747
        AcpiUtGetTypeName (Type), (char *) Buffer.Pointer);
748
 
749
    /* Extra path is used to append names like _STA, _INI, etc. */
750
 
751
    if (Path)
752
    {
753
        AcpiOsPrintf (".%s", Path);
754
    }
755
    AcpiOsPrintf ("\n");
756
 
757
    ACPI_FREE (Buffer.Pointer);
758
}
759
#endif
760
 
761
 
762
/*******************************************************************************
763
 *
764
 * FUNCTION:    AcpiUtValidAcpiChar
765
 *
766
 * PARAMETERS:  Char            - The character to be examined
767
 *              Position        - Byte position (0-3)
768
 *
769
 * RETURN:      TRUE if the character is valid, FALSE otherwise
770
 *
771
 * DESCRIPTION: Check for a valid ACPI character. Must be one of:
772
 *              1) Upper case alpha
773
 *              2) numeric
774
 *              3) underscore
775
 *
776
 *              We allow a '!' as the last character because of the ASF! table
777
 *
778
 ******************************************************************************/
779
 
780
BOOLEAN
781
AcpiUtValidAcpiChar (
782
    char                    Character,
783
    UINT32                  Position)
784
{
785
 
786
    if (!((Character >= 'A' && Character <= 'Z') ||
787
          (Character >= '0' && Character <= '9') ||
788
          (Character == '_')))
789
    {
790
        /* Allow a '!' in the last position */
791
 
792
        if (Character == '!' && Position == 3)
793
        {
794
            return (TRUE);
795
        }
796
 
797
        return (FALSE);
798
    }
799
 
800
    return (TRUE);
801
}
802
 
803
 
804
/*******************************************************************************
805
 *
806
 * FUNCTION:    AcpiUtValidAcpiName
807
 *
808
 * PARAMETERS:  Name            - The name to be examined
809
 *
810
 * RETURN:      TRUE if the name is valid, FALSE otherwise
811
 *
812
 * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
813
 *              1) Upper case alpha
814
 *              2) numeric
815
 *              3) underscore
816
 *
817
 ******************************************************************************/
818
 
819
BOOLEAN
820
AcpiUtValidAcpiName (
821
    UINT32                  Name)
822
{
823
    UINT32                  i;
824
 
825
 
826
    ACPI_FUNCTION_ENTRY ();
827
 
828
 
829
    for (i = 0; i < ACPI_NAME_SIZE; i++)
830
    {
831
        if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i))
832
        {
833
            return (FALSE);
834
        }
835
    }
836
 
837
    return (TRUE);
838
}
839
 
840
 
841
/*******************************************************************************
842
 *
843
 * FUNCTION:    AcpiUtRepairName
844
 *
845
 * PARAMETERS:  Name            - The ACPI name to be repaired
846
 *
847
 * RETURN:      Repaired version of the name
848
 *
849
 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
850
 *              return the new name. NOTE: the Name parameter must reside in
851
 *              read/write memory, cannot be a const.
852
 *
853
 * An ACPI Name must consist of valid ACPI characters. We will repair the name
854
 * if necessary because we don't want to abort because of this, but we want
855
 * all namespace names to be printable. A warning message is appropriate.
856
 *
857
 * This issue came up because there are in fact machines that exhibit
858
 * this problem, and we want to be able to enable ACPI support for them,
859
 * even though there are a few bad names.
860
 *
861
 ******************************************************************************/
862
 
863
void
864
AcpiUtRepairName (
865
    char                    *Name)
866
{
867
    UINT32                  i;
868
    BOOLEAN                 FoundBadChar = FALSE;
869
 
870
 
871
    ACPI_FUNCTION_NAME (UtRepairName);
872
 
873
 
874
    /* Check each character in the name */
875
 
876
    for (i = 0; i < ACPI_NAME_SIZE; i++)
877
    {
878
        if (AcpiUtValidAcpiChar (Name[i], i))
879
        {
880
            continue;
881
        }
882
 
883
        /*
884
         * Replace a bad character with something printable, yet technically
885
         * still invalid. This prevents any collisions with existing "good"
886
         * names in the namespace.
887
         */
888
        Name[i] = '*';
889
        FoundBadChar = TRUE;
890
    }
891
 
892
    if (FoundBadChar)
893
    {
894
        /* Report warning only if in strict mode or debug mode */
895
 
896
        if (!AcpiGbl_EnableInterpreterSlack)
897
        {
898
            ACPI_WARNING ((AE_INFO,
899
                "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
900
        }
901
        else
902
        {
903
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
904
                "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
905
        }
906
    }
907
}
908
 
909
 
910
/*******************************************************************************
911
 *
912
 * FUNCTION:    AcpiUtStrtoul64
913
 *
914
 * PARAMETERS:  String          - Null terminated string
915
 *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
916
 *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
917
 *              RetInteger      - Where the converted integer is returned
918
 *
919
 * RETURN:      Status and Converted value
920
 *
921
 * DESCRIPTION: Convert a string into an unsigned value. Performs either a
922
 *              32-bit or 64-bit conversion, depending on the current mode
923
 *              of the interpreter.
924
 *              NOTE: Does not support Octal strings, not needed.
925
 *
926
 ******************************************************************************/
927
 
928
ACPI_STATUS
929
AcpiUtStrtoul64 (
930
    char                    *String,
931
    UINT32                  Base,
932
    UINT64                  *RetInteger)
933
{
934
    UINT32                  ThisDigit = 0;
935
    UINT64                  ReturnValue = 0;
936
    UINT64                  Quotient;
937
    UINT64                  Dividend;
938
    UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
939
    UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
940
    UINT8                   ValidDigits = 0;
941
    UINT8                   SignOf0x = 0;
942
    UINT8                   Term = 0;
943
 
944
 
945
    ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
946
 
947
 
948
    switch (Base)
949
    {
950
    case ACPI_ANY_BASE:
951
    case 16:
952
        break;
953
 
954
    default:
955
        /* Invalid Base */
956
        return_ACPI_STATUS (AE_BAD_PARAMETER);
957
    }
958
 
959
    if (!String)
960
    {
961
        goto ErrorExit;
962
    }
963
 
964
    /* Skip over any white space in the buffer */
965
 
966
    while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
967
    {
968
        String++;
969
    }
970
 
971
    if (ToIntegerOp)
972
    {
973
        /*
974
         * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
975
         * We need to determine if it is decimal or hexadecimal.
976
         */
977
        if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
978
        {
979
            SignOf0x = 1;
980
            Base = 16;
981
 
982
            /* Skip over the leading '0x' */
983
            String += 2;
984
        }
985
        else
986
        {
987
            Base = 10;
988
        }
989
    }
990
 
991
    /* Any string left? Check that '0x' is not followed by white space. */
992
 
993
    if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
994
    {
995
        if (ToIntegerOp)
996
        {
997
            goto ErrorExit;
998
        }
999
        else
1000
        {
1001
            goto AllDone;
1002
        }
1003
    }
1004
 
1005
    /*
1006
     * Perform a 32-bit or 64-bit conversion, depending upon the current
1007
     * execution mode of the interpreter
1008
     */
1009
    Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
1010
 
1011
    /* Main loop: convert the string to a 32- or 64-bit integer */
1012
 
1013
    while (*String)
1014
    {
1015
        if (ACPI_IS_DIGIT (*String))
1016
        {
1017
            /* Convert ASCII 0-9 to Decimal value */
1018
 
1019
            ThisDigit = ((UINT8) *String) - '0';
1020
        }
1021
        else if (Base == 10)
1022
        {
1023
            /* Digit is out of range; possible in ToInteger case only */
1024
 
1025
            Term = 1;
1026
        }
1027
        else
1028
        {
1029
            ThisDigit = (UINT8) ACPI_TOUPPER (*String);
1030
            if (ACPI_IS_XDIGIT ((char) ThisDigit))
1031
            {
1032
                /* Convert ASCII Hex char to value */
1033
 
1034
                ThisDigit = ThisDigit - 'A' + 10;
1035
            }
1036
            else
1037
            {
1038
                Term = 1;
1039
            }
1040
        }
1041
 
1042
        if (Term)
1043
        {
1044
            if (ToIntegerOp)
1045
            {
1046
                goto ErrorExit;
1047
            }
1048
            else
1049
            {
1050
                break;
1051
            }
1052
        }
1053
        else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
1054
        {
1055
            /* Skip zeros */
1056
            String++;
1057
            continue;
1058
        }
1059
 
1060
        ValidDigits++;
1061
 
1062
        if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
1063
        {
1064
            /*
1065
             * This is ToInteger operation case.
1066
             * No any restrictions for string-to-integer conversion,
1067
             * see ACPI spec.
1068
             */
1069
            goto ErrorExit;
1070
        }
1071
 
1072
        /* Divide the digit into the correct position */
1073
 
1074
        (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
1075
                    Base, &Quotient, NULL);
1076
 
1077
        if (ReturnValue > Quotient)
1078
        {
1079
            if (ToIntegerOp)
1080
            {
1081
                goto ErrorExit;
1082
            }
1083
            else
1084
            {
1085
                break;
1086
            }
1087
        }
1088
 
1089
        ReturnValue *= Base;
1090
        ReturnValue += ThisDigit;
1091
        String++;
1092
    }
1093
 
1094
    /* All done, normal exit */
1095
 
1096
AllDone:
1097
 
1098
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
1099
        ACPI_FORMAT_UINT64 (ReturnValue)));
1100
 
1101
    *RetInteger = ReturnValue;
1102
    return_ACPI_STATUS (AE_OK);
1103
 
1104
 
1105
ErrorExit:
1106
    /* Base was set/validated above */
1107
 
1108
    if (Base == 10)
1109
    {
1110
        return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
1111
    }
1112
    else
1113
    {
1114
        return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
1115
    }
1116
}
1117
 
1118
 
1119
/*******************************************************************************
1120
 *
1121
 * FUNCTION:    AcpiUtCreateUpdateStateAndPush
1122
 *
1123
 * PARAMETERS:  Object          - Object to be added to the new state
1124
 *              Action          - Increment/Decrement
1125
 *              StateList       - List the state will be added to
1126
 *
1127
 * RETURN:      Status
1128
 *
1129
 * DESCRIPTION: Create a new state and push it
1130
 *
1131
 ******************************************************************************/
1132
 
1133
ACPI_STATUS
1134
AcpiUtCreateUpdateStateAndPush (
1135
    ACPI_OPERAND_OBJECT     *Object,
1136
    UINT16                  Action,
1137
    ACPI_GENERIC_STATE      **StateList)
1138
{
1139
    ACPI_GENERIC_STATE       *State;
1140
 
1141
 
1142
    ACPI_FUNCTION_ENTRY ();
1143
 
1144
 
1145
    /* Ignore null objects; these are expected */
1146
 
1147
    if (!Object)
1148
    {
1149
        return (AE_OK);
1150
    }
1151
 
1152
    State = AcpiUtCreateUpdateState (Object, Action);
1153
    if (!State)
1154
    {
1155
        return (AE_NO_MEMORY);
1156
    }
1157
 
1158
    AcpiUtPushGenericState (StateList, State);
1159
    return (AE_OK);
1160
}
1161
 
1162
 
1163
/*******************************************************************************
1164
 *
1165
 * FUNCTION:    AcpiUtWalkPackageTree
1166
 *
1167
 * PARAMETERS:  SourceObject        - The package to walk
1168
 *              TargetObject        - Target object (if package is being copied)
1169
 *              WalkCallback        - Called once for each package element
1170
 *              Context             - Passed to the callback function
1171
 *
1172
 * RETURN:      Status
1173
 *
1174
 * DESCRIPTION: Walk through a package
1175
 *
1176
 ******************************************************************************/
1177
 
1178
ACPI_STATUS
1179
AcpiUtWalkPackageTree (
1180
    ACPI_OPERAND_OBJECT     *SourceObject,
1181
    void                    *TargetObject,
1182
    ACPI_PKG_CALLBACK       WalkCallback,
1183
    void                    *Context)
1184
{
1185
    ACPI_STATUS             Status = AE_OK;
1186
    ACPI_GENERIC_STATE      *StateList = NULL;
1187
    ACPI_GENERIC_STATE      *State;
1188
    UINT32                  ThisIndex;
1189
    ACPI_OPERAND_OBJECT     *ThisSourceObj;
1190
 
1191
 
1192
    ACPI_FUNCTION_TRACE (UtWalkPackageTree);
1193
 
1194
 
1195
    State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
1196
    if (!State)
1197
    {
1198
        return_ACPI_STATUS (AE_NO_MEMORY);
1199
    }
1200
 
1201
    while (State)
1202
    {
1203
        /* Get one element of the package */
1204
 
1205
        ThisIndex     = State->Pkg.Index;
1206
        ThisSourceObj = (ACPI_OPERAND_OBJECT *)
1207
                        State->Pkg.SourceObject->Package.Elements[ThisIndex];
1208
 
1209
        /*
1210
         * Check for:
1211
         * 1) An uninitialized package element.  It is completely
1212
         *    legal to declare a package and leave it uninitialized
1213
         * 2) Not an internal object - can be a namespace node instead
1214
         * 3) Any type other than a package.  Packages are handled in else
1215
         *    case below.
1216
         */
1217
        if ((!ThisSourceObj) ||
1218
            (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
1219
            (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE))
1220
        {
1221
            Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
1222
                                    State, Context);
1223
            if (ACPI_FAILURE (Status))
1224
            {
1225
                return_ACPI_STATUS (Status);
1226
            }
1227
 
1228
            State->Pkg.Index++;
1229
            while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
1230
            {
1231
                /*
1232
                 * We've handled all of the objects at this level,  This means
1233
                 * that we have just completed a package.  That package may
1234
                 * have contained one or more packages itself.
1235
                 *
1236
                 * Delete this state and pop the previous state (package).
1237
                 */
1238
                AcpiUtDeleteGenericState (State);
1239
                State = AcpiUtPopGenericState (&StateList);
1240
 
1241
                /* Finished when there are no more states */
1242
 
1243
                if (!State)
1244
                {
1245
                    /*
1246
                     * We have handled all of the objects in the top level
1247
                     * package just add the length of the package objects
1248
                     * and exit
1249
                     */
1250
                    return_ACPI_STATUS (AE_OK);
1251
                }
1252
 
1253
                /*
1254
                 * Go back up a level and move the index past the just
1255
                 * completed package object.
1256
                 */
1257
                State->Pkg.Index++;
1258
            }
1259
        }
1260
        else
1261
        {
1262
            /* This is a subobject of type package */
1263
 
1264
            Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
1265
                                        State, Context);
1266
            if (ACPI_FAILURE (Status))
1267
            {
1268
                return_ACPI_STATUS (Status);
1269
            }
1270
 
1271
            /*
1272
             * Push the current state and create a new one
1273
             * The callback above returned a new target package object.
1274
             */
1275
            AcpiUtPushGenericState (&StateList, State);
1276
            State = AcpiUtCreatePkgState (ThisSourceObj,
1277
                                            State->Pkg.ThisTargetObj, 0);
1278
            if (!State)
1279
            {
1280
                /* Free any stacked Update State objects */
1281
 
1282
                while (StateList)
1283
                {
1284
                    State = AcpiUtPopGenericState (&StateList);
1285
                    AcpiUtDeleteGenericState (State);
1286
                }
1287
                return_ACPI_STATUS (AE_NO_MEMORY);
1288
            }
1289
        }
1290
    }
1291
 
1292
    /* We should never get here */
1293
 
1294
    return_ACPI_STATUS (AE_AML_INTERNAL);
1295
}
1296
 
1297
 
1298
/*******************************************************************************
1299
 *
1300
 * FUNCTION:    AcpiError, AcpiException, AcpiWarning, AcpiInfo
1301
 *
1302
 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1303
 *              LineNumber          - Caller's line number (for error output)
1304
 *              Format              - Printf format string + additional args
1305
 *
1306
 * RETURN:      None
1307
 *
1308
 * DESCRIPTION: Print message with module/line/version info
1309
 *
1310
 ******************************************************************************/
1311
 
1312
void  ACPI_INTERNAL_VAR_XFACE
1313
AcpiError (
1314
    const char              *ModuleName,
1315
    UINT32                  LineNumber,
1316
    const char              *Format,
1317
    ...)
1318
{
1319
    va_list                 args;
1320
 
1321
 
1322
    AcpiOsPrintf ("ACPI Error: ");
1323
 
1324
    va_start (args, Format);
1325
    AcpiOsVprintf (Format, args);
1326
    ACPI_COMMON_MSG_SUFFIX;
1327
    va_end (args);
1328
}
1329
 
1330
void  ACPI_INTERNAL_VAR_XFACE
1331
AcpiException (
1332
    const char              *ModuleName,
1333
    UINT32                  LineNumber,
1334
    ACPI_STATUS             Status,
1335
    const char              *Format,
1336
    ...)
1337
{
1338
    va_list                 args;
1339
 
1340
 
1341
    AcpiOsPrintf ("ACPI Exception: %s, ", AcpiFormatException (Status));
1342
 
1343
    va_start (args, Format);
1344
    AcpiOsVprintf (Format, args);
1345
    ACPI_COMMON_MSG_SUFFIX;
1346
    va_end (args);
1347
}
1348
 
1349
void  ACPI_INTERNAL_VAR_XFACE
1350
AcpiWarning (
1351
    const char              *ModuleName,
1352
    UINT32                  LineNumber,
1353
    const char              *Format,
1354
    ...)
1355
{
1356
    va_list                 args;
1357
 
1358
 
1359
    AcpiOsPrintf ("ACPI Warning: ");
1360
 
1361
    va_start (args, Format);
1362
    AcpiOsVprintf (Format, args);
1363
    ACPI_COMMON_MSG_SUFFIX;
1364
    va_end (args);
1365
}
1366
 
1367
void  ACPI_INTERNAL_VAR_XFACE
1368
AcpiInfo (
1369
    const char              *ModuleName,
1370
    UINT32                  LineNumber,
1371
    const char              *Format,
1372
    ...)
1373
{
1374
    va_list                 args;
1375
 
1376
 
1377
    AcpiOsPrintf ("ACPI: ");
1378
 
1379
    va_start (args, Format);
1380
    AcpiOsVprintf (Format, args);
1381
    AcpiOsPrintf ("\n");
1382
    va_end (args);
1383
}
1384
 
1385
ACPI_EXPORT_SYMBOL (AcpiError)
1386
ACPI_EXPORT_SYMBOL (AcpiException)
1387
ACPI_EXPORT_SYMBOL (AcpiWarning)
1388
ACPI_EXPORT_SYMBOL (AcpiInfo)
1389
 
1390
 
1391
/*******************************************************************************
1392
 *
1393
 * FUNCTION:    AcpiUtPredefinedWarning
1394
 *
1395
 * PARAMETERS:  ModuleName      - Caller's module name (for error output)
1396
 *              LineNumber      - Caller's line number (for error output)
1397
 *              Pathname        - Full pathname to the node
1398
 *              NodeFlags       - From Namespace node for the method/object
1399
 *              Format          - Printf format string + additional args
1400
 *
1401
 * RETURN:      None
1402
 *
1403
 * DESCRIPTION: Warnings for the predefined validation module. Messages are
1404
 *              only emitted the first time a problem with a particular
1405
 *              method/object is detected. This prevents a flood of error
1406
 *              messages for methods that are repeatedly evaluated.
1407
 *
1408
 ******************************************************************************/
1409
 
1410
void  ACPI_INTERNAL_VAR_XFACE
1411
AcpiUtPredefinedWarning (
1412
    const char              *ModuleName,
1413
    UINT32                  LineNumber,
1414
    char                    *Pathname,
1415
    UINT8                   NodeFlags,
1416
    const char              *Format,
1417
    ...)
1418
{
1419
    va_list                 args;
1420
 
1421
 
1422
    /*
1423
     * Warning messages for this method/object will be disabled after the
1424
     * first time a validation fails or an object is successfully repaired.
1425
     */
1426
    if (NodeFlags & ANOBJ_EVALUATED)
1427
    {
1428
        return;
1429
    }
1430
 
1431
    AcpiOsPrintf ("ACPI Warning for %s: ", Pathname);
1432
 
1433
    va_start (args, Format);
1434
    AcpiOsVprintf (Format, args);
1435
    ACPI_COMMON_MSG_SUFFIX;
1436
    va_end (args);
1437
}
1438
 
1439
/*******************************************************************************
1440
 *
1441
 * FUNCTION:    AcpiUtPredefinedInfo
1442
 *
1443
 * PARAMETERS:  ModuleName      - Caller's module name (for error output)
1444
 *              LineNumber      - Caller's line number (for error output)
1445
 *              Pathname        - Full pathname to the node
1446
 *              NodeFlags       - From Namespace node for the method/object
1447
 *              Format          - Printf format string + additional args
1448
 *
1449
 * RETURN:      None
1450
 *
1451
 * DESCRIPTION: Info messages for the predefined validation module. Messages
1452
 *              are only emitted the first time a problem with a particular
1453
 *              method/object is detected. This prevents a flood of
1454
 *              messages for methods that are repeatedly evaluated.
1455
 *
1456
 ******************************************************************************/
1457
 
1458
void  ACPI_INTERNAL_VAR_XFACE
1459
AcpiUtPredefinedInfo (
1460
    const char              *ModuleName,
1461
    UINT32                  LineNumber,
1462
    char                    *Pathname,
1463
    UINT8                   NodeFlags,
1464
    const char              *Format,
1465
    ...)
1466
{
1467
    va_list                 args;
1468
 
1469
 
1470
    /*
1471
     * Warning messages for this method/object will be disabled after the
1472
     * first time a validation fails or an object is successfully repaired.
1473
     */
1474
    if (NodeFlags & ANOBJ_EVALUATED)
1475
    {
1476
        return;
1477
    }
1478
 
1479
    AcpiOsPrintf ("ACPI Info for %s: ", Pathname);
1480
 
1481
    va_start (args, Format);
1482
    AcpiOsVprintf (Format, args);
1483
    ACPI_COMMON_MSG_SUFFIX;
1484
    va_end (args);
1485
}