GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / acpi / acpica / nsutils.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
5  *                        parents and siblings and Scope manipulation
6  *
7  * Copyright (C) 2000 - 2018, Intel Corp.
8  *
9  *****************************************************************************/
10
11 #include <acpi/acpi.h>
12 #include "accommon.h"
13 #include "acnamesp.h"
14 #include "amlcode.h"
15
16 #define _COMPONENT          ACPI_NAMESPACE
17 ACPI_MODULE_NAME("nsutils")
18
19 /* Local prototypes */
20 #ifdef ACPI_OBSOLETE_FUNCTIONS
21 acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
22 #endif
23
24 /*******************************************************************************
25  *
26  * FUNCTION:    acpi_ns_print_node_pathname
27  *
28  * PARAMETERS:  node            - Object
29  *              message         - Prefix message
30  *
31  * DESCRIPTION: Print an object's full namespace pathname
32  *              Manages allocation/freeing of a pathname buffer
33  *
34  ******************************************************************************/
35
36 void
37 acpi_ns_print_node_pathname(struct acpi_namespace_node *node,
38                             const char *message)
39 {
40         struct acpi_buffer buffer;
41         acpi_status status;
42
43         if (!node) {
44                 acpi_os_printf("[NULL NAME]");
45                 return;
46         }
47
48         /* Convert handle to full pathname and print it (with supplied message) */
49
50         buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
51
52         status = acpi_ns_handle_to_pathname(node, &buffer, TRUE);
53         if (ACPI_SUCCESS(status)) {
54                 if (message) {
55                         acpi_os_printf("%s ", message);
56                 }
57
58                 acpi_os_printf("%s", (char *)buffer.pointer);
59                 ACPI_FREE(buffer.pointer);
60         }
61 }
62
63 /*******************************************************************************
64  *
65  * FUNCTION:    acpi_ns_get_type
66  *
67  * PARAMETERS:  node        - Parent Node to be examined
68  *
69  * RETURN:      Type field from Node whose handle is passed
70  *
71  * DESCRIPTION: Return the type of a Namespace node
72  *
73  ******************************************************************************/
74
75 acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node)
76 {
77         ACPI_FUNCTION_TRACE(ns_get_type);
78
79         if (!node) {
80                 ACPI_WARNING((AE_INFO, "Null Node parameter"));
81                 return_UINT8(ACPI_TYPE_ANY);
82         }
83
84         return_UINT8(node->type);
85 }
86
87 /*******************************************************************************
88  *
89  * FUNCTION:    acpi_ns_local
90  *
91  * PARAMETERS:  type        - A namespace object type
92  *
93  * RETURN:      LOCAL if names must be found locally in objects of the
94  *              passed type, 0 if enclosing scopes should be searched
95  *
96  * DESCRIPTION: Returns scope rule for the given object type.
97  *
98  ******************************************************************************/
99
100 u32 acpi_ns_local(acpi_object_type type)
101 {
102         ACPI_FUNCTION_TRACE(ns_local);
103
104         if (!acpi_ut_valid_object_type(type)) {
105
106                 /* Type code out of range  */
107
108                 ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type));
109                 return_UINT32(ACPI_NS_NORMAL);
110         }
111
112         return_UINT32(acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
113 }
114
115 /*******************************************************************************
116  *
117  * FUNCTION:    acpi_ns_get_internal_name_length
118  *
119  * PARAMETERS:  info            - Info struct initialized with the
120  *                                external name pointer.
121  *
122  * RETURN:      None
123  *
124  * DESCRIPTION: Calculate the length of the internal (AML) namestring
125  *              corresponding to the external (ASL) namestring.
126  *
127  ******************************************************************************/
128
129 void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
130 {
131         const char *next_external_char;
132         u32 i;
133
134         ACPI_FUNCTION_ENTRY();
135
136         next_external_char = info->external_name;
137         info->num_carats = 0;
138         info->num_segments = 0;
139         info->fully_qualified = FALSE;
140
141         /*
142          * For the internal name, the required length is 4 bytes per segment,
143          * plus 1 each for root_prefix, multi_name_prefix_op, segment count,
144          * trailing null (which is not really needed, but no there's harm in
145          * putting it there)
146          *
147          * strlen() + 1 covers the first name_seg, which has no path separator
148          */
149         if (ACPI_IS_ROOT_PREFIX(*next_external_char)) {
150                 info->fully_qualified = TRUE;
151                 next_external_char++;
152
153                 /* Skip redundant root_prefix, like \\_SB.PCI0.SBRG.EC0 */
154
155                 while (ACPI_IS_ROOT_PREFIX(*next_external_char)) {
156                         next_external_char++;
157                 }
158         } else {
159                 /* Handle Carat prefixes */
160
161                 while (ACPI_IS_PARENT_PREFIX(*next_external_char)) {
162                         info->num_carats++;
163                         next_external_char++;
164                 }
165         }
166
167         /*
168          * Determine the number of ACPI name "segments" by counting the number of
169          * path separators within the string. Start with one segment since the
170          * segment count is [(# separators) + 1], and zero separators is ok.
171          */
172         if (*next_external_char) {
173                 info->num_segments = 1;
174                 for (i = 0; next_external_char[i]; i++) {
175                         if (ACPI_IS_PATH_SEPARATOR(next_external_char[i])) {
176                                 info->num_segments++;
177                         }
178                 }
179         }
180
181         info->length = (ACPI_NAME_SIZE * info->num_segments) +
182             4 + info->num_carats;
183
184         info->next_external_char = next_external_char;
185 }
186
187 /*******************************************************************************
188  *
189  * FUNCTION:    acpi_ns_build_internal_name
190  *
191  * PARAMETERS:  info            - Info struct fully initialized
192  *
193  * RETURN:      Status
194  *
195  * DESCRIPTION: Construct the internal (AML) namestring
196  *              corresponding to the external (ASL) namestring.
197  *
198  ******************************************************************************/
199
200 acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
201 {
202         u32 num_segments = info->num_segments;
203         char *internal_name = info->internal_name;
204         const char *external_name = info->next_external_char;
205         char *result = NULL;
206         u32 i;
207
208         ACPI_FUNCTION_TRACE(ns_build_internal_name);
209
210         /* Setup the correct prefixes, counts, and pointers */
211
212         if (info->fully_qualified) {
213                 internal_name[0] = AML_ROOT_PREFIX;
214
215                 if (num_segments <= 1) {
216                         result = &internal_name[1];
217                 } else if (num_segments == 2) {
218                         internal_name[1] = AML_DUAL_NAME_PREFIX;
219                         result = &internal_name[2];
220                 } else {
221                         internal_name[1] = AML_MULTI_NAME_PREFIX;
222                         internal_name[2] = (char)num_segments;
223                         result = &internal_name[3];
224                 }
225         } else {
226                 /*
227                  * Not fully qualified.
228                  * Handle Carats first, then append the name segments
229                  */
230                 i = 0;
231                 if (info->num_carats) {
232                         for (i = 0; i < info->num_carats; i++) {
233                                 internal_name[i] = AML_PARENT_PREFIX;
234                         }
235                 }
236
237                 if (num_segments <= 1) {
238                         result = &internal_name[i];
239                 } else if (num_segments == 2) {
240                         internal_name[i] = AML_DUAL_NAME_PREFIX;
241                         result = &internal_name[(acpi_size)i + 1];
242                 } else {
243                         internal_name[i] = AML_MULTI_NAME_PREFIX;
244                         internal_name[(acpi_size)i + 1] = (char)num_segments;
245                         result = &internal_name[(acpi_size)i + 2];
246                 }
247         }
248
249         /* Build the name (minus path separators) */
250
251         for (; num_segments; num_segments--) {
252                 for (i = 0; i < ACPI_NAME_SIZE; i++) {
253                         if (ACPI_IS_PATH_SEPARATOR(*external_name) ||
254                             (*external_name == 0)) {
255
256                                 /* Pad the segment with underscore(s) if segment is short */
257
258                                 result[i] = '_';
259                         } else {
260                                 /* Convert the character to uppercase and save it */
261
262                                 result[i] = (char)toupper((int)*external_name);
263                                 external_name++;
264                         }
265                 }
266
267                 /* Now we must have a path separator, or the pathname is bad */
268
269                 if (!ACPI_IS_PATH_SEPARATOR(*external_name) &&
270                     (*external_name != 0)) {
271                         return_ACPI_STATUS(AE_BAD_PATHNAME);
272                 }
273
274                 /* Move on the next segment */
275
276                 external_name++;
277                 result += ACPI_NAME_SIZE;
278         }
279
280         /* Terminate the string */
281
282         *result = 0;
283
284         if (info->fully_qualified) {
285                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
286                                   "Returning [%p] (abs) \"\\%s\"\n",
287                                   internal_name, internal_name));
288         } else {
289                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
290                                   internal_name, internal_name));
291         }
292
293         return_ACPI_STATUS(AE_OK);
294 }
295
296 /*******************************************************************************
297  *
298  * FUNCTION:    acpi_ns_internalize_name
299  *
300  * PARAMETERS:  *external_name          - External representation of name
301  *              **Converted name        - Where to return the resulting
302  *                                        internal represention of the name
303  *
304  * RETURN:      Status
305  *
306  * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
307  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
308  *
309  *******************************************************************************/
310
311 acpi_status
312 acpi_ns_internalize_name(const char *external_name, char **converted_name)
313 {
314         char *internal_name;
315         struct acpi_namestring_info info;
316         acpi_status status;
317
318         ACPI_FUNCTION_TRACE(ns_internalize_name);
319
320         if ((!external_name) || (*external_name == 0) || (!converted_name)) {
321                 return_ACPI_STATUS(AE_BAD_PARAMETER);
322         }
323
324         /* Get the length of the new internal name */
325
326         info.external_name = external_name;
327         acpi_ns_get_internal_name_length(&info);
328
329         /* We need a segment to store the internal  name */
330
331         internal_name = ACPI_ALLOCATE_ZEROED(info.length);
332         if (!internal_name) {
333                 return_ACPI_STATUS(AE_NO_MEMORY);
334         }
335
336         /* Build the name */
337
338         info.internal_name = internal_name;
339         status = acpi_ns_build_internal_name(&info);
340         if (ACPI_FAILURE(status)) {
341                 ACPI_FREE(internal_name);
342                 return_ACPI_STATUS(status);
343         }
344
345         *converted_name = internal_name;
346         return_ACPI_STATUS(AE_OK);
347 }
348
349 /*******************************************************************************
350  *
351  * FUNCTION:    acpi_ns_externalize_name
352  *
353  * PARAMETERS:  internal_name_length - Lenth of the internal name below
354  *              internal_name       - Internal representation of name
355  *              converted_name_length - Where the length is returned
356  *              converted_name      - Where the resulting external name
357  *                                    is returned
358  *
359  * RETURN:      Status
360  *
361  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
362  *              to its external (printable) form (e.g. "\_PR_.CPU0")
363  *
364  ******************************************************************************/
365
366 acpi_status
367 acpi_ns_externalize_name(u32 internal_name_length,
368                          const char *internal_name,
369                          u32 * converted_name_length, char **converted_name)
370 {
371         u32 names_index = 0;
372         u32 num_segments = 0;
373         u32 required_length;
374         u32 prefix_length = 0;
375         u32 i = 0;
376         u32 j = 0;
377
378         ACPI_FUNCTION_TRACE(ns_externalize_name);
379
380         if (!internal_name_length || !internal_name || !converted_name) {
381                 return_ACPI_STATUS(AE_BAD_PARAMETER);
382         }
383
384         /* Check for a prefix (one '\' | one or more '^') */
385
386         switch (internal_name[0]) {
387         case AML_ROOT_PREFIX:
388
389                 prefix_length = 1;
390                 break;
391
392         case AML_PARENT_PREFIX:
393
394                 for (i = 0; i < internal_name_length; i++) {
395                         if (ACPI_IS_PARENT_PREFIX(internal_name[i])) {
396                                 prefix_length = i + 1;
397                         } else {
398                                 break;
399                         }
400                 }
401
402                 if (i == internal_name_length) {
403                         prefix_length = i;
404                 }
405
406                 break;
407
408         default:
409
410                 break;
411         }
412
413         /*
414          * Check for object names. Note that there could be 0-255 of these
415          * 4-byte elements.
416          */
417         if (prefix_length < internal_name_length) {
418                 switch (internal_name[prefix_length]) {
419                 case AML_MULTI_NAME_PREFIX:
420
421                         /* <count> 4-byte names */
422
423                         names_index = prefix_length + 2;
424                         num_segments = (u8)
425                             internal_name[(acpi_size)prefix_length + 1];
426                         break;
427
428                 case AML_DUAL_NAME_PREFIX:
429
430                         /* Two 4-byte names */
431
432                         names_index = prefix_length + 1;
433                         num_segments = 2;
434                         break;
435
436                 case 0:
437
438                         /* null_name */
439
440                         names_index = 0;
441                         num_segments = 0;
442                         break;
443
444                 default:
445
446                         /* one 4-byte name */
447
448                         names_index = prefix_length;
449                         num_segments = 1;
450                         break;
451                 }
452         }
453
454         /*
455          * Calculate the length of converted_name, which equals the length
456          * of the prefix, length of all object names, length of any required
457          * punctuation ('.') between object names, plus the NULL terminator.
458          */
459         required_length = prefix_length + (4 * num_segments) +
460             ((num_segments > 0) ? (num_segments - 1) : 0) + 1;
461
462         /*
463          * Check to see if we're still in bounds. If not, there's a problem
464          * with internal_name (invalid format).
465          */
466         if (required_length > internal_name_length) {
467                 ACPI_ERROR((AE_INFO, "Invalid internal name"));
468                 return_ACPI_STATUS(AE_BAD_PATHNAME);
469         }
470
471         /* Build the converted_name */
472
473         *converted_name = ACPI_ALLOCATE_ZEROED(required_length);
474         if (!(*converted_name)) {
475                 return_ACPI_STATUS(AE_NO_MEMORY);
476         }
477
478         j = 0;
479
480         for (i = 0; i < prefix_length; i++) {
481                 (*converted_name)[j++] = internal_name[i];
482         }
483
484         if (num_segments > 0) {
485                 for (i = 0; i < num_segments; i++) {
486                         if (i > 0) {
487                                 (*converted_name)[j++] = '.';
488                         }
489
490                         /* Copy and validate the 4-char name segment */
491
492                         ACPI_MOVE_NAME(&(*converted_name)[j],
493                                        &internal_name[names_index]);
494                         acpi_ut_repair_name(&(*converted_name)[j]);
495
496                         j += ACPI_NAME_SIZE;
497                         names_index += ACPI_NAME_SIZE;
498                 }
499         }
500
501         if (converted_name_length) {
502                 *converted_name_length = (u32) required_length;
503         }
504
505         return_ACPI_STATUS(AE_OK);
506 }
507
508 /*******************************************************************************
509  *
510  * FUNCTION:    acpi_ns_validate_handle
511  *
512  * PARAMETERS:  handle          - Handle to be validated and typecast to a
513  *                                namespace node.
514  *
515  * RETURN:      A pointer to a namespace node
516  *
517  * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
518  *              cases for the root node.
519  *
520  * NOTE: Real integer handles would allow for more verification
521  *       and keep all pointers within this subsystem - however this introduces
522  *       more overhead and has not been necessary to this point. Drivers
523  *       holding handles are typically notified before a node becomes invalid
524  *       due to a table unload.
525  *
526  ******************************************************************************/
527
528 struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle)
529 {
530
531         ACPI_FUNCTION_ENTRY();
532
533         /* Parameter validation */
534
535         if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
536                 return (acpi_gbl_root_node);
537         }
538
539         /* We can at least attempt to verify the handle */
540
541         if (ACPI_GET_DESCRIPTOR_TYPE(handle) != ACPI_DESC_TYPE_NAMED) {
542                 return (NULL);
543         }
544
545         return (ACPI_CAST_PTR(struct acpi_namespace_node, handle));
546 }
547
548 /*******************************************************************************
549  *
550  * FUNCTION:    acpi_ns_terminate
551  *
552  * PARAMETERS:  none
553  *
554  * RETURN:      none
555  *
556  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
557  *
558  ******************************************************************************/
559
560 void acpi_ns_terminate(void)
561 {
562         acpi_status status;
563         union acpi_operand_object *prev;
564         union acpi_operand_object *next;
565
566         ACPI_FUNCTION_TRACE(ns_terminate);
567
568         /* Delete any module-level code blocks */
569
570         next = acpi_gbl_module_code_list;
571         while (next) {
572                 prev = next;
573                 next = next->method.mutex;
574                 prev->method.mutex = NULL;      /* Clear the Mutex (cheated) field */
575                 acpi_ut_remove_reference(prev);
576         }
577
578         /*
579          * Free the entire namespace -- all nodes and all objects
580          * attached to the nodes
581          */
582         acpi_ns_delete_namespace_subtree(acpi_gbl_root_node);
583
584         /* Delete any objects attached to the root node */
585
586         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
587         if (ACPI_FAILURE(status)) {
588                 return_VOID;
589         }
590
591         acpi_ns_delete_node(acpi_gbl_root_node);
592         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
593
594         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
595         return_VOID;
596 }
597
598 /*******************************************************************************
599  *
600  * FUNCTION:    acpi_ns_opens_scope
601  *
602  * PARAMETERS:  type        - A valid namespace type
603  *
604  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
605  *              to the ACPI specification, else 0
606  *
607  ******************************************************************************/
608
609 u32 acpi_ns_opens_scope(acpi_object_type type)
610 {
611         ACPI_FUNCTION_ENTRY();
612
613         if (type > ACPI_TYPE_LOCAL_MAX) {
614
615                 /* type code out of range  */
616
617                 ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type));
618                 return (ACPI_NS_NORMAL);
619         }
620
621         return (((u32)acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
622 }
623
624 /*******************************************************************************
625  *
626  * FUNCTION:    acpi_ns_get_node_unlocked
627  *
628  * PARAMETERS:  *pathname   - Name to be found, in external (ASL) format. The
629  *                            \ (backslash) and ^ (carat) prefixes, and the
630  *                            . (period) to separate segments are supported.
631  *              prefix_node  - Root of subtree to be searched, or NS_ALL for the
632  *                            root of the name space. If Name is fully
633  *                            qualified (first s8 is '\'), the passed value
634  *                            of Scope will not be accessed.
635  *              flags       - Used to indicate whether to perform upsearch or
636  *                            not.
637  *              return_node - Where the Node is returned
638  *
639  * DESCRIPTION: Look up a name relative to a given scope and return the
640  *              corresponding Node. NOTE: Scope can be null.
641  *
642  * MUTEX:       Doesn't locks namespace
643  *
644  ******************************************************************************/
645
646 acpi_status
647 acpi_ns_get_node_unlocked(struct acpi_namespace_node *prefix_node,
648                           const char *pathname,
649                           u32 flags, struct acpi_namespace_node **return_node)
650 {
651         union acpi_generic_state scope_info;
652         acpi_status status;
653         char *internal_path;
654
655         ACPI_FUNCTION_TRACE_PTR(ns_get_node_unlocked,
656                                 ACPI_CAST_PTR(char, pathname));
657
658         /* Simplest case is a null pathname */
659
660         if (!pathname) {
661                 *return_node = prefix_node;
662                 if (!prefix_node) {
663                         *return_node = acpi_gbl_root_node;
664                 }
665
666                 return_ACPI_STATUS(AE_OK);
667         }
668
669         /* Quick check for a reference to the root */
670
671         if (ACPI_IS_ROOT_PREFIX(pathname[0]) && (!pathname[1])) {
672                 *return_node = acpi_gbl_root_node;
673                 return_ACPI_STATUS(AE_OK);
674         }
675
676         /* Convert path to internal representation */
677
678         status = acpi_ns_internalize_name(pathname, &internal_path);
679         if (ACPI_FAILURE(status)) {
680                 return_ACPI_STATUS(status);
681         }
682
683         /* Setup lookup scope (search starting point) */
684
685         scope_info.scope.node = prefix_node;
686
687         /* Lookup the name in the namespace */
688
689         status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY,
690                                 ACPI_IMODE_EXECUTE,
691                                 (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
692                                 return_node);
693         if (ACPI_FAILURE(status)) {
694                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n",
695                                   pathname, acpi_format_exception(status)));
696         }
697
698         ACPI_FREE(internal_path);
699         return_ACPI_STATUS(status);
700 }
701
702 /*******************************************************************************
703  *
704  * FUNCTION:    acpi_ns_get_node
705  *
706  * PARAMETERS:  *pathname   - Name to be found, in external (ASL) format. The
707  *                            \ (backslash) and ^ (carat) prefixes, and the
708  *                            . (period) to separate segments are supported.
709  *              prefix_node  - Root of subtree to be searched, or NS_ALL for the
710  *                            root of the name space. If Name is fully
711  *                            qualified (first s8 is '\'), the passed value
712  *                            of Scope will not be accessed.
713  *              flags       - Used to indicate whether to perform upsearch or
714  *                            not.
715  *              return_node - Where the Node is returned
716  *
717  * DESCRIPTION: Look up a name relative to a given scope and return the
718  *              corresponding Node. NOTE: Scope can be null.
719  *
720  * MUTEX:       Locks namespace
721  *
722  ******************************************************************************/
723
724 acpi_status
725 acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
726                  const char *pathname,
727                  u32 flags, struct acpi_namespace_node **return_node)
728 {
729         acpi_status status;
730
731         ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname));
732
733         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
734         if (ACPI_FAILURE(status)) {
735                 return_ACPI_STATUS(status);
736         }
737
738         status = acpi_ns_get_node_unlocked(prefix_node, pathname,
739                                            flags, return_node);
740
741         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
742         return_ACPI_STATUS(status);
743 }