ACPICA: Add repair for predefined methods that return nested packages
Fixes a problem where a predefined method is defined to return a variable-length Package of sub-packages. If the length is one, the BIOS code occasionally creates a simple single package with no sub-packages. This code attempts to fix the problem by wrapping a new package object around the existing package. ACPICA BZ 790. http://acpica.org/bugzilla/show_bug.cgi?id=790 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Родитель
b2deadd53c
Коммит
e5f69d6ef7
|
@ -278,6 +278,10 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
|
|||
u32 package_index,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_repair_package_list(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **obj_desc_ptr);
|
||||
|
||||
/*
|
||||
* nssearch - Namespace searching and entry
|
||||
*/
|
||||
|
|
|
@ -566,9 +566,35 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
|
|||
case ACPI_PTYPE2_COUNT:
|
||||
|
||||
/*
|
||||
* These types all return a single package that consists of a
|
||||
* variable number of sub-packages.
|
||||
* These types all return a single Package that consists of a
|
||||
* variable number of sub-Packages.
|
||||
*
|
||||
* First, ensure that the first element is a sub-Package. If not,
|
||||
* the BIOS may have incorrectly returned the object as a single
|
||||
* package instead of a Package of Packages (a common error if
|
||||
* there is only one entry). We may be able to repair this by
|
||||
* wrapping the returned Package with a new outer Package.
|
||||
*/
|
||||
if ((*elements)->common.type != ACPI_TYPE_PACKAGE) {
|
||||
|
||||
/* Create the new outer package and populate it */
|
||||
|
||||
status =
|
||||
acpi_ns_repair_package_list(data,
|
||||
return_object_ptr);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
/* Update locals to point to the new package (of 1 element) */
|
||||
|
||||
return_object = *return_object_ptr;
|
||||
elements = return_object->package.elements;
|
||||
count = 1;
|
||||
}
|
||||
|
||||
/* Validate each sub-Package in the parent Package */
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
sub_package = *elements;
|
||||
sub_elements = sub_package->package.elements;
|
||||
|
|
|
@ -149,3 +149,55 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
|
|||
|
||||
return (AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_repair_package_list
|
||||
*
|
||||
* PARAMETERS: Data - Pointer to validation data structure
|
||||
* obj_desc_ptr - Pointer to the object to repair. The new
|
||||
* package object is returned here,
|
||||
* overwriting the old object.
|
||||
*
|
||||
* RETURN: Status, new object in *obj_desc_ptr
|
||||
*
|
||||
* DESCRIPTION: Repair a common problem with objects that are defined to return
|
||||
* a variable-length Package of Packages. If the variable-length
|
||||
* is one, some BIOS code mistakenly simply declares a single
|
||||
* Package instead of a Package with one sub-Package. This
|
||||
* function attempts to repair this error by wrapping a Package
|
||||
* object around the original Package, creating the correct
|
||||
* Package with one sub-Package.
|
||||
*
|
||||
* Names that can be repaired in this manner include:
|
||||
* _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ns_repair_package_list(struct acpi_predefined_data *data,
|
||||
union acpi_operand_object **obj_desc_ptr)
|
||||
{
|
||||
union acpi_operand_object *pkg_obj_desc;
|
||||
|
||||
/*
|
||||
* Create the new outer package and populate it. The new package will
|
||||
* have a single element, the lone subpackage.
|
||||
*/
|
||||
pkg_obj_desc = acpi_ut_create_package_object(1);
|
||||
if (!pkg_obj_desc) {
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
pkg_obj_desc->package.elements[0] = *obj_desc_ptr;
|
||||
|
||||
/* Return the new object in the object pointer */
|
||||
|
||||
*obj_desc_ptr = pkg_obj_desc;
|
||||
data->flags |= ACPI_OBJECT_REPAIRED;
|
||||
|
||||
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
|
||||
"Incorrectly formed Package, attempting repair"));
|
||||
|
||||
return (AE_OK);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче