1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45#include <acpi/acpi.h>
46#include "accommon.h"
47#include "acnamesp.h"
48#include "amlcode.h"
49
50#define _COMPONENT ACPI_NAMESPACE
51ACPI_MODULE_NAME("nsutils")
52
53
54#ifdef ACPI_OBSOLETE_FUNCTIONS
55acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
56#endif
57
58
59
60
61
62
63
64
65
66
67
68
69
70void
71acpi_ns_print_node_pathname(struct acpi_namespace_node *node,
72 const char *message)
73{
74 struct acpi_buffer buffer;
75 acpi_status status;
76
77 if (!node) {
78 acpi_os_printf("[NULL NAME]");
79 return;
80 }
81
82
83
84 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
85
86 status = acpi_ns_handle_to_pathname(node, &buffer, TRUE);
87 if (ACPI_SUCCESS(status)) {
88 if (message) {
89 acpi_os_printf("%s ", message);
90 }
91
92 acpi_os_printf("[%s] (Node %p)", (char *)buffer.pointer, node);
93 ACPI_FREE(buffer.pointer);
94 }
95}
96
97
98
99
100
101
102
103
104
105
106
107
108
109acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node)
110{
111 ACPI_FUNCTION_TRACE(ns_get_type);
112
113 if (!node) {
114 ACPI_WARNING((AE_INFO, "Null Node parameter"));
115 return_UINT8(ACPI_TYPE_ANY);
116 }
117
118 return_UINT8(node->type);
119}
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134u32 acpi_ns_local(acpi_object_type type)
135{
136 ACPI_FUNCTION_TRACE(ns_local);
137
138 if (!acpi_ut_valid_object_type(type)) {
139
140
141
142 ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type));
143 return_UINT32(ACPI_NS_NORMAL);
144 }
145
146 return_UINT32(acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
147}
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
164{
165 const char *next_external_char;
166 u32 i;
167
168 ACPI_FUNCTION_ENTRY();
169
170 next_external_char = info->external_name;
171 info->num_carats = 0;
172 info->num_segments = 0;
173 info->fully_qualified = FALSE;
174
175
176
177
178
179
180
181
182
183 if (ACPI_IS_ROOT_PREFIX(*next_external_char)) {
184 info->fully_qualified = TRUE;
185 next_external_char++;
186
187
188
189 while (ACPI_IS_ROOT_PREFIX(*next_external_char)) {
190 next_external_char++;
191 }
192 } else {
193
194
195 while (ACPI_IS_PARENT_PREFIX(*next_external_char)) {
196 info->num_carats++;
197 next_external_char++;
198 }
199 }
200
201
202
203
204
205
206 if (*next_external_char) {
207 info->num_segments = 1;
208 for (i = 0; next_external_char[i]; i++) {
209 if (ACPI_IS_PATH_SEPARATOR(next_external_char[i])) {
210 info->num_segments++;
211 }
212 }
213 }
214
215 info->length = (ACPI_NAME_SIZE * info->num_segments) +
216 4 + info->num_carats;
217
218 info->next_external_char = next_external_char;
219}
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
235{
236 u32 num_segments = info->num_segments;
237 char *internal_name = info->internal_name;
238 const char *external_name = info->next_external_char;
239 char *result = NULL;
240 u32 i;
241
242 ACPI_FUNCTION_TRACE(ns_build_internal_name);
243
244
245
246 if (info->fully_qualified) {
247 internal_name[0] = AML_ROOT_PREFIX;
248
249 if (num_segments <= 1) {
250 result = &internal_name[1];
251 } else if (num_segments == 2) {
252 internal_name[1] = AML_DUAL_NAME_PREFIX;
253 result = &internal_name[2];
254 } else {
255 internal_name[1] = AML_MULTI_NAME_PREFIX_OP;
256 internal_name[2] = (char)num_segments;
257 result = &internal_name[3];
258 }
259 } else {
260
261
262
263
264 i = 0;
265 if (info->num_carats) {
266 for (i = 0; i < info->num_carats; i++) {
267 internal_name[i] = AML_PARENT_PREFIX;
268 }
269 }
270
271 if (num_segments <= 1) {
272 result = &internal_name[i];
273 } else if (num_segments == 2) {
274 internal_name[i] = AML_DUAL_NAME_PREFIX;
275 result = &internal_name[(acpi_size)i + 1];
276 } else {
277 internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
278 internal_name[(acpi_size)i + 1] = (char)num_segments;
279 result = &internal_name[(acpi_size)i + 2];
280 }
281 }
282
283
284
285 for (; num_segments; num_segments--) {
286 for (i = 0; i < ACPI_NAME_SIZE; i++) {
287 if (ACPI_IS_PATH_SEPARATOR(*external_name) ||
288 (*external_name == 0)) {
289
290
291
292 result[i] = '_';
293 } else {
294
295
296 result[i] = (char)toupper((int)*external_name);
297 external_name++;
298 }
299 }
300
301
302
303 if (!ACPI_IS_PATH_SEPARATOR(*external_name) &&
304 (*external_name != 0)) {
305 return_ACPI_STATUS(AE_BAD_PATHNAME);
306 }
307
308
309
310 external_name++;
311 result += ACPI_NAME_SIZE;
312 }
313
314
315
316 *result = 0;
317
318 if (info->fully_qualified) {
319 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
320 "Returning [%p] (abs) \"\\%s\"\n",
321 internal_name, internal_name));
322 } else {
323 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
324 internal_name, internal_name));
325 }
326
327 return_ACPI_STATUS(AE_OK);
328}
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345acpi_status
346acpi_ns_internalize_name(const char *external_name, char **converted_name)
347{
348 char *internal_name;
349 struct acpi_namestring_info info;
350 acpi_status status;
351
352 ACPI_FUNCTION_TRACE(ns_internalize_name);
353
354 if ((!external_name) || (*external_name == 0) || (!converted_name)) {
355 return_ACPI_STATUS(AE_BAD_PARAMETER);
356 }
357
358
359
360 info.external_name = external_name;
361 acpi_ns_get_internal_name_length(&info);
362
363
364
365 internal_name = ACPI_ALLOCATE_ZEROED(info.length);
366 if (!internal_name) {
367 return_ACPI_STATUS(AE_NO_MEMORY);
368 }
369
370
371
372 info.internal_name = internal_name;
373 status = acpi_ns_build_internal_name(&info);
374 if (ACPI_FAILURE(status)) {
375 ACPI_FREE(internal_name);
376 return_ACPI_STATUS(status);
377 }
378
379 *converted_name = internal_name;
380 return_ACPI_STATUS(AE_OK);
381}
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400acpi_status
401acpi_ns_externalize_name(u32 internal_name_length,
402 const char *internal_name,
403 u32 * converted_name_length, char **converted_name)
404{
405 u32 names_index = 0;
406 u32 num_segments = 0;
407 u32 required_length;
408 u32 prefix_length = 0;
409 u32 i = 0;
410 u32 j = 0;
411
412 ACPI_FUNCTION_TRACE(ns_externalize_name);
413
414 if (!internal_name_length || !internal_name || !converted_name) {
415 return_ACPI_STATUS(AE_BAD_PARAMETER);
416 }
417
418
419
420 switch (internal_name[0]) {
421 case AML_ROOT_PREFIX:
422
423 prefix_length = 1;
424 break;
425
426 case AML_PARENT_PREFIX:
427
428 for (i = 0; i < internal_name_length; i++) {
429 if (ACPI_IS_PARENT_PREFIX(internal_name[i])) {
430 prefix_length = i + 1;
431 } else {
432 break;
433 }
434 }
435
436 if (i == internal_name_length) {
437 prefix_length = i;
438 }
439
440 break;
441
442 default:
443
444 break;
445 }
446
447
448
449
450
451 if (prefix_length < internal_name_length) {
452 switch (internal_name[prefix_length]) {
453 case AML_MULTI_NAME_PREFIX_OP:
454
455
456
457 names_index = prefix_length + 2;
458 num_segments = (u8)
459 internal_name[(acpi_size)prefix_length + 1];
460 break;
461
462 case AML_DUAL_NAME_PREFIX:
463
464
465
466 names_index = prefix_length + 1;
467 num_segments = 2;
468 break;
469
470 case 0:
471
472
473
474 names_index = 0;
475 num_segments = 0;
476 break;
477
478 default:
479
480
481
482 names_index = prefix_length;
483 num_segments = 1;
484 break;
485 }
486 }
487
488
489
490
491
492
493 required_length = prefix_length + (4 * num_segments) +
494 ((num_segments > 0) ? (num_segments - 1) : 0) + 1;
495
496
497
498
499
500 if (required_length > internal_name_length) {
501 ACPI_ERROR((AE_INFO, "Invalid internal name"));
502 return_ACPI_STATUS(AE_BAD_PATHNAME);
503 }
504
505
506
507 *converted_name = ACPI_ALLOCATE_ZEROED(required_length);
508 if (!(*converted_name)) {
509 return_ACPI_STATUS(AE_NO_MEMORY);
510 }
511
512 j = 0;
513
514 for (i = 0; i < prefix_length; i++) {
515 (*converted_name)[j++] = internal_name[i];
516 }
517
518 if (num_segments > 0) {
519 for (i = 0; i < num_segments; i++) {
520 if (i > 0) {
521 (*converted_name)[j++] = '.';
522 }
523
524
525
526 ACPI_MOVE_NAME(&(*converted_name)[j],
527 &internal_name[names_index]);
528 acpi_ut_repair_name(&(*converted_name)[j]);
529
530 j += ACPI_NAME_SIZE;
531 names_index += ACPI_NAME_SIZE;
532 }
533 }
534
535 if (converted_name_length) {
536 *converted_name_length = (u32) required_length;
537 }
538
539 return_ACPI_STATUS(AE_OK);
540}
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle)
563{
564
565 ACPI_FUNCTION_ENTRY();
566
567
568
569 if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
570 return (acpi_gbl_root_node);
571 }
572
573
574
575 if (ACPI_GET_DESCRIPTOR_TYPE(handle) != ACPI_DESC_TYPE_NAMED) {
576 return (NULL);
577 }
578
579 return (ACPI_CAST_PTR(struct acpi_namespace_node, handle));
580}
581
582
583
584
585
586
587
588
589
590
591
592
593
594void acpi_ns_terminate(void)
595{
596 acpi_status status;
597
598 ACPI_FUNCTION_TRACE(ns_terminate);
599
600#ifdef ACPI_EXEC_APP
601 {
602 union acpi_operand_object *prev;
603 union acpi_operand_object *next;
604
605
606
607 next = acpi_gbl_module_code_list;
608 while (next) {
609 prev = next;
610 next = next->method.mutex;
611 prev->method.mutex = NULL;
612 acpi_ut_remove_reference(prev);
613 }
614 }
615#endif
616
617
618
619
620
621 acpi_ns_delete_namespace_subtree(acpi_gbl_root_node);
622
623
624
625 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
626 if (ACPI_FAILURE(status)) {
627 return_VOID;
628 }
629
630 acpi_ns_delete_node(acpi_gbl_root_node);
631 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
632
633 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
634 return_VOID;
635}
636
637
638
639
640
641
642
643
644
645
646
647
648u32 acpi_ns_opens_scope(acpi_object_type type)
649{
650 ACPI_FUNCTION_ENTRY();
651
652 if (type > ACPI_TYPE_LOCAL_MAX) {
653
654
655
656 ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type));
657 return (ACPI_NS_NORMAL);
658 }
659
660 return (((u32)acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
661}
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685acpi_status
686acpi_ns_get_node_unlocked(struct acpi_namespace_node *prefix_node,
687 const char *pathname,
688 u32 flags, struct acpi_namespace_node **return_node)
689{
690 union acpi_generic_state scope_info;
691 acpi_status status;
692 char *internal_path;
693
694 ACPI_FUNCTION_TRACE_PTR(ns_get_node_unlocked,
695 ACPI_CAST_PTR(char, pathname));
696
697
698
699 if (!pathname) {
700 *return_node = prefix_node;
701 if (!prefix_node) {
702 *return_node = acpi_gbl_root_node;
703 }
704
705 return_ACPI_STATUS(AE_OK);
706 }
707
708
709
710 if (ACPI_IS_ROOT_PREFIX(pathname[0]) && (!pathname[1])) {
711 *return_node = acpi_gbl_root_node;
712 return_ACPI_STATUS(AE_OK);
713 }
714
715
716
717 status = acpi_ns_internalize_name(pathname, &internal_path);
718 if (ACPI_FAILURE(status)) {
719 return_ACPI_STATUS(status);
720 }
721
722
723
724 scope_info.scope.node = prefix_node;
725
726
727
728 status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY,
729 ACPI_IMODE_EXECUTE,
730 (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
731 return_node);
732 if (ACPI_FAILURE(status)) {
733 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n",
734 pathname, acpi_format_exception(status)));
735 }
736
737 ACPI_FREE(internal_path);
738 return_ACPI_STATUS(status);
739}
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763acpi_status
764acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
765 const char *pathname,
766 u32 flags, struct acpi_namespace_node **return_node)
767{
768 acpi_status status;
769
770 ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname));
771
772 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
773 if (ACPI_FAILURE(status)) {
774 return_ACPI_STATUS(status);
775 }
776
777 status = acpi_ns_get_node_unlocked(prefix_node, pathname,
778 flags, return_node);
779
780 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
781 return_ACPI_STATUS(status);
782}
783