acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) { union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *return_desc = NULL; acpi_status status = AE_OK; u64 index; union acpi_operand_object *this_element; ACPI_FUNCTION_TRACE_STR(ex_opcode_6A_0T_1R, acpi_ps_get_opcode_name(walk_state->opcode)); switch (walk_state->opcode) { case AML_MATCH_OP: if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) || (operand[3]->integer.value > MAX_MATCH_OPERATOR)) { ACPI_ERROR((AE_INFO, "Match operator out of range")); status = AE_AML_OPERAND_VALUE; goto cleanup; } index = operand[5]->integer.value; if (index >= operand[0]->package.count) { ACPI_ERROR((AE_INFO, "Index (0x%8.8X%8.8X) beyond package end (0x%X)", ACPI_FORMAT_UINT64(index), operand[0]->package.count)); status = AE_AML_PACKAGE_LIMIT; goto cleanup; } return_desc = acpi_ut_create_integer_object(ACPI_UINT64_MAX); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; } for (; index < operand[0]->package.count; index++) { this_element = operand[0]->package.elements[index]; if (!this_element) { continue; } if (!acpi_ex_do_match((u32) operand[1]->integer.value, this_element, operand[2])) { continue; } if (!acpi_ex_do_match((u32) operand[3]->integer.value, this_element, operand[4])) { continue; } return_desc->integer.value = index; break; } break; case AML_LOAD_TABLE_OP: status = acpi_ex_load_table_op(walk_state, &return_desc); break; default: ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } cleanup: if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(return_desc); } else { walk_state->result_obj = return_desc; } return_ACPI_STATUS(status); }
acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) { union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *return_desc = NULL; acpi_status status = AE_OK; acpi_integer index; union acpi_operand_object *this_element; ACPI_FUNCTION_TRACE_STR(ex_opcode_6A_0T_1R, acpi_ps_get_opcode_name(walk_state->opcode)); switch (walk_state->opcode) { case AML_MATCH_OP: /* * Match (search_pkg[0], match_op1[1], match_obj1[2], * match_op2[3], match_obj2[4], start_index[5]) */ /* Validate both Match Term Operators (MTR, MEQ, etc.) */ if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) || (operand[3]->integer.value > MAX_MATCH_OPERATOR)) { ACPI_ERROR((AE_INFO, "Match operator out of range")); status = AE_AML_OPERAND_VALUE; goto cleanup; } /* Get the package start_index, validate against the package length */ index = operand[5]->integer.value; if (index >= operand[0]->package.count) { ACPI_ERROR((AE_INFO, "Index (%X%8.8X) beyond package end (%X)", ACPI_FORMAT_UINT64(index), operand[0]->package.count)); status = AE_AML_PACKAGE_LIMIT; 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; goto cleanup; } /* Default return value if no match found */ return_desc->integer.value = ACPI_INTEGER_MAX; /* * 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 * 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 uninitialized (NULL) elements as non-matching */ if (!this_element) { continue; } /* * 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, operand[2])) { continue; } if (!acpi_ex_do_match((u32) operand[3]->integer.value, this_element, operand[4])) { continue; } /* Match found: Index is the return value */ return_desc->integer.value = index; break; } break; case AML_LOAD_TABLE_OP: status = acpi_ex_load_table_op(walk_state, &return_desc); break; default: ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } walk_state->result_obj = return_desc; cleanup: /* Delete return object on error */ if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(return_desc); } return_ACPI_STATUS(status); }
acpi_status acpi_ex_opcode_6A_0T_1R ( struct acpi_walk_state *walk_state) { union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object *return_desc = NULL; acpi_status status = AE_OK; u32 index; union acpi_operand_object *this_element; ACPI_FUNCTION_TRACE_STR ("ex_opcode_6A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); 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]) */ /* Validate match comparison sub-opcodes */ 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")); status = AE_AML_OPERAND_VALUE; goto cleanup; } index = (u32) operand[5]->integer.value; if (index >= (u32) operand[0]->package.count) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index beyond package end\n")); status = AE_AML_PACKAGE_LIMIT; goto cleanup; } return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); if (!return_desc) { status = AE_NO_MEMORY; goto cleanup; } /* Default return value if no match found */ return_desc->integer.value = ACPI_INTEGER_MAX; /* * Examine each element until a match is found. 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. */ for ( ; index < operand[0]->package.count; index++) { 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) { continue; } /* * "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)) { continue; } if (!acpi_ex_do_match ((u32) operand[3]->integer.value, this_element->integer.value, operand[4]->integer.value)) { continue; } /* Match found: Index is the return value */ return_desc->integer.value = index; break; } break; case AML_LOAD_TABLE_OP: status = acpi_ex_load_table_op (walk_state, &return_desc); break; default: ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } walk_state->result_obj = return_desc; cleanup: /* Delete return object on error */ if (ACPI_FAILURE (status)) { acpi_ut_remove_reference (return_desc); } return_ACPI_STATUS (status); }