]> git.hungrycats.org Git - linux/commitdiff
[ACPI] ACPICA 20050211 from Bob Moore
authorLen Brown <len.brown@intel.com>
Tue, 15 Feb 2005 17:30:04 +0000 (12:30 -0500)
committerLen Brown <lenb@dhcppc3.>
Tue, 15 Feb 2005 17:30:04 +0000 (12:30 -0500)
Implemented ACPI 3.0 support for implicit conversion within
the Match() operator. match_obj can now be of type
integer, buffer, or string instead of just type integer.
Package elements are implicitly converted to the type
of the match_obj. This change aligns the behavior of
Match() with the behavior of the other logical operators
(LLess(), etc.)  It also requires an errata change to the
ACPI specification as this support was intended for ACPI
3.0, but was inadvertently omitted.

Fixed a problem with the internal implicit "to buffer"
conversion.  Strings that are converted to buffers will
cause buffer truncation if the string is smaller than the
target buffer. Integers that are converted to buffers will
not cause buffer truncation, only zero extension (both as
per the ACPI spec.) The problem was introduced when code
was added to truncate the buffer, but this should not be
performed in all cases, only the string case.

Fixed a problem with the Buffer and Package operators
where the interpreter would get confused if two such
operators were used as operands to an ASL operator (such
as LLess(Buffer(1){0},Buffer(1){1}).  The internal result
stack was not being popped after the execution of these
operators, resulting in an AE_NO_RETURN_VALUE exception.

Fixed a problem with constructs of the form
Store(Index(...),...). The reference object returned from
Index was inadvertently resolved to an actual value. This
problem was introduced in version 20050114 when the
behavior of Store() was modified to restrict the object
types that can be used as the source operand (to match
the ACPI specification.)

Reduced stack use in acpi_get_object_info().

drivers/acpi/dispatcher/dswexec.c
drivers/acpi/executer/exoparg6.c
drivers/acpi/executer/exresop.c
drivers/acpi/executer/exstoren.c
drivers/acpi/executer/exstorob.c
drivers/acpi/namespace/nsxfname.c
drivers/acpi/parser/psopcode.c
drivers/acpi/tables/tbconvrt.c
include/acpi/acconfig.h
include/acpi/acinterp.h
include/acpi/platform/aclinux.h

index c40922640bda113afef9554b01582eb705f5d3c9..b02322e213de9d49bd12d355c0a9a0491c3fdf13 100644 (file)
@@ -578,6 +578,13 @@ acpi_ds_exec_end_op (
                                break;
                        }
 
+                       /* Done with this result state (Now that operand stack is built) */
+
+                       status = acpi_ds_result_stack_pop (walk_state);
+                       if (ACPI_FAILURE (status)) {
+                               goto cleanup;
+                       }
+
                        /*
                         * If a result object was returned from above, push it on the
                         * current result stack
index ea353f4f2c2c0ac911b212ff7ba60284285d4222..d32624331626a85e24570e50c3e140bf370291c0 100644 (file)
  * FUNCTION:    acpi_ex_do_match
  *
  * PARAMETERS:  match_op        - The AML match operand
- *              package_value   - Value from the target package
- *              match_value     - Value to be matched
+ *              package_obj     - Object from the target package
+ *              match_obj       - Object to be matched
  *
  * RETURN:      TRUE if the match is successful, FALSE otherwise
  *
- * DESCRIPTION: Implements the low-level match for the ASL Match operator
+ * DESCRIPTION: Implements the low-level match for the ASL Match operator.
+ *              Package elements will be implicitly converted to the type of
+ *              the match object (Integer/Buffer/String).
  *
  ******************************************************************************/
 
 u8
 acpi_ex_do_match (
        u32                             match_op,
-       acpi_integer                    package_value,
-       acpi_integer                    match_value)
+       union acpi_operand_object       *package_obj,
+       union acpi_operand_object       *match_obj)
 {
-
+       u8                              logical_result = TRUE;
+       acpi_status                     status;
+
+
+       /*
+        * Note: Since the package_obj/match_obj ordering is opposite to that of
+        * the standard logical operators, we have to reverse them when we call
+        * do_logical_op in order to make the implicit conversion rules work
+        * correctly. However, this means we have to flip the entire equation
+        * also. A bit ugly perhaps, but overall, better than fussing the
+        * parameters around at runtime, over and over again.
+        *
+        * Below, P[i] refers to the package element, M refers to the Match object.
+        */
        switch (match_op) {
-       case MATCH_MTR:   /* always true */
+       case MATCH_MTR:
 
-               break;
+               /* Always true */
 
+               break;
 
-       case MATCH_MEQ:   /* true if equal   */
+       case MATCH_MEQ:
 
-               if (package_value != match_value) {
+               /*
+                * True if equal: (P[i] == M)
+                * Change to:     (M == P[i])
+                */
+               status = acpi_ex_do_logical_op (AML_LEQUAL_OP, match_obj, package_obj,
+                                &logical_result);
+               if (ACPI_FAILURE (status)) {
                        return (FALSE);
                }
                break;
 
+       case MATCH_MLE:
 
-       case MATCH_MLE:   /* true if less than or equal  */
-
-               if (package_value > match_value) {
+               /*
+                * True if less than or equal: (P[i] <= M) (P[i] not_greater than M)
+                * Change to:                  (M >= P[i]) (M not_less than P[i])
+                */
+               status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
+                                &logical_result);
+               if (ACPI_FAILURE (status)) {
                        return (FALSE);
                }
+               logical_result = (u8) !logical_result;
                break;
 
+       case MATCH_MLT:
 
-       case MATCH_MLT:   /* true if less than   */
-
-               if (package_value >= match_value) {
+               /*
+                * True if less than: (P[i] < M)
+                * Change to:         (M > P[i])
+                */
+               status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
+                                &logical_result);
+               if (ACPI_FAILURE (status)) {
                        return (FALSE);
                }
                break;
 
+       case MATCH_MGE:
 
-       case MATCH_MGE:   /* true if greater than or equal   */
-
-               if (package_value < match_value) {
+               /*
+                * True if greater than or equal: (P[i] >= M) (P[i] not_less than M)
+                * Change to:                     (M <= P[i]) (M not_greater than P[i])
+                */
+               status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
+                                &logical_result);
+               if (ACPI_FAILURE (status)) {
                        return (FALSE);
                }
+               logical_result = (u8)!logical_result;
                break;
 
+       case MATCH_MGT:
 
-       case MATCH_MGT:   /* true if greater than    */
-
-               if (package_value <= match_value) {
+               /*
+                * True if greater than: (P[i] > M)
+                * Change to:            (M < P[i])
+                */
+               status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
+                                &logical_result);
+               if (ACPI_FAILURE (status)) {
                        return (FALSE);
                }
                break;
 
+       default:
 
-       default:    /* undefined   */
+               /* Undefined */
 
                return (FALSE);
        }
 
-
-       return TRUE;
+       return logical_result;
 }
 
 
@@ -182,19 +226,21 @@ acpi_ex_opcode_6A_0T_1R (
        switch (walk_state->opcode) {
        case AML_MATCH_OP:
                /*
-                * Match (search_package[0], match_op1[1], match_object1[2],
-                *                          match_op2[3], match_object2[4], start_index[5])
+                * Match (search_pkg[0], match_op1[1], match_obj1[2],
+                *                      match_op2[3], match_obj2[4], start_index[5])
                 */
 
-               /* Validate match comparison sub-opcodes */
+               /* Validate both Match Term Operators (MTR, MEQ, etc.) */
 
                if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
                        (operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
-                       ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "operation encoding out of range\n"));
+                       ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Match operator out of range\n"));
                        status = AE_AML_OPERAND_VALUE;
                        goto cleanup;
                }
 
+               /* Get the package start_index, validate against the package length */
+
                index = (u32) operand[5]->integer.value;
                if (index >= (u32) operand[0]->package.count) {
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index beyond package end\n"));
@@ -202,6 +248,8 @@ acpi_ex_opcode_6A_0T_1R (
                        goto cleanup;
                }
 
+               /* Create an integer for the return value */
+
                return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
                if (!return_desc) {
                        status = AE_NO_MEMORY;
@@ -214,37 +262,39 @@ acpi_ex_opcode_6A_0T_1R (
                return_desc->integer.value = ACPI_INTEGER_MAX;
 
                /*
-                * Examine each element until a match is found.  Within the loop,
+                * Examine each element until a match is found. Both match conditions
+                * must be satisfied for a match to occur. Within the loop,
                 * "continue" signifies that the current element does not match
                 * and the next should be examined.
                 *
                 * Upon finding a match, the loop will terminate via "break" at
-                * the bottom.  If it terminates "normally", match_value will be -1
-                * (its initial value) indicating that no match was found.  When
-                * returned as a Number, this will produce the Ones value as specified.
+                * the bottom.  If it terminates "normally", match_value will be
+                * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no
+                * match was found.
                 */
                for ( ; index < operand[0]->package.count; index++) {
+                       /* Get the current package element */
+
                        this_element = operand[0]->package.elements[index];
 
-                       /*
-                        * Treat any NULL or non-numeric elements as non-matching.
-                        */
-                       if (!this_element ||
-                               ACPI_GET_OBJECT_TYPE (this_element) != ACPI_TYPE_INTEGER) {
+                       /* Treat any uninitialized (NULL) elements as non-matching */
+
+                       if (!this_element) {
                                continue;
                        }
 
                        /*
-                        * "continue" (proceed to next iteration of enclosing
-                        * "for" loop) signifies a non-match.
+                        * Both match conditions must be satisfied. Execution of a continue
+                        * (proceed to next iteration of enclosing for loop) signifies a
+                        * non-match.
                         */
                        if (!acpi_ex_do_match ((u32) operand[1]->integer.value,
-                                          this_element->integer.value, operand[2]->integer.value)) {
+                                          this_element, operand[2])) {
                                continue;
                        }
 
                        if (!acpi_ex_do_match ((u32) operand[3]->integer.value,
-                                          this_element->integer.value, operand[4]->integer.value)) {
+                                          this_element, operand[4])) {
                                continue;
                        }
 
@@ -253,7 +303,6 @@ acpi_ex_opcode_6A_0T_1R (
                        return_desc->integer.value = index;
                        break;
                }
-
                break;
 
 
index 8dcfa427930e8ee4eb3f712ef035c7a15222d867..c92890220c3201d737f1fdef77886c8b110ae12a 100644 (file)
@@ -312,7 +312,7 @@ acpi_ex_resolve_operands (
                        goto next_operand;
 
 
-               case ARGI_ANYTYPE:
+               case ARGI_DATAREFOBJ:  /* Store operator only */
 
                        /*
                         * We don't want to resolve index_op reference objects during
index 8b908fc894e0cc9e375131b19d12320e486b1bbf..e663a48f8a1cb6d581f1aef4b6852926bb75170a 100644 (file)
@@ -206,6 +206,7 @@ acpi_ex_store_object_to_object (
 {
        union acpi_operand_object       *actual_src_desc;
        acpi_status                     status = AE_OK;
+       acpi_object_type                original_src_type;
 
 
        ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc);
@@ -222,7 +223,8 @@ acpi_ex_store_object_to_object (
                return_ACPI_STATUS (status);
        }
 
-       if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
+       original_src_type = ACPI_GET_OBJECT_TYPE (source_desc);
+       if (original_src_type != ACPI_GET_OBJECT_TYPE (dest_desc)) {
                /*
                 * The source type does not match the type of the destination.
                 * Perform the "implicit conversion" of the source to the current type
@@ -232,15 +234,15 @@ acpi_ex_store_object_to_object (
                 * Otherwise, actual_src_desc is a temporary object to hold the
                 * converted object.
                 */
-               status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc), source_desc,
-                                 &actual_src_desc, walk_state);
+               status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc),
+                                 source_desc, &actual_src_desc, walk_state);
                if (ACPI_FAILURE (status)) {
                        return_ACPI_STATUS (status);
                }
 
                if (source_desc == actual_src_desc) {
                        /*
-                        * No conversion was performed.  Return the source_desc as the
+                        * No conversion was performed. Return the source_desc as the
                         * new object.
                         */
                        *new_desc = source_desc;
@@ -269,12 +271,18 @@ acpi_ex_store_object_to_object (
 
        case ACPI_TYPE_BUFFER:
 
-               status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc);
+               /*
+                * Note: There is different store behavior depending on the original
+                * source type
+                */
+               status = acpi_ex_store_buffer_to_buffer (original_src_type, actual_src_desc,
+                                dest_desc);
                break;
 
        case ACPI_TYPE_PACKAGE:
 
-               status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc, walk_state);
+               status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc,
+                                walk_state);
                break;
 
        default:
index d5f5349543f8a9d6b6f5bf9ef046d7751dfba465..4e2b442ee5a3912ded1cf18ddb76f16a1974890b 100644 (file)
@@ -66,6 +66,7 @@
 
 acpi_status
 acpi_ex_store_buffer_to_buffer (
+       acpi_object_type                original_src_type,
        union acpi_operand_object       *source_desc,
        union acpi_operand_object       *target_desc)
 {
@@ -104,9 +105,16 @@ acpi_ex_store_buffer_to_buffer (
                ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
                ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);
 
-               /* Set the new length of the target */
+               /*
+                * If the original source was a string, we must truncate the buffer,
+                * according to the ACPI spec.  Integer-to-Buffer and Buffer-to-Buffer
+                * copy must not truncate the original buffer.
+                */
+               if (original_src_type == ACPI_TYPE_STRING) {
+                       /* Set the new length of the target */
 
-               target_desc->buffer.length = length;
+                       target_desc->buffer.length = length;
+               }
        }
        else {
                /* Truncate the source, copy only what will fit */
index a84d7004993bc401862c6e8d227aa82babae1e1b..f2405efd1b9a89157fc4a74a4a7d8a4b15f9ef37 100644 (file)
@@ -237,7 +237,7 @@ acpi_get_object_info (
 {
        acpi_status                     status;
        struct acpi_namespace_node      *node;
-       struct acpi_device_info         info;
+       struct acpi_device_info         *info;
        struct acpi_device_info         *return_info;
        struct acpi_compatible_id_list *cid_list = NULL;
        acpi_size                       size;
@@ -254,55 +254,59 @@ acpi_get_object_info (
                return (status);
        }
 
+       info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_device_info));
+       if (!info) {
+               return (AE_NO_MEMORY);
+       }
+
        status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
        if (ACPI_FAILURE (status)) {
-               return (status);
+               goto cleanup;
        }
 
        node = acpi_ns_map_handle_to_node (handle);
        if (!node) {
                (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
-               return (AE_BAD_PARAMETER);
+               goto cleanup;
        }
 
        /* Init return structure */
 
        size = sizeof (struct acpi_device_info);
-       ACPI_MEMSET (&info, 0, size);
 
-       info.type  = node->type;
-       info.name  = node->name.integer;
-       info.valid = 0;
+       info->type  = node->type;
+       info->name  = node->name.integer;
+       info->valid = 0;
 
        status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
        if (ACPI_FAILURE (status)) {
-               return (status);
+               goto cleanup;
        }
 
        /* If not a device, we are all done */
 
-       if (info.type == ACPI_TYPE_DEVICE) {
+       if (info->type == ACPI_TYPE_DEVICE) {
                /*
                 * Get extra info for ACPI Devices objects only:
                 * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
                 *
                 * Note: none of these methods are required, so they may or may
-                * not be present for this device.  The Info.Valid bitfield is used
+                * not be present for this device.  The Info->Valid bitfield is used
                 * to indicate which methods were found and ran successfully.
                 */
 
                /* Execute the Device._HID method */
 
-               status = acpi_ut_execute_HID (node, &info.hardware_id);
+               status = acpi_ut_execute_HID (node, &info->hardware_id);
                if (ACPI_SUCCESS (status)) {
-                       info.valid |= ACPI_VALID_HID;
+                       info->valid |= ACPI_VALID_HID;
                }
 
                /* Execute the Device._UID method */
 
-               status = acpi_ut_execute_UID (node, &info.unique_id);
+               status = acpi_ut_execute_UID (node, &info->unique_id);
                if (ACPI_SUCCESS (status)) {
-                       info.valid |= ACPI_VALID_UID;
+                       info->valid |= ACPI_VALID_UID;
                }
 
                /* Execute the Device._CID method */
@@ -311,32 +315,30 @@ acpi_get_object_info (
                if (ACPI_SUCCESS (status)) {
                        size += ((acpi_size) cid_list->count - 1) *
                                         sizeof (struct acpi_compatible_id);
-                       info.valid |= ACPI_VALID_CID;
+                       info->valid |= ACPI_VALID_CID;
                }
 
                /* Execute the Device._STA method */
 
-               status = acpi_ut_execute_STA (node, &info.current_status);
+               status = acpi_ut_execute_STA (node, &info->current_status);
                if (ACPI_SUCCESS (status)) {
-                       info.valid |= ACPI_VALID_STA;
+                       info->valid |= ACPI_VALID_STA;
                }
 
                /* Execute the Device._ADR method */
 
                status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node,
-                                 &info.address);
+                                 &info->address);
                if (ACPI_SUCCESS (status)) {
-                       info.valid |= ACPI_VALID_ADR;
+                       info->valid |= ACPI_VALID_ADR;
                }
 
                /* Execute the Device._sx_d methods */
 
-               status = acpi_ut_execute_sxds (node, info.highest_dstates);
+               status = acpi_ut_execute_sxds (node, info->highest_dstates);
                if (ACPI_SUCCESS (status)) {
-                       info.valid |= ACPI_VALID_SXDS;
+                       info->valid |= ACPI_VALID_SXDS;
                }
-
-               status = AE_OK;
        }
 
        /* Validate/Allocate/Clear caller buffer */
@@ -349,7 +351,7 @@ acpi_get_object_info (
        /* Populate the return buffer */
 
        return_info = buffer->pointer;
-       ACPI_MEMCPY (return_info, &info, sizeof (struct acpi_device_info));
+       ACPI_MEMCPY (return_info, info, sizeof (struct acpi_device_info));
 
        if (cid_list) {
                ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size);
@@ -357,6 +359,7 @@ acpi_get_object_info (
 
 
 cleanup:
+       ACPI_MEM_FREE (info);
        if (cid_list) {
                ACPI_MEM_FREE (cid_list);
        }
index eb1f4179128f3083363fa5eb9345b27ba65d9bd6..c1360fc23cee18f328c67039cecd0c9b3e84bd65 100644 (file)
 #define ARGI_LOCAL6                     ARG_NONE
 #define ARGI_LOCAL7                     ARG_NONE
 #define ARGI_LOR_OP                     ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
-#define ARGI_MATCH_OP                   ARGI_LIST6 (ARGI_PACKAGE,    ARGI_INTEGER,       ARGI_INTEGER,      ARGI_INTEGER,   ARGI_INTEGER,   ARGI_INTEGER)
+#define ARGI_MATCH_OP                   ARGI_LIST6 (ARGI_PACKAGE,    ARGI_INTEGER,   ARGI_COMPUTEDATA,      ARGI_INTEGER,ARGI_COMPUTEDATA,ARGI_INTEGER)
 #define ARGI_METHOD_OP                  ARGI_INVALID_OPCODE
 #define ARGI_METHODCALL_OP              ARGI_INVALID_OPCODE
 #define ARGI_MID_OP                     ARGI_LIST4 (ARGI_BUFFER_OR_STRING,ARGI_INTEGER,  ARGI_INTEGER,      ARGI_TARGETREF)
index dfc1559b173d611d3d74f03c3960c4d0b6f0e9f5..334327c1f66f5b965ca1c4528881a3b3d3cea2b0 100644 (file)
@@ -269,8 +269,8 @@ acpi_tb_convert_fadt1 (
                 * that immediately follows.
                 */
                ACPI_MEMCPY (&local_fadt->reset_register,
-                       &((struct fadt_descriptor_rev2_minus *) original_fadt)->reset_register,
-                       sizeof (struct acpi_generic_address) + 1);
+                       &(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus, original_fadt))->reset_register,
+                       sizeof (struct acpi_generic_address) + 1);
        }
        else {
                /*
index a830919a1de40b4e09bb3b937f03650607ddf9a7..6701c11b406b3f22e4c256757d77db4eb6f3f59f 100644 (file)
@@ -64,7 +64,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20050125
+#define ACPI_CA_VERSION                 0x20050211
 
 /*
  * OS name, used for the _OS object.  The _OS object is essentially obsolete,
index 6a5cbb355685efb839836781151906c4c38ab069..78395916e4cfbf33add1ec007ed8a2be967477e3 100644 (file)
@@ -217,8 +217,8 @@ acpi_ex_opcode_6A_0T_1R (
 u8
 acpi_ex_do_match (
        u32                             match_op,
-       acpi_integer                    package_value,
-       acpi_integer                    match_value);
+       union acpi_operand_object       *package_obj,
+       union acpi_operand_object       *match_obj);
 
 acpi_status
 acpi_ex_get_object_reference (
@@ -617,6 +617,7 @@ acpi_ex_store_object_to_object (
 
 acpi_status
 acpi_ex_store_buffer_to_buffer (
+       acpi_object_type                original_src_type,
        union acpi_operand_object       *source_desc,
        union acpi_operand_object       *target_desc);
 
index d807f2981d952c847e140ee3059bcfea644116dd..a3de0db856942cad99fa80c16451b4a028cade3f 100644 (file)
@@ -81,6 +81,8 @@
 #define ACPI_USE_NATIVE_DIVIDE
 #endif
 
+#define __cdecl
+#define ACPI_FLUSH_CPU_CACHE()
 #endif /* __KERNEL__ */
 
 /* Linux uses GCC */