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

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

ACPICA: ACPI 4.0 : Add new return package type, restructure module.



Added one new package type, a package that contains a revision number and
a variable number of sub-packages. Restructured the module to
put the sub-package list traversal in a separate function.

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 e5f69d6e
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@
 * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
 *      (Used for _HPX)
 *
 * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length
 *
 *****************************************************************************/

enum acpi_return_package_types {
@@ -101,7 +103,8 @@ enum acpi_return_package_types {
	ACPI_PTYPE2_COUNT = 5,
	ACPI_PTYPE2_PKG_COUNT = 6,
	ACPI_PTYPE2_FIXED = 7,
	ACPI_PTYPE2_MIN = 8
	ACPI_PTYPE2_MIN = 8,
	ACPI_PTYPE2_REV_FIXED = 9
};

/*
+192 −134
Original line number Diff line number Diff line
@@ -75,6 +75,11 @@ static acpi_status
acpi_ns_check_package(struct acpi_predefined_data *data,
		      union acpi_operand_object **return_object_ptr);

static acpi_status
acpi_ns_check_package_list(struct acpi_predefined_data *data,
			   const union acpi_predefined_info *package,
			   union acpi_operand_object **elements, u32 count);

static acpi_status
acpi_ns_check_package_elements(struct acpi_predefined_data *data,
			       union acpi_operand_object **elements,
@@ -393,14 +398,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
{
	union acpi_operand_object *return_object = *return_object_ptr;
	const union acpi_predefined_info *package;
	union acpi_operand_object *sub_package;
	union acpi_operand_object **elements;
	union acpi_operand_object **sub_elements;
	acpi_status status;
	acpi_status status = AE_OK;
	u32 expected_count;
	u32 count;
	u32 i;
	u32 j;

	ACPI_FUNCTION_NAME(ns_check_package);

@@ -465,9 +467,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
							object_type2,
							package->ret_info.
							count2, 0);
		if (ACPI_FAILURE(status)) {
			return (status);
		}
		break;

	case ACPI_PTYPE1_VAR:
@@ -534,6 +533,25 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
		}
		break;

	case ACPI_PTYPE2_REV_FIXED:

		/* First element is the (Integer) revision */

		status = acpi_ns_check_object_type(data, elements,
						   ACPI_RTYPE_INTEGER, 0);
		if (ACPI_FAILURE(status)) {
			return (status);
		}

		elements++;
		count--;

		/* Examine the sub-packages */

		status =
		    acpi_ns_check_package_list(data, package, elements, count);
		break;

	case ACPI_PTYPE2_PKG_COUNT:

		/* First element is the (Integer) count of sub-packages to follow */
@@ -556,9 +574,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
		count = expected_count;
		elements++;

		/* Now we can walk the sub-packages */
		/* Examine the sub-packages */

		/*lint -fallthrough */
		status =
		    acpi_ns_check_package_list(data, package, elements, count);
		break;

	case ACPI_PTYPE2:
	case ACPI_PTYPE2_FIXED:
@@ -593,6 +613,64 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
			count = 1;
		}

		/* Examine the sub-packages */

		status =
		    acpi_ns_check_package_list(data, package, elements, count);
		break;

	default:

		/* Should not get here if predefined info table is correct */

		ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
				      "Invalid internal return type in table entry: %X",
				      package->ret_info.type));

		return (AE_AML_INTERNAL);
	}

	return (status);

package_too_small:

	/* Error exit for the case with an incorrect package count */

	ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
			      "Return Package is too small - found %u elements, expected %u",
			      count, expected_count));

	return (AE_AML_OPERAND_VALUE);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ns_check_package_list
 *
 * PARAMETERS:  Data            - Pointer to validation data structure
 *              Package         - Pointer to package-specific info for method
 *              Elements        - Element list of parent package. All elements
 *                                of this list should be of type Package.
 *              Count           - Count of subpackages
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Examine a list of subpackages
 *
 ******************************************************************************/

static acpi_status
acpi_ns_check_package_list(struct acpi_predefined_data *data,
			   const union acpi_predefined_info *package,
			   union acpi_operand_object **elements, u32 count)
{
	union acpi_operand_object *sub_package;
	union acpi_operand_object **sub_elements;
	acpi_status status;
	u32 expected_count;
	u32 i;
	u32 j;

	/* Validate each sub-Package in the parent Package */

	for (i = 0; i < count; i++) {
@@ -602,43 +680,35 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
		/* Each sub-object must be of type Package */

		status = acpi_ns_check_object_type(data, &sub_package,
							   ACPI_RTYPE_PACKAGE,
							   i);
						   ACPI_RTYPE_PACKAGE, i);
		if (ACPI_FAILURE(status)) {
			return (status);
		}

			/* Examine the different types of sub-packages */
		/* Examine the different types of expected sub-packages */

		switch (package->ret_info.type) {
		case ACPI_PTYPE2:
		case ACPI_PTYPE2_PKG_COUNT:
		case ACPI_PTYPE2_REV_FIXED:

			/* Each subpackage has a fixed number of elements */

			expected_count =
				    package->ret_info.count1 +
				    package->ret_info.count2;
				if (sub_package->package.count !=
				    expected_count) {
					count = sub_package->package.count;
			    package->ret_info.count1 + package->ret_info.count2;
			if (sub_package->package.count < expected_count) {
				goto package_too_small;
			}

			status =
				    acpi_ns_check_package_elements(data,
								   sub_elements,
								   package->
								   ret_info.
			    acpi_ns_check_package_elements(data, sub_elements,
							   package->ret_info.
							   object_type1,
								   package->
								   ret_info.
							   package->ret_info.
							   count1,
								   package->
								   ret_info.
							   package->ret_info.
							   object_type2,
								   package->
								   ret_info.
							   package->ret_info.
							   count2, 0);
			if (ACPI_FAILURE(status)) {
				return (status);
@@ -651,7 +721,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data,

			expected_count = package->ret_info2.count;
			if (sub_package->package.count < expected_count) {
					count = sub_package->package.count;
				goto package_too_small;
			}

@@ -661,7 +730,10 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
				status =
				    acpi_ns_check_object_type(data,
							      &sub_elements[j],
						package->ret_info2.object_type[j], j);
							      package->
							      ret_info2.
							      object_type[j],
							      j);
				if (ACPI_FAILURE(status)) {
					return (status);
				}
@@ -674,22 +746,17 @@ acpi_ns_check_package(struct acpi_predefined_data *data,

			expected_count = package->ret_info.count1;
			if (sub_package->package.count < expected_count) {
					count = sub_package->package.count;
				goto package_too_small;
			}

			/* Check the type of each sub-package element */

			status =
				    acpi_ns_check_package_elements(data,
								   sub_elements,
								   package->
								   ret_info.
			    acpi_ns_check_package_elements(data, sub_elements,
							   package->ret_info.
							   object_type1,
								   sub_package->
								   package.
								   count, 0, 0,
								   0);
							   sub_package->package.
							   count, 0, 0, 0);
			if (ACPI_FAILURE(status)) {
				return (status);
			}
@@ -697,23 +764,28 @@ acpi_ns_check_package(struct acpi_predefined_data *data,

		case ACPI_PTYPE2_COUNT:

				/* First element is the (Integer) count of elements to follow */

				status =
				    acpi_ns_check_object_type(data,
							      sub_elements,
			/*
			 * First element is the (Integer) count of elements, including
			 * the count field.
			 */
			status = acpi_ns_check_object_type(data, sub_elements,
							   ACPI_RTYPE_INTEGER,
							   0);
			if (ACPI_FAILURE(status)) {
				return (status);
			}

				/* Make sure package is large enough for the Count */

				expected_count =
				    (u32) (*sub_elements)->integer.value;
			/*
			 * Make sure package is large enough for the Count and is
			 * is as large as the minimum size
			 */
			expected_count = (u32)(*sub_elements)->integer.value;
			if (sub_package->package.count < expected_count) {
					count = sub_package->package.count;
				goto package_too_small;
			}
			if (sub_package->package.count <
			    package->ret_info.count1) {
				expected_count = package->ret_info.count1;
				goto package_too_small;
			}

@@ -721,47 +793,33 @@ acpi_ns_check_package(struct acpi_predefined_data *data,

			status =
			    acpi_ns_check_package_elements(data,
								   (sub_elements
								    + 1),
								   package->
								   ret_info.
							   (sub_elements + 1),
							   package->ret_info.
							   object_type1,
								   (expected_count
								    - 1), 0, 0,
								   1);
							   (expected_count - 1),
							   0, 0, 1);
			if (ACPI_FAILURE(status)) {
				return (status);
			}
			break;

			default:
				break;
			}
		default:	/* Should not get here, type was validated by caller */

			elements++;
			return (AE_AML_INTERNAL);
		}
		break;

	default:

		/* Should not get here if predefined info table is correct */

		ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
				      "Invalid internal return type in table entry: %X",
				      package->ret_info.type));

		return (AE_AML_INTERNAL);
		elements++;
	}

	return (AE_OK);

package_too_small:

	/* Error exit for the case with an incorrect package count */
	/* The sub-package count was smaller than required */

	ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
			      "Return Package is too small - found %u, expected %u",
			      count, expected_count));
			      "Return Sub-Package[%u] is too small - found %u elements, expected %u",
			      i, sub_package->package.count, expected_count));

	return (AE_AML_OPERAND_VALUE);
}