|
@@ -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
|