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: nsutils - Utilities for accessing ACPI namespace, accessing
4
 *                        parents and siblings and Scope manipulation
5
 *
6
 *****************************************************************************/
7
 
8
/******************************************************************************
9
 *
10
 * 1. Copyright Notice
11
 *
12
 * Some or all of this work - Copyright (c) 1999 - 2010, 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
#define __NSUTILS_C__
118
 
119
#include "acpi.h"
120
#include "accommon.h"
121
#include "acnamesp.h"
122
#include "amlcode.h"
123
 
124
#define _COMPONENT          ACPI_NAMESPACE
125
        ACPI_MODULE_NAME    ("nsutils")
126
 
127
/* Local prototypes */
128
 
129
static BOOLEAN
130
AcpiNsValidPathSeparator (
131
    char                    Sep);
132
 
133
#ifdef ACPI_OBSOLETE_FUNCTIONS
134
ACPI_NAME
135
AcpiNsFindParentName (
136
    ACPI_NAMESPACE_NODE     *NodeToSearch);
137
#endif
138
 
139
 
140
/*******************************************************************************
141
 *
142
 * FUNCTION:    AcpiNsReportError
143
 *
144
 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
145
 *              LineNumber          - Caller's line number (for error output)
146
 *              InternalName        - Name or path of the namespace node
147
 *              LookupStatus        - Exception code from NS lookup
148
 *
149
 * RETURN:      None
150
 *
151
 * DESCRIPTION: Print warning message with full pathname
152
 *
153
 ******************************************************************************/
154
 
155
void
156
AcpiNsReportError (
157
    const char              *ModuleName,
158
    UINT32                  LineNumber,
159
    const char              *InternalName,
160
    ACPI_STATUS             LookupStatus)
161
{
162
    ACPI_STATUS             Status;
163
    UINT32                  BadName;
164
    char                    *Name = NULL;
165
 
166
 
167
    AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber);
168
 
169
    if (LookupStatus == AE_BAD_CHARACTER)
170
    {
171
        /* There is a non-ascii character in the name */
172
 
173
        ACPI_MOVE_32_TO_32 (&BadName, ACPI_CAST_PTR (UINT32, InternalName));
174
        AcpiOsPrintf ("[0x%4.4X] (NON-ASCII)", BadName);
175
    }
176
    else
177
    {
178
        /* Convert path to external format */
179
 
180
        Status = AcpiNsExternalizeName (ACPI_UINT32_MAX,
181
                    InternalName, NULL, &Name);
182
 
183
        /* Print target name */
184
 
185
        if (ACPI_SUCCESS (Status))
186
        {
187
            AcpiOsPrintf ("[%s]", Name);
188
        }
189
        else
190
        {
191
            AcpiOsPrintf ("[COULD NOT EXTERNALIZE NAME]");
192
        }
193
 
194
        if (Name)
195
        {
196
            ACPI_FREE (Name);
197
        }
198
    }
199
 
200
    AcpiOsPrintf (" Namespace lookup failure, %s\n",
201
        AcpiFormatException (LookupStatus));
202
}
203
 
204
 
205
/*******************************************************************************
206
 *
207
 * FUNCTION:    AcpiNsReportMethodError
208
 *
209
 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
210
 *              LineNumber          - Caller's line number (for error output)
211
 *              Message             - Error message to use on failure
212
 *              PrefixNode          - Prefix relative to the path
213
 *              Path                - Path to the node (optional)
214
 *              MethodStatus        - Execution status
215
 *
216
 * RETURN:      None
217
 *
218
 * DESCRIPTION: Print warning message with full pathname
219
 *
220
 ******************************************************************************/
221
 
222
void
223
AcpiNsReportMethodError (
224
    const char              *ModuleName,
225
    UINT32                  LineNumber,
226
    const char              *Message,
227
    ACPI_NAMESPACE_NODE     *PrefixNode,
228
    const char              *Path,
229
    ACPI_STATUS             MethodStatus)
230
{
231
    ACPI_STATUS             Status;
232
    ACPI_NAMESPACE_NODE     *Node = PrefixNode;
233
 
234
 
235
    AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber);
236
 
237
    if (Path)
238
    {
239
        Status = AcpiNsGetNode (PrefixNode, Path, ACPI_NS_NO_UPSEARCH,
240
                    &Node);
241
        if (ACPI_FAILURE (Status))
242
        {
243
            AcpiOsPrintf ("[Could not get node by pathname]");
244
        }
245
    }
246
 
247
    AcpiNsPrintNodePathname (Node, Message);
248
    AcpiOsPrintf (", %s\n", AcpiFormatException (MethodStatus));
249
}
250
 
251
 
252
/*******************************************************************************
253
 *
254
 * FUNCTION:    AcpiNsPrintNodePathname
255
 *
256
 * PARAMETERS:  Node            - Object
257
 *              Message         - Prefix message
258
 *
259
 * DESCRIPTION: Print an object's full namespace pathname
260
 *              Manages allocation/freeing of a pathname buffer
261
 *
262
 ******************************************************************************/
263
 
264
void
265
AcpiNsPrintNodePathname (
266
    ACPI_NAMESPACE_NODE     *Node,
267
    const char              *Message)
268
{
269
    ACPI_BUFFER             Buffer;
270
    ACPI_STATUS             Status;
271
 
272
 
273
    if (!Node)
274
    {
275
        AcpiOsPrintf ("[NULL NAME]");
276
        return;
277
    }
278
 
279
    /* Convert handle to full pathname and print it (with supplied message) */
280
 
281
    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
282
 
283
    Status = AcpiNsHandleToPathname (Node, &Buffer);
284
    if (ACPI_SUCCESS (Status))
285
    {
286
        if (Message)
287
        {
288
            AcpiOsPrintf ("%s ", Message);
289
        }
290
 
291
        AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
292
        ACPI_FREE (Buffer.Pointer);
293
    }
294
}
295
 
296
 
297
/*******************************************************************************
298
 *
299
 * FUNCTION:    AcpiNsValidRootPrefix
300
 *
301
 * PARAMETERS:  Prefix          - Character to be checked
302
 *
303
 * RETURN:      TRUE if a valid prefix
304
 *
305
 * DESCRIPTION: Check if a character is a valid ACPI Root prefix
306
 *
307
 ******************************************************************************/
308
 
309
BOOLEAN
310
AcpiNsValidRootPrefix (
311
    char                    Prefix)
312
{
313
 
314
    return ((BOOLEAN) (Prefix == '\\'));
315
}
316
 
317
 
318
/*******************************************************************************
319
 *
320
 * FUNCTION:    AcpiNsValidPathSeparator
321
 *
322
 * PARAMETERS:  Sep         - Character to be checked
323
 *
324
 * RETURN:      TRUE if a valid path separator
325
 *
326
 * DESCRIPTION: Check if a character is a valid ACPI path separator
327
 *
328
 ******************************************************************************/
329
 
330
static BOOLEAN
331
AcpiNsValidPathSeparator (
332
    char                    Sep)
333
{
334
 
335
    return ((BOOLEAN) (Sep == '.'));
336
}
337
 
338
 
339
/*******************************************************************************
340
 *
341
 * FUNCTION:    AcpiNsGetType
342
 *
343
 * PARAMETERS:  Node        - Parent Node to be examined
344
 *
345
 * RETURN:      Type field from Node whose handle is passed
346
 *
347
 * DESCRIPTION: Return the type of a Namespace node
348
 *
349
 ******************************************************************************/
350
 
351
ACPI_OBJECT_TYPE
352
AcpiNsGetType (
353
    ACPI_NAMESPACE_NODE     *Node)
354
{
355
    ACPI_FUNCTION_TRACE (NsGetType);
356
 
357
 
358
    if (!Node)
359
    {
360
        ACPI_WARNING ((AE_INFO, "Null Node parameter"));
361
        return_UINT32 (ACPI_TYPE_ANY);
362
    }
363
 
364
    return_UINT32 ((ACPI_OBJECT_TYPE) Node->Type);
365
}
366
 
367
 
368
/*******************************************************************************
369
 *
370
 * FUNCTION:    AcpiNsLocal
371
 *
372
 * PARAMETERS:  Type        - A namespace object type
373
 *
374
 * RETURN:      LOCAL if names must be found locally in objects of the
375
 *              passed type, 0 if enclosing scopes should be searched
376
 *
377
 * DESCRIPTION: Returns scope rule for the given object type.
378
 *
379
 ******************************************************************************/
380
 
381
UINT32
382
AcpiNsLocal (
383
    ACPI_OBJECT_TYPE        Type)
384
{
385
    ACPI_FUNCTION_TRACE (NsLocal);
386
 
387
 
388
    if (!AcpiUtValidObjectType (Type))
389
    {
390
        /* Type code out of range  */
391
 
392
        ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
393
        return_UINT32 (ACPI_NS_NORMAL);
394
    }
395
 
396
    return_UINT32 ((UINT32) AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
397
}
398
 
399
 
400
/*******************************************************************************
401
 *
402
 * FUNCTION:    AcpiNsGetInternalNameLength
403
 *
404
 * PARAMETERS:  Info            - Info struct initialized with the
405
 *                                external name pointer.
406
 *
407
 * RETURN:      None
408
 *
409
 * DESCRIPTION: Calculate the length of the internal (AML) namestring
410
 *              corresponding to the external (ASL) namestring.
411
 *
412
 ******************************************************************************/
413
 
414
void
415
AcpiNsGetInternalNameLength (
416
    ACPI_NAMESTRING_INFO    *Info)
417
{
418
    const char              *NextExternalChar;
419
    UINT32                  i;
420
 
421
 
422
    ACPI_FUNCTION_ENTRY ();
423
 
424
 
425
    NextExternalChar = Info->ExternalName;
426
    Info->NumCarats = 0;
427
    Info->NumSegments = 0;
428
    Info->FullyQualified = FALSE;
429
 
430
    /*
431
     * For the internal name, the required length is 4 bytes per segment, plus
432
     * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
433
     * (which is not really needed, but no there's harm in putting it there)
434
     *
435
     * strlen() + 1 covers the first NameSeg, which has no path separator
436
     */
437
    if (AcpiNsValidRootPrefix (*NextExternalChar))
438
    {
439
        Info->FullyQualified = TRUE;
440
        NextExternalChar++;
441
 
442
        /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
443
 
444
        while (AcpiNsValidRootPrefix (*NextExternalChar))
445
        {
446
            NextExternalChar++;
447
        }
448
    }
449
    else
450
    {
451
        /* Handle Carat prefixes */
452
 
453
        while (*NextExternalChar == '^')
454
        {
455
            Info->NumCarats++;
456
            NextExternalChar++;
457
        }
458
    }
459
 
460
    /*
461
     * Determine the number of ACPI name "segments" by counting the number of
462
     * path separators within the string. Start with one segment since the
463
     * segment count is [(# separators) + 1], and zero separators is ok.
464
     */
465
    if (*NextExternalChar)
466
    {
467
        Info->NumSegments = 1;
468
        for (i = 0; NextExternalChar[i]; i++)
469
        {
470
            if (AcpiNsValidPathSeparator (NextExternalChar[i]))
471
            {
472
                Info->NumSegments++;
473
            }
474
        }
475
    }
476
 
477
    Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
478
                    4 + Info->NumCarats;
479
 
480
    Info->NextExternalChar = NextExternalChar;
481
}
482
 
483
 
484
/*******************************************************************************
485
 *
486
 * FUNCTION:    AcpiNsBuildInternalName
487
 *
488
 * PARAMETERS:  Info            - Info struct fully initialized
489
 *
490
 * RETURN:      Status
491
 *
492
 * DESCRIPTION: Construct the internal (AML) namestring
493
 *              corresponding to the external (ASL) namestring.
494
 *
495
 ******************************************************************************/
496
 
497
ACPI_STATUS
498
AcpiNsBuildInternalName (
499
    ACPI_NAMESTRING_INFO    *Info)
500
{
501
    UINT32                  NumSegments = Info->NumSegments;
502
    char                    *InternalName = Info->InternalName;
503
    const char              *ExternalName = Info->NextExternalChar;
504
    char                    *Result = NULL;
505
    UINT32                  i;
506
 
507
 
508
    ACPI_FUNCTION_TRACE (NsBuildInternalName);
509
 
510
 
511
    /* Setup the correct prefixes, counts, and pointers */
512
 
513
    if (Info->FullyQualified)
514
    {
515
        InternalName[0] = '\\';
516
 
517
        if (NumSegments <= 1)
518
        {
519
            Result = &InternalName[1];
520
        }
521
        else if (NumSegments == 2)
522
        {
523
            InternalName[1] = AML_DUAL_NAME_PREFIX;
524
            Result = &InternalName[2];
525
        }
526
        else
527
        {
528
            InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
529
            InternalName[2] = (char) NumSegments;
530
            Result = &InternalName[3];
531
        }
532
    }
533
    else
534
    {
535
        /*
536
         * Not fully qualified.
537
         * Handle Carats first, then append the name segments
538
         */
539
        i = 0;
540
        if (Info->NumCarats)
541
        {
542
            for (i = 0; i < Info->NumCarats; i++)
543
            {
544
                InternalName[i] = '^';
545
            }
546
        }
547
 
548
        if (NumSegments <= 1)
549
        {
550
            Result = &InternalName[i];
551
        }
552
        else if (NumSegments == 2)
553
        {
554
            InternalName[i] = AML_DUAL_NAME_PREFIX;
555
            Result = &InternalName[(ACPI_SIZE) i+1];
556
        }
557
        else
558
        {
559
            InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
560
            InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
561
            Result = &InternalName[(ACPI_SIZE) i+2];
562
        }
563
    }
564
 
565
    /* Build the name (minus path separators) */
566
 
567
    for (; NumSegments; NumSegments--)
568
    {
569
        for (i = 0; i < ACPI_NAME_SIZE; i++)
570
        {
571
            if (AcpiNsValidPathSeparator (*ExternalName) ||
572
               (*ExternalName == 0))
573
            {
574
                /* Pad the segment with underscore(s) if segment is short */
575
 
576
                Result[i] = '_';
577
            }
578
            else
579
            {
580
                /* Convert the character to uppercase and save it */
581
 
582
                Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
583
                ExternalName++;
584
            }
585
        }
586
 
587
        /* Now we must have a path separator, or the pathname is bad */
588
 
589
        if (!AcpiNsValidPathSeparator (*ExternalName) &&
590
            (*ExternalName != 0))
591
        {
592
            return_ACPI_STATUS (AE_BAD_PARAMETER);
593
        }
594
 
595
        /* Move on the next segment */
596
 
597
        ExternalName++;
598
        Result += ACPI_NAME_SIZE;
599
    }
600
 
601
    /* Terminate the string */
602
 
603
    *Result = 0;
604
 
605
    if (Info->FullyQualified)
606
    {
607
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
608
            InternalName, InternalName));
609
    }
610
    else
611
    {
612
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
613
            InternalName, InternalName));
614
    }
615
 
616
    return_ACPI_STATUS (AE_OK);
617
}
618
 
619
 
620
/*******************************************************************************
621
 *
622
 * FUNCTION:    AcpiNsInternalizeName
623
 *
624
 * PARAMETERS:  *ExternalName           - External representation of name
625
 *              **Converted Name        - Where to return the resulting
626
 *                                        internal represention of the name
627
 *
628
 * RETURN:      Status
629
 *
630
 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
631
 *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
632
 *
633
 *******************************************************************************/
634
 
635
ACPI_STATUS
636
AcpiNsInternalizeName (
637
    const char              *ExternalName,
638
    char                    **ConvertedName)
639
{
640
    char                    *InternalName;
641
    ACPI_NAMESTRING_INFO    Info;
642
    ACPI_STATUS             Status;
643
 
644
 
645
    ACPI_FUNCTION_TRACE (NsInternalizeName);
646
 
647
 
648
    if ((!ExternalName)      ||
649
        (*ExternalName == 0) ||
650
        (!ConvertedName))
651
    {
652
        return_ACPI_STATUS (AE_BAD_PARAMETER);
653
    }
654
 
655
    /* Get the length of the new internal name */
656
 
657
    Info.ExternalName = ExternalName;
658
    AcpiNsGetInternalNameLength (&Info);
659
 
660
    /* We need a segment to store the internal  name */
661
 
662
    InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
663
    if (!InternalName)
664
    {
665
        return_ACPI_STATUS (AE_NO_MEMORY);
666
    }
667
 
668
    /* Build the name */
669
 
670
    Info.InternalName = InternalName;
671
    Status = AcpiNsBuildInternalName (&Info);
672
    if (ACPI_FAILURE (Status))
673
    {
674
        ACPI_FREE (InternalName);
675
        return_ACPI_STATUS (Status);
676
    }
677
 
678
    *ConvertedName = InternalName;
679
    return_ACPI_STATUS (AE_OK);
680
}
681
 
682
 
683
/*******************************************************************************
684
 *
685
 * FUNCTION:    AcpiNsExternalizeName
686
 *
687
 * PARAMETERS:  InternalNameLength  - Lenth of the internal name below
688
 *              InternalName        - Internal representation of name
689
 *              ConvertedNameLength - Where the length is returned
690
 *              ConvertedName       - Where the resulting external name
691
 *                                    is returned
692
 *
693
 * RETURN:      Status
694
 *
695
 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
696
 *              to its external (printable) form (e.g. "\_PR_.CPU0")
697
 *
698
 ******************************************************************************/
699
 
700
ACPI_STATUS
701
AcpiNsExternalizeName (
702
    UINT32                  InternalNameLength,
703
    const char              *InternalName,
704
    UINT32                  *ConvertedNameLength,
705
    char                    **ConvertedName)
706
{
707
    UINT32                  NamesIndex = 0;
708
    UINT32                  NumSegments = 0;
709
    UINT32                  RequiredLength;
710
    UINT32                  PrefixLength = 0;
711
    UINT32                  i = 0;
712
    UINT32                  j = 0;
713
 
714
 
715
    ACPI_FUNCTION_TRACE (NsExternalizeName);
716
 
717
 
718
    if (!InternalNameLength     ||
719
        !InternalName           ||
720
        !ConvertedName)
721
    {
722
        return_ACPI_STATUS (AE_BAD_PARAMETER);
723
    }
724
 
725
    /* Check for a prefix (one '\' | one or more '^') */
726
 
727
    switch (InternalName[0])
728
    {
729
    case '\\':
730
        PrefixLength = 1;
731
        break;
732
 
733
    case '^':
734
        for (i = 0; i < InternalNameLength; i++)
735
        {
736
            if (InternalName[i] == '^')
737
            {
738
                PrefixLength = i + 1;
739
            }
740
            else
741
            {
742
                break;
743
            }
744
        }
745
 
746
        if (i == InternalNameLength)
747
        {
748
            PrefixLength = i;
749
        }
750
 
751
        break;
752
 
753
    default:
754
        break;
755
    }
756
 
757
    /*
758
     * Check for object names. Note that there could be 0-255 of these
759
     * 4-byte elements.
760
     */
761
    if (PrefixLength < InternalNameLength)
762
    {
763
        switch (InternalName[PrefixLength])
764
        {
765
        case AML_MULTI_NAME_PREFIX_OP:
766
 
767
            /*  4-byte names */
768
 
769
            NamesIndex = PrefixLength + 2;
770
            NumSegments = (UINT8)
771
                InternalName[(ACPI_SIZE) PrefixLength + 1];
772
            break;
773
 
774
        case AML_DUAL_NAME_PREFIX:
775
 
776
            /* Two 4-byte names */
777
 
778
            NamesIndex = PrefixLength + 1;
779
            NumSegments = 2;
780
            break;
781
 
782
        case 0:
783
 
784
            /* NullName */
785
 
786
            NamesIndex = 0;
787
            NumSegments = 0;
788
            break;
789
 
790
        default:
791
 
792
            /* one 4-byte name */
793
 
794
            NamesIndex = PrefixLength;
795
            NumSegments = 1;
796
            break;
797
        }
798
    }
799
 
800
    /*
801
     * Calculate the length of ConvertedName, which equals the length
802
     * of the prefix, length of all object names, length of any required
803
     * punctuation ('.') between object names, plus the NULL terminator.
804
     */
805
    RequiredLength = PrefixLength + (4 * NumSegments) +
806
                        ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
807
 
808
    /*
809
     * Check to see if we're still in bounds.  If not, there's a problem
810
     * with InternalName (invalid format).
811
     */
812
    if (RequiredLength > InternalNameLength)
813
    {
814
        ACPI_ERROR ((AE_INFO, "Invalid internal name"));
815
        return_ACPI_STATUS (AE_BAD_PATHNAME);
816
    }
817
 
818
    /* Build the ConvertedName */
819
 
820
    *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
821
    if (!(*ConvertedName))
822
    {
823
        return_ACPI_STATUS (AE_NO_MEMORY);
824
    }
825
 
826
    j = 0;
827
 
828
    for (i = 0; i < PrefixLength; i++)
829
    {
830
        (*ConvertedName)[j++] = InternalName[i];
831
    }
832
 
833
    if (NumSegments > 0)
834
    {
835
        for (i = 0; i < NumSegments; i++)
836
        {
837
            if (i > 0)
838
            {
839
                (*ConvertedName)[j++] = '.';
840
            }
841
 
842
            (*ConvertedName)[j++] = InternalName[NamesIndex++];
843
            (*ConvertedName)[j++] = InternalName[NamesIndex++];
844
            (*ConvertedName)[j++] = InternalName[NamesIndex++];
845
            (*ConvertedName)[j++] = InternalName[NamesIndex++];
846
        }
847
    }
848
 
849
    if (ConvertedNameLength)
850
    {
851
        *ConvertedNameLength = (UINT32) RequiredLength;
852
    }
853
 
854
    return_ACPI_STATUS (AE_OK);
855
}
856
 
857
 
858
/*******************************************************************************
859
 *
860
 * FUNCTION:    AcpiNsValidateHandle
861
 *
862
 * PARAMETERS:  Handle          - Handle to be validated and typecast to a
863
 *                                namespace node.
864
 *
865
 * RETURN:      A pointer to a namespace node
866
 *
867
 * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
868
 *              cases for the root node.
869
 *
870
 * NOTE: Real integer handles would allow for more verification
871
 *       and keep all pointers within this subsystem - however this introduces
872
 *       more overhead and has not been necessary to this point. Drivers
873
 *       holding handles are typically notified before a node becomes invalid
874
 *       due to a table unload.
875
 *
876
 ******************************************************************************/
877
 
878
ACPI_NAMESPACE_NODE *
879
AcpiNsValidateHandle (
880
    ACPI_HANDLE             Handle)
881
{
882
 
883
    ACPI_FUNCTION_ENTRY ();
884
 
885
 
886
    /* Parameter validation */
887
 
888
    if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
889
    {
890
        return (AcpiGbl_RootNode);
891
    }
892
 
893
    /* We can at least attempt to verify the handle */
894
 
895
    if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
896
    {
897
        return (NULL);
898
    }
899
 
900
    return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
901
}
902
 
903
 
904
/*******************************************************************************
905
 *
906
 * FUNCTION:    AcpiNsTerminate
907
 *
908
 * PARAMETERS:  none
909
 *
910
 * RETURN:      none
911
 *
912
 * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
913
 *
914
 ******************************************************************************/
915
 
916
void
917
AcpiNsTerminate (
918
    void)
919
{
920
    ACPI_OPERAND_OBJECT     *ObjDesc;
921
 
922
 
923
    ACPI_FUNCTION_TRACE (NsTerminate);
924
 
925
 
926
    /*
927
     * 1) Free the entire namespace -- all nodes and objects
928
     *
929
     * Delete all object descriptors attached to namepsace nodes
930
     */
931
    AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
932
 
933
    /* Detach any objects attached to the root */
934
 
935
    ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode);
936
    if (ObjDesc)
937
    {
938
        AcpiNsDetachObject (AcpiGbl_RootNode);
939
    }
940
 
941
    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
942
    return_VOID;
943
}
944
 
945
 
946
/*******************************************************************************
947
 *
948
 * FUNCTION:    AcpiNsOpensScope
949
 *
950
 * PARAMETERS:  Type        - A valid namespace type
951
 *
952
 * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
953
 *              to the ACPI specification, else 0
954
 *
955
 ******************************************************************************/
956
 
957
UINT32
958
AcpiNsOpensScope (
959
    ACPI_OBJECT_TYPE        Type)
960
{
961
    ACPI_FUNCTION_TRACE_STR (NsOpensScope, AcpiUtGetTypeName (Type));
962
 
963
 
964
    if (!AcpiUtValidObjectType (Type))
965
    {
966
        /* type code out of range  */
967
 
968
        ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
969
        return_UINT32 (ACPI_NS_NORMAL);
970
    }
971
 
972
    return_UINT32 (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
973
}
974
 
975
 
976
/*******************************************************************************
977
 *
978
 * FUNCTION:    AcpiNsGetNode
979
 *
980
 * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
981
 *                            \ (backslash) and ^ (carat) prefixes, and the
982
 *                            . (period) to separate segments are supported.
983
 *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
984
 *                            root of the name space.  If Name is fully
985
 *                            qualified (first INT8 is '\'), the passed value
986
 *                            of Scope will not be accessed.
987
 *              Flags       - Used to indicate whether to perform upsearch or
988
 *                            not.
989
 *              ReturnNode  - Where the Node is returned
990
 *
991
 * DESCRIPTION: Look up a name relative to a given scope and return the
992
 *              corresponding Node.  NOTE: Scope can be null.
993
 *
994
 * MUTEX:       Locks namespace
995
 *
996
 ******************************************************************************/
997
 
998
ACPI_STATUS
999
AcpiNsGetNode (
1000
    ACPI_NAMESPACE_NODE     *PrefixNode,
1001
    const char              *Pathname,
1002
    UINT32                  Flags,
1003
    ACPI_NAMESPACE_NODE     **ReturnNode)
1004
{
1005
    ACPI_GENERIC_STATE      ScopeInfo;
1006
    ACPI_STATUS             Status;
1007
    char                    *InternalPath;
1008
 
1009
 
1010
    ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
1011
 
1012
 
1013
    if (!Pathname)
1014
    {
1015
        *ReturnNode = PrefixNode;
1016
        if (!PrefixNode)
1017
        {
1018
            *ReturnNode = AcpiGbl_RootNode;
1019
        }
1020
        return_ACPI_STATUS (AE_OK);
1021
    }
1022
 
1023
    /* Convert path to internal representation */
1024
 
1025
    Status = AcpiNsInternalizeName (Pathname, &InternalPath);
1026
    if (ACPI_FAILURE (Status))
1027
    {
1028
        return_ACPI_STATUS (Status);
1029
    }
1030
 
1031
    /* Must lock namespace during lookup */
1032
 
1033
    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1034
    if (ACPI_FAILURE (Status))
1035
    {
1036
        goto Cleanup;
1037
    }
1038
 
1039
    /* Setup lookup scope (search starting point) */
1040
 
1041
    ScopeInfo.Scope.Node = PrefixNode;
1042
 
1043
    /* Lookup the name in the namespace */
1044
 
1045
    Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
1046
                ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
1047
                NULL, ReturnNode);
1048
    if (ACPI_FAILURE (Status))
1049
    {
1050
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
1051
                Pathname, AcpiFormatException (Status)));
1052
    }
1053
 
1054
    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1055
 
1056
Cleanup:
1057
    ACPI_FREE (InternalPath);
1058
    return_ACPI_STATUS (Status);
1059
}