示例#1
0
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);
}
示例#2
0
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);
}