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