diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index ee986edfa0da32704133b949624aa6ff75f3bea2..ff6689eba9179329f79e89942dea7ff12d32ecca 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -369,6 +369,19 @@ union acpi_predefined_info { struct acpi_package_info3 ret_info3; }; +/* Data block used during object validation */ + +struct acpi_predefined_data { + char *pathname; + const union acpi_predefined_info *predefined; + u32 flags; + u8 node_flags; +}; + +/* Defines for Flags field above */ + +#define ACPI_OBJECT_REPAIRED 1 + /* * Bitmapped return value types * Note: the actual data types must be contiguous, a loop in nspredef.c diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 91ac7d7b4402a07bf9409cd2c7ef97fae9981e3b..3acd9c6760ea59977262d479f00b99798b1c45c5 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -340,6 +340,7 @@ */ #define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); +#define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist #else @@ -347,6 +348,7 @@ #define ACPI_ERROR_NAMESPACE(s, e) #define ACPI_ERROR_METHOD(s, n, p, e) +#define ACPI_WARN_PREDEFINED(plist) #endif /* ACPI_NO_ERROR_MESSAGES */ /* diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index b0add85de30876270763ddc4c14abde936c9ea56..863a264b829e4234bed3ed9db92eaf4c8f6c2edc 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -475,6 +475,12 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position); acpi_status acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_warning(const char *module_name, + u32 line_number, + char *pathname, + u8 node_flags, const char *format, ...); + /* Values for Base above (16=Hex, 10=Decimal) */ #define ACPI_ANY_BASE 0 diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index abbb855e1b9a5b592e8399328ac54332b7f574d9..1dc1a4737aa967fbdde9e5b6a7017e4ced8a8259 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -72,31 +72,33 @@ ACPI_MODULE_NAME("nspredef") ******************************************************************************/ /* Local prototypes */ static acpi_status -acpi_ns_check_package(char *pathname, - union acpi_operand_object **return_object_ptr, - const union acpi_predefined_info *predefined); +acpi_ns_check_package(struct acpi_predefined_data *data, + union acpi_operand_object **return_object_ptr); static acpi_status -acpi_ns_check_package_elements(char *pathname, +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(char *pathname, +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(char *pathname, +acpi_ns_check_reference(struct acpi_predefined_data *data, union acpi_operand_object *return_object); static acpi_status -acpi_ns_repair_object(u32 expected_btypes, +acpi_ns_repair_object(struct acpi_predefined_data *data, + u32 expected_btypes, u32 package_index, union acpi_operand_object **return_object_ptr); +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 @@ -109,13 +111,21 @@ static const char *acpi_rtype_names[] = { "/Reference", }; -#define ACPI_NOT_PACKAGE ACPI_UINT32_MAX +/* Object is not a package element */ + +#define ACPI_NOT_PACKAGE_ELEMENT ACPI_UINT32_MAX + +/* Always emit warning message, not dependent on node flags */ + +#define ACPI_WARN_ALWAYS 0 /******************************************************************************* * * FUNCTION: acpi_ns_check_predefined_names * * PARAMETERS: Node - Namespace node for the method/object + * 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 * evaluation of a method or object * @@ -135,12 +145,13 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, acpi_status status = AE_OK; 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 error messages */ + /* Get the full pathname to the object, for use in warning messages */ pathname = acpi_ns_get_external_pathname(node); if (!pathname) { @@ -158,28 +169,17 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, /* If not a predefined name, we cannot validate the return object */ if (!predefined) { - goto exit; - } - - /* If the method failed, we cannot validate the return object */ - - if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { - goto exit; + goto cleanup; } /* - * Only validate the return value on the first successful evaluation of - * the method. This ensures that any warnings will only be emitted during - * the very first evaluation of the method/object. + * If the method failed or did not actually return an object, we cannot + * validate the return object */ - if (node->flags & ANOBJ_EVALUATED) { - goto exit; + if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { + goto cleanup; } - /* Mark the node as having been successfully evaluated */ - - node->flags |= ANOBJ_EVALUATED; - /* * 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, @@ -190,46 +190,63 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, if (!return_object) { if ((predefined->info.expected_btypes) && (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { - ACPI_ERROR((AE_INFO, - "%s: Missing expected return value", - pathname)); + ACPI_WARN_PREDEFINED((AE_INFO, pathname, + ACPI_WARN_ALWAYS, + "Missing expected return value")); status = AE_AML_NO_RETURN_VALUE; } - goto exit; + goto cleanup; } /* * 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 + * not a problem. For example, if the "Implicit Return" feature is + * enabled, methods will always return a value. */ if (!predefined->info.expected_btypes) { - goto exit; + goto cleanup; + } + + /* Create the parameter data block for object validation */ + + data = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_predefined_data)); + if (!data) { + goto cleanup; } + data->predefined = predefined; + data->node_flags = node->flags; + data->pathname = pathname; /* * Check that the type of the return object is what is expected for * this predefined name */ - status = acpi_ns_check_object_type(pathname, return_object_ptr, + status = acpi_ns_check_object_type(data, return_object_ptr, predefined->info.expected_btypes, - ACPI_NOT_PACKAGE); + ACPI_NOT_PACKAGE_ELEMENT); if (ACPI_FAILURE(status)) { - goto exit; + goto check_validation_status; } /* For returned Package objects, check the type of all sub-objects */ if (return_object->common.type == ACPI_TYPE_PACKAGE) { - status = - acpi_ns_check_package(pathname, return_object_ptr, - predefined); + status = acpi_ns_check_package(data, return_object_ptr); } - exit: +check_validation_status: + /* + * If the object validation failed or if we successfully repaired one + * 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)) { + node->flags |= ANOBJ_EVALUATED; + } + ACPI_FREE(data); + +cleanup: ACPI_FREE(pathname); return (status); } @@ -268,64 +285,58 @@ acpi_ns_check_parameter_count(char *pathname, param_count = node->object->method.param_count; } - /* Argument count check for non-predefined methods/objects */ - 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_WARNING((AE_INFO, - "%s: Insufficient arguments - needs %d, found %d", - pathname, param_count, user_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_WARNING((AE_INFO, - "%s: Excess arguments - needs %d, found %d", - pathname, param_count, user_param_count)); + ACPI_WARN_PREDEFINED((AE_INFO, pathname, + ACPI_WARN_ALWAYS, + "Excess arguments - needs %u, found %u", + param_count, user_param_count)); } return; } - /* Allow two different legal argument counts (_SCP, etc.) */ - + /* + * 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) { - - /* Validate the user-supplied parameter count */ - if ((user_param_count != required_params_current) && (user_param_count != required_params_old)) { - ACPI_WARNING((AE_INFO, - "%s: Parameter count mismatch - " - "caller passed %d, ACPI requires %d", - pathname, user_param_count, - required_params_current)); + ACPI_WARN_PREDEFINED((AE_INFO, pathname, + ACPI_WARN_ALWAYS, + "Parameter count mismatch - " + "caller passed %u, ACPI requires %u", + user_param_count, + required_params_current)); } } - /* - * Only validate the argument count on the first successful evaluation of - * the method. This ensures that any warnings will only be emitted during - * the very first evaluation of the method/object. - */ - if (node->flags & ANOBJ_EVALUATED) { - return; - } - /* * Check that the ASL-defined parameter count is what is expected for - * this predefined name. + * this predefined name (parameter count as defined by the ACPI + * specification) */ if ((param_count != required_params_current) && (param_count != required_params_old)) { - ACPI_WARNING((AE_INFO, - "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", - pathname, param_count, required_params_current)); + ACPI_WARN_PREDEFINED((AE_INFO, pathname, node->flags, + "Parameter count mismatch - ASL declared %u, ACPI requires %u", + param_count, required_params_current)); } } @@ -358,9 +369,6 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct this_name = predefined_names; while (this_name->info.name[0]) { if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { - - /* Return pointer to this table entry */ - return (this_name); } @@ -375,17 +383,16 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct this_name++; } - return (NULL); + return (NULL); /* Not found */ } /******************************************************************************* * * FUNCTION: acpi_ns_check_package * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * return_object_ptr - Pointer to the object returned from the * evaluation of a method or object - * Predefined - Pointer to entry in predefined name table * * RETURN: Status * @@ -395,9 +402,8 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct ******************************************************************************/ static acpi_status -acpi_ns_check_package(char *pathname, - union acpi_operand_object **return_object_ptr, - const union acpi_predefined_info *predefined) +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; @@ -414,11 +420,11 @@ acpi_ns_check_package(char *pathname, /* The package info for this name is in the next table entry */ - package = predefined + 1; + package = data->predefined + 1; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s Validating return Package of Type %X, Count %X\n", - pathname, package->ret_info.type, + data->pathname, package->ret_info.type, return_object->package.count)); /* Extract package count and elements array */ @@ -429,9 +435,8 @@ acpi_ns_check_package(char *pathname, /* The package must have at least one element, else invalid */ if (!count) { - ACPI_WARNING((AE_INFO, - "%s: Return Package has no elements (empty)", - pathname)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return Package has no elements (empty)")); return (AE_AML_OPERAND_VALUE); } @@ -456,15 +461,16 @@ acpi_ns_check_package(char *pathname, if (count < expected_count) { goto package_too_small; } else if (count > expected_count) { - ACPI_WARNING((AE_INFO, - "%s: Return Package is larger than needed - " - "found %u, expected %u", pathname, count, - expected_count)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + data->node_flags, + "Return Package is larger than needed - " + "found %u, expected %u", count, + expected_count)); } /* Validate all elements of the returned package */ - status = acpi_ns_check_package_elements(pathname, elements, + status = acpi_ns_check_package_elements(data, elements, package->ret_info. object_type1, package->ret_info. @@ -485,7 +491,7 @@ acpi_ns_check_package(char *pathname, * elements must be of the same type */ for (i = 0; i < count; i++) { - status = acpi_ns_check_object_type(pathname, elements, + status = acpi_ns_check_object_type(data, elements, package->ret_info. object_type1, i); if (ACPI_FAILURE(status)) { @@ -517,8 +523,7 @@ acpi_ns_check_package(char *pathname, /* These are the required package elements (0, 1, or 2) */ status = - acpi_ns_check_object_type(pathname, - elements, + acpi_ns_check_object_type(data, elements, package-> ret_info3. object_type[i], @@ -530,8 +535,7 @@ acpi_ns_check_package(char *pathname, /* These are the optional package elements */ status = - acpi_ns_check_object_type(pathname, - elements, + acpi_ns_check_object_type(data, elements, package-> ret_info3. tail_object_type, @@ -548,7 +552,7 @@ acpi_ns_check_package(char *pathname, /* First element is the (Integer) count of sub-packages to follow */ - status = acpi_ns_check_object_type(pathname, elements, + status = acpi_ns_check_object_type(data, elements, ACPI_RTYPE_INTEGER, 0); if (ACPI_FAILURE(status)) { return (status); @@ -585,9 +589,9 @@ acpi_ns_check_package(char *pathname, /* Each sub-object must be of type Package */ - status = - acpi_ns_check_object_type(pathname, &sub_package, - ACPI_RTYPE_PACKAGE, i); + status = acpi_ns_check_object_type(data, &sub_package, + ACPI_RTYPE_PACKAGE, + i); if (ACPI_FAILURE(status)) { return (status); } @@ -610,7 +614,7 @@ acpi_ns_check_package(char *pathname, } status = - acpi_ns_check_package_elements(pathname, + acpi_ns_check_package_elements(data, sub_elements, package-> ret_info. @@ -643,7 +647,7 @@ acpi_ns_check_package(char *pathname, for (j = 0; j < expected_count; j++) { status = - acpi_ns_check_object_type(pathname, + acpi_ns_check_object_type(data, &sub_elements[j], package->ret_info2.object_type[j], j); if (ACPI_FAILURE(status)) { @@ -665,7 +669,7 @@ acpi_ns_check_package(char *pathname, /* Check the type of each sub-package element */ status = - acpi_ns_check_package_elements(pathname, + acpi_ns_check_package_elements(data, sub_elements, package-> ret_info. @@ -684,7 +688,7 @@ acpi_ns_check_package(char *pathname, /* First element is the (Integer) count of elements to follow */ status = - acpi_ns_check_object_type(pathname, + acpi_ns_check_object_type(data, sub_elements, ACPI_RTYPE_INTEGER, 0); @@ -704,7 +708,7 @@ acpi_ns_check_package(char *pathname, /* Check the type of each sub-package element */ status = - acpi_ns_check_package_elements(pathname, + acpi_ns_check_package_elements(data, (sub_elements + 1), package-> @@ -730,9 +734,9 @@ acpi_ns_check_package(char *pathname, /* Should not get here if predefined info table is correct */ - ACPI_WARNING((AE_INFO, - "%s: Invalid internal return type in table entry: %X", - pathname, package->ret_info.type)); + 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); } @@ -743,9 +747,9 @@ acpi_ns_check_package(char *pathname, /* Error exit for the case with an incorrect package count */ - ACPI_WARNING((AE_INFO, "%s: Return Package is too small - " - "found %u, expected %u", pathname, count, - expected_count)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return Package is too small - found %u, expected %u", + count, expected_count)); return (AE_AML_OPERAND_VALUE); } @@ -754,7 +758,7 @@ acpi_ns_check_package(char *pathname, * * FUNCTION: acpi_ns_check_package_elements * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * 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 @@ -770,7 +774,7 @@ acpi_ns_check_package(char *pathname, ******************************************************************************/ static acpi_status -acpi_ns_check_package_elements(char *pathname, +acpi_ns_check_package_elements(struct acpi_predefined_data *data, union acpi_operand_object **elements, u8 type1, u32 count1, @@ -786,7 +790,7 @@ acpi_ns_check_package_elements(char *pathname, * The second group can have a count of zero. */ for (i = 0; i < count1; i++) { - status = acpi_ns_check_object_type(pathname, this_element, + status = acpi_ns_check_object_type(data, this_element, type1, i + start_index); if (ACPI_FAILURE(status)) { return (status); @@ -795,7 +799,7 @@ acpi_ns_check_package_elements(char *pathname, } for (i = 0; i < count2; i++) { - status = acpi_ns_check_object_type(pathname, this_element, + status = acpi_ns_check_object_type(data, this_element, type2, (i + count1 + start_index)); if (ACPI_FAILURE(status)) { @@ -811,12 +815,13 @@ acpi_ns_check_package_elements(char *pathname, * * FUNCTION: acpi_ns_check_object_type * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * return_object_ptr - Pointer to the object returned from the * evaluation of a method or object * expected_btypes - Bitmap of expected return type(s) * package_index - Index of object within parent package (if - * applicable - ACPI_NOT_PACKAGE otherwise) + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) * * RETURN: Status * @@ -826,7 +831,7 @@ acpi_ns_check_package_elements(char *pathname, ******************************************************************************/ static acpi_status -acpi_ns_check_object_type(char *pathname, +acpi_ns_check_object_type(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr, u32 expected_btypes, u32 package_index) { @@ -834,9 +839,6 @@ acpi_ns_check_object_type(char *pathname, acpi_status status = AE_OK; u32 return_btype; char type_buffer[48]; /* Room for 5 types */ - u32 this_rtype; - u32 i; - u32 j; /* * If we get a NULL return_object here, it is a NULL package element, @@ -849,10 +851,11 @@ acpi_ns_check_object_type(char *pathname, /* A Namespace node should not get here, but make sure */ if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { - ACPI_WARNING((AE_INFO, - "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", - pathname, return_object->node.name.ascii, - acpi_ut_get_type_name(return_object->node.type))); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->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. + type))); return (AE_AML_OPERAND_TYPE); } @@ -897,10 +900,11 @@ acpi_ns_check_object_type(char *pathname, /* Type mismatch -- attempt repair of the returned object */ - status = acpi_ns_repair_object(expected_btypes, package_index, + status = acpi_ns_repair_object(data, expected_btypes, + package_index, return_object_ptr); if (ACPI_SUCCESS(status)) { - return (status); + return (AE_OK); /* Repair was successful */ } goto type_error_exit; } @@ -908,7 +912,7 @@ acpi_ns_check_object_type(char *pathname, /* For reference objects, check that the reference type is correct */ if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { - status = acpi_ns_check_reference(pathname, return_object); + status = acpi_ns_check_reference(data, return_object); } return (status); @@ -917,33 +921,19 @@ acpi_ns_check_object_type(char *pathname, /* Create a string with all expected types for this predefined object */ - j = 1; - type_buffer[0] = 0; - this_rtype = ACPI_RTYPE_INTEGER; - - for (i = 0; i < ACPI_NUM_RTYPES; i++) { - - /* If one of the expected types, concatenate the name of this type */ - - if (expected_btypes & this_rtype) { - ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]); - j = 0; /* Use name separator from now on */ - } - this_rtype <<= 1; /* Next Rtype */ - } + acpi_ns_get_expected_types(type_buffer, expected_btypes); - if (package_index == ACPI_NOT_PACKAGE) { - ACPI_WARNING((AE_INFO, - "%s: Return type mismatch - found %s, expected %s", - pathname, - acpi_ut_get_object_type_name(return_object), - type_buffer)); + if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return type mismatch - found %s, expected %s", + acpi_ut_get_object_type_name + (return_object), type_buffer)); } else { - ACPI_WARNING((AE_INFO, - "%s: Return Package type mismatch at index %u - " - "found %s, expected %s", pathname, package_index, - acpi_ut_get_object_type_name(return_object), - type_buffer)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return Package type mismatch at index %u - " + "found %s, expected %s", package_index, + acpi_ut_get_object_type_name + (return_object), type_buffer)); } return (AE_AML_OPERAND_TYPE); @@ -953,7 +943,7 @@ acpi_ns_check_object_type(char *pathname, * * FUNCTION: acpi_ns_check_reference * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * return_object - Object returned from the evaluation of a * method or object * @@ -966,7 +956,7 @@ acpi_ns_check_object_type(char *pathname, ******************************************************************************/ static acpi_status -acpi_ns_check_reference(char *pathname, +acpi_ns_check_reference(struct acpi_predefined_data *data, union acpi_operand_object *return_object) { @@ -979,11 +969,10 @@ acpi_ns_check_reference(char *pathname, return (AE_OK); } - ACPI_WARNING((AE_INFO, - "%s: Return type mismatch - " - "unexpected reference object type [%s] %2.2X", - pathname, acpi_ut_get_reference_name(return_object), - return_object->reference.class)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return type mismatch - unexpected reference object type [%s] %2.2X", + acpi_ut_get_reference_name(return_object), + return_object->reference.class)); return (AE_AML_OPERAND_TYPE); } @@ -992,8 +981,11 @@ acpi_ns_check_reference(char *pathname, * * FUNCTION: acpi_ns_repair_object * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) - * package_index - Used to determine if target is in a package + * PARAMETERS: Data - Pointer to validation data structure + * expected_btypes - Object types expected + * package_index - Index of object within parent package (if + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) * return_object_ptr - Pointer to the object returned from the * evaluation of a method or object * @@ -1005,7 +997,8 @@ acpi_ns_check_reference(char *pathname, ******************************************************************************/ static acpi_status -acpi_ns_repair_object(u32 expected_btypes, +acpi_ns_repair_object(struct acpi_predefined_data *data, + u32 expected_btypes, u32 package_index, union acpi_operand_object **return_object_ptr) { @@ -1016,6 +1009,8 @@ acpi_ns_repair_object(u32 expected_btypes, switch (return_object->common.type) { case ACPI_TYPE_BUFFER: + /* Does the method/object legally return a string? */ + if (!(expected_btypes & ACPI_RTYPE_STRING)) { return (AE_AML_OPERAND_TYPE); } @@ -1052,19 +1047,29 @@ acpi_ns_repair_object(u32 expected_btypes, * reference count of the old object. * 2. Decrement the reference count of the original object. */ - if (package_index != ACPI_NOT_PACKAGE) { + if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { new_object->common.reference_count = return_object->common.reference_count; if (return_object->common.reference_count > 1) { return_object->common.reference_count--; } + + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + data->node_flags, + "Converted Buffer to expected String at index %u", + package_index)); + } else { + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + data->node_flags, + "Converted Buffer to expected String")); } /* Delete old object, install the new return object */ acpi_ut_remove_reference(return_object); *return_object_ptr = new_object; + data->flags |= ACPI_OBJECT_REPAIRED; return (AE_OK); default: @@ -1073,3 +1078,39 @@ acpi_ns_repair_object(u32 expected_btypes, return (AE_AML_OPERAND_TYPE); } + +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_expected_types + * + * PARAMETERS: Buffer - Pointer to where the string is returned + * expected_btypes - Bitmap of expected return type(s) + * + * RETURN: Buffer is populated with type names. + * + * DESCRIPTION: Translate the expected types bitmap into a string of ascii + * names of expected types, for use in warning messages. + * + ******************************************************************************/ + +static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes) +{ + u32 this_rtype; + u32 i; + u32 j; + + j = 1; + buffer[0] = 0; + this_rtype = ACPI_RTYPE_INTEGER; + + for (i = 0; i < ACPI_NUM_RTYPES; i++) { + + /* If one of the expected types, concatenate the name of this type */ + + 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 */ + } +} diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 9cd65334ca750260d25c106c1da7260f8aa44997..5bd29606dc6134945eae9e273d38c85721a79a87 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -50,6 +50,11 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") +/* + * Common suffix for messages + */ +#define ACPI_COMMON_MSG_SUFFIX \ + acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, line_number) /******************************************************************************* * * FUNCTION: acpi_ut_validate_exception @@ -1065,8 +1070,7 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...) va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, - line_number); + ACPI_COMMON_MSG_SUFFIX; va_end(args); } @@ -1080,8 +1084,7 @@ acpi_exception(const char *module_name, va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, - line_number); + ACPI_COMMON_MSG_SUFFIX; va_end(args); } @@ -1094,8 +1097,7 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...) va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, - line_number); + ACPI_COMMON_MSG_SUFFIX; va_end(args); } @@ -1116,3 +1118,46 @@ ACPI_EXPORT_SYMBOL(acpi_error) ACPI_EXPORT_SYMBOL(acpi_exception) ACPI_EXPORT_SYMBOL(acpi_warning) ACPI_EXPORT_SYMBOL(acpi_info) + +/******************************************************************************* + * + * FUNCTION: acpi_ut_predefined_warning + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Pathname - Full pathname to the node + * node_flags - From Namespace node for the method/object + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Warnings for the predefined validation module. Messages are + * only emitted the first time a problem with a particular + * method/object is detected. This prevents a flood of error + * messages for methods that are repeatedly evaluated. + * +******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_warning(const char *module_name, + u32 line_number, + char *pathname, + u8 node_flags, const char *format, ...) +{ + va_list args; + + /* + * Warning messages for this method/object will be disabled after the + * first time a validation fails or an object is successfully repaired. + */ + if (node_flags & ANOBJ_EVALUATED) { + return; + } + + acpi_os_printf("ACPI Warning for %s: ", pathname); + + va_start(args, format); + acpi_os_vprintf(format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end(args); +}