diff options
Diffstat (limited to 'drivers/acpi/acpica/nspredef.c')
| -rw-r--r-- | drivers/acpi/acpica/nspredef.c | 423 |
1 files changed, 115 insertions, 308 deletions
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 224c3005340..392910ffbed 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,40 +61,29 @@ ACPI_MODULE_NAME("nspredef") * There are several areas that are validated: * * 1) The number of input arguments as defined by the method/object in the - * ASL is validated against the ACPI specification. + * ASL is validated against the ACPI specification. * 2) The type of the return object (if any) is validated against the ACPI - * specification. + * specification. * 3) For returned package objects, the count of package elements is - * validated, as well as the type of each package element. Nested - * packages are supported. + * validated, as well as the type of each package element. Nested + * packages are supported. * * For any problems found, a warning message is issued. * ******************************************************************************/ /* Local prototypes */ static acpi_status -acpi_ns_check_reference(struct acpi_predefined_data *data, +acpi_ns_check_reference(struct acpi_evaluate_info *info, union acpi_operand_object *return_object); -static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes); - -/* - * Names for the types that can be returned by the predefined objects. - * Used for warning messages. Must be in the same order as the ACPI_RTYPEs - */ -static const char *acpi_rtype_names[] = { - "/Integer", - "/String", - "/Buffer", - "/Package", - "/Reference", -}; +static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object); /******************************************************************************* * - * FUNCTION: acpi_ns_check_predefined_names + * FUNCTION: acpi_ns_check_return_value * * PARAMETERS: node - Namespace node for the method/object + * info - Method execution information block * user_param_count - Number of parameters actually passed * return_status - Status from the object evaluation * return_object_ptr - Pointer to the object returned from the @@ -102,45 +91,25 @@ static const char *acpi_rtype_names[] = { * * RETURN: Status * - * DESCRIPTION: Check an ACPI name for a match in the predefined name list. + * DESCRIPTION: Check the value returned from a predefined name. * ******************************************************************************/ acpi_status -acpi_ns_check_predefined_names(struct acpi_namespace_node *node, - u32 user_param_count, - acpi_status return_status, - union acpi_operand_object **return_object_ptr) +acpi_ns_check_return_value(struct acpi_namespace_node *node, + struct acpi_evaluate_info *info, + u32 user_param_count, + acpi_status return_status, + union acpi_operand_object **return_object_ptr) { - union acpi_operand_object *return_object = *return_object_ptr; - acpi_status status = AE_OK; + acpi_status status; const union acpi_predefined_info *predefined; - char *pathname; - struct acpi_predefined_data *data; - - /* Match the name for this method/object against the predefined list */ - - predefined = acpi_ns_check_for_predefined_name(node); - - /* Get the full pathname to the object, for use in warning messages */ - - pathname = acpi_ns_get_external_pathname(node); - if (!pathname) { - return (AE_OK); /* Could not get pathname, ignore */ - } - - /* - * Check that the parameter count for this method matches the ASL - * definition. For predefined names, ensure that both the caller and - * the method itself are in accordance with the ACPI specification. - */ - acpi_ns_check_parameter_count(pathname, node, user_param_count, - predefined); /* If not a predefined name, we cannot validate the return object */ + predefined = info->predefined; if (!predefined) { - goto cleanup; + return (AE_OK); } /* @@ -148,26 +117,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, * validate the return object */ if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { - goto cleanup; - } - - /* - * If there is no return value, check if we require a return value for - * this predefined name. Either one return value is expected, or none, - * for both methods and other objects. - * - * Exit now if there is no return object. Warning if one was expected. - */ - if (!return_object) { - if ((predefined->info.expected_btypes) && - (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { - ACPI_WARN_PREDEFINED((AE_INFO, pathname, - ACPI_WARN_ALWAYS, - "Missing expected return value")); - - status = AE_AML_NO_RETURN_VALUE; - } - goto cleanup; + return (AE_OK); } /* @@ -186,25 +136,14 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, if (acpi_gbl_disable_auto_repair || (!predefined->info.expected_btypes) || (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) { - goto cleanup; - } - - /* Create the parameter data block for object validation */ - - data = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_predefined_data)); - if (!data) { - goto cleanup; + return (AE_OK); } - data->predefined = predefined; - data->node = node; - data->node_flags = node->flags; - data->pathname = pathname; /* * Check that the type of the main return object is what is expected * for this predefined name */ - status = acpi_ns_check_object_type(data, return_object_ptr, + status = acpi_ns_check_object_type(info, return_object_ptr, predefined->info.expected_btypes, ACPI_NOT_PACKAGE_ELEMENT); if (ACPI_FAILURE(status)) { @@ -212,14 +151,29 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, } /* + * + * 4) If there is no return value and it is optional, just return + * AE_OK (_WAK). + */ + if (!(*return_object_ptr)) { + goto exit; + } + + /* * For returned Package objects, check the type of all sub-objects. * Note: Package may have been newly created by call above. */ if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) { - data->parent_package = *return_object_ptr; - status = acpi_ns_check_package(data, return_object_ptr); + info->parent_package = *return_object_ptr; + status = acpi_ns_check_package(info, return_object_ptr); if (ACPI_FAILURE(status)) { - goto exit; + + /* We might be able to fix some errors */ + + if ((status != AE_AML_OPERAND_TYPE) && + (status != AE_AML_OPERAND_VALUE)) { + goto exit; + } } } @@ -231,7 +185,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, * performed on a per-name basis, i.e., the code is specific to * particular predefined names. */ - status = acpi_ns_complex_repairs(data, node, status, return_object_ptr); + status = acpi_ns_complex_repairs(info, node, status, return_object_ptr); exit: /* @@ -239,156 +193,18 @@ exit: * or more objects, mark the parent node to suppress further warning * messages during the next evaluation of the same method/object. */ - if (ACPI_FAILURE(status) || (data->flags & ACPI_OBJECT_REPAIRED)) { + if (ACPI_FAILURE(status) || (info->return_flags & ACPI_OBJECT_REPAIRED)) { node->flags |= ANOBJ_EVALUATED; } - ACPI_FREE(data); -cleanup: - ACPI_FREE(pathname); return (status); } /******************************************************************************* * - * FUNCTION: acpi_ns_check_parameter_count - * - * PARAMETERS: pathname - Full pathname to the node (for error msgs) - * node - Namespace node for the method/object - * user_param_count - Number of args passed in by the caller - * predefined - Pointer to entry in predefined name table - * - * RETURN: None - * - * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a - * predefined name is what is expected (i.e., what is defined in - * the ACPI specification for this predefined name.) - * - ******************************************************************************/ - -void -acpi_ns_check_parameter_count(char *pathname, - struct acpi_namespace_node *node, - u32 user_param_count, - const union acpi_predefined_info *predefined) -{ - u32 param_count; - u32 required_params_current; - u32 required_params_old; - - /* Methods have 0-7 parameters. All other types have zero. */ - - param_count = 0; - if (node->type == ACPI_TYPE_METHOD) { - param_count = node->object->method.param_count; - } - - if (!predefined) { - /* - * Check the parameter count for non-predefined methods/objects. - * - * Warning if too few or too many arguments have been passed by the - * caller. An incorrect number of arguments may not cause the method - * to fail. However, the method will fail if there are too few - * arguments and the method attempts to use one of the missing ones. - */ - if (user_param_count < param_count) { - ACPI_WARN_PREDEFINED((AE_INFO, pathname, - ACPI_WARN_ALWAYS, - "Insufficient arguments - needs %u, found %u", - param_count, user_param_count)); - } else if (user_param_count > param_count) { - ACPI_WARN_PREDEFINED((AE_INFO, pathname, - ACPI_WARN_ALWAYS, - "Excess arguments - needs %u, found %u", - param_count, user_param_count)); - } - return; - } - - /* - * Validate the user-supplied parameter count. - * Allow two different legal argument counts (_SCP, etc.) - */ - required_params_current = predefined->info.param_count & 0x0F; - required_params_old = predefined->info.param_count >> 4; - - if (user_param_count != ACPI_UINT32_MAX) { - if ((user_param_count != required_params_current) && - (user_param_count != required_params_old)) { - ACPI_WARN_PREDEFINED((AE_INFO, pathname, - ACPI_WARN_ALWAYS, - "Parameter count mismatch - " - "caller passed %u, ACPI requires %u", - user_param_count, - required_params_current)); - } - } - - /* - * Check that the ASL-defined parameter count is what is expected for - * this predefined name (parameter count as defined by the ACPI - * specification) - */ - if ((param_count != required_params_current) && - (param_count != required_params_old)) { - ACPI_WARN_PREDEFINED((AE_INFO, pathname, node->flags, - "Parameter count mismatch - ASL declared %u, ACPI requires %u", - param_count, required_params_current)); - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_ns_check_for_predefined_name - * - * PARAMETERS: node - Namespace node for the method/object - * - * RETURN: Pointer to entry in predefined table. NULL indicates not found. - * - * DESCRIPTION: Check an object name against the predefined object list. - * - ******************************************************************************/ - -const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct - acpi_namespace_node - *node) -{ - const union acpi_predefined_info *this_name; - - /* Quick check for a predefined name, first character must be underscore */ - - if (node->name.ascii[0] != '_') { - return (NULL); - } - - /* Search info table for a predefined method/object name */ - - this_name = predefined_names; - while (this_name->info.name[0]) { - if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { - return (this_name); - } - - /* - * Skip next entry in the table if this name returns a Package - * (next entry contains the package info) - */ - if (this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) { - this_name++; - } - - this_name++; - } - - return (NULL); /* Not found */ -} - -/******************************************************************************* - * * FUNCTION: acpi_ns_check_object_type * - * PARAMETERS: data - Pointer to validation data structure + * PARAMETERS: info - Method execution information block * return_object_ptr - Pointer to the object returned from the * evaluation of a method or object * expected_btypes - Bitmap of expected return type(s) @@ -404,35 +220,20 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct ******************************************************************************/ acpi_status -acpi_ns_check_object_type(struct acpi_predefined_data *data, +acpi_ns_check_object_type(struct acpi_evaluate_info *info, union acpi_operand_object **return_object_ptr, u32 expected_btypes, u32 package_index) { union acpi_operand_object *return_object = *return_object_ptr; acpi_status status = AE_OK; - u32 return_btype; char type_buffer[48]; /* Room for 5 types */ - /* - * If we get a NULL return_object here, it is a NULL package element. - * Since all extraneous NULL package elements were removed earlier by a - * call to acpi_ns_remove_null_elements, this is an unexpected NULL element. - * We will attempt to repair it. - */ - if (!return_object) { - status = acpi_ns_repair_null_element(data, expected_btypes, - package_index, - return_object_ptr); - if (ACPI_SUCCESS(status)) { - return (AE_OK); /* Repair was successful */ - } - goto type_error_exit; - } - /* A Namespace node should not get here, but make sure */ - if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + if (return_object && + ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { + ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, + info->node_flags, "Invalid return type - Found a Namespace node [%4.4s] type %s", return_object->node.name.ascii, acpi_ut_get_type_name(return_object->node. @@ -448,67 +249,48 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data, * from all of the predefined names (including elements of returned * packages) */ - switch (return_object->common.type) { - case ACPI_TYPE_INTEGER: - return_btype = ACPI_RTYPE_INTEGER; - break; + info->return_btype = acpi_ns_get_bitmapped_type(return_object); + if (info->return_btype == ACPI_RTYPE_ANY) { - case ACPI_TYPE_BUFFER: - return_btype = ACPI_RTYPE_BUFFER; - break; - - case ACPI_TYPE_STRING: - return_btype = ACPI_RTYPE_STRING; - break; - - case ACPI_TYPE_PACKAGE: - return_btype = ACPI_RTYPE_PACKAGE; - break; - - case ACPI_TYPE_LOCAL_REFERENCE: - return_btype = ACPI_RTYPE_REFERENCE; - break; - - default: /* Not one of the supported objects, must be incorrect */ - goto type_error_exit; } - /* Is the object one of the expected types? */ - - if (return_btype & expected_btypes) { - - /* For reference objects, check that the reference type is correct */ - - if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { - status = acpi_ns_check_reference(data, return_object); - } + /* For reference objects, check that the reference type is correct */ + if ((info->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) { + status = acpi_ns_check_reference(info, return_object); return (status); } - /* Type mismatch -- attempt repair of the returned object */ + /* Attempt simple repair of the returned object if necessary */ - status = acpi_ns_repair_object(data, expected_btypes, + status = acpi_ns_simple_repair(info, expected_btypes, package_index, return_object_ptr); if (ACPI_SUCCESS(status)) { - return (AE_OK); /* Repair was successful */ + return (AE_OK); /* Successful repair */ } - type_error_exit: +type_error_exit: /* Create a string with all expected types for this predefined object */ - acpi_ns_get_expected_types(type_buffer, expected_btypes); + acpi_ut_get_expected_return_types(type_buffer, expected_btypes); - if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + if (!return_object) { + ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, + info->node_flags, + "Expected return object of type %s", + type_buffer)); + } else if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { + ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, + info->node_flags, "Return type mismatch - found %s, expected %s", acpi_ut_get_object_type_name (return_object), type_buffer)); } else { - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, + info->node_flags, "Return Package type mismatch at index %u - " "found %s, expected %s", package_index, acpi_ut_get_object_type_name @@ -522,7 +304,7 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data, * * FUNCTION: acpi_ns_check_reference * - * PARAMETERS: data - Pointer to validation data structure + * PARAMETERS: info - Method execution information block * return_object - Object returned from the evaluation of a * method or object * @@ -535,7 +317,7 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data, ******************************************************************************/ static acpi_status -acpi_ns_check_reference(struct acpi_predefined_data *data, +acpi_ns_check_reference(struct acpi_evaluate_info *info, union acpi_operand_object *return_object) { @@ -548,7 +330,7 @@ acpi_ns_check_reference(struct acpi_predefined_data *data, return (AE_OK); } - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags, "Return type mismatch - unexpected reference object type [%s] %2.2X", acpi_ut_get_reference_name(return_object), return_object->reference.class)); @@ -558,36 +340,61 @@ acpi_ns_check_reference(struct acpi_predefined_data *data, /******************************************************************************* * - * FUNCTION: acpi_ns_get_expected_types + * FUNCTION: acpi_ns_get_bitmapped_type * - * PARAMETERS: buffer - Pointer to where the string is returned - * expected_btypes - Bitmap of expected return type(s) + * PARAMETERS: return_object - Object returned from method/obj evaluation * - * RETURN: Buffer is populated with type names. + * RETURN: Object return type. ACPI_RTYPE_ANY indicates that the object + * type is not supported. ACPI_RTYPE_NONE indicates that no + * object was returned (return_object is NULL). * - * DESCRIPTION: Translate the expected types bitmap into a string of ascii - * names of expected types, for use in warning messages. + * DESCRIPTION: Convert object type into a bitmapped object return type. * ******************************************************************************/ -static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes) +static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object) { - u32 this_rtype; - u32 i; - u32 j; + u32 return_btype; - j = 1; - buffer[0] = 0; - this_rtype = ACPI_RTYPE_INTEGER; + if (!return_object) { + return (ACPI_RTYPE_NONE); + } - for (i = 0; i < ACPI_NUM_RTYPES; i++) { + /* Map acpi_object_type to internal bitmapped type */ - /* If one of the expected types, concatenate the name of this type */ + switch (return_object->common.type) { + case ACPI_TYPE_INTEGER: - if (expected_btypes & this_rtype) { - ACPI_STRCAT(buffer, &acpi_rtype_names[i][j]); - j = 0; /* Use name separator from now on */ - } - this_rtype <<= 1; /* Next Rtype */ + return_btype = ACPI_RTYPE_INTEGER; + break; + + case ACPI_TYPE_BUFFER: + + return_btype = ACPI_RTYPE_BUFFER; + break; + + case ACPI_TYPE_STRING: + + return_btype = ACPI_RTYPE_STRING; + break; + + case ACPI_TYPE_PACKAGE: + + return_btype = ACPI_RTYPE_PACKAGE; + break; + + case ACPI_TYPE_LOCAL_REFERENCE: + + return_btype = ACPI_RTYPE_REFERENCE; + break; + + default: + + /* Not one of the supported objects, must be incorrect */ + + return_btype = ACPI_RTYPE_ANY; + break; } + + return (return_btype); } |
