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

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
......@@ -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
};
/*
......
......@@ -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,175 +613,213 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
count = 1;
}
/* Validate each sub-Package in the parent Package */
/* Examine the sub-packages */
for (i = 0; i < count; i++) {
sub_package = *elements;
sub_elements = sub_package->package.elements;
status =
acpi_ns_check_package_list(data, package, elements, count);
break;
/* Each sub-object must be of type Package */
default:
status = acpi_ns_check_object_type(data, &sub_package,
ACPI_RTYPE_PACKAGE,
i);
if (ACPI_FAILURE(status)) {
return (status);
}
/* Should not get here if predefined info table is correct */
/* Examine the different types of sub-packages */
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
"Invalid internal return type in table entry: %X",
package->ret_info.type));
switch (package->ret_info.type) {
case ACPI_PTYPE2:
case ACPI_PTYPE2_PKG_COUNT:
return (AE_AML_INTERNAL);
}
/* Each subpackage has a fixed number of elements */
return (status);
expected_count =
package->ret_info.count1 +
package->ret_info.count2;
if (sub_package->package.count !=
expected_count) {
count = sub_package->package.count;
goto package_too_small;
}
package_too_small:
status =
acpi_ns_check_package_elements(data,
sub_elements,
package->
ret_info.
object_type1,
package->
ret_info.
count1,
package->
ret_info.
object_type2,
package->
ret_info.
count2, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
break;
/* Error exit for the case with an incorrect package count */
case ACPI_PTYPE2_FIXED:
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
"Return Package is too small - found %u elements, expected %u",
count, expected_count));
/* Each sub-package has a fixed length */
return (AE_AML_OPERAND_VALUE);
}
expected_count = package->ret_info2.count;
if (sub_package->package.count < expected_count) {
count = sub_package->package.count;
goto package_too_small;
}
/*******************************************************************************
*
* 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
*
******************************************************************************/
/* Check the type of each sub-package element */
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;
for (j = 0; j < expected_count; j++) {
status =
acpi_ns_check_object_type(data,
&sub_elements[j],
package->ret_info2.object_type[j], j);
if (ACPI_FAILURE(status)) {
return (status);
}
}
break;
/* Validate each sub-Package in the parent Package */
case ACPI_PTYPE2_MIN:
for (i = 0; i < count; i++) {
sub_package = *elements;
sub_elements = sub_package->package.elements;
/* Each sub-package has a variable but minimum length */
/* Each sub-object must be of type Package */
expected_count = package->ret_info.count1;
if (sub_package->package.count < expected_count) {
count = sub_package->package.count;
goto package_too_small;
}
status = acpi_ns_check_object_type(data, &sub_package,
ACPI_RTYPE_PACKAGE, i);
if (ACPI_FAILURE(status)) {
return (status);
}
/* Check the type of each sub-package element */
/* Examine the different types of expected sub-packages */
status =
acpi_ns_check_package_elements(data,
sub_elements,
package->
ret_info.
object_type1,
sub_package->
package.
count, 0, 0,
0);
if (ACPI_FAILURE(status)) {
return (status);
}
break;
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) {
goto package_too_small;
}
status =
acpi_ns_check_package_elements(data, sub_elements,
package->ret_info.
object_type1,
package->ret_info.
count1,
package->ret_info.
object_type2,
package->ret_info.
count2, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
break;
case ACPI_PTYPE2_FIXED:
/* Each sub-package has a fixed length */
case ACPI_PTYPE2_COUNT:
expected_count = package->ret_info2.count;
if (sub_package->package.count < expected_count) {
goto package_too_small;
}
/* First element is the (Integer) count of elements to follow */
/* Check the type of each sub-package element */
for (j = 0; j < expected_count; j++) {
status =
acpi_ns_check_object_type(data,
sub_elements,
ACPI_RTYPE_INTEGER,
0);
&sub_elements[j],
package->
ret_info2.
object_type[j],
j);
if (ACPI_FAILURE(status)) {
return (status);
}
}
break;
/* Make sure package is large enough for the Count */
case ACPI_PTYPE2_MIN:
expected_count =
(u32) (*sub_elements)->integer.value;
if (sub_package->package.count < expected_count) {
count = sub_package->package.count;
goto package_too_small;
}
/* Each sub-package has a variable but minimum length */
/* Check the type of each sub-package element */
expected_count = package->ret_info.count1;
if (sub_package->package.count < expected_count) {
goto package_too_small;
}
status =
acpi_ns_check_package_elements(data,
(sub_elements
+ 1),
package->
ret_info.
object_type1,
(expected_count
- 1), 0, 0,
1);
if (ACPI_FAILURE(status)) {
return (status);
}
break;
/* Check the type of each sub-package element */
default:
break;
status =
acpi_ns_check_package_elements(data, sub_elements,
package->ret_info.
object_type1,
sub_package->package.
count, 0, 0, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
break;
elements++;
}
break;
case ACPI_PTYPE2_COUNT:
default:
/*
* 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);
}
/* Should not get here if predefined info table is correct */
/*
* 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) {
goto package_too_small;
}
if (sub_package->package.count <
package->ret_info.count1) {
expected_count = package->ret_info.count1;
goto package_too_small;
}
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
"Invalid internal return type in table entry: %X",
package->ret_info.type));
/* Check the type of each sub-package element */
return (AE_AML_INTERNAL);
status =
acpi_ns_check_package_elements(data,
(sub_elements + 1),
package->ret_info.
object_type1,
(expected_count - 1),
0, 0, 1);
if (ACPI_FAILURE(status)) {
return (status);
}
break;
default: /* Should not get here, type was validated by caller */
return (AE_AML_INTERNAL);
}
elements++;
}
return (AE_OK);
package_too_small:
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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment