xref: /linux/drivers/acpi/acpica/psargs.c (revision 66da65005aa819e0b8d3a08f5ec1491b7690cb67)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
21da177e4SLinus Torvalds /******************************************************************************
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Module Name: psargs - Parse AML opcode arguments
51da177e4SLinus Torvalds  *
6487ea80aSBob Moore  * Copyright (C) 2000 - 2022, Intel Corp.
71da177e4SLinus Torvalds  *
895857638SErik Schmauss  *****************************************************************************/
91da177e4SLinus Torvalds 
101da177e4SLinus Torvalds #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"
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds #define _COMPONENT          ACPI_PARSER
191da177e4SLinus Torvalds ACPI_MODULE_NAME("psargs")
201da177e4SLinus Torvalds 
2144f6c012SRobert Moore /* Local prototypes */
2244f6c012SRobert Moore static u32
234be44fcdSLen Brown acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
2444f6c012SRobert Moore 
254be44fcdSLen Brown static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
264be44fcdSLen Brown 						       *parser_state);
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds /*******************************************************************************
291da177e4SLinus Torvalds  *
301da177e4SLinus Torvalds  * FUNCTION:    acpi_ps_get_next_package_length
311da177e4SLinus Torvalds  *
321da177e4SLinus Torvalds  * PARAMETERS:  parser_state        - Current parser state object
331da177e4SLinus Torvalds  *
341da177e4SLinus Torvalds  * RETURN:      Decoded package length. On completion, the AML pointer points
351da177e4SLinus Torvalds  *              past the length byte or bytes.
361da177e4SLinus Torvalds  *
37c51a4de8SBob Moore  * DESCRIPTION: Decode and return a package length field.
38c51a4de8SBob Moore  *              Note: Largest package length is 28 bits, from ACPI specification
391da177e4SLinus Torvalds  *
401da177e4SLinus Torvalds  ******************************************************************************/
411da177e4SLinus Torvalds 
4244f6c012SRobert Moore static u32
434be44fcdSLen Brown acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
441da177e4SLinus Torvalds {
45c51a4de8SBob Moore 	u8 *aml = parser_state->aml;
46c51a4de8SBob Moore 	u32 package_length = 0;
4767a119f9SBob Moore 	u32 byte_count;
48c51a4de8SBob Moore 	u8 byte_zero_mask = 0x3F;	/* Default [0:5] */
491da177e4SLinus Torvalds 
50b229cf92SBob Moore 	ACPI_FUNCTION_TRACE(ps_get_next_package_length);
511da177e4SLinus Torvalds 
52c51a4de8SBob Moore 	/*
53c51a4de8SBob Moore 	 * Byte 0 bits [6:7] contain the number of additional bytes
54c51a4de8SBob Moore 	 * used to encode the package length, either 0,1,2, or 3
55c51a4de8SBob Moore 	 */
56c51a4de8SBob Moore 	byte_count = (aml[0] >> 6);
5767a119f9SBob Moore 	parser_state->aml += ((acpi_size)byte_count + 1);
581da177e4SLinus Torvalds 
59c51a4de8SBob Moore 	/* Get bytes 3, 2, 1 as needed */
601da177e4SLinus Torvalds 
61c51a4de8SBob Moore 	while (byte_count) {
62c51a4de8SBob Moore 		/*
63c51a4de8SBob Moore 		 * Final bit positions for the package length bytes:
64c51a4de8SBob Moore 		 *      Byte3->[20:27]
65c51a4de8SBob Moore 		 *      Byte2->[12:19]
66c51a4de8SBob Moore 		 *      Byte1->[04:11]
67c51a4de8SBob Moore 		 *      Byte0->[00:03]
68c51a4de8SBob Moore 		 */
69c51a4de8SBob Moore 		package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
701da177e4SLinus Torvalds 
71c51a4de8SBob Moore 		byte_zero_mask = 0x0F;	/* Use bits [0:3] of byte 0 */
72c51a4de8SBob Moore 		byte_count--;
731da177e4SLinus Torvalds 	}
741da177e4SLinus Torvalds 
75c51a4de8SBob Moore 	/* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
76c51a4de8SBob Moore 
77c51a4de8SBob Moore 	package_length |= (aml[0] & byte_zero_mask);
78fd1af712SBob Moore 	return_UINT32(package_length);
791da177e4SLinus Torvalds }
801da177e4SLinus Torvalds 
811da177e4SLinus Torvalds /*******************************************************************************
821da177e4SLinus Torvalds  *
831da177e4SLinus Torvalds  * FUNCTION:    acpi_ps_get_next_package_end
841da177e4SLinus Torvalds  *
851da177e4SLinus Torvalds  * PARAMETERS:  parser_state        - Current parser state object
861da177e4SLinus Torvalds  *
871da177e4SLinus Torvalds  * RETURN:      Pointer to end-of-package +1
881da177e4SLinus Torvalds  *
891da177e4SLinus Torvalds  * DESCRIPTION: Get next package length and return a pointer past the end of
901da177e4SLinus Torvalds  *              the package. Consumes the package length field
911da177e4SLinus Torvalds  *
921da177e4SLinus Torvalds  ******************************************************************************/
931da177e4SLinus Torvalds 
944be44fcdSLen Brown u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
951da177e4SLinus Torvalds {
961da177e4SLinus Torvalds 	u8 *start = parser_state->aml;
97c51a4de8SBob Moore 	u32 package_length;
981da177e4SLinus Torvalds 
99b229cf92SBob Moore 	ACPI_FUNCTION_TRACE(ps_get_next_package_end);
1001da177e4SLinus Torvalds 
101c51a4de8SBob Moore 	/* Function below updates parser_state->Aml */
1021da177e4SLinus Torvalds 
103c51a4de8SBob Moore 	package_length = acpi_ps_get_next_package_length(parser_state);
1041da177e4SLinus Torvalds 
105c51a4de8SBob Moore 	return_PTR(start + package_length);	/* end of package */
1061da177e4SLinus Torvalds }
1071da177e4SLinus Torvalds 
1081da177e4SLinus Torvalds /*******************************************************************************
1091da177e4SLinus Torvalds  *
1101da177e4SLinus Torvalds  * FUNCTION:    acpi_ps_get_next_namestring
1111da177e4SLinus Torvalds  *
1121da177e4SLinus Torvalds  * PARAMETERS:  parser_state        - Current parser state object
1131da177e4SLinus Torvalds  *
1141da177e4SLinus Torvalds  * RETURN:      Pointer to the start of the name string (pointer points into
1151da177e4SLinus Torvalds  *              the AML.
1161da177e4SLinus Torvalds  *
1171da177e4SLinus Torvalds  * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
1181da177e4SLinus Torvalds  *              prefix characters. Set parser state to point past the string.
1191da177e4SLinus Torvalds  *              (Name is consumed from the AML.)
1201da177e4SLinus Torvalds  *
1211da177e4SLinus Torvalds  ******************************************************************************/
1221da177e4SLinus Torvalds 
1234be44fcdSLen Brown char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
1241da177e4SLinus Torvalds {
1251da177e4SLinus Torvalds 	u8 *start = parser_state->aml;
1261da177e4SLinus Torvalds 	u8 *end = parser_state->aml;
1271da177e4SLinus Torvalds 
128b229cf92SBob Moore 	ACPI_FUNCTION_TRACE(ps_get_next_namestring);
1291da177e4SLinus Torvalds 
130c51a4de8SBob Moore 	/* Point past any namestring prefix characters (backslash or carat) */
1311da177e4SLinus Torvalds 
13204a81dceSBob Moore 	while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) {
1331da177e4SLinus Torvalds 		end++;
1341da177e4SLinus Torvalds 	}
1351da177e4SLinus Torvalds 
136c51a4de8SBob Moore 	/* Decode the path prefix character */
1371da177e4SLinus Torvalds 
138c51a4de8SBob Moore 	switch (*end) {
1391da177e4SLinus Torvalds 	case 0:
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 		/* null_name */
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds 		if (end == start) {
1441da177e4SLinus Torvalds 			start = NULL;
1451da177e4SLinus Torvalds 		}
1461da177e4SLinus Torvalds 		end++;
1471da177e4SLinus Torvalds 		break;
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds 	case AML_DUAL_NAME_PREFIX:
1501da177e4SLinus Torvalds 
1511da177e4SLinus Torvalds 		/* Two name segments */
1521da177e4SLinus Torvalds 
15332786755SBob Moore 		end += 1 + (2 * ACPI_NAMESEG_SIZE);
1541da177e4SLinus Torvalds 		break;
1551da177e4SLinus Torvalds 
1569ff5a21aSBob Moore 	case AML_MULTI_NAME_PREFIX:
1571da177e4SLinus Torvalds 
158c51a4de8SBob Moore 		/* Multiple name segments, 4 chars each, count in next byte */
1591da177e4SLinus Torvalds 
16032786755SBob Moore 		end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE);
1611da177e4SLinus Torvalds 		break;
1621da177e4SLinus Torvalds 
1631da177e4SLinus Torvalds 	default:
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds 		/* Single name segment */
1661da177e4SLinus Torvalds 
16732786755SBob Moore 		end += ACPI_NAMESEG_SIZE;
1681da177e4SLinus Torvalds 		break;
1691da177e4SLinus Torvalds 	}
1701da177e4SLinus Torvalds 
171c51a4de8SBob Moore 	parser_state->aml = end;
1721da177e4SLinus Torvalds 	return_PTR((char *)start);
1731da177e4SLinus Torvalds }
1741da177e4SLinus Torvalds 
1751da177e4SLinus Torvalds /*******************************************************************************
1761da177e4SLinus Torvalds  *
1771da177e4SLinus Torvalds  * FUNCTION:    acpi_ps_get_next_namepath
1781da177e4SLinus Torvalds  *
1791da177e4SLinus Torvalds  * PARAMETERS:  parser_state        - Current parser state object
180ba494beeSBob Moore  *              arg                 - Where the namepath will be stored
1811da177e4SLinus Torvalds  *              arg_count           - If the namepath points to a control method
1821da177e4SLinus Torvalds  *                                    the method's argument is returned here.
183defba1d8SBob Moore  *              possible_method_call - Whether the namepath can possibly be the
1841da177e4SLinus Torvalds  *                                    start of a method call
1851da177e4SLinus Torvalds  *
1861da177e4SLinus Torvalds  * RETURN:      Status
1871da177e4SLinus Torvalds  *
1881da177e4SLinus Torvalds  * DESCRIPTION: Get next name (if method call, return # of required args).
1891da177e4SLinus Torvalds  *              Names are looked up in the internal namespace to determine
1901da177e4SLinus Torvalds  *              if the name represents a control method. If a method
1911da177e4SLinus Torvalds  *              is found, the number of arguments to the method is returned.
1921da177e4SLinus Torvalds  *              This information is critical for parsing to continue correctly.
1931da177e4SLinus Torvalds  *
1941da177e4SLinus Torvalds  ******************************************************************************/
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds acpi_status
1974be44fcdSLen Brown acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
1981da177e4SLinus Torvalds 			  struct acpi_parse_state *parser_state,
199defba1d8SBob Moore 			  union acpi_parse_object *arg, u8 possible_method_call)
2001da177e4SLinus Torvalds {
20114808822SLin Ming 	acpi_status status;
2021da177e4SLinus Torvalds 	char *path;
2031da177e4SLinus Torvalds 	union acpi_parse_object *name_op;
2041da177e4SLinus Torvalds 	union acpi_operand_object *method_desc;
2051da177e4SLinus Torvalds 	struct acpi_namespace_node *node;
206bc7a36abSLin Ming 	u8 *start = parser_state->aml;
2071da177e4SLinus Torvalds 
208b229cf92SBob Moore 	ACPI_FUNCTION_TRACE(ps_get_next_namepath);
2091da177e4SLinus Torvalds 
2101da177e4SLinus Torvalds 	path = acpi_ps_get_next_namestring(parser_state);
211defba1d8SBob Moore 	acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
2121da177e4SLinus Torvalds 
213defba1d8SBob Moore 	/* Null path case is allowed, just exit */
2141da177e4SLinus Torvalds 
215defba1d8SBob Moore 	if (!path) {
216defba1d8SBob Moore 		arg->common.value.name = path;
217defba1d8SBob Moore 		return_ACPI_STATUS(AE_OK);
218defba1d8SBob Moore 	}
219defba1d8SBob Moore 
2201da177e4SLinus Torvalds 	/*
22114808822SLin Ming 	 * Lookup the name in the internal namespace, starting with the current
22214808822SLin Ming 	 * scope. We don't want to add anything new to the namespace here,
22314808822SLin Ming 	 * however, so we use MODE_EXECUTE.
224defba1d8SBob Moore 	 * Allow searching of the parent tree, but don't open a new scope -
225defba1d8SBob Moore 	 * we just want to lookup the object (must be mode EXECUTE to perform
226defba1d8SBob Moore 	 * the upsearch)
2271da177e4SLinus Torvalds 	 */
22814808822SLin Ming 	status = acpi_ns_lookup(walk_state->scope_info, path,
22914808822SLin Ming 				ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
230defba1d8SBob Moore 				ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
231defba1d8SBob Moore 				NULL, &node);
232defba1d8SBob Moore 
233defba1d8SBob Moore 	/*
234defba1d8SBob Moore 	 * If this name is a control method invocation, we must
235defba1d8SBob Moore 	 * setup the method call
236defba1d8SBob Moore 	 */
237defba1d8SBob Moore 	if (ACPI_SUCCESS(status) &&
238defba1d8SBob Moore 	    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 		}
25352fc0b02SBob Moore 
25444f6c012SRobert Moore 		/* This name is actually a control method invocation */
25544f6c012SRobert Moore 
2561da177e4SLinus Torvalds 		method_desc = acpi_ns_get_attached_object(node);
2571da177e4SLinus Torvalds 		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));
2601da177e4SLinus Torvalds 
26162eb935bSLv Zheng 		name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start);
2621da177e4SLinus Torvalds 		if (!name_op) {
2631da177e4SLinus Torvalds 			return_ACPI_STATUS(AE_NO_MEMORY);
2641da177e4SLinus Torvalds 		}
2651da177e4SLinus Torvalds 
266defba1d8SBob Moore 		/* Change Arg into a METHOD CALL and attach name to it */
2671da177e4SLinus Torvalds 
2681da177e4SLinus Torvalds 		acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
2691da177e4SLinus Torvalds 		name_op->common.value.name = path;
2701da177e4SLinus Torvalds 
2711da177e4SLinus Torvalds 		/* Point METHODCALL/NAME to the METHOD Node */
2721da177e4SLinus Torvalds 
2731da177e4SLinus Torvalds 		name_op->common.node = node;
2741da177e4SLinus Torvalds 		acpi_ps_append_arg(arg, name_op);
2751da177e4SLinus Torvalds 
2761da177e4SLinus Torvalds 		if (!method_desc) {
277b8e4d893SBob Moore 			ACPI_ERROR((AE_INFO,
278b8e4d893SBob Moore 				    "Control Method %p has no attached object",
279b8e4d893SBob Moore 				    node));
2801da177e4SLinus Torvalds 			return_ACPI_STATUS(AE_AML_INTERNAL);
2811da177e4SLinus Torvalds 		}
2821da177e4SLinus Torvalds 
2831da177e4SLinus Torvalds 		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
2841da177e4SLinus Torvalds 				  "Control Method - %p Args %X\n",
285defba1d8SBob Moore 				  node, method_desc->method.param_count));
2861da177e4SLinus Torvalds 
2871da177e4SLinus Torvalds 		/* Get the number of arguments to expect */
2881da177e4SLinus Torvalds 
289defba1d8SBob Moore 		walk_state->arg_count = method_desc->method.param_count;
2901da177e4SLinus Torvalds 		return_ACPI_STATUS(AE_OK);
2911da177e4SLinus Torvalds 	}
2921da177e4SLinus Torvalds 
2931da177e4SLinus Torvalds 	/*
294defba1d8SBob Moore 	 * Special handling if the name was not found during the lookup -
295defba1d8SBob Moore 	 * some not_found cases are allowed
2961da177e4SLinus Torvalds 	 */
297defba1d8SBob Moore 	if (status == AE_NOT_FOUND) {
29852fc0b02SBob Moore 
299defba1d8SBob Moore 		/* 1) not_found is ok during load pass 1/2 (allow forward references) */
300defba1d8SBob Moore 
301defba1d8SBob Moore 		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
302defba1d8SBob Moore 		    ACPI_PARSE_EXECUTE) {
303defba1d8SBob Moore 			status = AE_OK;
3041da177e4SLinus Torvalds 		}
3051da177e4SLinus Torvalds 
306defba1d8SBob Moore 		/* 2) not_found during a cond_ref_of(x) is ok by definition */
3071da177e4SLinus Torvalds 
308defba1d8SBob Moore 		else if (walk_state->op->common.aml_opcode ==
3099ff5a21aSBob Moore 			 AML_CONDITIONAL_REF_OF_OP) {
310defba1d8SBob Moore 			status = AE_OK;
311defba1d8SBob Moore 		}
312defba1d8SBob Moore 
3131da177e4SLinus Torvalds 		/*
314defba1d8SBob Moore 		 * 3) not_found while building a Package is ok at this point, we
315defba1d8SBob Moore 		 * may flag as an error later if slack mode is not enabled.
316defba1d8SBob Moore 		 * (Some ASL code depends on allowing this behavior)
3171da177e4SLinus Torvalds 		 */
318defba1d8SBob Moore 		else if ((arg->common.parent) &&
319defba1d8SBob Moore 			 ((arg->common.parent->common.aml_opcode ==
320defba1d8SBob Moore 			   AML_PACKAGE_OP)
321defba1d8SBob Moore 			  || (arg->common.parent->common.aml_opcode ==
3229ff5a21aSBob Moore 			      AML_VARIABLE_PACKAGE_OP))) {
3231da177e4SLinus Torvalds 			status = AE_OK;
3241da177e4SLinus Torvalds 		}
3251da177e4SLinus Torvalds 	}
326defba1d8SBob Moore 
327defba1d8SBob Moore 	/* Final exception check (may have been changed from code above) */
328defba1d8SBob Moore 
329defba1d8SBob Moore 	if (ACPI_FAILURE(status)) {
33016ccf829SBob Moore 		ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status);
331defba1d8SBob Moore 
332defba1d8SBob Moore 		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
333defba1d8SBob Moore 		    ACPI_PARSE_EXECUTE) {
33452fc0b02SBob Moore 
335defba1d8SBob Moore 			/* Report a control method execution error */
336defba1d8SBob Moore 
337defba1d8SBob Moore 			status = acpi_ds_method_error(status, walk_state);
338defba1d8SBob Moore 		}
3391da177e4SLinus Torvalds 	}
3401da177e4SLinus Torvalds 
341defba1d8SBob Moore 	/* Save the namepath */
3421da177e4SLinus Torvalds 
343defba1d8SBob Moore 	arg->common.value.name = path;
3441da177e4SLinus Torvalds 	return_ACPI_STATUS(status);
3451da177e4SLinus Torvalds }
3461da177e4SLinus Torvalds 
3471da177e4SLinus Torvalds /*******************************************************************************
3481da177e4SLinus Torvalds  *
3491da177e4SLinus Torvalds  * FUNCTION:    acpi_ps_get_next_simple_arg
3501da177e4SLinus Torvalds  *
3511da177e4SLinus Torvalds  * PARAMETERS:  parser_state        - Current parser state object
3521da177e4SLinus Torvalds  *              arg_type            - The argument type (AML_*_ARG)
353ba494beeSBob Moore  *              arg                 - Where the argument is returned
3541da177e4SLinus Torvalds  *
3551da177e4SLinus Torvalds  * RETURN:      None
3561da177e4SLinus Torvalds  *
3571da177e4SLinus Torvalds  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
3581da177e4SLinus Torvalds  *
3591da177e4SLinus Torvalds  ******************************************************************************/
3601da177e4SLinus Torvalds 
3611da177e4SLinus Torvalds void
3624be44fcdSLen Brown acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
3634be44fcdSLen Brown 			    u32 arg_type, union acpi_parse_object *arg)
3641da177e4SLinus Torvalds {
365c51a4de8SBob Moore 	u32 length;
366c51a4de8SBob Moore 	u16 opcode;
367c51a4de8SBob Moore 	u8 *aml = parser_state->aml;
3681da177e4SLinus Torvalds 
369b229cf92SBob Moore 	ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
3701da177e4SLinus Torvalds 
3711da177e4SLinus Torvalds 	switch (arg_type) {
3721da177e4SLinus Torvalds 	case ARGP_BYTEDATA:
3731da177e4SLinus Torvalds 
374c51a4de8SBob Moore 		/* Get 1 byte from the AML stream */
375c51a4de8SBob Moore 
376c51a4de8SBob Moore 		opcode = AML_BYTE_OP;
3775df7e6cbSBob Moore 		arg->common.value.integer = (u64) *aml;
378c51a4de8SBob Moore 		length = 1;
3791da177e4SLinus Torvalds 		break;
3801da177e4SLinus Torvalds 
3811da177e4SLinus Torvalds 	case ARGP_WORDDATA:
3821da177e4SLinus Torvalds 
3831da177e4SLinus Torvalds 		/* Get 2 bytes from the AML stream */
3841da177e4SLinus Torvalds 
385c51a4de8SBob Moore 		opcode = AML_WORD_OP;
386c51a4de8SBob Moore 		ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
387c51a4de8SBob Moore 		length = 2;
3881da177e4SLinus Torvalds 		break;
3891da177e4SLinus Torvalds 
3901da177e4SLinus Torvalds 	case ARGP_DWORDDATA:
3911da177e4SLinus Torvalds 
3921da177e4SLinus Torvalds 		/* Get 4 bytes from the AML stream */
3931da177e4SLinus Torvalds 
394c51a4de8SBob Moore 		opcode = AML_DWORD_OP;
395c51a4de8SBob Moore 		ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
396c51a4de8SBob Moore 		length = 4;
3971da177e4SLinus Torvalds 		break;
3981da177e4SLinus Torvalds 
3991da177e4SLinus Torvalds 	case ARGP_QWORDDATA:
4001da177e4SLinus Torvalds 
4011da177e4SLinus Torvalds 		/* Get 8 bytes from the AML stream */
4021da177e4SLinus Torvalds 
403c51a4de8SBob Moore 		opcode = AML_QWORD_OP;
404c51a4de8SBob Moore 		ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
405c51a4de8SBob Moore 		length = 8;
4061da177e4SLinus Torvalds 		break;
4071da177e4SLinus Torvalds 
4081da177e4SLinus Torvalds 	case ARGP_CHARLIST:
4091da177e4SLinus Torvalds 
410c51a4de8SBob Moore 		/* Get a pointer to the string, point past the string */
4111da177e4SLinus Torvalds 
412c51a4de8SBob Moore 		opcode = AML_STRING_OP;
413c51a4de8SBob Moore 		arg->common.value.string = ACPI_CAST_PTR(char, aml);
414c51a4de8SBob Moore 
415c51a4de8SBob Moore 		/* Find the null terminator */
416c51a4de8SBob Moore 
417c51a4de8SBob Moore 		length = 0;
418c51a4de8SBob Moore 		while (aml[length]) {
419c51a4de8SBob Moore 			length++;
4201da177e4SLinus Torvalds 		}
421c51a4de8SBob Moore 		length++;
4221da177e4SLinus Torvalds 		break;
4231da177e4SLinus Torvalds 
4241da177e4SLinus Torvalds 	case ARGP_NAME:
4251da177e4SLinus Torvalds 	case ARGP_NAMESTRING:
4261da177e4SLinus Torvalds 
4271da177e4SLinus Torvalds 		acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
4284be44fcdSLen Brown 		arg->common.value.name =
4294be44fcdSLen Brown 		    acpi_ps_get_next_namestring(parser_state);
430c51a4de8SBob Moore 		return_VOID;
4311da177e4SLinus Torvalds 
4321da177e4SLinus Torvalds 	default:
4331da177e4SLinus Torvalds 
434f6a22b0bSBob Moore 		ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type));
435c51a4de8SBob Moore 		return_VOID;
4361da177e4SLinus Torvalds 	}
4371da177e4SLinus Torvalds 
438c51a4de8SBob Moore 	acpi_ps_init_op(arg, opcode);
439c51a4de8SBob Moore 	parser_state->aml += length;
4401da177e4SLinus Torvalds 	return_VOID;
4411da177e4SLinus Torvalds }
4421da177e4SLinus Torvalds 
4431da177e4SLinus Torvalds /*******************************************************************************
4441da177e4SLinus Torvalds  *
4451da177e4SLinus Torvalds  * FUNCTION:    acpi_ps_get_next_field
4461da177e4SLinus Torvalds  *
4471da177e4SLinus Torvalds  * PARAMETERS:  parser_state        - Current parser state object
4481da177e4SLinus Torvalds  *
4491da177e4SLinus Torvalds  * RETURN:      A newly allocated FIELD op
4501da177e4SLinus Torvalds  *
4511da177e4SLinus Torvalds  * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
4521da177e4SLinus Torvalds  *
4531da177e4SLinus Torvalds  ******************************************************************************/
4541da177e4SLinus Torvalds 
4554be44fcdSLen Brown static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
4564be44fcdSLen Brown 						       *parser_state)
4571da177e4SLinus Torvalds {
458950a429cSLv Zheng 	u8 *aml;
4591da177e4SLinus Torvalds 	union acpi_parse_object *field;
4609ce81784SBob Moore 	union acpi_parse_object *arg = NULL;
4611da177e4SLinus Torvalds 	u16 opcode;
4621da177e4SLinus Torvalds 	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;
4691da177e4SLinus Torvalds 
470b229cf92SBob Moore 	ACPI_FUNCTION_TRACE(ps_get_next_field);
4711da177e4SLinus Torvalds 
4729cf7adecSBob Moore 	ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
473950a429cSLv Zheng 	aml = parser_state->aml;
4749ce81784SBob Moore 
47544f6c012SRobert Moore 	/* Determine field type */
4761da177e4SLinus Torvalds 
4771da177e4SLinus Torvalds 	switch (ACPI_GET8(parser_state->aml)) {
4789ce81784SBob Moore 	case AML_FIELD_OFFSET_OP:
4791da177e4SLinus Torvalds 
4801da177e4SLinus Torvalds 		opcode = AML_INT_RESERVEDFIELD_OP;
4811da177e4SLinus Torvalds 		parser_state->aml++;
4821da177e4SLinus Torvalds 		break;
4831da177e4SLinus Torvalds 
4849ce81784SBob Moore 	case AML_FIELD_ACCESS_OP:
4851da177e4SLinus Torvalds 
4861da177e4SLinus Torvalds 		opcode = AML_INT_ACCESSFIELD_OP;
4871da177e4SLinus Torvalds 		parser_state->aml++;
4881da177e4SLinus Torvalds 		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;
5061da177e4SLinus Torvalds 	}
5071da177e4SLinus Torvalds 
5081da177e4SLinus Torvalds 	/* Allocate a new field op */
5091da177e4SLinus Torvalds 
51062eb935bSLv Zheng 	field = acpi_ps_alloc_op(opcode, aml);
5111da177e4SLinus Torvalds 	if (!field) {
5121da177e4SLinus Torvalds 		return_PTR(NULL);
5131da177e4SLinus Torvalds 	}
5141da177e4SLinus Torvalds 
5151da177e4SLinus Torvalds 	/* Decode the field type */
5161da177e4SLinus Torvalds 
5179cf7adecSBob Moore 	ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
5181da177e4SLinus Torvalds 	switch (opcode) {
5191da177e4SLinus Torvalds 	case AML_INT_NAMEDFIELD_OP:
5201da177e4SLinus Torvalds 
5211da177e4SLinus Torvalds 		/* Get the 4-character name */
5221da177e4SLinus Torvalds 
5231da177e4SLinus Torvalds 		ACPI_MOVE_32_TO_32(&name, parser_state->aml);
5241da177e4SLinus Torvalds 		acpi_ps_set_name(field, name);
52532786755SBob Moore 		parser_state->aml += ACPI_NAMESEG_SIZE;
5261da177e4SLinus Torvalds 
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 
5431da177e4SLinus Torvalds 		/* Get the length which is encoded as a package length */
5441da177e4SLinus Torvalds 
5454be44fcdSLen Brown 		field->common.value.size =
5464be44fcdSLen Brown 		    acpi_ps_get_next_package_length(parser_state);
5471da177e4SLinus Torvalds 		break;
5481da177e4SLinus Torvalds 
5491da177e4SLinus Torvalds 	case AML_INT_RESERVEDFIELD_OP:
5501da177e4SLinus Torvalds 
5511da177e4SLinus Torvalds 		/* Get the length which is encoded as a package length */
5521da177e4SLinus Torvalds 
5534be44fcdSLen Brown 		field->common.value.size =
5544be44fcdSLen Brown 		    acpi_ps_get_next_package_length(parser_state);
5551da177e4SLinus Torvalds 		break;
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds 	case AML_INT_ACCESSFIELD_OP:
5589ce81784SBob Moore 	case AML_INT_EXTACCESSFIELD_OP:
5591da177e4SLinus Torvalds 
5601da177e4SLinus Torvalds 		/*
5611da177e4SLinus Torvalds 		 * 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.
5641da177e4SLinus Torvalds 		 */
5659ce81784SBob Moore 
5669ce81784SBob Moore 		/* Get the two bytes (Type/Attribute) */
5679ce81784SBob Moore 
5689ce81784SBob Moore 		access_type = ACPI_GET8(parser_state->aml);
5691da177e4SLinus Torvalds 		parser_state->aml++;
5709ce81784SBob Moore 		access_attribute = ACPI_GET8(parser_state->aml);
5711da177e4SLinus Torvalds 		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);
6751da177e4SLinus Torvalds 		break;
6761da177e4SLinus Torvalds 
6771da177e4SLinus Torvalds 	default:
6781da177e4SLinus Torvalds 
6791da177e4SLinus Torvalds 		/* Opcode was set in previous switch */
6801da177e4SLinus Torvalds 		break;
6811da177e4SLinus Torvalds 	}
6821da177e4SLinus Torvalds 
6831da177e4SLinus Torvalds 	return_PTR(field);
6841da177e4SLinus Torvalds }
6851da177e4SLinus Torvalds 
6861da177e4SLinus Torvalds /*******************************************************************************
6871da177e4SLinus Torvalds  *
6881da177e4SLinus Torvalds  * FUNCTION:    acpi_ps_get_next_arg
6891da177e4SLinus Torvalds  *
69044f6c012SRobert Moore  * PARAMETERS:  walk_state          - Current state
69144f6c012SRobert Moore  *              parser_state        - Current parser state object
6920dda8851SBob Moore  *              arg_type            - The argument type (AML_*_ARG)
69344f6c012SRobert Moore  *              return_arg          - Where the next arg is returned
6941da177e4SLinus Torvalds  *
6951da177e4SLinus Torvalds  * RETURN:      Status, and an op object containing the next argument.
6961da177e4SLinus Torvalds  *
6971da177e4SLinus Torvalds  * DESCRIPTION: Get next argument (including complex list arguments that require
6981da177e4SLinus Torvalds  *              pushing the parser stack)
6991da177e4SLinus Torvalds  *
7001da177e4SLinus Torvalds  ******************************************************************************/
7011da177e4SLinus Torvalds 
7021da177e4SLinus Torvalds acpi_status
7034be44fcdSLen Brown acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
7041da177e4SLinus Torvalds 		     struct acpi_parse_state *parser_state,
7054be44fcdSLen Brown 		     u32 arg_type, union acpi_parse_object **return_arg)
7061da177e4SLinus Torvalds {
7071da177e4SLinus Torvalds 	union acpi_parse_object *arg = NULL;
7081da177e4SLinus Torvalds 	union acpi_parse_object *prev = NULL;
7091da177e4SLinus Torvalds 	union acpi_parse_object *field;
7101da177e4SLinus Torvalds 	u32 subop;
7111da177e4SLinus Torvalds 	acpi_status status = AE_OK;
7121da177e4SLinus Torvalds 
713b229cf92SBob Moore 	ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
7141da177e4SLinus Torvalds 
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 
7191da177e4SLinus Torvalds 	switch (arg_type) {
7201da177e4SLinus Torvalds 	case ARGP_BYTEDATA:
7211da177e4SLinus Torvalds 	case ARGP_WORDDATA:
7221da177e4SLinus Torvalds 	case ARGP_DWORDDATA:
7231da177e4SLinus Torvalds 	case ARGP_CHARLIST:
7241da177e4SLinus Torvalds 	case ARGP_NAME:
7251da177e4SLinus Torvalds 	case ARGP_NAMESTRING:
7261da177e4SLinus Torvalds 
72744f6c012SRobert Moore 		/* Constants, strings, and namestrings are all the same size */
7281da177e4SLinus Torvalds 
72962eb935bSLv Zheng 		arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml);
7301da177e4SLinus Torvalds 		if (!arg) {
7311da177e4SLinus Torvalds 			return_ACPI_STATUS(AE_NO_MEMORY);
7321da177e4SLinus Torvalds 		}
7331fad8738SBob Moore 
7341da177e4SLinus Torvalds 		acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
7351da177e4SLinus Torvalds 		break;
7361da177e4SLinus Torvalds 
7371da177e4SLinus Torvalds 	case ARGP_PKGLENGTH:
7381da177e4SLinus Torvalds 
7391da177e4SLinus Torvalds 		/* Package length, nothing returned */
7401da177e4SLinus Torvalds 
7414be44fcdSLen Brown 		parser_state->pkg_end =
7424be44fcdSLen Brown 		    acpi_ps_get_next_package_end(parser_state);
7431da177e4SLinus Torvalds 		break;
7441da177e4SLinus Torvalds 
7451da177e4SLinus Torvalds 	case ARGP_FIELDLIST:
7461da177e4SLinus Torvalds 
7471da177e4SLinus Torvalds 		if (parser_state->aml < parser_state->pkg_end) {
74852fc0b02SBob Moore 
7491da177e4SLinus Torvalds 			/* Non-empty list */
7501da177e4SLinus Torvalds 
7511da177e4SLinus Torvalds 			while (parser_state->aml < parser_state->pkg_end) {
7521da177e4SLinus Torvalds 				field = acpi_ps_get_next_field(parser_state);
7531da177e4SLinus Torvalds 				if (!field) {
7541da177e4SLinus Torvalds 					return_ACPI_STATUS(AE_NO_MEMORY);
7551da177e4SLinus Torvalds 				}
7561da177e4SLinus Torvalds 
7571da177e4SLinus Torvalds 				if (prev) {
7581da177e4SLinus Torvalds 					prev->common.next = field;
7594be44fcdSLen Brown 				} else {
7601da177e4SLinus Torvalds 					arg = field;
7611da177e4SLinus Torvalds 				}
7621da177e4SLinus Torvalds 				prev = field;
7631da177e4SLinus Torvalds 			}
7641da177e4SLinus Torvalds 
7651da177e4SLinus Torvalds 			/* Skip to End of byte data */
7661da177e4SLinus Torvalds 
7671da177e4SLinus Torvalds 			parser_state->aml = parser_state->pkg_end;
7681da177e4SLinus Torvalds 		}
7691da177e4SLinus Torvalds 		break;
7701da177e4SLinus Torvalds 
7711da177e4SLinus Torvalds 	case ARGP_BYTELIST:
7721da177e4SLinus Torvalds 
7731da177e4SLinus Torvalds 		if (parser_state->aml < parser_state->pkg_end) {
77452fc0b02SBob Moore 
7751da177e4SLinus Torvalds 			/* Non-empty list */
7761da177e4SLinus Torvalds 
77762eb935bSLv Zheng 			arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP,
77862eb935bSLv Zheng 					       parser_state->aml);
7791da177e4SLinus Torvalds 			if (!arg) {
7801da177e4SLinus Torvalds 				return_ACPI_STATUS(AE_NO_MEMORY);
7811da177e4SLinus Torvalds 			}
7821da177e4SLinus Torvalds 
7831da177e4SLinus Torvalds 			/* Fill in bytelist data */
7841da177e4SLinus Torvalds 
78544f6c012SRobert Moore 			arg->common.value.size = (u32)
7864be44fcdSLen Brown 			    ACPI_PTR_DIFF(parser_state->pkg_end,
7874be44fcdSLen Brown 					  parser_state->aml);
7881da177e4SLinus Torvalds 			arg->named.data = parser_state->aml;
7891da177e4SLinus Torvalds 
7901da177e4SLinus Torvalds 			/* Skip to End of byte data */
7911da177e4SLinus Torvalds 
7921da177e4SLinus Torvalds 			parser_state->aml = parser_state->pkg_end;
7931da177e4SLinus Torvalds 		}
7941da177e4SLinus Torvalds 		break;
7951da177e4SLinus Torvalds 
7961da177e4SLinus Torvalds 	case ARGP_SIMPLENAME:
797cca7a6eaSBob Moore 	case ARGP_NAME_OR_REF:
7981da177e4SLinus Torvalds 
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 
8041da177e4SLinus Torvalds 		subop = acpi_ps_peek_opcode(parser_state);
8051da177e4SLinus Torvalds 		if (subop == 0 ||
8061da177e4SLinus Torvalds 		    acpi_ps_is_leading_char(subop) ||
80704a81dceSBob Moore 		    ACPI_IS_ROOT_PREFIX(subop) ||
80804a81dceSBob Moore 		    ACPI_IS_PARENT_PREFIX(subop)) {
80952fc0b02SBob Moore 
8101da177e4SLinus Torvalds 			/* null_name or name_string */
8111da177e4SLinus Torvalds 
81262eb935bSLv Zheng 			arg =
81362eb935bSLv Zheng 			    acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
81462eb935bSLv Zheng 					     parser_state->aml);
8151da177e4SLinus Torvalds 			if (!arg) {
8161da177e4SLinus Torvalds 				return_ACPI_STATUS(AE_NO_MEMORY);
8171da177e4SLinus Torvalds 			}
8181da177e4SLinus Torvalds 
8194be44fcdSLen 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;
827bc7a36abSLin Ming 		}
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 			}
8674be44fcdSLen Brown 		} else {
86844f6c012SRobert Moore 			/* Single complex argument, nothing returned */
8691da177e4SLinus Torvalds 
8701da177e4SLinus Torvalds 			walk_state->arg_count = 1;
8711da177e4SLinus Torvalds 		}
8721da177e4SLinus Torvalds 		break;
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds 	case ARGP_DATAOBJ:
8751da177e4SLinus Torvalds 	case ARGP_TERMARG:
8761da177e4SLinus Torvalds 
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 
88244f6c012SRobert Moore 		/* Single complex argument, nothing returned */
8831da177e4SLinus Torvalds 
8841da177e4SLinus Torvalds 		walk_state->arg_count = 1;
8851da177e4SLinus Torvalds 		break;
8861da177e4SLinus Torvalds 
8871da177e4SLinus Torvalds 	case ARGP_DATAOBJLIST:
8881da177e4SLinus Torvalds 	case ARGP_TERMLIST:
8891da177e4SLinus Torvalds 	case ARGP_OBJLIST:
8901da177e4SLinus Torvalds 
8911da177e4SLinus Torvalds 		if (parser_state->aml < parser_state->pkg_end) {
89252fc0b02SBob Moore 
89344f6c012SRobert Moore 			/* Non-empty list of variable arguments, nothing returned */
8941da177e4SLinus Torvalds 
8951da177e4SLinus Torvalds 			walk_state->arg_count = ACPI_VAR_ARGS;
8961da177e4SLinus Torvalds 		}
8971da177e4SLinus Torvalds 		break;
8981da177e4SLinus Torvalds 
8991da177e4SLinus Torvalds 	default:
9001da177e4SLinus Torvalds 
901f6a22b0bSBob Moore 		ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type));
9021da177e4SLinus Torvalds 		status = AE_AML_OPERAND_TYPE;
9031da177e4SLinus Torvalds 		break;
9041da177e4SLinus Torvalds 	}
9051da177e4SLinus Torvalds 
9061da177e4SLinus Torvalds 	*return_arg = arg;
9071da177e4SLinus Torvalds 	return_ACPI_STATUS(status);
9081da177e4SLinus Torvalds }
909