acpi_status acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, struct acpi_parse_state *parser_state, u32 arg_type, union acpi_parse_object **return_arg) { union acpi_parse_object *arg = NULL; union acpi_parse_object *prev = NULL; union acpi_parse_object *field; u32 subop; acpi_status status = AE_OK; ACPI_FUNCTION_TRACE_PTR("ps_get_next_arg", parser_state); switch (arg_type) { case ARGP_BYTEDATA: case ARGP_WORDDATA: case ARGP_DWORDDATA: case ARGP_CHARLIST: case ARGP_NAME: case ARGP_NAMESTRING: /* Constants, strings, and namestrings are all the same size */ arg = acpi_ps_alloc_op(AML_BYTE_OP); if (!arg) { return_ACPI_STATUS(AE_NO_MEMORY); } acpi_ps_get_next_simple_arg(parser_state, arg_type, arg); break; case ARGP_PKGLENGTH: /* Package length, nothing returned */ parser_state->pkg_end = acpi_ps_get_next_package_end(parser_state); break; case ARGP_FIELDLIST: if (parser_state->aml < parser_state->pkg_end) { /* Non-empty list */ while (parser_state->aml < parser_state->pkg_end) { field = acpi_ps_get_next_field(parser_state); if (!field) { return_ACPI_STATUS(AE_NO_MEMORY); } if (prev) { prev->common.next = field; } else { arg = field; } prev = field; } /* Skip to End of byte data */ parser_state->aml = parser_state->pkg_end; } break; case ARGP_BYTELIST: if (parser_state->aml < parser_state->pkg_end) { /* Non-empty list */ arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP); if (!arg) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Fill in bytelist data */ arg->common.value.size = (u32) ACPI_PTR_DIFF(parser_state->pkg_end, parser_state->aml); arg->named.data = parser_state->aml; /* Skip to End of byte data */ parser_state->aml = parser_state->pkg_end; } break; case ARGP_TARGET: case ARGP_SUPERNAME: case ARGP_SIMPLENAME: subop = acpi_ps_peek_opcode(parser_state); if (subop == 0 || acpi_ps_is_leading_char(subop) || acpi_ps_is_prefix_char(subop)) { /* null_name or name_string */ arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); if (!arg) { return_ACPI_STATUS(AE_NO_MEMORY); } status = acpi_ps_get_next_namepath(walk_state, parser_state, arg, 0); } else { /* Single complex argument, nothing returned */ walk_state->arg_count = 1; } break; case ARGP_DATAOBJ: case ARGP_TERMARG: /* Single complex argument, nothing returned */ walk_state->arg_count = 1; break; case ARGP_DATAOBJLIST: case ARGP_TERMLIST: case ARGP_OBJLIST: if (parser_state->aml < parser_state->pkg_end) { /* Non-empty list of variable arguments, nothing returned */ walk_state->arg_count = ACPI_VAR_ARGS; } break; default: ACPI_REPORT_ERROR(("Invalid arg_type: %X\n", arg_type)); status = AE_AML_OPERAND_TYPE; break; } *return_arg = arg; return_ACPI_STATUS(status); }
ACPI_PARSE_OBJECT * acpi_ps_get_next_arg ( ACPI_PARSE_STATE *parser_state, u32 arg_type, u32 *arg_count) { ACPI_PARSE_OBJECT *arg = NULL; ACPI_PARSE_OBJECT *prev = NULL; ACPI_PARSE_OBJECT *field; u32 subop; switch (arg_type) { case ARGP_BYTEDATA: case ARGP_WORDDATA: case ARGP_DWORDDATA: case ARGP_CHARLIST: case ARGP_NAME: case ARGP_NAMESTRING: /* constants, strings, and namestrings are all the same size */ arg = acpi_ps_alloc_op (AML_BYTE_OP); if (arg) { acpi_ps_get_next_simple_arg (parser_state, arg_type, arg); } break; case ARGP_PKGLENGTH: /* package length, nothing returned */ parser_state->pkg_end = acpi_ps_get_next_package_end (parser_state); break; case ARGP_FIELDLIST: if (parser_state->aml < parser_state->pkg_end) { /* non-empty list */ while (parser_state->aml < parser_state->pkg_end) { field = acpi_ps_get_next_field (parser_state); if (!field) { break; } if (prev) { prev->next = field; } else { arg = field; } prev = field; } /* skip to End of byte data */ parser_state->aml = parser_state->pkg_end; } break; case ARGP_BYTELIST: if (parser_state->aml < parser_state->pkg_end) { /* non-empty list */ arg = acpi_ps_alloc_op (AML_BYTELIST_OP); if (arg) { /* fill in bytelist data */ arg->value.size = (parser_state->pkg_end - parser_state->aml); ((ACPI_PARSE2_OBJECT *) arg)->data = parser_state->aml; } /* skip to End of byte data */ parser_state->aml = parser_state->pkg_end; } break; case ARGP_TARGET: case ARGP_SUPERNAME: { subop = acpi_ps_peek_opcode (parser_state); if (subop == 0 || acpi_ps_is_leading_char (subop) || acpi_ps_is_prefix_char (subop)) { /* Null_name or Name_string */ arg = acpi_ps_alloc_op (AML_NAMEPATH_OP); if (arg) { acpi_ps_get_next_namepath (parser_state, arg, arg_count, 0); } } else { /* single complex argument, nothing returned */ *arg_count = 1; } } break; case ARGP_DATAOBJ: case ARGP_TERMARG: /* single complex argument, nothing returned */ *arg_count = 1; break; case ARGP_DATAOBJLIST: case ARGP_TERMLIST: case ARGP_OBJLIST: if (parser_state->aml < parser_state->pkg_end) { /* non-empty list of variable arguments, nothing returned */ *arg_count = ACPI_VAR_ARGS; } break; } return (arg); }