xref: /openbmc/linux/drivers/acpi/acpica/psargs.c (revision 612c2932)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown  *
495b482a8SLen Brown  * Module Name: psargs - Parse AML opcode arguments
595b482a8SLen Brown  *
6*612c2932SBob Moore  * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown  *
895857638SErik Schmauss  *****************************************************************************/
995b482a8SLen Brown 
1095b482a8SLen Brown #include <acpi/acpi.h>
11e2f7a777SLen Brown #include "accommon.h"
12e2f7a777SLen Brown #include "acparser.h"
13e2f7a777SLen Brown #include "amlcode.h"
14e2f7a777SLen Brown #include "acnamesp.h"
15e2f7a777SLen Brown #include "acdispat.h"
169cf7adecSBob Moore #include "acconvert.h"
1795b482a8SLen Brown 
1895b482a8SLen Brown #define _COMPONENT          ACPI_PARSER
1995b482a8SLen Brown ACPI_MODULE_NAME("psargs")
2095b482a8SLen Brown 
2195b482a8SLen Brown /* Local prototypes */
2295b482a8SLen Brown static u32
2395b482a8SLen Brown acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
2495b482a8SLen Brown 
2595b482a8SLen Brown static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
2695b482a8SLen Brown 						       *parser_state);
2795b482a8SLen Brown 
2895b482a8SLen Brown /*******************************************************************************
2995b482a8SLen Brown  *
3095b482a8SLen Brown  * FUNCTION:    acpi_ps_get_next_package_length
3195b482a8SLen Brown  *
3295b482a8SLen Brown  * PARAMETERS:  parser_state        - Current parser state object
3395b482a8SLen Brown  *
3495b482a8SLen Brown  * RETURN:      Decoded package length. On completion, the AML pointer points
3595b482a8SLen Brown  *              past the length byte or bytes.
3695b482a8SLen Brown  *
3795b482a8SLen Brown  * DESCRIPTION: Decode and return a package length field.
3895b482a8SLen Brown  *              Note: Largest package length is 28 bits, from ACPI specification
3995b482a8SLen Brown  *
4095b482a8SLen Brown  ******************************************************************************/
4195b482a8SLen Brown 
4295b482a8SLen Brown static u32
acpi_ps_get_next_package_length(struct acpi_parse_state * parser_state)4395b482a8SLen Brown acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
4495b482a8SLen Brown {
4595b482a8SLen Brown 	u8 *aml = parser_state->aml;
4695b482a8SLen Brown 	u32 package_length = 0;
4795b482a8SLen Brown 	u32 byte_count;
4895b482a8SLen Brown 	u8 byte_zero_mask = 0x3F;	/* Default [0:5] */
4995b482a8SLen Brown 
5095b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ps_get_next_package_length);
5195b482a8SLen Brown 
5295b482a8SLen Brown 	/*
5395b482a8SLen Brown 	 * Byte 0 bits [6:7] contain the number of additional bytes
5495b482a8SLen Brown 	 * used to encode the package length, either 0,1,2, or 3
5595b482a8SLen Brown 	 */
5695b482a8SLen Brown 	byte_count = (aml[0] >> 6);
5795b482a8SLen Brown 	parser_state->aml += ((acpi_size)byte_count + 1);
5895b482a8SLen Brown 
5995b482a8SLen Brown 	/* Get bytes 3, 2, 1 as needed */
6095b482a8SLen Brown 
6195b482a8SLen Brown 	while (byte_count) {
6295b482a8SLen Brown 		/*
6395b482a8SLen Brown 		 * Final bit positions for the package length bytes:
6495b482a8SLen Brown 		 *      Byte3->[20:27]
6595b482a8SLen Brown 		 *      Byte2->[12:19]
6695b482a8SLen Brown 		 *      Byte1->[04:11]
6795b482a8SLen Brown 		 *      Byte0->[00:03]
6895b482a8SLen Brown 		 */
6995b482a8SLen Brown 		package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
7095b482a8SLen Brown 
7195b482a8SLen Brown 		byte_zero_mask = 0x0F;	/* Use bits [0:3] of byte 0 */
7295b482a8SLen Brown 		byte_count--;
7395b482a8SLen Brown 	}
7495b482a8SLen Brown 
7595b482a8SLen Brown 	/* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
7695b482a8SLen Brown 
7795b482a8SLen Brown 	package_length |= (aml[0] & byte_zero_mask);
78fd1af712SBob Moore 	return_UINT32(package_length);
7995b482a8SLen Brown }
8095b482a8SLen Brown 
8195b482a8SLen Brown /*******************************************************************************
8295b482a8SLen Brown  *
8395b482a8SLen Brown  * FUNCTION:    acpi_ps_get_next_package_end
8495b482a8SLen Brown  *
8595b482a8SLen Brown  * PARAMETERS:  parser_state        - Current parser state object
8695b482a8SLen Brown  *
8795b482a8SLen Brown  * RETURN:      Pointer to end-of-package +1
8895b482a8SLen Brown  *
8995b482a8SLen Brown  * DESCRIPTION: Get next package length and return a pointer past the end of
9095b482a8SLen Brown  *              the package. Consumes the package length field
9195b482a8SLen Brown  *
9295b482a8SLen Brown  ******************************************************************************/
9395b482a8SLen Brown 
acpi_ps_get_next_package_end(struct acpi_parse_state * parser_state)9495b482a8SLen Brown u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
9595b482a8SLen Brown {
9695b482a8SLen Brown 	u8 *start = parser_state->aml;
9795b482a8SLen Brown 	u32 package_length;
9895b482a8SLen Brown 
9995b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ps_get_next_package_end);
10095b482a8SLen Brown 
10195b482a8SLen Brown 	/* Function below updates parser_state->Aml */
10295b482a8SLen Brown 
10395b482a8SLen Brown 	package_length = acpi_ps_get_next_package_length(parser_state);
10495b482a8SLen Brown 
10595b482a8SLen Brown 	return_PTR(start + package_length);	/* end of package */
10695b482a8SLen Brown }
10795b482a8SLen Brown 
10895b482a8SLen Brown /*******************************************************************************
10995b482a8SLen Brown  *
11095b482a8SLen Brown  * FUNCTION:    acpi_ps_get_next_namestring
11195b482a8SLen Brown  *
11295b482a8SLen Brown  * PARAMETERS:  parser_state        - Current parser state object
11395b482a8SLen Brown  *
11495b482a8SLen Brown  * RETURN:      Pointer to the start of the name string (pointer points into
11595b482a8SLen Brown  *              the AML.
11695b482a8SLen Brown  *
11795b482a8SLen Brown  * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
11895b482a8SLen Brown  *              prefix characters. Set parser state to point past the string.
11995b482a8SLen Brown  *              (Name is consumed from the AML.)
12095b482a8SLen Brown  *
12195b482a8SLen Brown  ******************************************************************************/
12295b482a8SLen Brown 
acpi_ps_get_next_namestring(struct acpi_parse_state * parser_state)12395b482a8SLen Brown char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
12495b482a8SLen Brown {
12595b482a8SLen Brown 	u8 *start = parser_state->aml;
12695b482a8SLen Brown 	u8 *end = parser_state->aml;
12795b482a8SLen Brown 
12895b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ps_get_next_namestring);
12995b482a8SLen Brown 
13095b482a8SLen Brown 	/* Point past any namestring prefix characters (backslash or carat) */
13195b482a8SLen Brown 
13204a81dceSBob Moore 	while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) {
13395b482a8SLen Brown 		end++;
13495b482a8SLen Brown 	}
13595b482a8SLen Brown 
13695b482a8SLen Brown 	/* Decode the path prefix character */
13795b482a8SLen Brown 
13895b482a8SLen Brown 	switch (*end) {
13995b482a8SLen Brown 	case 0:
14095b482a8SLen Brown 
14195b482a8SLen Brown 		/* null_name */
14295b482a8SLen Brown 
14395b482a8SLen Brown 		if (end == start) {
14495b482a8SLen Brown 			start = NULL;
14595b482a8SLen Brown 		}
14695b482a8SLen Brown 		end++;
14795b482a8SLen Brown 		break;
14895b482a8SLen Brown 
14995b482a8SLen Brown 	case AML_DUAL_NAME_PREFIX:
15095b482a8SLen Brown 
15195b482a8SLen Brown 		/* Two name segments */
15295b482a8SLen Brown 
15332786755SBob Moore 		end += 1 + (2 * ACPI_NAMESEG_SIZE);
15495b482a8SLen Brown 		break;
15595b482a8SLen Brown 
1569ff5a21aSBob Moore 	case AML_MULTI_NAME_PREFIX:
15795b482a8SLen Brown 
15895b482a8SLen Brown 		/* Multiple name segments, 4 chars each, count in next byte */
15995b482a8SLen Brown 
16032786755SBob Moore 		end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE);
16195b482a8SLen Brown 		break;
16295b482a8SLen Brown 
16395b482a8SLen Brown 	default:
16495b482a8SLen Brown 
16595b482a8SLen Brown 		/* Single name segment */
16695b482a8SLen Brown 
16732786755SBob Moore 		end += ACPI_NAMESEG_SIZE;
16895b482a8SLen Brown 		break;
16995b482a8SLen Brown 	}
17095b482a8SLen Brown 
17195b482a8SLen Brown 	parser_state->aml = end;
17295b482a8SLen Brown 	return_PTR((char *)start);
17395b482a8SLen Brown }
17495b482a8SLen Brown 
17595b482a8SLen Brown /*******************************************************************************
17695b482a8SLen Brown  *
17795b482a8SLen Brown  * FUNCTION:    acpi_ps_get_next_namepath
17895b482a8SLen Brown  *
17995b482a8SLen Brown  * PARAMETERS:  parser_state        - Current parser state object
180ba494beeSBob Moore  *              arg                 - Where the namepath will be stored
18195b482a8SLen Brown  *              arg_count           - If the namepath points to a control method
18295b482a8SLen Brown  *                                    the method's argument is returned here.
18395b482a8SLen Brown  *              possible_method_call - Whether the namepath can possibly be the
18495b482a8SLen Brown  *                                    start of a method call
18595b482a8SLen Brown  *
18695b482a8SLen Brown  * RETURN:      Status
18795b482a8SLen Brown  *
18895b482a8SLen Brown  * DESCRIPTION: Get next name (if method call, return # of required args).
18995b482a8SLen Brown  *              Names are looked up in the internal namespace to determine
19095b482a8SLen Brown  *              if the name represents a control method. If a method
19195b482a8SLen Brown  *              is found, the number of arguments to the method is returned.
19295b482a8SLen Brown  *              This information is critical for parsing to continue correctly.
19395b482a8SLen Brown  *
19495b482a8SLen Brown  ******************************************************************************/
19595b482a8SLen Brown 
19695b482a8SLen Brown acpi_status
acpi_ps_get_next_namepath(struct acpi_walk_state * walk_state,struct acpi_parse_state * parser_state,union acpi_parse_object * arg,u8 possible_method_call)19795b482a8SLen Brown acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
19895b482a8SLen Brown 			  struct acpi_parse_state *parser_state,
19995b482a8SLen Brown 			  union acpi_parse_object *arg, u8 possible_method_call)
20095b482a8SLen Brown {
20195b482a8SLen Brown 	acpi_status status;
20295b482a8SLen Brown 	char *path;
20395b482a8SLen Brown 	union acpi_parse_object *name_op;
20495b482a8SLen Brown 	union acpi_operand_object *method_desc;
20595b482a8SLen Brown 	struct acpi_namespace_node *node;
20695b482a8SLen Brown 	u8 *start = parser_state->aml;
20795b482a8SLen Brown 
20895b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ps_get_next_namepath);
20995b482a8SLen Brown 
21095b482a8SLen Brown 	path = acpi_ps_get_next_namestring(parser_state);
21195b482a8SLen Brown 	acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
21295b482a8SLen Brown 
21395b482a8SLen Brown 	/* Null path case is allowed, just exit */
21495b482a8SLen Brown 
21595b482a8SLen Brown 	if (!path) {
21695b482a8SLen Brown 		arg->common.value.name = path;
21795b482a8SLen Brown 		return_ACPI_STATUS(AE_OK);
21895b482a8SLen Brown 	}
21995b482a8SLen Brown 
22095b482a8SLen Brown 	/*
22195b482a8SLen Brown 	 * Lookup the name in the internal namespace, starting with the current
22295b482a8SLen Brown 	 * scope. We don't want to add anything new to the namespace here,
22395b482a8SLen Brown 	 * however, so we use MODE_EXECUTE.
22495b482a8SLen Brown 	 * Allow searching of the parent tree, but don't open a new scope -
22595b482a8SLen Brown 	 * we just want to lookup the object (must be mode EXECUTE to perform
22695b482a8SLen Brown 	 * the upsearch)
22795b482a8SLen Brown 	 */
22895b482a8SLen Brown 	status = acpi_ns_lookup(walk_state->scope_info, path,
22995b482a8SLen Brown 				ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
23095b482a8SLen Brown 				ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
23195b482a8SLen Brown 				NULL, &node);
23295b482a8SLen Brown 
23395b482a8SLen Brown 	/*
23495b482a8SLen Brown 	 * If this name is a control method invocation, we must
23595b482a8SLen Brown 	 * setup the method call
23695b482a8SLen Brown 	 */
23795b482a8SLen Brown 	if (ACPI_SUCCESS(status) &&
23895b482a8SLen Brown 	    possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
2399a947291SBob Moore 		if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
2409a947291SBob Moore 		     ARGP_SUPERNAME)
2419a947291SBob Moore 		    || (GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
2429a947291SBob Moore 			ARGP_TARGET)) {
2439a947291SBob Moore 			/*
2449a947291SBob Moore 			 * acpi_ps_get_next_namestring has increased the AML pointer past
2459a947291SBob Moore 			 * the method invocation namestring, so we need to restore the
2469a947291SBob Moore 			 * saved AML pointer back to the original method invocation
2479a947291SBob Moore 			 * namestring.
2489a947291SBob Moore 			 */
2499a947291SBob Moore 			walk_state->parser_state.aml = start;
2509a947291SBob Moore 			walk_state->arg_count = 1;
2519a947291SBob Moore 			acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
2529a947291SBob Moore 		}
25395b482a8SLen Brown 
25495b482a8SLen Brown 		/* This name is actually a control method invocation */
25595b482a8SLen Brown 
25695b482a8SLen Brown 		method_desc = acpi_ns_get_attached_object(node);
25795b482a8SLen Brown 		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
258ce87e09dSBob Moore 				  "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
259ce87e09dSBob Moore 				  node->name.ascii, node, method_desc, path));
26095b482a8SLen Brown 
26162eb935bSLv Zheng 		name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start);
26295b482a8SLen Brown 		if (!name_op) {
26395b482a8SLen Brown 			return_ACPI_STATUS(AE_NO_MEMORY);
26495b482a8SLen Brown 		}
26595b482a8SLen Brown 
26695b482a8SLen Brown 		/* Change Arg into a METHOD CALL and attach name to it */
26795b482a8SLen Brown 
26895b482a8SLen Brown 		acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
26995b482a8SLen Brown 		name_op->common.value.name = path;
27095b482a8SLen Brown 
27195b482a8SLen Brown 		/* Point METHODCALL/NAME to the METHOD Node */
27295b482a8SLen Brown 
27395b482a8SLen Brown 		name_op->common.node = node;
27495b482a8SLen Brown 		acpi_ps_append_arg(arg, name_op);
27595b482a8SLen Brown 
27695b482a8SLen Brown 		if (!method_desc) {
27795b482a8SLen Brown 			ACPI_ERROR((AE_INFO,
27895b482a8SLen Brown 				    "Control Method %p has no attached object",
27995b482a8SLen Brown 				    node));
28095b482a8SLen Brown 			return_ACPI_STATUS(AE_AML_INTERNAL);
28195b482a8SLen Brown 		}
28295b482a8SLen Brown 
28395b482a8SLen Brown 		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
28495b482a8SLen Brown 				  "Control Method - %p Args %X\n",
28595b482a8SLen Brown 				  node, method_desc->method.param_count));
28695b482a8SLen Brown 
28795b482a8SLen Brown 		/* Get the number of arguments to expect */
28895b482a8SLen Brown 
28995b482a8SLen Brown 		walk_state->arg_count = method_desc->method.param_count;
29095b482a8SLen Brown 		return_ACPI_STATUS(AE_OK);
29195b482a8SLen Brown 	}
29295b482a8SLen Brown 
29395b482a8SLen Brown 	/*
29495b482a8SLen Brown 	 * Special handling if the name was not found during the lookup -
29595b482a8SLen Brown 	 * some not_found cases are allowed
29695b482a8SLen Brown 	 */
29795b482a8SLen Brown 	if (status == AE_NOT_FOUND) {
29895b482a8SLen Brown 
29995b482a8SLen Brown 		/* 1) not_found is ok during load pass 1/2 (allow forward references) */
30095b482a8SLen Brown 
30195b482a8SLen Brown 		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
30295b482a8SLen Brown 		    ACPI_PARSE_EXECUTE) {
30395b482a8SLen Brown 			status = AE_OK;
30495b482a8SLen Brown 		}
30595b482a8SLen Brown 
30695b482a8SLen Brown 		/* 2) not_found during a cond_ref_of(x) is ok by definition */
30795b482a8SLen Brown 
30895b482a8SLen Brown 		else if (walk_state->op->common.aml_opcode ==
3099ff5a21aSBob Moore 			 AML_CONDITIONAL_REF_OF_OP) {
31095b482a8SLen Brown 			status = AE_OK;
31195b482a8SLen Brown 		}
31295b482a8SLen Brown 
31395b482a8SLen Brown 		/*
31495b482a8SLen Brown 		 * 3) not_found while building a Package is ok at this point, we
31595b482a8SLen Brown 		 * may flag as an error later if slack mode is not enabled.
31695b482a8SLen Brown 		 * (Some ASL code depends on allowing this behavior)
31795b482a8SLen Brown 		 */
31895b482a8SLen Brown 		else if ((arg->common.parent) &&
31995b482a8SLen Brown 			 ((arg->common.parent->common.aml_opcode ==
32095b482a8SLen Brown 			   AML_PACKAGE_OP)
32195b482a8SLen Brown 			  || (arg->common.parent->common.aml_opcode ==
3229ff5a21aSBob Moore 			      AML_VARIABLE_PACKAGE_OP))) {
32395b482a8SLen Brown 			status = AE_OK;
32495b482a8SLen Brown 		}
32595b482a8SLen Brown 	}
32695b482a8SLen Brown 
32795b482a8SLen Brown 	/* Final exception check (may have been changed from code above) */
32895b482a8SLen Brown 
32995b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
33016ccf829SBob Moore 		ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status);
33195b482a8SLen Brown 
33295b482a8SLen Brown 		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
33395b482a8SLen Brown 		    ACPI_PARSE_EXECUTE) {
33495b482a8SLen Brown 
33595b482a8SLen Brown 			/* Report a control method execution error */
33695b482a8SLen Brown 
33795b482a8SLen Brown 			status = acpi_ds_method_error(status, walk_state);
33895b482a8SLen Brown 		}
33995b482a8SLen Brown 	}
34095b482a8SLen Brown 
34195b482a8SLen Brown 	/* Save the namepath */
34295b482a8SLen Brown 
34395b482a8SLen Brown 	arg->common.value.name = path;
34495b482a8SLen Brown 	return_ACPI_STATUS(status);
34595b482a8SLen Brown }
34695b482a8SLen Brown 
34795b482a8SLen Brown /*******************************************************************************
34895b482a8SLen Brown  *
34995b482a8SLen Brown  * FUNCTION:    acpi_ps_get_next_simple_arg
35095b482a8SLen Brown  *
35195b482a8SLen Brown  * PARAMETERS:  parser_state        - Current parser state object
35295b482a8SLen Brown  *              arg_type            - The argument type (AML_*_ARG)
353ba494beeSBob Moore  *              arg                 - Where the argument is returned
35495b482a8SLen Brown  *
35595b482a8SLen Brown  * RETURN:      None
35695b482a8SLen Brown  *
35795b482a8SLen Brown  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
35895b482a8SLen Brown  *
35995b482a8SLen Brown  ******************************************************************************/
36095b482a8SLen Brown 
36195b482a8SLen Brown void
acpi_ps_get_next_simple_arg(struct acpi_parse_state * parser_state,u32 arg_type,union acpi_parse_object * arg)36295b482a8SLen Brown acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
36395b482a8SLen Brown 			    u32 arg_type, union acpi_parse_object *arg)
36495b482a8SLen Brown {
36595b482a8SLen Brown 	u32 length;
36695b482a8SLen Brown 	u16 opcode;
36795b482a8SLen Brown 	u8 *aml = parser_state->aml;
36895b482a8SLen Brown 
36995b482a8SLen Brown 	ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
37095b482a8SLen Brown 
37195b482a8SLen Brown 	switch (arg_type) {
37295b482a8SLen Brown 	case ARGP_BYTEDATA:
37395b482a8SLen Brown 
37495b482a8SLen Brown 		/* Get 1 byte from the AML stream */
37595b482a8SLen Brown 
37695b482a8SLen Brown 		opcode = AML_BYTE_OP;
3775df7e6cbSBob Moore 		arg->common.value.integer = (u64) *aml;
37895b482a8SLen Brown 		length = 1;
37995b482a8SLen Brown 		break;
38095b482a8SLen Brown 
38195b482a8SLen Brown 	case ARGP_WORDDATA:
38295b482a8SLen Brown 
38395b482a8SLen Brown 		/* Get 2 bytes from the AML stream */
38495b482a8SLen Brown 
38595b482a8SLen Brown 		opcode = AML_WORD_OP;
38695b482a8SLen Brown 		ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
38795b482a8SLen Brown 		length = 2;
38895b482a8SLen Brown 		break;
38995b482a8SLen Brown 
39095b482a8SLen Brown 	case ARGP_DWORDDATA:
39195b482a8SLen Brown 
39295b482a8SLen Brown 		/* Get 4 bytes from the AML stream */
39395b482a8SLen Brown 
39495b482a8SLen Brown 		opcode = AML_DWORD_OP;
39595b482a8SLen Brown 		ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
39695b482a8SLen Brown 		length = 4;
39795b482a8SLen Brown 		break;
39895b482a8SLen Brown 
39995b482a8SLen Brown 	case ARGP_QWORDDATA:
40095b482a8SLen Brown 
40195b482a8SLen Brown 		/* Get 8 bytes from the AML stream */
40295b482a8SLen Brown 
40395b482a8SLen Brown 		opcode = AML_QWORD_OP;
40495b482a8SLen Brown 		ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
40595b482a8SLen Brown 		length = 8;
40695b482a8SLen Brown 		break;
40795b482a8SLen Brown 
40895b482a8SLen Brown 	case ARGP_CHARLIST:
40995b482a8SLen Brown 
41095b482a8SLen Brown 		/* Get a pointer to the string, point past the string */
41195b482a8SLen Brown 
41295b482a8SLen Brown 		opcode = AML_STRING_OP;
41395b482a8SLen Brown 		arg->common.value.string = ACPI_CAST_PTR(char, aml);
41495b482a8SLen Brown 
41595b482a8SLen Brown 		/* Find the null terminator */
41695b482a8SLen Brown 
41795b482a8SLen Brown 		length = 0;
41895b482a8SLen Brown 		while (aml[length]) {
41995b482a8SLen Brown 			length++;
42095b482a8SLen Brown 		}
42195b482a8SLen Brown 		length++;
42295b482a8SLen Brown 		break;
42395b482a8SLen Brown 
42495b482a8SLen Brown 	case ARGP_NAME:
42595b482a8SLen Brown 	case ARGP_NAMESTRING:
42695b482a8SLen Brown 
42795b482a8SLen Brown 		acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
42895b482a8SLen Brown 		arg->common.value.name =
42995b482a8SLen Brown 		    acpi_ps_get_next_namestring(parser_state);
43095b482a8SLen Brown 		return_VOID;
43195b482a8SLen Brown 
43295b482a8SLen Brown 	default:
43395b482a8SLen Brown 
434f6a22b0bSBob Moore 		ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type));
43595b482a8SLen Brown 		return_VOID;
43695b482a8SLen Brown 	}
43795b482a8SLen Brown 
43895b482a8SLen Brown 	acpi_ps_init_op(arg, opcode);
43995b482a8SLen Brown 	parser_state->aml += length;
44095b482a8SLen Brown 	return_VOID;
44195b482a8SLen Brown }
44295b482a8SLen Brown 
44395b482a8SLen Brown /*******************************************************************************
44495b482a8SLen Brown  *
44595b482a8SLen Brown  * FUNCTION:    acpi_ps_get_next_field
44695b482a8SLen Brown  *
44795b482a8SLen Brown  * PARAMETERS:  parser_state        - Current parser state object
44895b482a8SLen Brown  *
44995b482a8SLen Brown  * RETURN:      A newly allocated FIELD op
45095b482a8SLen Brown  *
45195b482a8SLen Brown  * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
45295b482a8SLen Brown  *
45395b482a8SLen Brown  ******************************************************************************/
45495b482a8SLen Brown 
acpi_ps_get_next_field(struct acpi_parse_state * parser_state)45595b482a8SLen Brown static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
45695b482a8SLen Brown 						       *parser_state)
45795b482a8SLen Brown {
458950a429cSLv Zheng 	u8 *aml;
45995b482a8SLen Brown 	union acpi_parse_object *field;
4609ce81784SBob Moore 	union acpi_parse_object *arg = NULL;
46195b482a8SLen Brown 	u16 opcode;
46295b482a8SLen Brown 	u32 name;
4639ce81784SBob Moore 	u8 access_type;
4649ce81784SBob Moore 	u8 access_attribute;
4659ce81784SBob Moore 	u8 access_length;
4669ce81784SBob Moore 	u32 pkg_length;
4679ce81784SBob Moore 	u8 *pkg_end;
4689ce81784SBob Moore 	u32 buffer_length;
46995b482a8SLen Brown 
47095b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ps_get_next_field);
47195b482a8SLen Brown 
4729cf7adecSBob Moore 	ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
473950a429cSLv Zheng 	aml = parser_state->aml;
4749ce81784SBob Moore 
47595b482a8SLen Brown 	/* Determine field type */
47695b482a8SLen Brown 
47795b482a8SLen Brown 	switch (ACPI_GET8(parser_state->aml)) {
4789ce81784SBob Moore 	case AML_FIELD_OFFSET_OP:
47995b482a8SLen Brown 
48095b482a8SLen Brown 		opcode = AML_INT_RESERVEDFIELD_OP;
48195b482a8SLen Brown 		parser_state->aml++;
48295b482a8SLen Brown 		break;
48395b482a8SLen Brown 
4849ce81784SBob Moore 	case AML_FIELD_ACCESS_OP:
48595b482a8SLen Brown 
48695b482a8SLen Brown 		opcode = AML_INT_ACCESSFIELD_OP;
48795b482a8SLen Brown 		parser_state->aml++;
48895b482a8SLen Brown 		break;
4899ce81784SBob Moore 
4909ce81784SBob Moore 	case AML_FIELD_CONNECTION_OP:
4919ce81784SBob Moore 
4929ce81784SBob Moore 		opcode = AML_INT_CONNECTION_OP;
4939ce81784SBob Moore 		parser_state->aml++;
4949ce81784SBob Moore 		break;
4959ce81784SBob Moore 
4969ce81784SBob Moore 	case AML_FIELD_EXT_ACCESS_OP:
4979ce81784SBob Moore 
4989ce81784SBob Moore 		opcode = AML_INT_EXTACCESSFIELD_OP;
4999ce81784SBob Moore 		parser_state->aml++;
5009ce81784SBob Moore 		break;
5019ce81784SBob Moore 
5029ce81784SBob Moore 	default:
5039ce81784SBob Moore 
5049ce81784SBob Moore 		opcode = AML_INT_NAMEDFIELD_OP;
5059ce81784SBob Moore 		break;
50695b482a8SLen Brown 	}
50795b482a8SLen Brown 
50895b482a8SLen Brown 	/* Allocate a new field op */
50995b482a8SLen Brown 
51062eb935bSLv Zheng 	field = acpi_ps_alloc_op(opcode, aml);
51195b482a8SLen Brown 	if (!field) {
51295b482a8SLen Brown 		return_PTR(NULL);
51395b482a8SLen Brown 	}
51495b482a8SLen Brown 
51595b482a8SLen Brown 	/* Decode the field type */
51695b482a8SLen Brown 
5179cf7adecSBob Moore 	ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
51895b482a8SLen Brown 	switch (opcode) {
51995b482a8SLen Brown 	case AML_INT_NAMEDFIELD_OP:
52095b482a8SLen Brown 
52195b482a8SLen Brown 		/* Get the 4-character name */
52295b482a8SLen Brown 
52395b482a8SLen Brown 		ACPI_MOVE_32_TO_32(&name, parser_state->aml);
52495b482a8SLen Brown 		acpi_ps_set_name(field, name);
52532786755SBob Moore 		parser_state->aml += ACPI_NAMESEG_SIZE;
52695b482a8SLen Brown 
5279cf7adecSBob Moore 		ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
5289cf7adecSBob Moore 
5299cf7adecSBob Moore #ifdef ACPI_ASL_COMPILER
5309cf7adecSBob Moore 		/*
5319cf7adecSBob Moore 		 * Because the package length isn't represented as a parse tree object,
5329cf7adecSBob Moore 		 * take comments surrounding this and add to the previously created
5339cf7adecSBob Moore 		 * parse node.
5349cf7adecSBob Moore 		 */
5359cf7adecSBob Moore 		if (field->common.inline_comment) {
5369cf7adecSBob Moore 			field->common.name_comment =
5379cf7adecSBob Moore 			    field->common.inline_comment;
5389cf7adecSBob Moore 		}
5399cf7adecSBob Moore 		field->common.inline_comment = acpi_gbl_current_inline_comment;
5409cf7adecSBob Moore 		acpi_gbl_current_inline_comment = NULL;
5419cf7adecSBob Moore #endif
5429cf7adecSBob Moore 
54395b482a8SLen Brown 		/* Get the length which is encoded as a package length */
54495b482a8SLen Brown 
54595b482a8SLen Brown 		field->common.value.size =
54695b482a8SLen Brown 		    acpi_ps_get_next_package_length(parser_state);
54795b482a8SLen Brown 		break;
54895b482a8SLen Brown 
54995b482a8SLen Brown 	case AML_INT_RESERVEDFIELD_OP:
55095b482a8SLen Brown 
55195b482a8SLen Brown 		/* Get the length which is encoded as a package length */
55295b482a8SLen Brown 
55395b482a8SLen Brown 		field->common.value.size =
55495b482a8SLen Brown 		    acpi_ps_get_next_package_length(parser_state);
55595b482a8SLen Brown 		break;
55695b482a8SLen Brown 
55795b482a8SLen Brown 	case AML_INT_ACCESSFIELD_OP:
5589ce81784SBob Moore 	case AML_INT_EXTACCESSFIELD_OP:
55995b482a8SLen Brown 
56095b482a8SLen Brown 		/*
56195b482a8SLen Brown 		 * Get access_type and access_attrib and merge into the field Op
5629ce81784SBob Moore 		 * access_type is first operand, access_attribute is second. stuff
5639ce81784SBob Moore 		 * these bytes into the node integer value for convenience.
56495b482a8SLen Brown 		 */
5659ce81784SBob Moore 
5669ce81784SBob Moore 		/* Get the two bytes (Type/Attribute) */
5679ce81784SBob Moore 
5689ce81784SBob Moore 		access_type = ACPI_GET8(parser_state->aml);
56995b482a8SLen Brown 		parser_state->aml++;
5709ce81784SBob Moore 		access_attribute = ACPI_GET8(parser_state->aml);
57195b482a8SLen Brown 		parser_state->aml++;
5729ce81784SBob Moore 
5739ce81784SBob Moore 		field->common.value.integer = (u8)access_type;
5749ce81784SBob Moore 		field->common.value.integer |= (u16)(access_attribute << 8);
5759ce81784SBob Moore 
5769ce81784SBob Moore 		/* This opcode has a third byte, access_length */
5779ce81784SBob Moore 
5789ce81784SBob Moore 		if (opcode == AML_INT_EXTACCESSFIELD_OP) {
5799ce81784SBob Moore 			access_length = ACPI_GET8(parser_state->aml);
5809ce81784SBob Moore 			parser_state->aml++;
5819ce81784SBob Moore 
5829ce81784SBob Moore 			field->common.value.integer |=
5839ce81784SBob Moore 			    (u32)(access_length << 16);
5849ce81784SBob Moore 		}
5859ce81784SBob Moore 		break;
5869ce81784SBob Moore 
5879ce81784SBob Moore 	case AML_INT_CONNECTION_OP:
5889ce81784SBob Moore 
5899ce81784SBob Moore 		/*
5909ce81784SBob Moore 		 * Argument for Connection operator can be either a Buffer
5919ce81784SBob Moore 		 * (resource descriptor), or a name_string.
5929ce81784SBob Moore 		 */
59362eb935bSLv Zheng 		aml = parser_state->aml;
5949ce81784SBob Moore 		if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
5959ce81784SBob Moore 			parser_state->aml++;
5969ce81784SBob Moore 
5979cf7adecSBob Moore 			ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
5989ce81784SBob Moore 			pkg_end = parser_state->aml;
5999ce81784SBob Moore 			pkg_length =
6009ce81784SBob Moore 			    acpi_ps_get_next_package_length(parser_state);
6019ce81784SBob Moore 			pkg_end += pkg_length;
6029ce81784SBob Moore 
6039cf7adecSBob Moore 			ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
6049ce81784SBob Moore 			if (parser_state->aml < pkg_end) {
6059ce81784SBob Moore 
6069ce81784SBob Moore 				/* Non-empty list */
6079ce81784SBob Moore 
60862eb935bSLv Zheng 				arg =
60962eb935bSLv Zheng 				    acpi_ps_alloc_op(AML_INT_BYTELIST_OP, aml);
6109ce81784SBob Moore 				if (!arg) {
6116af1c4fcSJesper Juhl 					acpi_ps_free_op(field);
6129ce81784SBob Moore 					return_PTR(NULL);
6139ce81784SBob Moore 				}
6149ce81784SBob Moore 
6159ce81784SBob Moore 				/* Get the actual buffer length argument */
6169ce81784SBob Moore 
6179ce81784SBob Moore 				opcode = ACPI_GET8(parser_state->aml);
6189ce81784SBob Moore 				parser_state->aml++;
6199ce81784SBob Moore 
6209cf7adecSBob Moore 				ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
6219ce81784SBob Moore 				switch (opcode) {
6229ce81784SBob Moore 				case AML_BYTE_OP:	/* AML_BYTEDATA_ARG */
6231d1ea1b7SChao Guan 
6249ce81784SBob Moore 					buffer_length =
6259ce81784SBob Moore 					    ACPI_GET8(parser_state->aml);
6269ce81784SBob Moore 					parser_state->aml += 1;
6279ce81784SBob Moore 					break;
6289ce81784SBob Moore 
6299ce81784SBob Moore 				case AML_WORD_OP:	/* AML_WORDDATA_ARG */
6301d1ea1b7SChao Guan 
6319ce81784SBob Moore 					buffer_length =
6329ce81784SBob Moore 					    ACPI_GET16(parser_state->aml);
6339ce81784SBob Moore 					parser_state->aml += 2;
6349ce81784SBob Moore 					break;
6359ce81784SBob Moore 
6369ce81784SBob Moore 				case AML_DWORD_OP:	/* AML_DWORDATA_ARG */
6371d1ea1b7SChao Guan 
6389ce81784SBob Moore 					buffer_length =
6399ce81784SBob Moore 					    ACPI_GET32(parser_state->aml);
6409ce81784SBob Moore 					parser_state->aml += 4;
6419ce81784SBob Moore 					break;
6429ce81784SBob Moore 
6439ce81784SBob Moore 				default:
6441d1ea1b7SChao Guan 
6459ce81784SBob Moore 					buffer_length = 0;
6469ce81784SBob Moore 					break;
6479ce81784SBob Moore 				}
6489ce81784SBob Moore 
6499ce81784SBob Moore 				/* Fill in bytelist data */
6509ce81784SBob Moore 
6519cf7adecSBob Moore 				ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
6529ce81784SBob Moore 				arg->named.value.size = buffer_length;
6539ce81784SBob Moore 				arg->named.data = parser_state->aml;
6549ce81784SBob Moore 			}
6559ce81784SBob Moore 
6569ce81784SBob Moore 			/* Skip to End of byte data */
6579ce81784SBob Moore 
6589ce81784SBob Moore 			parser_state->aml = pkg_end;
6599ce81784SBob Moore 		} else {
66062eb935bSLv Zheng 			arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, aml);
6619ce81784SBob Moore 			if (!arg) {
6626af1c4fcSJesper Juhl 				acpi_ps_free_op(field);
6639ce81784SBob Moore 				return_PTR(NULL);
6649ce81784SBob Moore 			}
6659ce81784SBob Moore 
6669ce81784SBob Moore 			/* Get the Namestring argument */
6679ce81784SBob Moore 
6689ce81784SBob Moore 			arg->common.value.name =
6699ce81784SBob Moore 			    acpi_ps_get_next_namestring(parser_state);
6709ce81784SBob Moore 		}
6719ce81784SBob Moore 
6729ce81784SBob Moore 		/* Link the buffer/namestring to parent (CONNECTION_OP) */
6739ce81784SBob Moore 
6749ce81784SBob Moore 		acpi_ps_append_arg(field, arg);
67595b482a8SLen Brown 		break;
67695b482a8SLen Brown 
67795b482a8SLen Brown 	default:
67895b482a8SLen Brown 
67995b482a8SLen Brown 		/* Opcode was set in previous switch */
68095b482a8SLen Brown 		break;
68195b482a8SLen Brown 	}
68295b482a8SLen Brown 
68395b482a8SLen Brown 	return_PTR(field);
68495b482a8SLen Brown }
68595b482a8SLen Brown 
68695b482a8SLen Brown /*******************************************************************************
68795b482a8SLen Brown  *
68895b482a8SLen Brown  * FUNCTION:    acpi_ps_get_next_arg
68995b482a8SLen Brown  *
69095b482a8SLen Brown  * PARAMETERS:  walk_state          - Current state
69195b482a8SLen Brown  *              parser_state        - Current parser state object
6920dda8851SBob Moore  *              arg_type            - The argument type (AML_*_ARG)
69395b482a8SLen Brown  *              return_arg          - Where the next arg is returned
69495b482a8SLen Brown  *
69595b482a8SLen Brown  * RETURN:      Status, and an op object containing the next argument.
69695b482a8SLen Brown  *
69795b482a8SLen Brown  * DESCRIPTION: Get next argument (including complex list arguments that require
69895b482a8SLen Brown  *              pushing the parser stack)
69995b482a8SLen Brown  *
70095b482a8SLen Brown  ******************************************************************************/
70195b482a8SLen Brown 
70295b482a8SLen Brown 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)70395b482a8SLen Brown acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
70495b482a8SLen Brown 		     struct acpi_parse_state *parser_state,
70595b482a8SLen Brown 		     u32 arg_type, union acpi_parse_object **return_arg)
70695b482a8SLen Brown {
70795b482a8SLen Brown 	union acpi_parse_object *arg = NULL;
70895b482a8SLen Brown 	union acpi_parse_object *prev = NULL;
70995b482a8SLen Brown 	union acpi_parse_object *field;
71095b482a8SLen Brown 	u32 subop;
71195b482a8SLen Brown 	acpi_status status = AE_OK;
71295b482a8SLen Brown 
71395b482a8SLen Brown 	ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
71495b482a8SLen Brown 
715ce87e09dSBob Moore 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
716ce87e09dSBob Moore 			  "Expected argument type ARGP: %s (%2.2X)\n",
717ce87e09dSBob Moore 			  acpi_ut_get_argument_type_name(arg_type), arg_type));
718ce87e09dSBob Moore 
71995b482a8SLen Brown 	switch (arg_type) {
72095b482a8SLen Brown 	case ARGP_BYTEDATA:
72195b482a8SLen Brown 	case ARGP_WORDDATA:
72295b482a8SLen Brown 	case ARGP_DWORDDATA:
72395b482a8SLen Brown 	case ARGP_CHARLIST:
72495b482a8SLen Brown 	case ARGP_NAME:
72595b482a8SLen Brown 	case ARGP_NAMESTRING:
72695b482a8SLen Brown 
72795b482a8SLen Brown 		/* Constants, strings, and namestrings are all the same size */
72895b482a8SLen Brown 
72962eb935bSLv Zheng 		arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml);
73095b482a8SLen Brown 		if (!arg) {
73195b482a8SLen Brown 			return_ACPI_STATUS(AE_NO_MEMORY);
73295b482a8SLen Brown 		}
7331fad8738SBob Moore 
73495b482a8SLen Brown 		acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
73595b482a8SLen Brown 		break;
73695b482a8SLen Brown 
73795b482a8SLen Brown 	case ARGP_PKGLENGTH:
73895b482a8SLen Brown 
73995b482a8SLen Brown 		/* Package length, nothing returned */
74095b482a8SLen Brown 
74195b482a8SLen Brown 		parser_state->pkg_end =
74295b482a8SLen Brown 		    acpi_ps_get_next_package_end(parser_state);
74395b482a8SLen Brown 		break;
74495b482a8SLen Brown 
74595b482a8SLen Brown 	case ARGP_FIELDLIST:
74695b482a8SLen Brown 
74795b482a8SLen Brown 		if (parser_state->aml < parser_state->pkg_end) {
74895b482a8SLen Brown 
74995b482a8SLen Brown 			/* Non-empty list */
75095b482a8SLen Brown 
75195b482a8SLen Brown 			while (parser_state->aml < parser_state->pkg_end) {
75295b482a8SLen Brown 				field = acpi_ps_get_next_field(parser_state);
75395b482a8SLen Brown 				if (!field) {
75495b482a8SLen Brown 					return_ACPI_STATUS(AE_NO_MEMORY);
75595b482a8SLen Brown 				}
75695b482a8SLen Brown 
75795b482a8SLen Brown 				if (prev) {
75895b482a8SLen Brown 					prev->common.next = field;
75995b482a8SLen Brown 				} else {
76095b482a8SLen Brown 					arg = field;
76195b482a8SLen Brown 				}
76295b482a8SLen Brown 				prev = field;
76395b482a8SLen Brown 			}
76495b482a8SLen Brown 
76595b482a8SLen Brown 			/* Skip to End of byte data */
76695b482a8SLen Brown 
76795b482a8SLen Brown 			parser_state->aml = parser_state->pkg_end;
76895b482a8SLen Brown 		}
76995b482a8SLen Brown 		break;
77095b482a8SLen Brown 
77195b482a8SLen Brown 	case ARGP_BYTELIST:
77295b482a8SLen Brown 
77395b482a8SLen Brown 		if (parser_state->aml < parser_state->pkg_end) {
77495b482a8SLen Brown 
77595b482a8SLen Brown 			/* Non-empty list */
77695b482a8SLen Brown 
77762eb935bSLv Zheng 			arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP,
77862eb935bSLv Zheng 					       parser_state->aml);
77995b482a8SLen Brown 			if (!arg) {
78095b482a8SLen Brown 				return_ACPI_STATUS(AE_NO_MEMORY);
78195b482a8SLen Brown 			}
78295b482a8SLen Brown 
78395b482a8SLen Brown 			/* Fill in bytelist data */
78495b482a8SLen Brown 
78595b482a8SLen Brown 			arg->common.value.size = (u32)
78695b482a8SLen Brown 			    ACPI_PTR_DIFF(parser_state->pkg_end,
78795b482a8SLen Brown 					  parser_state->aml);
78895b482a8SLen Brown 			arg->named.data = parser_state->aml;
78995b482a8SLen Brown 
79095b482a8SLen Brown 			/* Skip to End of byte data */
79195b482a8SLen Brown 
79295b482a8SLen Brown 			parser_state->aml = parser_state->pkg_end;
79395b482a8SLen Brown 		}
79495b482a8SLen Brown 		break;
79595b482a8SLen Brown 
79695b482a8SLen Brown 	case ARGP_SIMPLENAME:
797cca7a6eaSBob Moore 	case ARGP_NAME_OR_REF:
79895b482a8SLen Brown 
799ce87e09dSBob Moore 		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
800ce87e09dSBob Moore 				  "**** SimpleName/NameOrRef: %s (%2.2X)\n",
801ce87e09dSBob Moore 				  acpi_ut_get_argument_type_name(arg_type),
802ce87e09dSBob Moore 				  arg_type));
803ce87e09dSBob Moore 
80495b482a8SLen Brown 		subop = acpi_ps_peek_opcode(parser_state);
80595b482a8SLen Brown 		if (subop == 0 ||
80695b482a8SLen Brown 		    acpi_ps_is_leading_char(subop) ||
80704a81dceSBob Moore 		    ACPI_IS_ROOT_PREFIX(subop) ||
80804a81dceSBob Moore 		    ACPI_IS_PARENT_PREFIX(subop)) {
80995b482a8SLen Brown 
81095b482a8SLen Brown 			/* null_name or name_string */
81195b482a8SLen Brown 
81262eb935bSLv Zheng 			arg =
81362eb935bSLv Zheng 			    acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
81462eb935bSLv Zheng 					     parser_state->aml);
81595b482a8SLen Brown 			if (!arg) {
81695b482a8SLen Brown 				return_ACPI_STATUS(AE_NO_MEMORY);
81795b482a8SLen Brown 			}
81895b482a8SLen Brown 
81995b482a8SLen Brown 			status =
820ce87e09dSBob Moore 			    acpi_ps_get_next_namepath(walk_state, parser_state,
821ce87e09dSBob Moore 						      arg,
82289438f96SBob Moore 						      ACPI_NOT_METHOD_CALL);
823ce87e09dSBob Moore 		} else {
824ce87e09dSBob Moore 			/* Single complex argument, nothing returned */
825ce87e09dSBob Moore 
826ce87e09dSBob Moore 			walk_state->arg_count = 1;
82795b482a8SLen Brown 		}
828ce87e09dSBob Moore 		break;
829ce87e09dSBob Moore 
830ce87e09dSBob Moore 	case ARGP_TARGET:
831ce87e09dSBob Moore 	case ARGP_SUPERNAME:
832ce87e09dSBob Moore 
833ce87e09dSBob Moore 		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
834ce87e09dSBob Moore 				  "**** Target/Supername: %s (%2.2X)\n",
835ce87e09dSBob Moore 				  acpi_ut_get_argument_type_name(arg_type),
836ce87e09dSBob Moore 				  arg_type));
837ce87e09dSBob Moore 
838ce87e09dSBob Moore 		subop = acpi_ps_peek_opcode(parser_state);
8399a947291SBob Moore 		if (subop == 0 ||
8409a947291SBob Moore 		    acpi_ps_is_leading_char(subop) ||
8419a947291SBob Moore 		    ACPI_IS_ROOT_PREFIX(subop) ||
8429a947291SBob Moore 		    ACPI_IS_PARENT_PREFIX(subop)) {
843ce87e09dSBob Moore 
844ce87e09dSBob Moore 			/* NULL target (zero). Convert to a NULL namepath */
845ce87e09dSBob Moore 
846ce87e09dSBob Moore 			arg =
847ce87e09dSBob Moore 			    acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
848ce87e09dSBob Moore 					     parser_state->aml);
849ce87e09dSBob Moore 			if (!arg) {
850ce87e09dSBob Moore 				return_ACPI_STATUS(AE_NO_MEMORY);
851ce87e09dSBob Moore 			}
852ce87e09dSBob Moore 
853ce87e09dSBob Moore 			status =
854ce87e09dSBob Moore 			    acpi_ps_get_next_namepath(walk_state, parser_state,
855ce87e09dSBob Moore 						      arg,
856ce87e09dSBob Moore 						      ACPI_POSSIBLE_METHOD_CALL);
8579a947291SBob Moore 
8589a947291SBob Moore 			if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
8591c29c372SBob Moore 
8601c29c372SBob Moore 				/* Free method call op and corresponding namestring sub-ob */
8611c29c372SBob Moore 
8621c29c372SBob Moore 				acpi_ps_free_op(arg->common.value.arg);
8639a947291SBob Moore 				acpi_ps_free_op(arg);
8649a947291SBob Moore 				arg = NULL;
8659a947291SBob Moore 				walk_state->arg_count = 1;
8669a947291SBob Moore 			}
86795b482a8SLen Brown 		} else {
86895b482a8SLen Brown 			/* Single complex argument, nothing returned */
86995b482a8SLen Brown 
87095b482a8SLen Brown 			walk_state->arg_count = 1;
87195b482a8SLen Brown 		}
87295b482a8SLen Brown 		break;
87395b482a8SLen Brown 
87495b482a8SLen Brown 	case ARGP_DATAOBJ:
87595b482a8SLen Brown 	case ARGP_TERMARG:
87695b482a8SLen Brown 
877ce87e09dSBob Moore 		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
878ce87e09dSBob Moore 				  "**** TermArg/DataObj: %s (%2.2X)\n",
879ce87e09dSBob Moore 				  acpi_ut_get_argument_type_name(arg_type),
880ce87e09dSBob Moore 				  arg_type));
881ce87e09dSBob Moore 
88295b482a8SLen Brown 		/* Single complex argument, nothing returned */
88395b482a8SLen Brown 
88495b482a8SLen Brown 		walk_state->arg_count = 1;
88595b482a8SLen Brown 		break;
88695b482a8SLen Brown 
88795b482a8SLen Brown 	case ARGP_DATAOBJLIST:
88895b482a8SLen Brown 	case ARGP_TERMLIST:
88995b482a8SLen Brown 	case ARGP_OBJLIST:
89095b482a8SLen Brown 
89195b482a8SLen Brown 		if (parser_state->aml < parser_state->pkg_end) {
89295b482a8SLen Brown 
89395b482a8SLen Brown 			/* Non-empty list of variable arguments, nothing returned */
89495b482a8SLen Brown 
89595b482a8SLen Brown 			walk_state->arg_count = ACPI_VAR_ARGS;
89695b482a8SLen Brown 		}
89795b482a8SLen Brown 		break;
89895b482a8SLen Brown 
89995b482a8SLen Brown 	default:
90095b482a8SLen Brown 
901f6a22b0bSBob Moore 		ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type));
90295b482a8SLen Brown 		status = AE_AML_OPERAND_TYPE;
90395b482a8SLen Brown 		break;
90495b482a8SLen Brown 	}
90595b482a8SLen Brown 
90695b482a8SLen Brown 	*return_arg = arg;
90795b482a8SLen Brown 	return_ACPI_STATUS(status);
90895b482a8SLen Brown }
909