psargs.c

来自「linux2.6.16版本」· C语言 代码 · 共 722 行 · 第 1/2 页

C
722
字号
	/* Save the namepath */	arg->common.value.name = path;	return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION:    acpi_ps_get_next_simple_arg * * PARAMETERS:  parser_state        - Current parser state object *              arg_type            - The argument type (AML_*_ARG) *              Arg                 - Where the argument is returned * * RETURN:      None * * DESCRIPTION: Get the next simple argument (constant, string, or namestring) * ******************************************************************************/voidacpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,			    u32 arg_type, union acpi_parse_object *arg){	u32 length;	u16 opcode;	u8 *aml = parser_state->aml;	ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type);	switch (arg_type) {	case ARGP_BYTEDATA:		/* Get 1 byte from the AML stream */		opcode = AML_BYTE_OP;		arg->common.value.integer = (acpi_integer) * aml;		length = 1;		break;	case ARGP_WORDDATA:		/* Get 2 bytes from the AML stream */		opcode = AML_WORD_OP;		ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);		length = 2;		break;	case ARGP_DWORDDATA:		/* Get 4 bytes from the AML stream */		opcode = AML_DWORD_OP;		ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);		length = 4;		break;	case ARGP_QWORDDATA:		/* Get 8 bytes from the AML stream */		opcode = AML_QWORD_OP;		ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);		length = 8;		break;	case ARGP_CHARLIST:		/* Get a pointer to the string, point past the string */		opcode = AML_STRING_OP;		arg->common.value.string = ACPI_CAST_PTR(char, aml);		/* Find the null terminator */		length = 0;		while (aml[length]) {			length++;		}		length++;		break;	case ARGP_NAME:	case ARGP_NAMESTRING:		acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);		arg->common.value.name =		    acpi_ps_get_next_namestring(parser_state);		return_VOID;	default:		ACPI_ERROR((AE_INFO, "Invalid arg_type %X", arg_type));		return_VOID;	}	acpi_ps_init_op(arg, opcode);	parser_state->aml += length;	return_VOID;}/******************************************************************************* * * FUNCTION:    acpi_ps_get_next_field * * PARAMETERS:  parser_state        - Current parser state object * * RETURN:      A newly allocated FIELD op * * DESCRIPTION: Get next field (named_field, reserved_field, or access_field) * ******************************************************************************/static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state						       *parser_state){	u32 aml_offset = (u32)	    ACPI_PTR_DIFF(parser_state->aml,			  parser_state->aml_start);	union acpi_parse_object *field;	u16 opcode;	u32 name;	ACPI_FUNCTION_TRACE("ps_get_next_field");	/* Determine field type */	switch (ACPI_GET8(parser_state->aml)) {	default:		opcode = AML_INT_NAMEDFIELD_OP;		break;	case 0x00:		opcode = AML_INT_RESERVEDFIELD_OP;		parser_state->aml++;		break;	case 0x01:		opcode = AML_INT_ACCESSFIELD_OP;		parser_state->aml++;		break;	}	/* Allocate a new field op */	field = acpi_ps_alloc_op(opcode);	if (!field) {		return_PTR(NULL);	}	field->common.aml_offset = aml_offset;	/* Decode the field type */	switch (opcode) {	case AML_INT_NAMEDFIELD_OP:		/* Get the 4-character name */		ACPI_MOVE_32_TO_32(&name, parser_state->aml);		acpi_ps_set_name(field, name);		parser_state->aml += ACPI_NAME_SIZE;		/* Get the length which is encoded as a package length */		field->common.value.size =		    acpi_ps_get_next_package_length(parser_state);		break;	case AML_INT_RESERVEDFIELD_OP:		/* Get the length which is encoded as a package length */		field->common.value.size =		    acpi_ps_get_next_package_length(parser_state);		break;	case AML_INT_ACCESSFIELD_OP:		/*		 * Get access_type and access_attrib and merge into the field Op		 * access_type is first operand, access_attribute is second		 */		field->common.value.integer =		    (((u32) ACPI_GET8(parser_state->aml) << 8));		parser_state->aml++;		field->common.value.integer |= ACPI_GET8(parser_state->aml);		parser_state->aml++;		break;	default:		/* Opcode was set in previous switch */		break;	}	return_PTR(field);}/******************************************************************************* * * FUNCTION:    acpi_ps_get_next_arg * * PARAMETERS:  walk_state          - Current state *              parser_state        - Current parser state object *              arg_type            - The argument type (AML_*_ARG) *              return_arg          - Where the next arg is returned * * RETURN:      Status, and an op object containing the next argument. * * DESCRIPTION: Get next argument (including complex list arguments that require *              pushing the parser stack) * ******************************************************************************/acpi_statusacpi_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_ERROR((AE_INFO, "Invalid arg_type: %X", arg_type));		status = AE_AML_OPERAND_TYPE;		break;	}	*return_arg = arg;	return_ACPI_STATUS(status);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?