11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module Name: psargs - Parse AML opcode arguments
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
8fbb7a2dc2be493c87399550bdc2ddaa510cdf450Bob Moore * Copyright (C) 2000 - 2014, Intel Corp.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All rights reserved.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Redistribution and use in source and binary forms, with or without
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modification, are permitted provided that the following conditions
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are met:
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Redistributions of source code must retain the above copyright
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    notice, this list of conditions, and the following disclaimer,
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    without modification.
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Redistributions in binary form must reproduce at minimum a disclaimer
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    substantially similar to the "NO WARRANTY" disclaimer below
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    ("Disclaimer") and any redistribution must be conditioned upon
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    including a substantially similar Disclaimer requirement for further
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    binary redistribution.
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Neither the names of the above-listed copyright holders nor the names
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    of any contributors may be used to endorse or promote products derived
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    from this software without specific prior written permission.
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Alternatively, this software may be distributed under the terms of the
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License ("GPL") version 2 as published by the Free
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software Foundation.
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NO WARRANTY
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * POSSIBILITY OF SUCH DAMAGES.
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi.h>
45e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "accommon.h"
46e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acparser.h"
47e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "amlcode.h"
48e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acnamesp.h"
49e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acdispat.h"
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT          ACPI_PARSER
524be44fcd3bf648b782f4460fd06dfae6c42ded4bLen BrownACPI_MODULE_NAME("psargs")
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore/* Local prototypes */
5544f6c01242da4e162f28d8e1216a8c7a91174605Robert Moorestatic u32
564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
5744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore
584be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
594be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						       *parser_state);
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ps_get_next_package_length
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  parser_state        - Current parser state object
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
67c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore * RETURN:      Decoded package length. On completion, the AML pointer points
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              past the length byte or bytes.
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
70c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore * DESCRIPTION: Decode and return a package length field.
71c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore *              Note: Largest package length is 28 bits, from ACPI specification
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7544f6c01242da4e162f28d8e1216a8c7a91174605Robert Moorestatic u32
764be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
78c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	u8 *aml = parser_state->aml;
79c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	u32 package_length = 0;
8067a119f990063f5662574f6d6414fe9bc5ece86aBob Moore	u32 byte_count;
81c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	u8 byte_zero_mask = 0x3F;	/* Default [0:5] */
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
83b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ps_get_next_package_length);
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
85c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	/*
86c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	 * Byte 0 bits [6:7] contain the number of additional bytes
87c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	 * used to encode the package length, either 0,1,2, or 3
88c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	 */
89c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	byte_count = (aml[0] >> 6);
9067a119f990063f5662574f6d6414fe9bc5ece86aBob Moore	parser_state->aml += ((acpi_size) byte_count + 1);
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
92c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	/* Get bytes 3, 2, 1 as needed */
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
94c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	while (byte_count) {
95c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		/*
96c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		 * Final bit positions for the package length bytes:
97c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		 *      Byte3->[20:27]
98c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		 *      Byte2->[12:19]
99c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		 *      Byte1->[04:11]
100c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		 *      Byte0->[00:03]
101c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		 */
102c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
104c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		byte_zero_mask = 0x0F;	/* Use bits [0:3] of byte 0 */
105c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		byte_count--;
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
108c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	/* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
109c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore
110c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	package_length |= (aml[0] & byte_zero_mask);
111fd1af7126fb62688cfcf4b563c73b2909ac30f74Bob Moore	return_UINT32(package_length);
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ps_get_next_package_end
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  parser_state        - Current parser state object
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Pointer to end-of-package +1
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Get next package length and return a pointer past the end of
12373a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *              the package. Consumes the package length field
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1274be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownu8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1294be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u8 *start = parser_state->aml;
130c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	u32 package_length;
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
132b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ps_get_next_package_end);
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
134c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	/* Function below updates parser_state->Aml */
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
136c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	package_length = acpi_ps_get_next_package_length(parser_state);
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
138c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	return_PTR(start + package_length);	/* end of package */
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ps_get_next_namestring
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  parser_state        - Current parser state object
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Pointer to the start of the name string (pointer points into
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              the AML.
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
15073a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
15173a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *              prefix characters. Set parser state to point past the string.
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              (Name is consumed from the AML.)
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownchar *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1584be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u8 *start = parser_state->aml;
1594be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u8 *end = parser_state->aml;
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
161b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ps_get_next_namestring);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
163c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	/* Point past any namestring prefix characters (backslash or carat) */
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16504a81dce13c672757637b759039de216ed29a536Bob Moore	while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) {
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		end++;
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
169c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	/* Decode the path prefix character */
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	switch (*end) {
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0:
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* null_name */
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (end == start) {
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			start = NULL;
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		end++;
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_DUAL_NAME_PREFIX:
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Two name segments */
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		end += 1 + (2 * ACPI_NAME_SIZE);
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_MULTI_NAME_PREFIX_OP:
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
191c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		/* Multiple name segments, 4 chars each, count in next byte */
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
193c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		end += 2 + (*(end + 1) * ACPI_NAME_SIZE);
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Single name segment */
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		end += ACPI_NAME_SIZE;
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
204c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	parser_state->aml = end;
2054be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_PTR((char *)start);
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ps_get_next_namepath
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  parser_state        - Current parser state object
213ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              arg                 - Where the namepath will be stored
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              arg_count           - If the namepath points to a control method
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                                    the method's argument is returned here.
216defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore *              possible_method_call - Whether the namepath can possibly be the
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                                    start of a method call
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Get next name (if method call, return # of required args).
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              Names are looked up in the internal namespace to determine
22373a3090a2160fb01317f5a44af6ee5a064a29625Bob Moore *              if the name represents a control method. If a method
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              is found, the number of arguments to the method is returned.
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              This information is critical for parsing to continue correctly.
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
2304be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
2314be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			  struct acpi_parse_state *parser_state,
232defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			  union acpi_parse_object *arg, u8 possible_method_call)
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
23414808822a9cea782c2e6f8d39e438cc3891f6472Lin Ming	acpi_status status;
2354be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	char *path;
2364be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_parse_object *name_op;
2374be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_operand_object *method_desc;
2384be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	struct acpi_namespace_node *node;
239bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming	u8 *start = parser_state->aml;
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
241b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ps_get_next_namepath);
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2434be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	path = acpi_ps_get_next_namestring(parser_state);
244defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
246defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	/* Null path case is allowed, just exit */
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
248defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	if (!path) {
249defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		arg->common.value.name = path;
250defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		return_ACPI_STATUS(AE_OK);
251defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	}
252defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
253defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	/*
25414808822a9cea782c2e6f8d39e438cc3891f6472Lin Ming	 * Lookup the name in the internal namespace, starting with the current
25514808822a9cea782c2e6f8d39e438cc3891f6472Lin Ming	 * scope. We don't want to add anything new to the namespace here,
25614808822a9cea782c2e6f8d39e438cc3891f6472Lin Ming	 * however, so we use MODE_EXECUTE.
257defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 * Allow searching of the parent tree, but don't open a new scope -
258defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 * we just want to lookup the object (must be mode EXECUTE to perform
259defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 * the upsearch)
260defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 */
26114808822a9cea782c2e6f8d39e438cc3891f6472Lin Ming	status = acpi_ns_lookup(walk_state->scope_info, path,
26214808822a9cea782c2e6f8d39e438cc3891f6472Lin Ming				ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
26314808822a9cea782c2e6f8d39e438cc3891f6472Lin Ming				ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
26414808822a9cea782c2e6f8d39e438cc3891f6472Lin Ming				NULL, &node);
265defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
266defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	/*
267defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 * If this name is a control method invocation, we must
268defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 * setup the method call
269defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 */
270defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	if (ACPI_SUCCESS(status) &&
271defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	    possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
2728410565f540db87ca938f56f92780d251e4f157dBob Moore		if (walk_state->opcode == AML_UNLOAD_OP) {
273bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			/*
274bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			 * acpi_ps_get_next_namestring has increased the AML pointer,
275bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			 * so we need to restore the saved AML pointer for method call.
276bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			 */
277bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			walk_state->parser_state.aml = start;
278bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			walk_state->arg_count = 1;
279bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
280bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			return_ACPI_STATUS(AE_OK);
281bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming		}
28252fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
283defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		/* This name is actually a control method invocation */
284defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
285defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		method_desc = acpi_ns_get_attached_object(node);
286defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
287defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore				  "Control Method - %p Desc %p Path=%p\n", node,
288defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore				  method_desc, path));
289defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
290defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
291defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		if (!name_op) {
292defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			return_ACPI_STATUS(AE_NO_MEMORY);
293defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		}
294defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
295defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		/* Change Arg into a METHOD CALL and attach name to it */
296defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
297defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
298defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		name_op->common.value.name = path;
299defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
300defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		/* Point METHODCALL/NAME to the METHOD Node */
301defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
302defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		name_op->common.node = node;
303defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		acpi_ps_append_arg(arg, name_op);
304defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
305defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		if (!method_desc) {
306b8e4d89357fc434618a59c1047cac72641191805Bob Moore			ACPI_ERROR((AE_INFO,
307b8e4d89357fc434618a59c1047cac72641191805Bob Moore				    "Control Method %p has no attached object",
308b8e4d89357fc434618a59c1047cac72641191805Bob Moore				    node));
309defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			return_ACPI_STATUS(AE_AML_INTERNAL);
310defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		}
311defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
312defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
313defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore				  "Control Method - %p Args %X\n",
314defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore				  node, method_desc->method.param_count));
315defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
316defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		/* Get the number of arguments to expect */
317defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
318defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		walk_state->arg_count = method_desc->method.param_count;
319defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		return_ACPI_STATUS(AE_OK);
320defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	}
321defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
322defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	/*
323defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 * Special handling if the name was not found during the lookup -
324defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 * some not_found cases are allowed
325defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	 */
326defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	if (status == AE_NOT_FOUND) {
32752fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
328defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		/* 1) not_found is ok during load pass 1/2 (allow forward references) */
329defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
330defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
331defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		    ACPI_PARSE_EXECUTE) {
332defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			status = AE_OK;
333defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		}
334defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
335defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		/* 2) not_found during a cond_ref_of(x) is ok by definition */
336defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
337defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		else if (walk_state->op->common.aml_opcode ==
338defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			 AML_COND_REF_OF_OP) {
339defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			status = AE_OK;
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
343defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		 * 3) not_found while building a Package is ok at this point, we
344defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		 * may flag as an error later if slack mode is not enabled.
345defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		 * (Some ASL code depends on allowing this behavior)
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
347defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		else if ((arg->common.parent) &&
348defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			 ((arg->common.parent->common.aml_opcode ==
349defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			   AML_PACKAGE_OP)
350defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			  || (arg->common.parent->common.aml_opcode ==
351defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			      AML_VAR_PACKAGE_OP))) {
352defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			status = AE_OK;
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
354defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	}
355defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
356defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	/* Final exception check (may have been changed from code above) */
357defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
358defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	if (ACPI_FAILURE(status)) {
359b8e4d89357fc434618a59c1047cac72641191805Bob Moore		ACPI_ERROR_NAMESPACE(path, status);
360defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore
361defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
362defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore		    ACPI_PARSE_EXECUTE) {
36352fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
364defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			/* Report a control method execution error */
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
366defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore			status = acpi_ds_method_error(status, walk_state);
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
370defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	/* Save the namepath */
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
372defba1d8f233c0d5cf3e1ea6aeb898eca7231860Bob Moore	arg->common.value.name = path;
3734be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(status);
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ps_get_next_simple_arg
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  parser_state        - Current parser state object
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              arg_type            - The argument type (AML_*_ARG)
382ba494beeaa69bc0fb01eb89464ad5d57d26e3901Bob Moore *              arg                 - Where the argument is returned
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      None
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
3914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
3924be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			    u32 arg_type, union acpi_parse_object *arg)
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
394c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	u32 length;
395c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	u16 opcode;
396c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	u8 *aml = parser_state->aml;
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
398b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (arg_type) {
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_BYTEDATA:
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
403c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		/* Get 1 byte from the AML stream */
404c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore
405c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		opcode = AML_BYTE_OP;
4065df7e6cb42da36c7d878239bebc81907b15f3943Bob Moore		arg->common.value.integer = (u64) *aml;
407c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		length = 1;
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_WORDDATA:
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Get 2 bytes from the AML stream */
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
414c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		opcode = AML_WORD_OP;
415c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
416c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		length = 2;
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_DWORDDATA:
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Get 4 bytes from the AML stream */
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
423c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		opcode = AML_DWORD_OP;
424c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
425c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		length = 4;
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_QWORDDATA:
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Get 8 bytes from the AML stream */
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
432c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		opcode = AML_QWORD_OP;
433c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
434c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		length = 8;
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_CHARLIST:
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
439c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		/* Get a pointer to the string, point past the string */
440c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore
441c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		opcode = AML_STRING_OP;
442c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		arg->common.value.string = ACPI_CAST_PTR(char, aml);
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
444c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		/* Find the null terminator */
445c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore
446c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		length = 0;
447c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		while (aml[length]) {
448c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore			length++;
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
450c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		length++;
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_NAME:
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_NAMESTRING:
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
4574be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		arg->common.value.name =
4584be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    acpi_ps_get_next_namestring(parser_state);
459c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		return_VOID;
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
463f6a22b0bc417042e83117f52ab1a03696af185abBob Moore		ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type));
464c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore		return_VOID;
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
467c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	acpi_ps_init_op(arg, opcode);
468c51a4de85de720670f2fbc592a6f8040af72ad87Bob Moore	parser_state->aml += length;
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return_VOID;
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ps_get_next_field
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  parser_state        - Current parser state object
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      A newly allocated FIELD op
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4844be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
4854be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown						       *parser_state)
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4879ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	u32 aml_offset;
4884be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_parse_object *field;
4899ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	union acpi_parse_object *arg = NULL;
4904be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u16 opcode;
4914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u32 name;
4929ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	u8 access_type;
4939ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	u8 access_attribute;
4949ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	u8 access_length;
4959ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	u32 pkg_length;
4969ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	u8 *pkg_end;
4979ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	u32 buffer_length;
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
499b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE(ps_get_next_field);
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5019ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	aml_offset =
5029ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	    (u32)ACPI_PTR_DIFF(parser_state->aml, parser_state->aml_start);
5039ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
50444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore	/* Determine field type */
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5064be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	switch (ACPI_GET8(parser_state->aml)) {
5079ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	case AML_FIELD_OFFSET_OP:
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5099ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		opcode = AML_INT_RESERVEDFIELD_OP;
5109ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		parser_state->aml++;
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5139ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	case AML_FIELD_ACCESS_OP:
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5159ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		opcode = AML_INT_ACCESSFIELD_OP;
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		parser_state->aml++;
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5199ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	case AML_FIELD_CONNECTION_OP:
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5219ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		opcode = AML_INT_CONNECTION_OP;
5229ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		parser_state->aml++;
5239ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		break;
5249ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5259ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	case AML_FIELD_EXT_ACCESS_OP:
5269ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5279ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		opcode = AML_INT_EXTACCESSFIELD_OP;
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		parser_state->aml++;
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5309ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5319ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	default:
5329ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5339ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		opcode = AML_INT_NAMEDFIELD_OP;
5349ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		break;
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Allocate a new field op */
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5394be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	field = acpi_ps_alloc_op(opcode);
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!field) {
5414be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		return_PTR(NULL);
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	field->common.aml_offset = aml_offset;
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Decode the field type */
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (opcode) {
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_INT_NAMEDFIELD_OP:
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Get the 4-character name */
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5534be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		ACPI_MOVE_32_TO_32(&name, parser_state->aml);
5544be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		acpi_ps_set_name(field, name);
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		parser_state->aml += ACPI_NAME_SIZE;
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Get the length which is encoded as a package length */
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5594be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		field->common.value.size =
5604be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    acpi_ps_get_next_package_length(parser_state);
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_INT_RESERVEDFIELD_OP:
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Get the length which is encoded as a package length */
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5674be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		field->common.value.size =
5684be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    acpi_ps_get_next_package_length(parser_state);
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_INT_ACCESSFIELD_OP:
5729ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	case AML_INT_EXTACCESSFIELD_OP:
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Get access_type and access_attrib and merge into the field Op
5769ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		 * access_type is first operand, access_attribute is second. stuff
5779ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		 * these bytes into the node integer value for convenience.
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
5799ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5809ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		/* Get the two bytes (Type/Attribute) */
5819ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5829ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		access_type = ACPI_GET8(parser_state->aml);
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		parser_state->aml++;
5849ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		access_attribute = ACPI_GET8(parser_state->aml);
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		parser_state->aml++;
5869ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5879ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		field->common.value.integer = (u8)access_type;
5889ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		field->common.value.integer |= (u16)(access_attribute << 8);
5899ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5909ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		/* This opcode has a third byte, access_length */
5919ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5929ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		if (opcode == AML_INT_EXTACCESSFIELD_OP) {
5939ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			access_length = ACPI_GET8(parser_state->aml);
5949ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			parser_state->aml++;
5959ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
5969ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			field->common.value.integer |=
5979ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			    (u32)(access_length << 16);
5989ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		}
5999ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		break;
6009ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6019ce81784c9c0396a6a6be05248928a71134fe60bBob Moore	case AML_INT_CONNECTION_OP:
6029ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6039ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		/*
6049ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		 * Argument for Connection operator can be either a Buffer
6059ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		 * (resource descriptor), or a name_string.
6069ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		 */
6079ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
6089ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			parser_state->aml++;
6099ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6109ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			pkg_end = parser_state->aml;
6119ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			pkg_length =
6129ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			    acpi_ps_get_next_package_length(parser_state);
6139ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			pkg_end += pkg_length;
6149ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6159ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			if (parser_state->aml < pkg_end) {
6169ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6179ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				/* Non-empty list */
6189ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6199ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP);
6209ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				if (!arg) {
6216af1c4fc5227af65092ebc848989693562bfa3e8Jesper Juhl					acpi_ps_free_op(field);
6229ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					return_PTR(NULL);
6239ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				}
6249ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6259ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				/* Get the actual buffer length argument */
6269ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6279ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				opcode = ACPI_GET8(parser_state->aml);
6289ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				parser_state->aml++;
6299ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6309ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				switch (opcode) {
6319ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				case AML_BYTE_OP:	/* AML_BYTEDATA_ARG */
6321d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
6339ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					buffer_length =
6349ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					    ACPI_GET8(parser_state->aml);
6359ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					parser_state->aml += 1;
6369ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					break;
6379ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6389ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				case AML_WORD_OP:	/* AML_WORDDATA_ARG */
6391d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
6409ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					buffer_length =
6419ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					    ACPI_GET16(parser_state->aml);
6429ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					parser_state->aml += 2;
6439ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					break;
6449ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6459ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				case AML_DWORD_OP:	/* AML_DWORDATA_ARG */
6461d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
6479ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					buffer_length =
6489ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					    ACPI_GET32(parser_state->aml);
6499ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					parser_state->aml += 4;
6509ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					break;
6519ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6529ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				default:
6531d1ea1b723d9f239f736b8cf284327cbbf9d15d1Chao Guan
6549ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					buffer_length = 0;
6559ce81784c9c0396a6a6be05248928a71134fe60bBob Moore					break;
6569ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				}
6579ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6589ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				/* Fill in bytelist data */
6599ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6609ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				arg->named.value.size = buffer_length;
6619ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				arg->named.data = parser_state->aml;
6629ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			}
6639ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6649ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			/* Skip to End of byte data */
6659ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6669ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			parser_state->aml = pkg_end;
6679ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		} else {
6689ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
6699ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			if (!arg) {
6706af1c4fc5227af65092ebc848989693562bfa3e8Jesper Juhl				acpi_ps_free_op(field);
6719ce81784c9c0396a6a6be05248928a71134fe60bBob Moore				return_PTR(NULL);
6729ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			}
6739ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6749ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			/* Get the Namestring argument */
6759ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6769ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			arg->common.value.name =
6779ce81784c9c0396a6a6be05248928a71134fe60bBob Moore			    acpi_ps_get_next_namestring(parser_state);
6789ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		}
6799ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6809ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		/* Link the buffer/namestring to parent (CONNECTION_OP) */
6819ce81784c9c0396a6a6be05248928a71134fe60bBob Moore
6829ce81784c9c0396a6a6be05248928a71134fe60bBob Moore		acpi_ps_append_arg(field, arg);
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Opcode was set in previous switch */
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_PTR(field);
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ps_get_next_arg
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
69844f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * PARAMETERS:  walk_state          - Current state
69944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore *              parser_state        - Current parser state object
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              arg_type            - The argument type (AML_*_ARG)
70144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore *              return_arg          - Where the next arg is returned
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status, and an op object containing the next argument.
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Get next argument (including complex list arguments that require
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              pushing the parser stack)
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
7114be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
7124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		     struct acpi_parse_state *parser_state,
7134be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		     u32 arg_type, union acpi_parse_object **return_arg)
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7154be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_parse_object *arg = NULL;
7164be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_parse_object *prev = NULL;
7174be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	union acpi_parse_object *field;
7184be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	u32 subop;
7194be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	acpi_status status = AE_OK;
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
721b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore	ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (arg_type) {
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_BYTEDATA:
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_WORDDATA:
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_DWORDDATA:
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_CHARLIST:
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_NAME:
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_NAMESTRING:
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
73144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore		/* Constants, strings, and namestrings are all the same size */
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7334be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		arg = acpi_ps_alloc_op(AML_BYTE_OP);
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!arg) {
7354be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			return_ACPI_STATUS(AE_NO_MEMORY);
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7374be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_PKGLENGTH:
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Package length, nothing returned */
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		parser_state->pkg_end =
7454be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    acpi_ps_get_next_package_end(parser_state);
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_FIELDLIST:
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (parser_state->aml < parser_state->pkg_end) {
75152fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Non-empty list */
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			while (parser_state->aml < parser_state->pkg_end) {
7554be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				field = acpi_ps_get_next_field(parser_state);
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (!field) {
7574be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					return_ACPI_STATUS(AE_NO_MEMORY);
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (prev) {
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					prev->common.next = field;
7624be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				} else {
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					arg = field;
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				prev = field;
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Skip to End of byte data */
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			parser_state->aml = parser_state->pkg_end;
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_BYTELIST:
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (parser_state->aml < parser_state->pkg_end) {
77752fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Non-empty list */
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7804be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP);
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!arg) {
7824be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				return_ACPI_STATUS(AE_NO_MEMORY);
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Fill in bytelist data */
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
78744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			arg->common.value.size = (u32)
7884be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			    ACPI_PTR_DIFF(parser_state->pkg_end,
7894be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown					  parser_state->aml);
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			arg->named.data = parser_state->aml;
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Skip to End of byte data */
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			parser_state->aml = parser_state->pkg_end;
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_TARGET:
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_SUPERNAME:
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_SIMPLENAME:
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8024be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		subop = acpi_ps_peek_opcode(parser_state);
8034be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		if (subop == 0 ||
8044be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		    acpi_ps_is_leading_char(subop) ||
80504a81dce13c672757637b759039de216ed29a536Bob Moore		    ACPI_IS_ROOT_PREFIX(subop) ||
80604a81dce13c672757637b759039de216ed29a536Bob Moore		    ACPI_IS_PARENT_PREFIX(subop)) {
80752fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* null_name or name_string */
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8104be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown			arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!arg) {
8124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown				return_ACPI_STATUS(AE_NO_MEMORY);
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
815bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			/* To support super_name arg of Unload */
816bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming
8178410565f540db87ca938f56f92780d251e4f157dBob Moore			if (walk_state->opcode == AML_UNLOAD_OP) {
818bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				status =
819bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				    acpi_ps_get_next_namepath(walk_state,
820bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming							      parser_state, arg,
821bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming							      1);
822bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming
823bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				/*
824bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				 * If the super_name arg of Unload is a method call,
825bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				 * we have restored the AML pointer, just free this Arg
826bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				 */
827bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				if (arg->common.aml_opcode ==
828bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				    AML_INT_METHODCALL_OP) {
829bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming					acpi_ps_free_op(arg);
830bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming					arg = NULL;
831bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				}
832bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			} else {
833bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				status =
834bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming				    acpi_ps_get_next_namepath(walk_state,
835bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming							      parser_state, arg,
836bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming							      0);
837bc7a36ab74e09da7bb63e2477b0740ac992b290eLin Ming			}
8384be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown		} else {
83944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			/* Single complex argument, nothing returned */
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			walk_state->arg_count = 1;
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_DATAOBJ:
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_TERMARG:
8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
84844f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore		/* Single complex argument, nothing returned */
8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->arg_count = 1;
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_DATAOBJLIST:
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_TERMLIST:
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ARGP_OBJLIST:
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (parser_state->aml < parser_state->pkg_end) {
85852fc0b026e99b5d5d585095148d997d5634bbc25Bob Moore
85944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			/* Non-empty list of variable arguments, nothing returned */
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			walk_state->arg_count = ACPI_VAR_ARGS;
8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
867f6a22b0bc417042e83117f52ab1a03696af185abBob Moore		ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type));
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = AE_AML_OPERAND_TYPE;
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*return_arg = arg;
8734be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown	return_ACPI_STATUS(status);
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
875