linux/drivers/acpi/acpica/dsinit.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: dsinit - Object initialization namespace walk
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2011, Intel Corp.
   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 "accommon.h"
  46#include "acdispat.h"
  47#include "acnamesp.h"
  48#include "actables.h"
  49
  50#define _COMPONENT          ACPI_DISPATCHER
  51ACPI_MODULE_NAME("dsinit")
  52
  53/* Local prototypes */
  54static acpi_status
  55acpi_ds_init_one_object(acpi_handle obj_handle,
  56                        u32 level, void *context, void **return_value);
  57
  58/*******************************************************************************
  59 *
  60 * FUNCTION:    acpi_ds_init_one_object
  61 *
  62 * PARAMETERS:  obj_handle      - Node for the object
  63 *              Level           - Current nesting level
  64 *              Context         - Points to a init info struct
  65 *              return_value    - Not used
  66 *
  67 * RETURN:      Status
  68 *
  69 * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object
  70 *              within the namespace.
  71 *
  72 *              Currently, the only objects that require initialization are:
  73 *              1) Methods
  74 *              2) Operation Regions
  75 *
  76 ******************************************************************************/
  77
  78static acpi_status
  79acpi_ds_init_one_object(acpi_handle obj_handle,
  80                        u32 level, void *context, void **return_value)
  81{
  82        struct acpi_init_walk_info *info =
  83            (struct acpi_init_walk_info *)context;
  84        struct acpi_namespace_node *node =
  85            (struct acpi_namespace_node *)obj_handle;
  86        acpi_object_type type;
  87        acpi_status status;
  88
  89        ACPI_FUNCTION_ENTRY();
  90
  91        /*
  92         * We are only interested in NS nodes owned by the table that
  93         * was just loaded
  94         */
  95        if (node->owner_id != info->owner_id) {
  96                return (AE_OK);
  97        }
  98
  99        info->object_count++;
 100
 101        /* And even then, we are only interested in a few object types */
 102
 103        type = acpi_ns_get_type(obj_handle);
 104
 105        switch (type) {
 106        case ACPI_TYPE_REGION:
 107
 108                status = acpi_ds_initialize_region(obj_handle);
 109                if (ACPI_FAILURE(status)) {
 110                        ACPI_EXCEPTION((AE_INFO, status,
 111                                        "During Region initialization %p [%4.4s]",
 112                                        obj_handle,
 113                                        acpi_ut_get_node_name(obj_handle)));
 114                }
 115
 116                info->op_region_count++;
 117                break;
 118
 119        case ACPI_TYPE_METHOD:
 120
 121                info->method_count++;
 122                break;
 123
 124        case ACPI_TYPE_DEVICE:
 125
 126                info->device_count++;
 127                break;
 128
 129        default:
 130                break;
 131        }
 132
 133        /*
 134         * We ignore errors from above, and always return OK, since
 135         * we don't want to abort the walk on a single error.
 136         */
 137        return (AE_OK);
 138}
 139
 140/*******************************************************************************
 141 *
 142 * FUNCTION:    acpi_ds_initialize_objects
 143 *
 144 * PARAMETERS:  table_desc      - Descriptor for parent ACPI table
 145 *              start_node      - Root of subtree to be initialized.
 146 *
 147 * RETURN:      Status
 148 *
 149 * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
 150 *              necessary initialization on the objects found therein
 151 *
 152 ******************************************************************************/
 153
 154acpi_status
 155acpi_ds_initialize_objects(u32 table_index,
 156                           struct acpi_namespace_node * start_node)
 157{
 158        acpi_status status;
 159        struct acpi_init_walk_info info;
 160        struct acpi_table_header *table;
 161        acpi_owner_id owner_id;
 162
 163        ACPI_FUNCTION_TRACE(ds_initialize_objects);
 164
 165        status = acpi_tb_get_owner_id(table_index, &owner_id);
 166        if (ACPI_FAILURE(status)) {
 167                return_ACPI_STATUS(status);
 168        }
 169
 170        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 171                          "**** Starting initialization of namespace objects ****\n"));
 172        ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:"));
 173
 174        /* Set all init info to zero */
 175
 176        ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info));
 177
 178        info.owner_id = owner_id;
 179        info.table_index = table_index;
 180
 181        /* Walk entire namespace from the supplied root */
 182
 183        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 184        if (ACPI_FAILURE(status)) {
 185                return_ACPI_STATUS(status);
 186        }
 187
 188        /*
 189         * We don't use acpi_walk_namespace since we do not want to acquire
 190         * the namespace reader lock.
 191         */
 192        status =
 193            acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
 194                                   ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
 195                                   NULL, &info, NULL);
 196        if (ACPI_FAILURE(status)) {
 197                ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
 198        }
 199        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 200
 201        status = acpi_get_table_by_index(table_index, &table);
 202        if (ACPI_FAILURE(status)) {
 203                return_ACPI_STATUS(status);
 204        }
 205
 206        ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
 207                              "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n",
 208                              table->signature, owner_id, info.object_count,
 209                              info.device_count, info.method_count,
 210                              info.op_region_count));
 211
 212        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 213                          "%u Methods, %u Regions\n", info.method_count,
 214                          info.op_region_count));
 215
 216        return_ACPI_STATUS(AE_OK);
 217}
 218