0001
0002
0003
0004
0005
0006
0007
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acparser.h"
0011 #include "acinterp.h"
0012 #include "acnamesp.h"
0013
0014 #define _COMPONENT ACPI_NAMESPACE
0015 ACPI_MODULE_NAME("nseval")
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
0043 {
0044 acpi_status status;
0045
0046 ACPI_FUNCTION_TRACE(ns_evaluate);
0047
0048 if (!info) {
0049 return_ACPI_STATUS(AE_BAD_PARAMETER);
0050 }
0051
0052 if (!info->node) {
0053
0054
0055
0056
0057
0058
0059
0060
0061 status =
0062 acpi_ns_get_node(info->prefix_node, info->relative_pathname,
0063 ACPI_NS_NO_UPSEARCH, &info->node);
0064 if (ACPI_FAILURE(status)) {
0065 return_ACPI_STATUS(status);
0066 }
0067 }
0068
0069
0070
0071
0072
0073 if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
0074 info->node =
0075 ACPI_CAST_PTR(struct acpi_namespace_node,
0076 info->node->object);
0077 }
0078
0079
0080
0081 info->return_object = NULL;
0082 info->node_flags = info->node->flags;
0083 info->obj_desc = acpi_ns_get_attached_object(info->node);
0084
0085 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
0086 info->relative_pathname, info->node,
0087 acpi_ns_get_attached_object(info->node)));
0088
0089
0090
0091 info->predefined =
0092 acpi_ut_match_predefined_method(info->node->name.ascii);
0093
0094
0095
0096 info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE);
0097 if (!info->full_pathname) {
0098 return_ACPI_STATUS(AE_NO_MEMORY);
0099 }
0100
0101
0102
0103 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
0104 "%-26s: %s (%s)\n", " Enter evaluation",
0105 &info->full_pathname[1],
0106 acpi_ut_get_type_name(info->node->type)));
0107
0108
0109
0110 info->param_count = 0;
0111 if (info->parameters) {
0112 while (info->parameters[info->param_count]) {
0113 info->param_count++;
0114 }
0115
0116
0117
0118 if (info->param_count > ACPI_METHOD_NUM_ARGS) {
0119 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
0120 ACPI_WARN_ALWAYS,
0121 "Excess arguments (%u) - using only %u",
0122 info->param_count,
0123 ACPI_METHOD_NUM_ARGS));
0124
0125 info->param_count = ACPI_METHOD_NUM_ARGS;
0126 }
0127 }
0128
0129
0130
0131
0132
0133 acpi_ns_check_acpi_compliance(info->full_pathname, info->node,
0134 info->predefined);
0135
0136
0137
0138
0139
0140 acpi_ns_check_argument_count(info->full_pathname, info->node,
0141 info->param_count, info->predefined);
0142
0143
0144
0145 acpi_ns_check_argument_types(info);
0146
0147
0148
0149
0150
0151
0152
0153
0154 switch (acpi_ns_get_type(info->node)) {
0155 case ACPI_TYPE_ANY:
0156 case ACPI_TYPE_DEVICE:
0157 case ACPI_TYPE_EVENT:
0158 case ACPI_TYPE_MUTEX:
0159 case ACPI_TYPE_REGION:
0160 case ACPI_TYPE_THERMAL:
0161 case ACPI_TYPE_LOCAL_SCOPE:
0162
0163
0164
0165
0166 ACPI_ERROR((AE_INFO,
0167 "%s: This object type [%s] "
0168 "never contains data and cannot be evaluated",
0169 info->full_pathname,
0170 acpi_ut_get_type_name(info->node->type)));
0171
0172 status = AE_TYPE;
0173 goto cleanup;
0174
0175 case ACPI_TYPE_METHOD:
0176
0177
0178
0179
0180
0181
0182 if (!info->obj_desc) {
0183 ACPI_ERROR((AE_INFO,
0184 "%s: Method has no attached sub-object",
0185 info->full_pathname));
0186 status = AE_NULL_OBJECT;
0187 goto cleanup;
0188 }
0189
0190 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0191 "**** Execute method [%s] at AML address %p length %X\n",
0192 info->full_pathname,
0193 info->obj_desc->method.aml_start + 1,
0194 info->obj_desc->method.aml_length - 1));
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204 acpi_ex_enter_interpreter();
0205 status = acpi_ps_execute_method(info);
0206 acpi_ex_exit_interpreter();
0207 break;
0208
0209 default:
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 acpi_ex_enter_interpreter();
0231
0232
0233
0234 info->return_object =
0235 ACPI_CAST_PTR(union acpi_operand_object, info->node);
0236
0237 status =
0238 acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
0239 (struct acpi_namespace_node,
0240 &info->return_object), NULL);
0241 acpi_ex_exit_interpreter();
0242
0243 if (ACPI_FAILURE(status)) {
0244 info->return_object = NULL;
0245 goto cleanup;
0246 }
0247
0248 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Returned object %p [%s]\n",
0249 info->return_object,
0250 acpi_ut_get_object_type_name(info->
0251 return_object)));
0252
0253 status = AE_CTRL_RETURN_VALUE;
0254 break;
0255 }
0256
0257
0258
0259
0260
0261 (void)acpi_ns_check_return_value(info->node, info, info->param_count,
0262 status, &info->return_object);
0263
0264
0265
0266 if (status == AE_CTRL_RETURN_VALUE) {
0267
0268
0269
0270 if (info->flags & ACPI_IGNORE_RETURN_VALUE) {
0271 acpi_ut_remove_reference(info->return_object);
0272 info->return_object = NULL;
0273 }
0274
0275
0276
0277 status = AE_OK;
0278 } else if (ACPI_FAILURE(status)) {
0279
0280
0281
0282 if (info->return_object) {
0283 acpi_ut_remove_reference(info->return_object);
0284 info->return_object = NULL;
0285 }
0286 }
0287
0288 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0289 "*** Completed evaluation of object %s ***\n",
0290 info->relative_pathname));
0291
0292 cleanup:
0293
0294
0295 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
0296 "%-26s: %s\n", " Exit evaluation",
0297 &info->full_pathname[1]));
0298
0299
0300
0301
0302
0303 ACPI_FREE(info->full_pathname);
0304 info->full_pathname = NULL;
0305 return_ACPI_STATUS(status);
0306 }