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