ACPICA: Namespace: Add String -> ObjectReference conversion support
authorLv Zheng <lv.zheng@intel.com>
Tue, 29 Dec 2015 05:58:02 +0000 (13:58 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 1 Jan 2016 02:47:36 +0000 (03:47 +0100)
ACPICA commit 80e60d72959bb51c5d08c8500d978607a42ed81d

BIOS developers may accidently put the quotes around the name strings,
which converts the object references in the packages indicated by the name
strings into the data objects (strings). Such kind of error has been seen
in _DEP control methods on some platforms. This patch implements a
workaround to correct it. Reported by Bastien Nocera. Fixed by Lv Zheng.

Link: https://github.com/acpica/acpica/commit/80e60d72
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=106231
Reported-and-tested-by: Bastien Nocera <bugzilla@hadess.net>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/acpica/acnamesp.h
drivers/acpi/acpica/nsconvert.c
drivers/acpi/acpica/nsrepair.c

index 1f42c3c30ff70bd7023abfca14c9ecc5246df749..d082e62d73080d05d2d81b0a27d3197d3e798a38 100644 (file)
@@ -77,6 +77,7 @@
 /* Object is not a package element */
 
 #define ACPI_NOT_PACKAGE_ELEMENT    ACPI_UINT32_MAX
+#define ACPI_ALL_PACKAGE_ELEMENTS   (ACPI_UINT32_MAX-1)
 
 /* Always emit warning message, not dependent on node flags */
 
@@ -192,6 +193,11 @@ acpi_ns_convert_to_resource(struct acpi_namespace_node *scope,
                            union acpi_operand_object *original_object,
                            union acpi_operand_object **return_object);
 
+acpi_status
+acpi_ns_convert_to_reference(struct acpi_namespace_node *scope,
+                            union acpi_operand_object *original_object,
+                            union acpi_operand_object **return_object);
+
 /*
  * nsdump - Namespace dump/print utilities
  */
index ab47a50cc101012a48d57bee0e9be8e69e2317e6..f21568ba325b2f53f2dd82569ecffb8271d9214d 100644 (file)
@@ -446,3 +446,78 @@ acpi_ns_convert_to_resource(struct acpi_namespace_node * scope,
        *return_object = new_object;
        return (AE_OK);
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_convert_to_reference
+ *
+ * PARAMETERS:  scope               - Namespace node for the method/object
+ *              original_object     - Object to be converted
+ *              return_object       - Where the new converted object is returned
+ *
+ * RETURN:      Status. AE_OK if conversion was successful
+ *
+ * DESCRIPTION: Attempt to convert a Integer object to a object_reference.
+ *              Buffer.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_convert_to_reference(struct acpi_namespace_node * scope,
+                            union acpi_operand_object *original_object,
+                            union acpi_operand_object **return_object)
+{
+       union acpi_operand_object *new_object = NULL;
+       acpi_status status;
+       struct acpi_namespace_node *node;
+       union acpi_generic_state scope_info;
+       char *name;
+
+       ACPI_FUNCTION_NAME(ns_convert_to_reference);
+
+       /* Convert path into internal presentation */
+
+       status =
+           acpi_ns_internalize_name(original_object->string.pointer, &name);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /* Find the namespace node */
+
+       scope_info.scope.node =
+           ACPI_CAST_PTR(struct acpi_namespace_node, scope);
+       status =
+           acpi_ns_lookup(&scope_info, name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+                          ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+                          NULL, &node);
+       if (ACPI_FAILURE(status)) {
+
+               /* Check if we are resolving a named reference within a package */
+
+               ACPI_ERROR_NAMESPACE(original_object->string.pointer, status);
+               goto error_exit;
+       }
+
+       /* Create and init a new internal ACPI object */
+
+       new_object = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
+       if (!new_object) {
+               status = AE_NO_MEMORY;
+               goto error_exit;
+       }
+       new_object->reference.node = node;
+       new_object->reference.object = node->object;
+       new_object->reference.class = ACPI_REFCLASS_NAME;
+
+       /*
+        * Increase reference of the object if needed (the object is likely a
+        * null for device nodes).
+        */
+       acpi_ut_add_reference(node->object);
+
+error_exit:
+       ACPI_FREE(name);
+       *return_object = new_object;
+       return (AE_OK);
+}
index 4b7dbff66a144491bb1a10ab6fc04a2a63cfa56c..6418863f93d50591789b4cec503ce01f98cea185 100644 (file)
@@ -116,6 +116,11 @@ static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
         ACPI_NOT_PACKAGE_ELEMENT,
         acpi_ns_convert_to_resource},
 
+       /* Object reference conversions */
+
+       {"_DEP", ACPI_RTYPE_STRING, ACPI_ALL_PACKAGE_ELEMENTS,
+        acpi_ns_convert_to_reference},
+
        /* Unicode conversions */
 
        {"_MLS", ACPI_RTYPE_STRING, 1,
@@ -360,7 +365,9 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
                        /* Check if we can actually repair this name/type combination */
 
                        if ((return_btype & this_name->unexpected_btypes) &&
-                           (package_index == this_name->package_index)) {
+                           (this_name->package_index ==
+                            ACPI_ALL_PACKAGE_ELEMENTS
+                            || package_index == this_name->package_index)) {
                                return (this_name);
                        }