ACPICA: ACPI 4.0 : Add new return package type, restructure module.
authorBob Moore <robert.moore@intel.com>
Fri, 24 Jul 2009 03:22:11 +0000 (11:22 +0800)
committerLen Brown <len.brown@intel.com>
Fri, 28 Aug 2009 23:40:38 +0000 (19:40 -0400)
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: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/acpica/acpredef.h
drivers/acpi/acpica/nspredef.c

index 63f656ae3604d6c4acb06049416c9abc3bdcb52d..144b1f41663fc62d8cb348ed777218929b414d29 100644 (file)
@@ -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
 };
 
 /*
index 0091504df0745b8aa2a83f1769d74b1018464f64..0b2cdb37a678ee77081b13496c9c6da95de66ff6 100644 (file)
@@ -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);
 }