]> rtime.felk.cvut.cz Git - linux-imx.git/commitdiff
ACPICA: Move _PRT repair into the standard complex repair module
authorLv Zheng <lv.zheng@intel.com>
Sat, 8 Jun 2013 01:01:01 +0000 (09:01 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 19 Jun 2013 23:31:57 +0000 (01:31 +0200)
Moved this longstanding repair to the relatively new predefined
name repair module. ACPICA BZ 783. Lv Zheng.

No functional change.  This change simply moves the repair code from
where it was originally implemented to the (more recent) repair
module where it now belongs.

References: https://bugs.acpica.org/show_bug.cgi?id=783
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/nspredef.c
drivers/acpi/acpica/nsrepair2.c
drivers/acpi/acpica/rscalc.c
drivers/acpi/acpica/rscreate.c

index 600268d33aa875ee64fc20713424e699edb61d08..8d59ac2399e02c5352247da749d2978a7c8be14c 100644 (file)
@@ -158,7 +158,12 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node,
                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 an operand type error (_PRT) */
+
+                       if (status != AE_AML_OPERAND_TYPE) {
+                               goto exit;
+                       }
                }
        }
 
index daac8daeaa9f98ae157747fe1555e04536348372..aca9bdf74e1f5918d7dc63e2486784e86d04fe39 100644 (file)
@@ -86,6 +86,10 @@ static acpi_status
 acpi_ns_repair_HID(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr);
 
+static acpi_status
+acpi_ns_repair_PRT(struct acpi_evaluate_info *info,
+                  union acpi_operand_object **return_object_ptr);
+
 static acpi_status
 acpi_ns_repair_PSS(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr);
@@ -121,6 +125,7 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
  * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
  * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
  * _HID: Strings: uppercase all, remove any leading asterisk
+ * _PRT: Fix reversed source_name and source_index
  * _PSS: Sort the list descending by Power
  * _TSS: Sort the list descending by Power
  *
@@ -137,6 +142,7 @@ static const struct acpi_repair_info acpi_ns_repairable_names[] = {
        {"_FDE", acpi_ns_repair_FDE},
        {"_GTM", acpi_ns_repair_FDE},   /* _GTM has same repair as _FDE */
        {"_HID", acpi_ns_repair_HID},
+       {"_PRT", acpi_ns_repair_PRT},
        {"_PSS", acpi_ns_repair_PSS},
        {"_TSS", acpi_ns_repair_TSS},
        {{0, 0, 0, 0}, NULL}    /* Table terminator */
@@ -488,7 +494,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info,
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_ns_repair_TSS
+ * FUNCTION:    acpi_ns_repair_PRT
  *
  * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
@@ -496,38 +502,54 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info,
  *
  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  *
- * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
- *              descending by the power dissipation values.
+ * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
+ *              source_name and source_index field, a common BIOS bug.
  *
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_TSS(struct acpi_evaluate_info *info,
+acpi_ns_repair_PRT(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr)
 {
-       union acpi_operand_object *return_object = *return_object_ptr;
-       acpi_status status;
-       struct acpi_namespace_node *node;
+       union acpi_operand_object *package_object = *return_object_ptr;
+       union acpi_operand_object **top_object_list;
+       union acpi_operand_object **sub_object_list;
+       union acpi_operand_object *obj_desc;
+       u32 element_count;
+       u32 index;
 
-       /*
-        * We can only sort the _TSS return package if there is no _PSS in the
-        * same scope. This is because if _PSS is present, the ACPI specification
-        * dictates that the _TSS Power Dissipation field is to be ignored, and
-        * therefore some BIOSs leave garbage values in the _TSS Power field(s).
-        * In this case, it is best to just return the _TSS package as-is.
-        * (May, 2011)
-        */
-       status = acpi_ns_get_node(info->node, "^_PSS",
-                                 ACPI_NS_NO_UPSEARCH, &node);
-       if (ACPI_SUCCESS(status)) {
-               return (AE_OK);
-       }
+       /* Each element in the _PRT package is a subpackage */
 
-       status = acpi_ns_check_sorted_list(info, return_object, 5, 1,
-                                          ACPI_SORT_DESCENDING,
-                                          "PowerDissipation");
+       top_object_list = package_object->package.elements;
+       element_count = package_object->package.count;
 
-       return (status);
+       for (index = 0; index < element_count; index++) {
+               sub_object_list = (*top_object_list)->package.elements;
+
+               /*
+                * If the BIOS has erroneously reversed the _PRT source_name (index 2)
+                * and the source_index (index 3), fix it. _PRT is important enough to
+                * workaround this BIOS error. This also provides compatibility with
+                * other ACPI implementations.
+                */
+               obj_desc = sub_object_list[3];
+               if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
+                       sub_object_list[3] = sub_object_list[2];
+                       sub_object_list[2] = obj_desc;
+                       info->return_flags |= ACPI_OBJECT_REPAIRED;
+
+                       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                             info->node_flags,
+                                             "PRT[%X]: Fixed reversed SourceName and SourceIndex",
+                                             index));
+               }
+
+               /* Point to the next union acpi_operand_object in the top level package */
+
+               top_object_list++;
+       }
+
+       return (AE_OK);
 }
 
 /******************************************************************************
@@ -599,6 +621,50 @@ acpi_ns_repair_PSS(struct acpi_evaluate_info *info,
        return (AE_OK);
 }
 
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_TSS
+ *
+ * PARAMETERS:  info                - Method execution information block
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
+ *              descending by the power dissipation values.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_TSS(struct acpi_evaluate_info *info,
+                  union acpi_operand_object **return_object_ptr)
+{
+       union acpi_operand_object *return_object = *return_object_ptr;
+       acpi_status status;
+       struct acpi_namespace_node *node;
+
+       /*
+        * We can only sort the _TSS return package if there is no _PSS in the
+        * same scope. This is because if _PSS is present, the ACPI specification
+        * dictates that the _TSS Power Dissipation field is to be ignored, and
+        * therefore some BIOSs leave garbage values in the _TSS Power field(s).
+        * In this case, it is best to just return the _TSS package as-is.
+        * (May, 2011)
+        */
+       status = acpi_ns_get_node(info->node, "^_PSS",
+                                 ACPI_NS_NO_UPSEARCH, &node);
+       if (ACPI_SUCCESS(status)) {
+               return (AE_OK);
+       }
+
+       status = acpi_ns_check_sorted_list(info, return_object, 5, 1,
+                                          ACPI_SORT_DESCENDING,
+                                          "PowerDissipation");
+
+       return (status);
+}
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_ns_check_sorted_list
index 608ebb56b6715609868f95c795a5bfecdba33f04..b62a0f4f4f9bb527cd49fc95279b7032ba1a689a 100644 (file)
@@ -652,8 +652,9 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
 
                name_found = FALSE;
 
-               for (table_index = 0; table_index < 4 && !name_found;
-                    table_index++) {
+               for (table_index = 0;
+                    table_index < package_element->package.count
+                    && !name_found; table_index++) {
                        if (*sub_object_list && /* Null object allowed */
                            ((ACPI_TYPE_STRING ==
                              (*sub_object_list)->common.type) ||
index f8b55b426c9d9b83abfe7f1d1a42692406cf0cc7..65f3e1c5b5989f61bdcb03e6620cdd1a7371dba9 100644 (file)
@@ -273,17 +273,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
                 */
                user_prt->length = (sizeof(struct acpi_pci_routing_table) - 4);
 
-               /* Each element of the top-level package must also be a package */
-
-               if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) {
-                       ACPI_ERROR((AE_INFO,
-                                   "(PRT[%u]) Need sub-package, found %s",
-                                   index,
-                                   acpi_ut_get_object_type_name
-                                   (*top_object_list)));
-                       return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
-               }
-
                /* Each sub-package must be of length 4 */
 
                if ((*top_object_list)->package.count != 4) {
@@ -326,22 +315,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
 
                user_prt->pin = (u32) obj_desc->integer.value;
 
-               /*
-                * If the BIOS has erroneously reversed the _PRT source_name (index 2)
-                * and the source_index (index 3), fix it. _PRT is important enough to
-                * workaround this BIOS error. This also provides compatibility with
-                * other ACPI implementations.
-                */
-               obj_desc = sub_object_list[3];
-               if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
-                       sub_object_list[3] = sub_object_list[2];
-                       sub_object_list[2] = obj_desc;
-
-                       ACPI_WARNING((AE_INFO,
-                                     "(PRT[%X].Source) SourceName and SourceIndex are reversed, fixed",
-                                     index));
-               }
-
                /*
                 * 3) Third subobject: Dereference the PRT.source_name
                 * The name may be unresolved (slack mode), so allow a null object