summaryrefslogtreecommitdiff
path: root/drivers/acpi/acpica/nsrepair.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/nsrepair.c')
-rw-r--r--drivers/acpi/acpica/nsrepair.c134
1 files changed, 130 insertions, 4 deletions
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c
index 9e83335..f9c9fd4 100644
--- a/drivers/acpi/acpica/nsrepair.c
+++ b/drivers/acpi/acpica/nsrepair.c
@@ -46,6 +46,7 @@
#include "acnamesp.h"
#include "acinterp.h"
#include "acpredef.h"
+#include "amlresrc.h"
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsrepair")
@@ -71,6 +72,11 @@ ACPI_MODULE_NAME("nsrepair")
* Buffer -> String
* Buffer -> Package of Integers
* Package -> Package of one Package
+ *
+ * Additional conversions that are available:
+ * Convert a null return or zero return value to an end_tag descriptor
+ * Convert an ASCII string to a Unicode buffer
+ *
* An incorrect standalone object is wrapped with required outer package
*
* Additional possible repairs:
@@ -90,9 +96,26 @@ static acpi_status
acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
union acpi_operand_object **return_object);
+static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
+ acpi_namespace_node
+ *node,
+ u32
+ return_btype,
+ u32
+ package_index);
+
+/*
+ * Special but simple repairs for some names.
+ *
+ * 2nd argument: Unexpected types that can be repaired
+ */
+static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
+ {{0, 0, 0, 0}, 0, 0, NULL} /* Table terminator */
+};
+
/*******************************************************************************
*
- * FUNCTION: acpi_ns_repair_object
+ * FUNCTION: acpi_ns_simple_repair
*
* PARAMETERS: data - Pointer to validation data structure
* expected_btypes - Object types expected
@@ -110,16 +133,54 @@ acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
******************************************************************************/
acpi_status
-acpi_ns_repair_object(struct acpi_predefined_data *data,
+acpi_ns_simple_repair(struct acpi_predefined_data *data,
u32 expected_btypes,
u32 package_index,
union acpi_operand_object **return_object_ptr)
{
union acpi_operand_object *return_object = *return_object_ptr;
- union acpi_operand_object *new_object;
+ union acpi_operand_object *new_object = NULL;
acpi_status status;
+ const struct acpi_simple_repair_info *predefined;
- ACPI_FUNCTION_NAME(ns_repair_object);
+ ACPI_FUNCTION_NAME(ns_simple_repair);
+
+ /*
+ * Special repairs for certain names that are in the repair table.
+ * Check if this name is in the list of repairable names.
+ */
+ predefined = acpi_ns_match_simple_repair(data->node,
+ data->return_btype,
+ package_index);
+ if (predefined) {
+ if (!return_object) {
+ ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
+ ACPI_WARN_ALWAYS,
+ "Missing expected return value"));
+ }
+
+ status =
+ predefined->object_converter(return_object, &new_object);
+ if (ACPI_FAILURE(status)) {
+
+ /* A fatal error occurred during a conversion */
+
+ ACPI_EXCEPTION((AE_INFO, status,
+ "During return object analysis"));
+ return (status);
+ }
+ if (new_object) {
+ goto object_repaired;
+ }
+ }
+
+ /*
+ * Do not perform simple object repair unless the return type is not
+ * expected.
+ */
+ if (data->return_btype & expected_btypes) {
+ return (AE_OK);
+ }
/*
* At this point, we know that the type of the returned object was not
@@ -127,6 +188,24 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
* repair the object by converting it to one of the expected object
* types for this predefined name.
*/
+
+ /*
+ * 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 (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
+ ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
+ ACPI_WARN_ALWAYS,
+ "Missing expected return value"));
+
+ return (AE_AML_NO_RETURN_VALUE);
+ }
+ }
+
if (expected_btypes & ACPI_RTYPE_INTEGER) {
status = acpi_ns_convert_to_integer(return_object, &new_object);
if (ACPI_SUCCESS(status)) {
@@ -216,6 +295,53 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
return (AE_OK);
}
+/******************************************************************************
+ *
+ * FUNCTION: acpi_ns_match_simple_repair
+ *
+ * PARAMETERS: node - Namespace node for the method/object
+ * return_btype - Object type that was returned
+ * package_index - Index of object within parent package (if
+ * applicable - ACPI_NOT_PACKAGE_ELEMENT
+ * otherwise)
+ *
+ * RETURN: Pointer to entry in repair table. NULL indicates not found.
+ *
+ * DESCRIPTION: Check an object name against the repairable object list.
+ *
+ *****************************************************************************/
+
+static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
+ acpi_namespace_node
+ *node,
+ u32
+ return_btype,
+ u32
+ package_index)
+{
+ const struct acpi_simple_repair_info *this_name;
+
+ /* Search info table for a repairable predefined method/object name */
+
+ this_name = acpi_object_repair_info;
+ while (this_name->object_converter) {
+ if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) {
+
+ /* Check if we can actually repair this name/type combination */
+
+ if ((return_btype & this_name->unexpected_btypes) &&
+ (package_index == this_name->package_index)) {
+ return (this_name);
+ }
+
+ return (NULL);
+ }
+ this_name++;
+ }
+
+ return (NULL); /* Name was not found in the repair table */
+}
+
/*******************************************************************************
*
* FUNCTION: acpi_ns_convert_to_integer