at v2.6.13 246 lines 7.4 kB view raw
1/****************************************************************************** 2 * 3 * Module Name: psxface - Parser external interfaces 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2005, 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 45#include <acpi/acpi.h> 46#include <acpi/acparser.h> 47#include <acpi/acdispat.h> 48#include <acpi/acinterp.h> 49#include <acpi/acnamesp.h> 50 51 52#define _COMPONENT ACPI_PARSER 53 ACPI_MODULE_NAME ("psxface") 54 55 56/******************************************************************************* 57 * 58 * FUNCTION: acpi_psx_execute 59 * 60 * PARAMETERS: Info - Method info block, contains: 61 * Node - Method Node to execute 62 * Parameters - List of parameters to pass to the method, 63 * terminated by NULL. Params itself may be 64 * NULL if no parameters are being passed. 65 * return_object - Where to put method's return value (if 66 * any). If NULL, no value is returned. 67 * parameter_type - Type of Parameter list 68 * return_object - Where to put method's return value (if 69 * any). If NULL, no value is returned. 70 * 71 * RETURN: Status 72 * 73 * DESCRIPTION: Execute a control method 74 * 75 ******************************************************************************/ 76 77acpi_status 78acpi_psx_execute ( 79 struct acpi_parameter_info *info) 80{ 81 acpi_status status; 82 union acpi_operand_object *obj_desc; 83 u32 i; 84 union acpi_parse_object *op; 85 struct acpi_walk_state *walk_state; 86 87 88 ACPI_FUNCTION_TRACE ("psx_execute"); 89 90 91 /* Validate the Node and get the attached object */ 92 93 if (!info || !info->node) { 94 return_ACPI_STATUS (AE_NULL_ENTRY); 95 } 96 97 obj_desc = acpi_ns_get_attached_object (info->node); 98 if (!obj_desc) { 99 return_ACPI_STATUS (AE_NULL_OBJECT); 100 } 101 102 /* Init for new method, wait on concurrency semaphore */ 103 104 status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL); 105 if (ACPI_FAILURE (status)) { 106 return_ACPI_STATUS (status); 107 } 108 109 if ((info->parameter_type == ACPI_PARAM_ARGS) && 110 (info->parameters)) { 111 /* 112 * The caller "owns" the parameters, so give each one an extra 113 * reference 114 */ 115 for (i = 0; info->parameters[i]; i++) { 116 acpi_ut_add_reference (info->parameters[i]); 117 } 118 } 119 120 /* 121 * 1) Perform the first pass parse of the method to enter any 122 * named objects that it creates into the namespace 123 */ 124 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 125 "**** Begin Method Parse **** Entry=%p obj=%p\n", 126 info->node, obj_desc)); 127 128 /* Create and init a Root Node */ 129 130 op = acpi_ps_create_scope_op (); 131 if (!op) { 132 status = AE_NO_MEMORY; 133 goto cleanup1; 134 } 135 136 /* 137 * Get a new owner_id for objects created by this method. Namespace 138 * objects (such as Operation Regions) can be created during the 139 * first pass parse. 140 */ 141 obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); 142 143 /* Create and initialize a new walk state */ 144 145 walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, 146 NULL, NULL, NULL); 147 if (!walk_state) { 148 status = AE_NO_MEMORY; 149 goto cleanup2; 150 } 151 152 status = acpi_ds_init_aml_walk (walk_state, op, info->node, 153 obj_desc->method.aml_start, 154 obj_desc->method.aml_length, NULL, 1); 155 if (ACPI_FAILURE (status)) { 156 goto cleanup3; 157 } 158 159 /* Parse the AML */ 160 161 status = acpi_ps_parse_aml (walk_state); 162 acpi_ps_delete_parse_tree (op); 163 if (ACPI_FAILURE (status)) { 164 goto cleanup1; /* Walk state is already deleted */ 165 } 166 167 /* 168 * 2) Execute the method. Performs second pass parse simultaneously 169 */ 170 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 171 "**** Begin Method Execution **** Entry=%p obj=%p\n", 172 info->node, obj_desc)); 173 174 /* Create and init a Root Node */ 175 176 op = acpi_ps_create_scope_op (); 177 if (!op) { 178 status = AE_NO_MEMORY; 179 goto cleanup1; 180 } 181 182 /* Init new op with the method name and pointer back to the NS node */ 183 184 acpi_ps_set_name (op, info->node->name.integer); 185 op->common.node = info->node; 186 187 /* Create and initialize a new walk state */ 188 189 walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); 190 if (!walk_state) { 191 status = AE_NO_MEMORY; 192 goto cleanup2; 193 } 194 195 status = acpi_ds_init_aml_walk (walk_state, op, info->node, 196 obj_desc->method.aml_start, 197 obj_desc->method.aml_length, info, 3); 198 if (ACPI_FAILURE (status)) { 199 goto cleanup3; 200 } 201 202 /* The walk of the parse tree is where we actually execute the method */ 203 204 status = acpi_ps_parse_aml (walk_state); 205 goto cleanup2; /* Walk state already deleted */ 206 207 208cleanup3: 209 acpi_ds_delete_walk_state (walk_state); 210 211cleanup2: 212 acpi_ps_delete_parse_tree (op); 213 214cleanup1: 215 if ((info->parameter_type == ACPI_PARAM_ARGS) && 216 (info->parameters)) { 217 /* Take away the extra reference that we gave the parameters above */ 218 219 for (i = 0; info->parameters[i]; i++) { 220 /* Ignore errors, just do them all */ 221 222 (void) acpi_ut_update_object_reference ( 223 info->parameters[i], REF_DECREMENT); 224 } 225 } 226 227 if (ACPI_FAILURE (status)) { 228 return_ACPI_STATUS (status); 229 } 230 231 /* 232 * If the method has returned an object, signal this to the caller with 233 * a control exception code 234 */ 235 if (info->return_object) { 236 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n", 237 info->return_object)); 238 ACPI_DUMP_STACK_ENTRY (info->return_object); 239 240 status = AE_CTRL_RETURN_VALUE; 241 } 242 243 return_ACPI_STATUS (status); 244} 245 246