Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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