Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5f69d6e authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

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: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLin Ming <ming.m.lin@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent b2deadd5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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
 */
+28 −2
Original line number Diff line number Diff line
@@ -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;
+52 −0
Original line number Diff line number Diff line
@@ -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);
}