|
@@ -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);
|
|
|
}
|