diff options
Diffstat (limited to 'drivers/acpi/acpica/nspredef.c')
| -rw-r--r-- | drivers/acpi/acpica/nspredef.c | 993 |
1 files changed, 128 insertions, 865 deletions
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 7096bcda0c7..392910ffbed 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -1,12 +1,11 @@ /****************************************************************************** * * Module Name: nspredef - Validation of ACPI predefined methods and objects - * $Revision: 1.1 $ * *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -62,61 +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_package(struct acpi_predefined_data *data, - union acpi_operand_object **return_object_ptr); - -static acpi_status -acpi_ns_check_package_list(struct acpi_predefined_data *data, - const union acpi_predefined_info *package, - union acpi_operand_object **elements, u32 count); - -static acpi_status -acpi_ns_check_package_elements(struct acpi_predefined_data *data, - union acpi_operand_object **elements, - u8 type1, - u32 count1, - u8 type2, u32 count2, u32 start_index); - -static acpi_status -acpi_ns_check_object_type(struct acpi_predefined_data *data, - union acpi_operand_object **return_object_ptr, - u32 expected_btypes, u32 package_index); - -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 + * 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 @@ -124,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); } /* @@ -170,56 +117,33 @@ 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; + return (AE_OK); } /* - * 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. + * Return value validation and possible repair. * - * 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; - } - - /* - * 1) We have a return value, but if one wasn't expected, just exit, this is - * not a problem. For example, if the "Implicit Return" feature is - * enabled, methods will always return a value. + * 1) Don't perform return value validation/repair if this feature + * has been disabled via a global option. * - * 2) If the return value can be of any type, then we cannot perform any - * validation, exit. + * 2) We have a return value, but if one wasn't expected, just exit, + * this is not a problem. For example, if the "Implicit Return" + * feature is enabled, methods will always return a value. + * + * 3) If the return value can be of any type, then we cannot perform + * any validation, just exit. */ - if ((!predefined->info.expected_btypes) || + 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_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)) { @@ -227,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; + } } } @@ -246,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: /* @@ -254,685 +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_package - * - * PARAMETERS: Data - Pointer to validation data structure - * return_object_ptr - Pointer to the object returned from the - * evaluation of a method or object - * - * RETURN: Status - * - * DESCRIPTION: Check a returned package object for the correct count and - * correct type of all sub-objects. - * - ******************************************************************************/ - -static acpi_status -acpi_ns_check_package(struct acpi_predefined_data *data, - union acpi_operand_object **return_object_ptr) -{ - union acpi_operand_object *return_object = *return_object_ptr; - const union acpi_predefined_info *package; - union acpi_operand_object **elements; - acpi_status status = AE_OK; - u32 expected_count; - u32 count; - u32 i; - - ACPI_FUNCTION_NAME(ns_check_package); - - /* The package info for this name is in the next table entry */ - - package = data->predefined + 1; - - ACPI_DEBUG_PRINT((ACPI_DB_NAMES, - "%s Validating return Package of Type %X, Count %X\n", - data->pathname, package->ret_info.type, - return_object->package.count)); - - /* - * For variable-length Packages, we can safely remove all embedded - * and trailing NULL package elements - */ - acpi_ns_remove_null_elements(data, package->ret_info.type, - return_object); - - /* Extract package count and elements array */ - - elements = return_object->package.elements; - count = return_object->package.count; - - /* The package must have at least one element, else invalid */ - - if (!count) { - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, - "Return Package has no elements (empty)")); - - return (AE_AML_OPERAND_VALUE); - } - - /* - * Decode the type of the expected package contents - * - * PTYPE1 packages contain no subpackages - * PTYPE2 packages contain sub-packages - */ - switch (package->ret_info.type) { - case ACPI_PTYPE1_FIXED: - - /* - * The package count is fixed and there are no sub-packages - * - * If package is too small, exit. - * If package is larger than expected, issue warning but continue - */ - expected_count = - package->ret_info.count1 + package->ret_info.count2; - if (count < expected_count) { - goto package_too_small; - } else if (count > expected_count) { - ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, - "%s: Return Package is larger than needed - " - "found %u, expected %u\n", - data->pathname, count, - expected_count)); - } - - /* Validate all elements of the returned package */ - - status = acpi_ns_check_package_elements(data, elements, - package->ret_info. - object_type1, - package->ret_info. - count1, - package->ret_info. - object_type2, - package->ret_info. - count2, 0); - break; - - case ACPI_PTYPE1_VAR: - - /* - * The package count is variable, there are no sub-packages, and all - * elements must be of the same type - */ - for (i = 0; i < count; i++) { - status = acpi_ns_check_object_type(data, elements, - package->ret_info. - object_type1, i); - if (ACPI_FAILURE(status)) { - return (status); - } - elements++; - } - break; - - case ACPI_PTYPE1_OPTION: - - /* - * The package count is variable, there are no sub-packages. There are - * a fixed number of required elements, and a variable number of - * optional elements. - * - * Check if package is at least as large as the minimum required - */ - expected_count = package->ret_info3.count; - if (count < expected_count) { - goto package_too_small; - } - - /* Variable number of sub-objects */ - - for (i = 0; i < count; i++) { - if (i < package->ret_info3.count) { - - /* These are the required package elements (0, 1, or 2) */ - - status = - acpi_ns_check_object_type(data, elements, - package-> - ret_info3. - object_type[i], - i); - if (ACPI_FAILURE(status)) { - return (status); - } - } else { - /* These are the optional package elements */ - - status = - acpi_ns_check_object_type(data, elements, - package-> - ret_info3. - tail_object_type, - i); - if (ACPI_FAILURE(status)) { - return (status); - } - } - elements++; - } - break; - - case ACPI_PTYPE2_REV_FIXED: - - /* First element is the (Integer) revision */ - - status = acpi_ns_check_object_type(data, elements, - ACPI_RTYPE_INTEGER, 0); - if (ACPI_FAILURE(status)) { - return (status); - } - - elements++; - count--; - - /* Examine the sub-packages */ - - status = - acpi_ns_check_package_list(data, package, elements, count); - break; - - case ACPI_PTYPE2_PKG_COUNT: - - /* First element is the (Integer) count of sub-packages to follow */ - - status = acpi_ns_check_object_type(data, elements, - ACPI_RTYPE_INTEGER, 0); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* - * Count cannot be larger than the parent package length, but allow it - * to be smaller. The >= accounts for the Integer above. - */ - expected_count = (u32) (*elements)->integer.value; - if (expected_count >= count) { - goto package_too_small; - } - - count = expected_count; - elements++; - - /* Examine the sub-packages */ - - status = - acpi_ns_check_package_list(data, package, elements, count); - break; - - case ACPI_PTYPE2: - case ACPI_PTYPE2_FIXED: - case ACPI_PTYPE2_MIN: - case ACPI_PTYPE2_COUNT: - - /* - * These types all return a single Package that consists of a - * variable number of sub-Packages. - * - * First, ensure that the first element is a sub-Package. If not, - * the BIOS may have incorrectly returned the object as a single - * package instead of a Package of Packages (a common error if - * there is only one entry). We may be able to repair this by - * wrapping the returned Package with a new outer Package. - */ - if (*elements - && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) { - - /* Create the new outer package and populate it */ - - status = - acpi_ns_repair_package_list(data, - return_object_ptr); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Update locals to point to the new package (of 1 element) */ - - return_object = *return_object_ptr; - elements = return_object->package.elements; - count = 1; - } - - /* Examine the sub-packages */ - - status = - acpi_ns_check_package_list(data, package, elements, count); - break; - - default: - - /* Should not get here if predefined info table is correct */ - - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, - "Invalid internal return type in table entry: %X", - package->ret_info.type)); - - return (AE_AML_INTERNAL); - } - - return (status); - -package_too_small: - - /* Error exit for the case with an incorrect package count */ - - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, - "Return Package is too small - found %u elements, expected %u", - count, expected_count)); - - return (AE_AML_OPERAND_VALUE); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ns_check_package_list - * - * PARAMETERS: Data - Pointer to validation data structure - * Package - Pointer to package-specific info for method - * Elements - Element list of parent package. All elements - * of this list should be of type Package. - * Count - Count of subpackages - * - * RETURN: Status - * - * DESCRIPTION: Examine a list of subpackages - * - ******************************************************************************/ - -static acpi_status -acpi_ns_check_package_list(struct acpi_predefined_data *data, - const union acpi_predefined_info *package, - union acpi_operand_object **elements, u32 count) -{ - union acpi_operand_object *sub_package; - union acpi_operand_object **sub_elements; - acpi_status status; - u32 expected_count; - u32 i; - u32 j; - - /* - * Validate each sub-Package in the parent Package - * - * NOTE: assumes list of sub-packages contains no NULL elements. - * Any NULL elements should have been removed by earlier call - * to acpi_ns_remove_null_elements. - */ - for (i = 0; i < count; i++) { - sub_package = *elements; - sub_elements = sub_package->package.elements; - data->parent_package = sub_package; - - /* Each sub-object must be of type Package */ - - status = acpi_ns_check_object_type(data, &sub_package, - ACPI_RTYPE_PACKAGE, i); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Examine the different types of expected sub-packages */ - - data->parent_package = sub_package; - switch (package->ret_info.type) { - case ACPI_PTYPE2: - case ACPI_PTYPE2_PKG_COUNT: - case ACPI_PTYPE2_REV_FIXED: - - /* Each subpackage has a fixed number of elements */ - - expected_count = - package->ret_info.count1 + package->ret_info.count2; - if (sub_package->package.count < expected_count) { - goto package_too_small; - } - - status = - acpi_ns_check_package_elements(data, sub_elements, - package->ret_info. - object_type1, - package->ret_info. - count1, - package->ret_info. - object_type2, - package->ret_info. - count2, 0); - if (ACPI_FAILURE(status)) { - return (status); - } - break; - - case ACPI_PTYPE2_FIXED: - - /* Each sub-package has a fixed length */ - - expected_count = package->ret_info2.count; - if (sub_package->package.count < expected_count) { - goto package_too_small; - } - - /* Check the type of each sub-package element */ - - for (j = 0; j < expected_count; j++) { - status = - acpi_ns_check_object_type(data, - &sub_elements[j], - package-> - ret_info2. - object_type[j], - j); - if (ACPI_FAILURE(status)) { - return (status); - } - } - break; - - case ACPI_PTYPE2_MIN: - - /* Each sub-package has a variable but minimum length */ - - expected_count = package->ret_info.count1; - if (sub_package->package.count < expected_count) { - goto package_too_small; - } - - /* Check the type of each sub-package element */ - - status = - acpi_ns_check_package_elements(data, sub_elements, - package->ret_info. - object_type1, - sub_package->package. - count, 0, 0, 0); - if (ACPI_FAILURE(status)) { - return (status); - } - break; - - case ACPI_PTYPE2_COUNT: - - /* - * First element is the (Integer) count of elements, including - * the count field (the ACPI name is num_elements) - */ - status = acpi_ns_check_object_type(data, sub_elements, - ACPI_RTYPE_INTEGER, - 0); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* - * Make sure package is large enough for the Count and is - * is as large as the minimum size - */ - expected_count = (u32)(*sub_elements)->integer.value; - if (sub_package->package.count < expected_count) { - goto package_too_small; - } - if (sub_package->package.count < - package->ret_info.count1) { - expected_count = package->ret_info.count1; - goto package_too_small; - } - if (expected_count == 0) { - /* - * Either the num_entries element was originally zero or it was - * a NULL element and repaired to an Integer of value zero. - * In either case, repair it by setting num_entries to be the - * actual size of the subpackage. - */ - expected_count = sub_package->package.count; - (*sub_elements)->integer.value = expected_count; - } - - /* Check the type of each sub-package element */ - - status = - acpi_ns_check_package_elements(data, - (sub_elements + 1), - package->ret_info. - object_type1, - (expected_count - 1), - 0, 0, 1); - if (ACPI_FAILURE(status)) { - return (status); - } - break; - - default: /* Should not get here, type was validated by caller */ - - return (AE_AML_INTERNAL); - } - - elements++; - } - - return (AE_OK); - -package_too_small: - - /* The sub-package count was smaller than required */ - - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, - "Return Sub-Package[%u] is too small - found %u elements, expected %u", - i, sub_package->package.count, expected_count)); - - return (AE_AML_OPERAND_VALUE); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ns_check_package_elements - * - * PARAMETERS: Data - Pointer to validation data structure - * Elements - Pointer to the package elements array - * Type1 - Object type for first group - * Count1 - Count for first group - * Type2 - Object type for second group - * Count2 - Count for second group - * start_index - Start of the first group of elements - * - * RETURN: Status - * - * DESCRIPTION: Check that all elements of a package are of the correct object - * type. Supports up to two groups of different object types. - * - ******************************************************************************/ - -static acpi_status -acpi_ns_check_package_elements(struct acpi_predefined_data *data, - union acpi_operand_object **elements, - u8 type1, - u32 count1, - u8 type2, u32 count2, u32 start_index) -{ - union acpi_operand_object **this_element = elements; - acpi_status status; - u32 i; - - /* - * Up to two groups of package elements are supported by the data - * structure. All elements in each group must be of the same type. - * The second group can have a count of zero. - */ - for (i = 0; i < count1; i++) { - status = acpi_ns_check_object_type(data, this_element, - type1, i + start_index); - if (ACPI_FAILURE(status)) { - return (status); - } - this_element++; - } - - for (i = 0; i < count2; i++) { - status = acpi_ns_check_object_type(data, this_element, - type2, - (i + count1 + start_index)); - if (ACPI_FAILURE(status)) { - return (status); - } - this_element++; - } - - return (AE_OK); -} - -/******************************************************************************* - * * 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) @@ -947,36 +219,21 @@ acpi_ns_check_package_elements(struct acpi_predefined_data *data, * ******************************************************************************/ -static acpi_status -acpi_ns_check_object_type(struct acpi_predefined_data *data, +acpi_status +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. @@ -992,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; - - 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; + info->return_btype = acpi_ns_get_bitmapped_type(return_object); + if (info->return_btype == ACPI_RTYPE_ANY) { - 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 @@ -1066,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 * @@ -1079,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) { @@ -1092,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)); @@ -1102,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; + + if (!return_object) { + return (ACPI_RTYPE_NONE); + } - j = 1; - buffer[0] = 0; - this_rtype = ACPI_RTYPE_INTEGER; + /* Map acpi_object_type to internal bitmapped type */ - for (i = 0; i < ACPI_NUM_RTYPES; i++) { + switch (return_object->common.type) { + case ACPI_TYPE_INTEGER: - /* If one of the expected types, concatenate the name of this type */ + return_btype = ACPI_RTYPE_INTEGER; + break; - 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 */ + 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); } |
