diff options
Diffstat (limited to 'drivers/acpi/namespace/nseval.c')
| -rw-r--r-- | drivers/acpi/namespace/nseval.c | 73 |
1 files changed, 62 insertions, 11 deletions
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index d369164e00b..4cdf03ac2b4 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c | |||
| @@ -78,6 +78,7 @@ ACPI_MODULE_NAME("nseval") | |||
| 78 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | 78 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) |
| 79 | { | 79 | { |
| 80 | acpi_status status; | 80 | acpi_status status; |
| 81 | struct acpi_namespace_node *node; | ||
| 81 | 82 | ||
| 82 | ACPI_FUNCTION_TRACE(ns_evaluate); | 83 | ACPI_FUNCTION_TRACE(ns_evaluate); |
| 83 | 84 | ||
| @@ -117,6 +118,8 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
| 117 | info->resolved_node, | 118 | info->resolved_node, |
| 118 | acpi_ns_get_attached_object(info->resolved_node))); | 119 | acpi_ns_get_attached_object(info->resolved_node))); |
| 119 | 120 | ||
| 121 | node = info->resolved_node; | ||
| 122 | |||
| 120 | /* | 123 | /* |
| 121 | * Two major cases here: | 124 | * Two major cases here: |
| 122 | * | 125 | * |
| @@ -148,21 +151,22 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
| 148 | info->param_count++; | 151 | info->param_count++; |
| 149 | } | 152 | } |
| 150 | 153 | ||
| 151 | /* Error if too few arguments were passed in */ | 154 | /* |
| 155 | * Warning if too few or too many arguments have been passed by the | ||
| 156 | * caller. We don't want to abort here with an error because an | ||
| 157 | * incorrect number of arguments may not cause the method to fail. | ||
| 158 | * However, the method will fail if there are too few arguments passed | ||
| 159 | * and the method attempts to use one of the missing ones. | ||
| 160 | */ | ||
| 152 | 161 | ||
| 153 | if (info->param_count < info->obj_desc->method.param_count) { | 162 | if (info->param_count < info->obj_desc->method.param_count) { |
| 154 | ACPI_ERROR((AE_INFO, | 163 | ACPI_WARNING((AE_INFO, |
| 155 | "Insufficient arguments - " | 164 | "Insufficient arguments - " |
| 156 | "method [%4.4s] needs %d, found %d", | 165 | "method [%4.4s] needs %d, found %d", |
| 157 | acpi_ut_get_node_name(info->resolved_node), | 166 | acpi_ut_get_node_name(info->resolved_node), |
| 158 | info->obj_desc->method.param_count, | 167 | info->obj_desc->method.param_count, |
| 159 | info->param_count)); | 168 | info->param_count)); |
| 160 | return_ACPI_STATUS(AE_MISSING_ARGUMENTS); | 169 | } else if (info->param_count > |
| 161 | } | ||
| 162 | |||
| 163 | /* Just a warning if too many arguments */ | ||
| 164 | |||
| 165 | else if (info->param_count > | ||
| 166 | info->obj_desc->method.param_count) { | 170 | info->obj_desc->method.param_count) { |
| 167 | ACPI_WARNING((AE_INFO, | 171 | ACPI_WARNING((AE_INFO, |
| 168 | "Excess arguments - " | 172 | "Excess arguments - " |
| @@ -195,7 +199,28 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
| 195 | } else { | 199 | } else { |
| 196 | /* | 200 | /* |
| 197 | * 2) Object is not a method, return its current value | 201 | * 2) Object is not a method, return its current value |
| 202 | * | ||
| 203 | * Disallow certain object types. For these, "evaluation" is undefined. | ||
| 198 | */ | 204 | */ |
| 205 | switch (info->resolved_node->type) { | ||
| 206 | case ACPI_TYPE_DEVICE: | ||
| 207 | case ACPI_TYPE_EVENT: | ||
| 208 | case ACPI_TYPE_MUTEX: | ||
| 209 | case ACPI_TYPE_REGION: | ||
| 210 | case ACPI_TYPE_THERMAL: | ||
| 211 | case ACPI_TYPE_LOCAL_SCOPE: | ||
| 212 | |||
| 213 | ACPI_ERROR((AE_INFO, | ||
| 214 | "[%4.4s] Evaluation of object type [%s] is not supported", | ||
| 215 | info->resolved_node->name.ascii, | ||
| 216 | acpi_ut_get_type_name(info->resolved_node-> | ||
| 217 | type))); | ||
| 218 | |||
| 219 | return_ACPI_STATUS(AE_TYPE); | ||
| 220 | |||
| 221 | default: | ||
| 222 | break; | ||
| 223 | } | ||
| 199 | 224 | ||
| 200 | /* | 225 | /* |
| 201 | * Objects require additional resolution steps (e.g., the Node may be | 226 | * Objects require additional resolution steps (e.g., the Node may be |
| @@ -239,9 +264,35 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
| 239 | } | 264 | } |
| 240 | } | 265 | } |
| 241 | 266 | ||
| 242 | /* | 267 | /* Validation of return values for ACPI-predefined methods and objects */ |
| 243 | * Check if there is a return value that must be dealt with | 268 | |
| 244 | */ | 269 | if ((status == AE_OK) || (status == AE_CTRL_RETURN_VALUE)) { |
| 270 | /* | ||
| 271 | * If this is the first evaluation, check the return value. This | ||
| 272 | * ensures that any warnings will only be emitted during the very | ||
| 273 | * first evaluation of the object. | ||
| 274 | */ | ||
| 275 | if (!(node->flags & ANOBJ_EVALUATED)) { | ||
| 276 | /* | ||
| 277 | * Check for a predefined ACPI name. If found, validate the | ||
| 278 | * returned object. | ||
| 279 | * | ||
| 280 | * Note: Ignore return status for now, emit warnings if there are | ||
| 281 | * problems with the returned object. May change later to abort | ||
| 282 | * the method on invalid return object. | ||
| 283 | */ | ||
| 284 | (void)acpi_ns_check_predefined_names(node, | ||
| 285 | info-> | ||
| 286 | return_object); | ||
| 287 | } | ||
| 288 | |||
| 289 | /* Mark the node as having been evaluated */ | ||
| 290 | |||
| 291 | node->flags |= ANOBJ_EVALUATED; | ||
| 292 | } | ||
| 293 | |||
| 294 | /* Check if there is a return value that must be dealt with */ | ||
| 295 | |||
| 245 | if (status == AE_CTRL_RETURN_VALUE) { | 296 | if (status == AE_CTRL_RETURN_VALUE) { |
| 246 | 297 | ||
| 247 | /* If caller does not want the return value, delete it */ | 298 | /* If caller does not want the return value, delete it */ |
