CTC++ Coverage Report - Execution Profile    #210/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/acpi/namespace/nsaccess.c
Instrumentation mode: function-decision-multicondition
TER: 67 % ( 90/134)

Start/ End/    
True False - Line Source

  1 /*******************************************************************************
  2  *
  3  * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
  4  *
  5  ******************************************************************************/
  6 
  7 /*
  8  * Copyright (C) 2000 - 2006, R. Byron Moore
  9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 #include <acpi/acpi.h>
  45 #include <acpi/amlcode.h>
  46 #include <acpi/acnamesp.h>
  47 #include <acpi/acdispat.h>
  48 
  49 #define _COMPONENT          ACPI_NAMESPACE
  50 ACPI_MODULE_NAME("nsaccess")
  51 
  52 /*******************************************************************************
  53  *
  54  * FUNCTION:    acpi_ns_root_initialize
  55  *
  56  * PARAMETERS:  None
  57  *
  58  * RETURN:      Status
  59  *
  60  * DESCRIPTION: Allocate and initialize the default root named objects
  61  *
  62  * MUTEX:       Locks namespace for entire execution
  63  *
  64  ******************************************************************************/
 
  65 acpi_status acpi_ns_root_initialize(void)
  66 {
  67    acpi_status status;
  68    const struct acpi_predefined_names *init_val = NULL;
  69    struct acpi_namespace_node *new_node;
  70    union acpi_operand_object *obj_desc;
  71    acpi_string val = NULL;
  72 
  73    ACPI_FUNCTION_TRACE("ns_root_initialize");
  74 
  75    status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
- 76    if (ACPI_FAILURE(status)) {
 - 77       return_ACPI_STATUS(status);
  78    }
  79 
  80    /*
  81     * The global root ptr is initially NULL, so a non-NULL value indicates
  82     * that acpi_ns_root_initialize() has already been called; just return.
  83     */
- 84    if (acpi_gbl_root_node) {
  85       status = AE_OK;
 - 86       goto unlock_and_exit;
  87    }
  88 
  89    /*
  90     * Tell the rest of the subsystem that the root is initialized
  91     * (This is OK because the namespace is locked)
  92     */
  93    acpi_gbl_root_node = &acpi_gbl_root_node_struct;
  94 
  95    /* Enter the pre-defined names in the name table */
  96 
  97    ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  98            "Entering predefined entries into namespace\n"));
  99 
54   100    for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
  101       /* _OSI is optional for now, will be permanent later */
  102 
  103       if (!ACPI_STRCMP(init_val->name, "_OSI")
54 - 104           && !acpi_gbl_create_osi_method) {
 - 104     T && T
   104     T && F
 48   104     F && _
 - 105          continue;
  106       }
  107 
  108       status = acpi_ns_lookup(NULL, init_val->name, init_val->type,
  109                ACPI_IMODE_LOAD_PASS2,
  110                ACPI_NS_NO_UPSEARCH, NULL, &new_node);
  111 
54 - 112       if (ACPI_FAILURE(status) || (!new_node)) {   /* Must be on same line for code converter */
 - 112     (T) || (_)
 - 112     (F) || (T)
 54   112     (F) || (F)
  113          ACPI_EXCEPTION((AE_INFO, status,
  114                "Could not create predefined name %s",
  115                init_val->name));
  116       }
  117 
  118       /*
  119        * Name entered successfully.
  120        * If entry in pre_defined_names[] specifies an
  121        * initial value, create the initial value.
  122        */
24 30   123       if (init_val->val) {
  124          status = acpi_os_predefined_override(init_val, &val);
24 - 125          if (ACPI_FAILURE(status)) {
  126             ACPI_ERROR((AE_INFO,
  127                    "Could not override predefined %s",
  128                    init_val->name));
  129          }
  130 
24 - 131          if (!val) {
  132             val = init_val->val;
  133          }
  134 
  135          /*
  136           * Entry requests an initial value, allocate a
  137           * descriptor for it.
  138           */
  139          obj_desc =
  140              acpi_ut_create_internal_object(init_val->type);
24 - 141          if (!obj_desc) {
  142             status = AE_NO_MEMORY;
 - 143             goto unlock_and_exit;
  144          }
  145 
  146          /*
  147           * Convert value string from table entry to
  148           * internal representation. Only types actually
  149           * used for initial values are implemented here.
  150           */
    151          switch (init_val->type) {
   152          case ACPI_TYPE_METHOD:
  153             obj_desc->method.param_count =
  154                 (u8) ACPI_TO_INTEGER(val);
  155             obj_desc->common.flags |= AOPOBJ_DATA_VALID;
  156 
  157 #if defined (ACPI_ASL_COMPILER)
  158 
  159             /* save the parameter count for the i_aSL compiler */
  160 
  161             new_node->value = obj_desc->method.param_count;
  162 #else
  163             /* Mark this as a very SPECIAL method */
  164 
  165             obj_desc->method.method_flags =
  166                 AML_METHOD_INTERNAL_ONLY;
  167 
  168 #ifndef ACPI_DUMP_APP
  169             obj_desc->method.implementation =
  170                 acpi_ut_osi_implementation;
  171 #endif
  172 #endif
   173             break;
  174 
   175          case ACPI_TYPE_INTEGER:
  176 
  177             obj_desc->integer.value = ACPI_TO_INTEGER(val);
   178             break;
  179 
   180          case ACPI_TYPE_STRING:
  181 
  182             /*
  183              * Build an object around the static string
  184              */
  185             obj_desc->string.length =
  186                 (u32) ACPI_STRLEN(val);
  187             obj_desc->string.pointer = val;
  188             obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
   189             break;
  190 
   191          case ACPI_TYPE_MUTEX:
  192 
  193             obj_desc->mutex.node = new_node;
  194             obj_desc->mutex.sync_level =
  195                 (u8) (ACPI_TO_INTEGER(val) - 1);
  196 
- 197             if (ACPI_STRCMP(init_val->name, "_GL_") == 0) {
  198                /*
  199                 * Create a counting semaphore for the
  200                 * global lock
  201                 */
  202                status =
  203                    acpi_os_create_semaphore
  204                    (ACPI_NO_UNIT_LIMIT, 1,
  205                     &obj_desc->mutex.semaphore);
- 206                if (ACPI_FAILURE(status)) {
  207                   acpi_ut_remove_reference
  208                       (obj_desc);
 - 209                   goto unlock_and_exit;
  210                }
  211 
  212                /*
  213                 * We just created the mutex for the
  214                 * global lock, save it
  215                 */
  216                acpi_gbl_global_lock_semaphore =
  217                    obj_desc->mutex.semaphore;
    218             } else {
  219                /* Create a mutex */
  220 
  221                status = acpi_os_create_semaphore(1, 1,
  222                              &obj_desc->
  223                              mutex.
  224                              semaphore);
- 225                if (ACPI_FAILURE(status)) {
  226                   acpi_ut_remove_reference
  227                       (obj_desc);
 - 228                   goto unlock_and_exit;
  229                }
  230             }
   231             break;
  232 
 - 233          default:
  234 
  235             ACPI_ERROR((AE_INFO,
  236                    "Unsupported initial type value %X",
  237                    init_val->type));
  238             acpi_ut_remove_reference(obj_desc);
  239             obj_desc = NULL;
 - 240             continue;
  241          }
  242 
  243          /* Store pointer to value descriptor in the Node */
  244 
  245          status = acpi_ns_attach_object(new_node, obj_desc,
  246                          ACPI_GET_OBJECT_TYPE
  247                          (obj_desc));
  248 
  249          /* Remove local reference to the object */
  250 
  251          acpi_ut_remove_reference(obj_desc);
  252       }
  253    }
  254 
  255       unlock_and_exit:
  256    (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  257 
  258    /* Save a handle to "_GPE", it is always present */
  259 
- 260    if (ACPI_SUCCESS(status)) {
  261       status =
  262           acpi_ns_get_node_by_path("\\_GPE", NULL,
  263                     ACPI_NS_NO_UPSEARCH,
  264                     &acpi_gbl_fadt_gpe_device);
  265    }
  266 
   267    return_ACPI_STATUS(status);
  268 }
  269 
  270 /*******************************************************************************
  271  *
  272  * FUNCTION:    acpi_ns_lookup
  273  *
  274  * PARAMETERS:  scope_info      - Current scope info block
  275  *              Pathname        - Search pathname, in internal format
  276  *                                (as represented in the AML stream)
  277  *              Type            - Type associated with name
  278  *              interpreter_mode - IMODE_LOAD_PASS2 => add name if not found
  279  *              Flags           - Flags describing the search restrictions
  280  *              walk_state      - Current state of the walk
  281  *              return_node     - Where the Node is placed (if found
  282  *                                or created successfully)
  283  *
  284  * RETURN:      Status
  285  *
  286  * DESCRIPTION: Find or enter the passed name in the name space.
  287  *              Log an error if name not found in Exec mode.
  288  *
  289  * MUTEX:       Assumes namespace is locked.
  290  *
  291  ******************************************************************************/
  292 
  293 acpi_status
 
960285   294 acpi_ns_lookup(union acpi_generic_state *scope_info,
  295           char *pathname,
  296           acpi_object_type type,
  297           acpi_interpreter_mode interpreter_mode,
  298           u32 flags,
  299           struct acpi_walk_state *walk_state,
  300           struct acpi_namespace_node **return_node)
  301 {
  302    acpi_status status;
  303    char *path = pathname;
  304    struct acpi_namespace_node *prefix_node;
  305    struct acpi_namespace_node *current_node = NULL;
  306    struct acpi_namespace_node *this_node = NULL;
  307    u32 num_segments;
  308    u32 num_carats;
  309    acpi_name simple_name;
  310    acpi_object_type type_to_check_for;
  311    acpi_object_type this_search_type;
  312    u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
  313    u32 local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND |
  314                 ACPI_NS_SEARCH_PARENT);
  315 
  316    ACPI_FUNCTION_TRACE("ns_lookup");
  317 
960285 - 318    if (!return_node) {
 - 319       return_ACPI_STATUS(AE_BAD_PARAMETER);
  320    }
  321 
  322    acpi_gbl_ns_lookup_count++;
  323    *return_node = ACPI_ENTRY_NOT_FOUND;
  324 
960285 - 325    if (!acpi_gbl_root_node) {
 - 326       return_ACPI_STATUS(AE_NO_NAMESPACE);
  327    }
  328 
  329    /*
  330     * Get the prefix scope.
  331     * A null scope means use the root scope
  332     */
492 959793   333    if ((!scope_info) || (!scope_info->scope.node)) {
396    333   (T) || (_)
96    333   (F) || (T)
 959793   333   (F) || (F)
  334       ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  335               "Null scope prefix, using root node (%p)\n",
  336               acpi_gbl_root_node));
  337 
  338       prefix_node = acpi_gbl_root_node;
    339    } else {
  340       prefix_node = scope_info->scope.node;
  341       if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
959793 - 342           ACPI_DESC_TYPE_NAMED) {
  343          ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]",
  344                 prefix_node,
  345                 acpi_ut_get_descriptor_name(prefix_node)));
 - 346          return_ACPI_STATUS(AE_AML_INTERNAL);
  347       }
  348 
  349       /*
  350        * This node might not be a actual "scope" node (such as a
  351        * Device/Method, etc.)  It could be a Package or other object node.
  352        * Backup up the tree to find the containing scope node.
  353        */
  354       while (!acpi_ns_opens_scope(prefix_node->type) &&
630 959793   355              prefix_node->type != ACPI_TYPE_ANY) {
630    355     T && T
 - 355     T && F
 959793   355     F && _
  356          prefix_node = acpi_ns_get_parent_node(prefix_node);
  357       }
  358    }
  359 
  360    /* Save type   TBD: may be no longer necessary */
  361 
  362    type_to_check_for = type;
  363 
  364    /*
  365     * Begin examination of the actual pathname
  366     */
960285 - 367    if (!pathname) {
  368       /* A Null name_path is allowed and refers to the root */
  369 
  370       num_segments = 0;
  371       this_node = acpi_gbl_root_node;
  372       path = "";
  373 
  374       ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  375               "Null Pathname (Zero segments), Flags=%X\n",
  376               flags));
    377    } else {
  378       /*
  379        * Name pointer is valid (and must be in internal name format)
  380        *
  381        * Check for scope prefixes:
  382        *
  383        * As represented in the AML stream, a namepath consists of an
  384        * optional scope prefix followed by a name segment part.
  385        *
  386        * If present, the scope prefix is either a Root Prefix (in
  387        * which case the name is fully qualified), or one or more
  388        * Parent Prefixes (in which case the name's scope is relative
  389        * to the current scope).
  390        */
128672 831613   391       if (*path == (u8) AML_ROOT_PREFIX) {
  392          /* Pathname is fully qualified, start from the root */
  393 
  394          this_node = acpi_gbl_root_node;
  395          search_parent_flag = ACPI_NS_NO_UPSEARCH;
  396 
  397          /* Point to name segment part */
  398 
  399          path++;
  400 
  401          ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  402                  "Path is absolute from root [%p]\n",
  403                  this_node));
    404       } else {
  405          /* Pathname is relative to current scope, start there */
  406 
  407          ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  408                  "Searching relative to prefix scope [%4.4s] (%p)\n",
  409                  acpi_ut_get_node_name(prefix_node),
  410                  prefix_node));
  411 
  412          /*
  413           * Handle multiple Parent Prefixes (carat) by just getting
  414           * the parent node for each prefix instance.
  415           */
  416          this_node = prefix_node;
  417          num_carats = 0;
270 831613   418          while (*path == (u8) AML_PARENT_PREFIX) {
  419             /* Name is fully qualified, no search rules apply */
  420 
  421             search_parent_flag = ACPI_NS_NO_UPSEARCH;
  422             /*
  423              * Point past this prefix to the name segment
  424              * part or the next Parent Prefix
  425              */
  426             path++;
  427 
  428             /* Backup to the parent node */
  429 
  430             num_carats++;
  431             this_node = acpi_ns_get_parent_node(this_node);
270 - 432             if (!this_node) {
  433                /* Current scope has no parent scope */
  434 
  435                ACPI_ERROR((AE_INFO,
  436                       "ACPI path has too many parent prefixes (^) - reached beyond root node"));
 - 437                return_ACPI_STATUS(AE_NOT_FOUND);
  438             }
  439          }
  440 
270 831343   441          if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
  442             ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  443                     "Search scope is [%4.4s], path has %d carat(s)\n",
  444                     acpi_ut_get_node_name
  445                     (this_node), num_carats));
  446          }
  447       }
  448 
  449       /*
  450        * Determine the number of ACPI name segments in this pathname.
  451        *
  452        * The segment part consists of either:
  453        *  - A Null name segment (0)
  454        *  - A dual_name_prefix followed by two 4-byte name segments
  455        *  - A multi_name_prefix followed by a byte indicating the
  456        *      number of segments and the segments themselves.
  457        *  - A single 4-byte name segment
  458        *
  459        * Examine the name prefix opcode, if any, to determine the number of
  460        * segments.
  461        */
    462       switch (*path) {
 - 463       case 0:
  464          /*
  465           * Null name after a root or parent prefixes. We already
  466           * have the correct target node and there are no name segments.
  467           */
  468          num_segments = 0;
  469          type = this_node->type;
  470 
  471          ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  472                  "Prefix-only Pathname (Zero name segments), Flags=%X\n",
  473                  flags));
 - 474          break;
  475 
32496    476       case AML_DUAL_NAME_PREFIX:
  477 
  478          /* More than one name_seg, search rules do not apply */
  479 
  480          search_parent_flag = ACPI_NS_NO_UPSEARCH;
  481 
  482          /* Two segments, point to first name segment */
  483 
  484          num_segments = 2;
  485          path++;
  486 
  487          ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  488                  "Dual Pathname (2 segments, Flags=%X)\n",
  489                  flags));
32496    490          break;
  491 
95960    492       case AML_MULTI_NAME_PREFIX_OP:
  493 
  494          /* More than one name_seg, search rules do not apply */
  495 
  496          search_parent_flag = ACPI_NS_NO_UPSEARCH;
  497 
  498          /* Extract segment count, point to first name segment */
  499 
  500          path++;
  501          num_segments = (u32) (u8) * path;
  502          path++;
  503 
  504          ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  505                  "Multi Pathname (%d Segments, Flags=%X)\n",
  506                  num_segments, flags));
95960    507          break;
  508 
831829    509       default:
  510          /*
  511           * Not a Null name, no Dual or Multi prefix, hence there is
  512           * only one name segment and Pathname is already pointing to it.
  513           */
  514          num_segments = 1;
  515 
  516