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 @@ ...@@ -91,6 +91,8 @@
* ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
* (Used for _HPX) * (Used for _HPX)
* *
* ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length
*
*****************************************************************************/ *****************************************************************************/
enum acpi_return_package_types { enum acpi_return_package_types {
...@@ -101,7 +103,8 @@ enum acpi_return_package_types { ...@@ -101,7 +103,8 @@ enum acpi_return_package_types {
ACPI_PTYPE2_COUNT = 5, ACPI_PTYPE2_COUNT = 5,
ACPI_PTYPE2_PKG_COUNT = 6, ACPI_PTYPE2_PKG_COUNT = 6,
ACPI_PTYPE2_FIXED = 7, ACPI_PTYPE2_FIXED = 7,
ACPI_PTYPE2_MIN = 8 ACPI_PTYPE2_MIN = 8,
ACPI_PTYPE2_REV_FIXED = 9
}; };
/* /*
......
...@@ -75,6 +75,11 @@ static acpi_status ...@@ -75,6 +75,11 @@ static acpi_status
acpi_ns_check_package(struct acpi_predefined_data *data, acpi_ns_check_package(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr); 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 static acpi_status
acpi_ns_check_package_elements(struct acpi_predefined_data *data, acpi_ns_check_package_elements(struct acpi_predefined_data *data,
union acpi_operand_object **elements, union acpi_operand_object **elements,
...@@ -393,14 +398,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -393,14 +398,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
{ {
union acpi_operand_object *return_object = *return_object_ptr; union acpi_operand_object *return_object = *return_object_ptr;
const union acpi_predefined_info *package; const union acpi_predefined_info *package;
union acpi_operand_object *sub_package;
union acpi_operand_object **elements; union acpi_operand_object **elements;
union acpi_operand_object **sub_elements; acpi_status status = AE_OK;
acpi_status status;
u32 expected_count; u32 expected_count;
u32 count; u32 count;
u32 i; u32 i;
u32 j;
ACPI_FUNCTION_NAME(ns_check_package); ACPI_FUNCTION_NAME(ns_check_package);
...@@ -465,9 +467,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -465,9 +467,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
object_type2, object_type2,
package->ret_info. package->ret_info.
count2, 0); count2, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
break; break;
case ACPI_PTYPE1_VAR: case ACPI_PTYPE1_VAR:
...@@ -534,6 +533,25 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -534,6 +533,25 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
} }
break; 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: case ACPI_PTYPE2_PKG_COUNT:
/* First element is the (Integer) count of sub-packages to follow */ /* First element is the (Integer) count of sub-packages to follow */
...@@ -556,9 +574,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -556,9 +574,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
count = expected_count; count = expected_count;
elements++; 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:
case ACPI_PTYPE2_FIXED: case ACPI_PTYPE2_FIXED:
...@@ -593,6 +613,64 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -593,6 +613,64 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
count = 1; 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 */ /* Validate each sub-Package in the parent Package */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
...@@ -602,43 +680,35 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -602,43 +680,35 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
/* Each sub-object must be of type Package */ /* Each sub-object must be of type Package */
status = acpi_ns_check_object_type(data, &sub_package, status = acpi_ns_check_object_type(data, &sub_package,
ACPI_RTYPE_PACKAGE, ACPI_RTYPE_PACKAGE, i);
i);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
} }
/* Examine the different types of sub-packages */ /* Examine the different types of expected sub-packages */
switch (package->ret_info.type) { switch (package->ret_info.type) {
case ACPI_PTYPE2: case ACPI_PTYPE2:
case ACPI_PTYPE2_PKG_COUNT: case ACPI_PTYPE2_PKG_COUNT:
case ACPI_PTYPE2_REV_FIXED:
/* Each subpackage has a fixed number of elements */ /* Each subpackage has a fixed number of elements */
expected_count = expected_count =
package->ret_info.count1 + package->ret_info.count1 + package->ret_info.count2;
package->ret_info.count2; if (sub_package->package.count < expected_count) {
if (sub_package->package.count !=
expected_count) {
count = sub_package->package.count;
goto package_too_small; goto package_too_small;
} }
status = status =
acpi_ns_check_package_elements(data, acpi_ns_check_package_elements(data, sub_elements,
sub_elements, package->ret_info.
package->
ret_info.
object_type1, object_type1,
package-> package->ret_info.
ret_info.
count1, count1,
package-> package->ret_info.
ret_info.
object_type2, object_type2,
package-> package->ret_info.
ret_info.
count2, 0); count2, 0);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
...@@ -651,7 +721,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -651,7 +721,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
expected_count = package->ret_info2.count; expected_count = package->ret_info2.count;
if (sub_package->package.count < expected_count) { if (sub_package->package.count < expected_count) {
count = sub_package->package.count;
goto package_too_small; goto package_too_small;
} }
...@@ -661,7 +730,10 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -661,7 +730,10 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
status = status =
acpi_ns_check_object_type(data, acpi_ns_check_object_type(data,
&sub_elements[j], &sub_elements[j],
package->ret_info2.object_type[j], j); package->
ret_info2.
object_type[j],
j);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
} }
...@@ -674,22 +746,17 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -674,22 +746,17 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
expected_count = package->ret_info.count1; expected_count = package->ret_info.count1;
if (sub_package->package.count < expected_count) { if (sub_package->package.count < expected_count) {
count = sub_package->package.count;
goto package_too_small; goto package_too_small;
} }
/* Check the type of each sub-package element */ /* Check the type of each sub-package element */
status = status =
acpi_ns_check_package_elements(data, acpi_ns_check_package_elements(data, sub_elements,
sub_elements, package->ret_info.
package->
ret_info.
object_type1, object_type1,
sub_package-> sub_package->package.
package. count, 0, 0, 0);
count, 0, 0,
0);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
} }
...@@ -697,23 +764,28 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -697,23 +764,28 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
case ACPI_PTYPE2_COUNT: case ACPI_PTYPE2_COUNT:
/* First element is the (Integer) count of elements to follow */ /*
* First element is the (Integer) count of elements, including
status = * the count field.
acpi_ns_check_object_type(data, */
sub_elements, status = acpi_ns_check_object_type(data, sub_elements,
ACPI_RTYPE_INTEGER, ACPI_RTYPE_INTEGER,
0); 0);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
} }
/* Make sure package is large enough for the Count */ /*
* Make sure package is large enough for the Count and is
expected_count = * is as large as the minimum size
(u32) (*sub_elements)->integer.value; */
expected_count = (u32)(*sub_elements)->integer.value;
if (sub_package->package.count < expected_count) { 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; goto package_too_small;
} }
...@@ -721,47 +793,33 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -721,47 +793,33 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
status = status =
acpi_ns_check_package_elements(data, acpi_ns_check_package_elements(data,
(sub_elements (sub_elements + 1),
+ 1), package->ret_info.
package->
ret_info.
object_type1, object_type1,
(expected_count (expected_count - 1),
- 1), 0, 0, 0, 0, 1);
1);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
} }
break; break;
default: default: /* Should not get here, type was validated by caller */
break;
}
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, elements++;
"Invalid internal return type in table entry: %X",
package->ret_info.type));
return (AE_AML_INTERNAL);
} }
return (AE_OK); 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, ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
"Return Package is too small - found %u, expected %u", "Return Sub-Package[%u] is too small - found %u elements, expected %u",
count, expected_count)); i, sub_package->package.count, expected_count));
return (AE_AML_OPERAND_VALUE); 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