195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 21da177e4SLinus Torvalds /****************************************************************************** 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Module Name: psargs - Parse AML opcode arguments 51da177e4SLinus Torvalds * 6487ea80aSBob Moore * Copyright (C) 2000 - 2022, Intel Corp. 71da177e4SLinus Torvalds * 895857638SErik Schmauss *****************************************************************************/ 91da177e4SLinus Torvalds 101da177e4SLinus Torvalds #include <acpi/acpi.h> 11e2f7a777SLen Brown #include "accommon.h" 12e2f7a777SLen Brown #include "acparser.h" 13e2f7a777SLen Brown #include "amlcode.h" 14e2f7a777SLen Brown #include "acnamesp.h" 15e2f7a777SLen Brown #include "acdispat.h" 169cf7adecSBob Moore #include "acconvert.h" 171da177e4SLinus Torvalds 181da177e4SLinus Torvalds #define _COMPONENT ACPI_PARSER 191da177e4SLinus Torvalds ACPI_MODULE_NAME("psargs") 201da177e4SLinus Torvalds 2144f6c012SRobert Moore /* Local prototypes */ 2244f6c012SRobert Moore static u32 234be44fcdSLen Brown acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state); 2444f6c012SRobert Moore 254be44fcdSLen Brown static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state 264be44fcdSLen Brown *parser_state); 271da177e4SLinus Torvalds 281da177e4SLinus Torvalds /******************************************************************************* 291da177e4SLinus Torvalds * 301da177e4SLinus Torvalds * FUNCTION: acpi_ps_get_next_package_length 311da177e4SLinus Torvalds * 321da177e4SLinus Torvalds * PARAMETERS: parser_state - Current parser state object 331da177e4SLinus Torvalds * 341da177e4SLinus Torvalds * RETURN: Decoded package length. On completion, the AML pointer points 351da177e4SLinus Torvalds * past the length byte or bytes. 361da177e4SLinus Torvalds * 37c51a4de8SBob Moore * DESCRIPTION: Decode and return a package length field. 38c51a4de8SBob Moore * Note: Largest package length is 28 bits, from ACPI specification 391da177e4SLinus Torvalds * 401da177e4SLinus Torvalds ******************************************************************************/ 411da177e4SLinus Torvalds 4244f6c012SRobert Moore static u32 434be44fcdSLen Brown acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) 441da177e4SLinus Torvalds { 45c51a4de8SBob Moore u8 *aml = parser_state->aml; 46c51a4de8SBob Moore u32 package_length = 0; 4767a119f9SBob Moore u32 byte_count; 48c51a4de8SBob Moore u8 byte_zero_mask = 0x3F; /* Default [0:5] */ 491da177e4SLinus Torvalds 50b229cf92SBob Moore ACPI_FUNCTION_TRACE(ps_get_next_package_length); 511da177e4SLinus Torvalds 52c51a4de8SBob Moore /* 53c51a4de8SBob Moore * Byte 0 bits [6:7] contain the number of additional bytes 54c51a4de8SBob Moore * used to encode the package length, either 0,1,2, or 3 55c51a4de8SBob Moore */ 56c51a4de8SBob Moore byte_count = (aml[0] >> 6); 5767a119f9SBob Moore parser_state->aml += ((acpi_size)byte_count + 1); 581da177e4SLinus Torvalds 59c51a4de8SBob Moore /* Get bytes 3, 2, 1 as needed */ 601da177e4SLinus Torvalds 61c51a4de8SBob Moore while (byte_count) { 62c51a4de8SBob Moore /* 63c51a4de8SBob Moore * Final bit positions for the package length bytes: 64c51a4de8SBob Moore * Byte3->[20:27] 65c51a4de8SBob Moore * Byte2->[12:19] 66c51a4de8SBob Moore * Byte1->[04:11] 67c51a4de8SBob Moore * Byte0->[00:03] 68c51a4de8SBob Moore */ 69c51a4de8SBob Moore package_length |= (aml[byte_count] << ((byte_count << 3) - 4)); 701da177e4SLinus Torvalds 71c51a4de8SBob Moore byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */ 72c51a4de8SBob Moore byte_count--; 731da177e4SLinus Torvalds } 741da177e4SLinus Torvalds 75c51a4de8SBob Moore /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ 76c51a4de8SBob Moore 77c51a4de8SBob Moore package_length |= (aml[0] & byte_zero_mask); 78fd1af712SBob Moore return_UINT32(package_length); 791da177e4SLinus Torvalds } 801da177e4SLinus Torvalds 811da177e4SLinus Torvalds /******************************************************************************* 821da177e4SLinus Torvalds * 831da177e4SLinus Torvalds * FUNCTION: acpi_ps_get_next_package_end 841da177e4SLinus Torvalds * 851da177e4SLinus Torvalds * PARAMETERS: parser_state - Current parser state object 861da177e4SLinus Torvalds * 871da177e4SLinus Torvalds * RETURN: Pointer to end-of-package +1 881da177e4SLinus Torvalds * 891da177e4SLinus Torvalds * DESCRIPTION: Get next package length and return a pointer past the end of 901da177e4SLinus Torvalds * the package. Consumes the package length field 911da177e4SLinus Torvalds * 921da177e4SLinus Torvalds ******************************************************************************/ 931da177e4SLinus Torvalds 944be44fcdSLen Brown u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state) 951da177e4SLinus Torvalds { 961da177e4SLinus Torvalds u8 *start = parser_state->aml; 97c51a4de8SBob Moore u32 package_length; 981da177e4SLinus Torvalds 99b229cf92SBob Moore ACPI_FUNCTION_TRACE(ps_get_next_package_end); 1001da177e4SLinus Torvalds 101c51a4de8SBob Moore /* Function below updates parser_state->Aml */ 1021da177e4SLinus Torvalds 103c51a4de8SBob Moore package_length = acpi_ps_get_next_package_length(parser_state); 1041da177e4SLinus Torvalds 105c51a4de8SBob Moore return_PTR(start + package_length); /* end of package */ 1061da177e4SLinus Torvalds } 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds /******************************************************************************* 1091da177e4SLinus Torvalds * 1101da177e4SLinus Torvalds * FUNCTION: acpi_ps_get_next_namestring 1111da177e4SLinus Torvalds * 1121da177e4SLinus Torvalds * PARAMETERS: parser_state - Current parser state object 1131da177e4SLinus Torvalds * 1141da177e4SLinus Torvalds * RETURN: Pointer to the start of the name string (pointer points into 1151da177e4SLinus Torvalds * the AML. 1161da177e4SLinus Torvalds * 1171da177e4SLinus Torvalds * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name 1181da177e4SLinus Torvalds * prefix characters. Set parser state to point past the string. 1191da177e4SLinus Torvalds * (Name is consumed from the AML.) 1201da177e4SLinus Torvalds * 1211da177e4SLinus Torvalds ******************************************************************************/ 1221da177e4SLinus Torvalds 1234be44fcdSLen Brown char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) 1241da177e4SLinus Torvalds { 1251da177e4SLinus Torvalds u8 *start = parser_state->aml; 1261da177e4SLinus Torvalds u8 *end = parser_state->aml; 1271da177e4SLinus Torvalds 128b229cf92SBob Moore ACPI_FUNCTION_TRACE(ps_get_next_namestring); 1291da177e4SLinus Torvalds 130c51a4de8SBob Moore /* Point past any namestring prefix characters (backslash or carat) */ 1311da177e4SLinus Torvalds 13204a81dceSBob Moore while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) { 1331da177e4SLinus Torvalds end++; 1341da177e4SLinus Torvalds } 1351da177e4SLinus Torvalds 136c51a4de8SBob Moore /* Decode the path prefix character */ 1371da177e4SLinus Torvalds 138c51a4de8SBob Moore switch (*end) { 1391da177e4SLinus Torvalds case 0: 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds /* null_name */ 1421da177e4SLinus Torvalds 1431da177e4SLinus Torvalds if (end == start) { 1441da177e4SLinus Torvalds start = NULL; 1451da177e4SLinus Torvalds } 1461da177e4SLinus Torvalds end++; 1471da177e4SLinus Torvalds break; 1481da177e4SLinus Torvalds 1491da177e4SLinus Torvalds case AML_DUAL_NAME_PREFIX: 1501da177e4SLinus Torvalds 1511da177e4SLinus Torvalds /* Two name segments */ 1521da177e4SLinus Torvalds 15332786755SBob Moore end += 1 + (2 * ACPI_NAMESEG_SIZE); 1541da177e4SLinus Torvalds break; 1551da177e4SLinus Torvalds 1569ff5a21aSBob Moore case AML_MULTI_NAME_PREFIX: 1571da177e4SLinus Torvalds 158c51a4de8SBob Moore /* Multiple name segments, 4 chars each, count in next byte */ 1591da177e4SLinus Torvalds 16032786755SBob Moore end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE); 1611da177e4SLinus Torvalds break; 1621da177e4SLinus Torvalds 1631da177e4SLinus Torvalds default: 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds /* Single name segment */ 1661da177e4SLinus Torvalds 16732786755SBob Moore end += ACPI_NAMESEG_SIZE; 1681da177e4SLinus Torvalds break; 1691da177e4SLinus Torvalds } 1701da177e4SLinus Torvalds 171c51a4de8SBob Moore parser_state->aml = end; 1721da177e4SLinus Torvalds return_PTR((char *)start); 1731da177e4SLinus Torvalds } 1741da177e4SLinus Torvalds 1751da177e4SLinus Torvalds /******************************************************************************* 1761da177e4SLinus Torvalds * 1771da177e4SLinus Torvalds * FUNCTION: acpi_ps_get_next_namepath 1781da177e4SLinus Torvalds * 1791da177e4SLinus Torvalds * PARAMETERS: parser_state - Current parser state object 180ba494beeSBob Moore * arg - Where the namepath will be stored 1811da177e4SLinus Torvalds * arg_count - If the namepath points to a control method 1821da177e4SLinus Torvalds * the method's argument is returned here. 183defba1d8SBob Moore * possible_method_call - Whether the namepath can possibly be the 1841da177e4SLinus Torvalds * start of a method call 1851da177e4SLinus Torvalds * 1861da177e4SLinus Torvalds * RETURN: Status 1871da177e4SLinus Torvalds * 1881da177e4SLinus Torvalds * DESCRIPTION: Get next name (if method call, return # of required args). 1891da177e4SLinus Torvalds * Names are looked up in the internal namespace to determine 1901da177e4SLinus Torvalds * if the name represents a control method. If a method 1911da177e4SLinus Torvalds * is found, the number of arguments to the method is returned. 1921da177e4SLinus Torvalds * This information is critical for parsing to continue correctly. 1931da177e4SLinus Torvalds * 1941da177e4SLinus Torvalds ******************************************************************************/ 1951da177e4SLinus Torvalds 1961da177e4SLinus Torvalds acpi_status 1974be44fcdSLen Brown acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, 1981da177e4SLinus Torvalds struct acpi_parse_state *parser_state, 199defba1d8SBob Moore union acpi_parse_object *arg, u8 possible_method_call) 2001da177e4SLinus Torvalds { 20114808822SLin Ming acpi_status status; 2021da177e4SLinus Torvalds char *path; 2031da177e4SLinus Torvalds union acpi_parse_object *name_op; 2041da177e4SLinus Torvalds union acpi_operand_object *method_desc; 2051da177e4SLinus Torvalds struct acpi_namespace_node *node; 206bc7a36abSLin Ming u8 *start = parser_state->aml; 2071da177e4SLinus Torvalds 208b229cf92SBob Moore ACPI_FUNCTION_TRACE(ps_get_next_namepath); 2091da177e4SLinus Torvalds 2101da177e4SLinus Torvalds path = acpi_ps_get_next_namestring(parser_state); 211defba1d8SBob Moore acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); 2121da177e4SLinus Torvalds 213defba1d8SBob Moore /* Null path case is allowed, just exit */ 2141da177e4SLinus Torvalds 215defba1d8SBob Moore if (!path) { 216defba1d8SBob Moore arg->common.value.name = path; 217defba1d8SBob Moore return_ACPI_STATUS(AE_OK); 218defba1d8SBob Moore } 219defba1d8SBob Moore 2201da177e4SLinus Torvalds /* 22114808822SLin Ming * Lookup the name in the internal namespace, starting with the current 22214808822SLin Ming * scope. We don't want to add anything new to the namespace here, 22314808822SLin Ming * however, so we use MODE_EXECUTE. 224defba1d8SBob Moore * Allow searching of the parent tree, but don't open a new scope - 225defba1d8SBob Moore * we just want to lookup the object (must be mode EXECUTE to perform 226defba1d8SBob Moore * the upsearch) 2271da177e4SLinus Torvalds */ 22814808822SLin Ming status = acpi_ns_lookup(walk_state->scope_info, path, 22914808822SLin Ming ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 230defba1d8SBob Moore ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 231defba1d8SBob Moore NULL, &node); 232defba1d8SBob Moore 233defba1d8SBob Moore /* 234defba1d8SBob Moore * If this name is a control method invocation, we must 235defba1d8SBob Moore * setup the method call 236defba1d8SBob Moore */ 237defba1d8SBob Moore if (ACPI_SUCCESS(status) && 238defba1d8SBob Moore possible_method_call && (node->type == ACPI_TYPE_METHOD)) { 2399a947291SBob Moore if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) == 2409a947291SBob Moore ARGP_SUPERNAME) 2419a947291SBob Moore || (GET_CURRENT_ARG_TYPE(walk_state->arg_types) == 2429a947291SBob Moore ARGP_TARGET)) { 2439a947291SBob Moore /* 2449a947291SBob Moore * acpi_ps_get_next_namestring has increased the AML pointer past 2459a947291SBob Moore * the method invocation namestring, so we need to restore the 2469a947291SBob Moore * saved AML pointer back to the original method invocation 2479a947291SBob Moore * namestring. 2489a947291SBob Moore */ 2499a947291SBob Moore walk_state->parser_state.aml = start; 2509a947291SBob Moore walk_state->arg_count = 1; 2519a947291SBob Moore acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); 2529a947291SBob Moore } 25352fc0b02SBob Moore 25444f6c012SRobert Moore /* This name is actually a control method invocation */ 25544f6c012SRobert Moore 2561da177e4SLinus Torvalds method_desc = acpi_ns_get_attached_object(node); 2571da177e4SLinus Torvalds ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 258ce87e09dSBob Moore "Control Method invocation %4.4s - %p Desc %p Path=%p\n", 259ce87e09dSBob Moore node->name.ascii, node, method_desc, path)); 2601da177e4SLinus Torvalds 26162eb935bSLv Zheng name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start); 2621da177e4SLinus Torvalds if (!name_op) { 2631da177e4SLinus Torvalds return_ACPI_STATUS(AE_NO_MEMORY); 2641da177e4SLinus Torvalds } 2651da177e4SLinus Torvalds 266defba1d8SBob Moore /* Change Arg into a METHOD CALL and attach name to it */ 2671da177e4SLinus Torvalds 2681da177e4SLinus Torvalds acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); 2691da177e4SLinus Torvalds name_op->common.value.name = path; 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds /* Point METHODCALL/NAME to the METHOD Node */ 2721da177e4SLinus Torvalds 2731da177e4SLinus Torvalds name_op->common.node = node; 2741da177e4SLinus Torvalds acpi_ps_append_arg(arg, name_op); 2751da177e4SLinus Torvalds 2761da177e4SLinus Torvalds if (!method_desc) { 277b8e4d893SBob Moore ACPI_ERROR((AE_INFO, 278b8e4d893SBob Moore "Control Method %p has no attached object", 279b8e4d893SBob Moore node)); 2801da177e4SLinus Torvalds return_ACPI_STATUS(AE_AML_INTERNAL); 2811da177e4SLinus Torvalds } 2821da177e4SLinus Torvalds 2831da177e4SLinus Torvalds ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 2841da177e4SLinus Torvalds "Control Method - %p Args %X\n", 285defba1d8SBob Moore node, method_desc->method.param_count)); 2861da177e4SLinus Torvalds 2871da177e4SLinus Torvalds /* Get the number of arguments to expect */ 2881da177e4SLinus Torvalds 289defba1d8SBob Moore walk_state->arg_count = method_desc->method.param_count; 2901da177e4SLinus Torvalds return_ACPI_STATUS(AE_OK); 2911da177e4SLinus Torvalds } 2921da177e4SLinus Torvalds 2931da177e4SLinus Torvalds /* 294defba1d8SBob Moore * Special handling if the name was not found during the lookup - 295defba1d8SBob Moore * some not_found cases are allowed 2961da177e4SLinus Torvalds */ 297defba1d8SBob Moore if (status == AE_NOT_FOUND) { 29852fc0b02SBob Moore 299defba1d8SBob Moore /* 1) not_found is ok during load pass 1/2 (allow forward references) */ 300defba1d8SBob Moore 301defba1d8SBob Moore if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) != 302defba1d8SBob Moore ACPI_PARSE_EXECUTE) { 303defba1d8SBob Moore status = AE_OK; 3041da177e4SLinus Torvalds } 3051da177e4SLinus Torvalds 306defba1d8SBob Moore /* 2) not_found during a cond_ref_of(x) is ok by definition */ 3071da177e4SLinus Torvalds 308defba1d8SBob Moore else if (walk_state->op->common.aml_opcode == 3099ff5a21aSBob Moore AML_CONDITIONAL_REF_OF_OP) { 310defba1d8SBob Moore status = AE_OK; 311defba1d8SBob Moore } 312defba1d8SBob Moore 3131da177e4SLinus Torvalds /* 314defba1d8SBob Moore * 3) not_found while building a Package is ok at this point, we 315defba1d8SBob Moore * may flag as an error later if slack mode is not enabled. 316defba1d8SBob Moore * (Some ASL code depends on allowing this behavior) 3171da177e4SLinus Torvalds */ 318defba1d8SBob Moore else if ((arg->common.parent) && 319defba1d8SBob Moore ((arg->common.parent->common.aml_opcode == 320defba1d8SBob Moore AML_PACKAGE_OP) 321defba1d8SBob Moore || (arg->common.parent->common.aml_opcode == 3229ff5a21aSBob Moore AML_VARIABLE_PACKAGE_OP))) { 3231da177e4SLinus Torvalds status = AE_OK; 3241da177e4SLinus Torvalds } 3251da177e4SLinus Torvalds } 326defba1d8SBob Moore 327defba1d8SBob Moore /* Final exception check (may have been changed from code above) */ 328defba1d8SBob Moore 329defba1d8SBob Moore if (ACPI_FAILURE(status)) { 33016ccf829SBob Moore ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status); 331defba1d8SBob Moore 332defba1d8SBob Moore if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == 333defba1d8SBob Moore ACPI_PARSE_EXECUTE) { 33452fc0b02SBob Moore 335defba1d8SBob Moore /* Report a control method execution error */ 336defba1d8SBob Moore 337defba1d8SBob Moore status = acpi_ds_method_error(status, walk_state); 338defba1d8SBob Moore } 3391da177e4SLinus Torvalds } 3401da177e4SLinus Torvalds 341defba1d8SBob Moore /* Save the namepath */ 3421da177e4SLinus Torvalds 343defba1d8SBob Moore arg->common.value.name = path; 3441da177e4SLinus Torvalds return_ACPI_STATUS(status); 3451da177e4SLinus Torvalds } 3461da177e4SLinus Torvalds 3471da177e4SLinus Torvalds /******************************************************************************* 3481da177e4SLinus Torvalds * 3491da177e4SLinus Torvalds * FUNCTION: acpi_ps_get_next_simple_arg 3501da177e4SLinus Torvalds * 3511da177e4SLinus Torvalds * PARAMETERS: parser_state - Current parser state object 3521da177e4SLinus Torvalds * arg_type - The argument type (AML_*_ARG) 353ba494beeSBob Moore * arg - Where the argument is returned 3541da177e4SLinus Torvalds * 3551da177e4SLinus Torvalds * RETURN: None 3561da177e4SLinus Torvalds * 3571da177e4SLinus Torvalds * DESCRIPTION: Get the next simple argument (constant, string, or namestring) 3581da177e4SLinus Torvalds * 3591da177e4SLinus Torvalds ******************************************************************************/ 3601da177e4SLinus Torvalds 3611da177e4SLinus Torvalds void 3624be44fcdSLen Brown acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, 3634be44fcdSLen Brown u32 arg_type, union acpi_parse_object *arg) 3641da177e4SLinus Torvalds { 365c51a4de8SBob Moore u32 length; 366c51a4de8SBob Moore u16 opcode; 367c51a4de8SBob Moore u8 *aml = parser_state->aml; 3681da177e4SLinus Torvalds 369b229cf92SBob Moore ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type); 3701da177e4SLinus Torvalds 3711da177e4SLinus Torvalds switch (arg_type) { 3721da177e4SLinus Torvalds case ARGP_BYTEDATA: 3731da177e4SLinus Torvalds 374c51a4de8SBob Moore /* Get 1 byte from the AML stream */ 375c51a4de8SBob Moore 376c51a4de8SBob Moore opcode = AML_BYTE_OP; 3775df7e6cbSBob Moore arg->common.value.integer = (u64) *aml; 378c51a4de8SBob Moore length = 1; 3791da177e4SLinus Torvalds break; 3801da177e4SLinus Torvalds 3811da177e4SLinus Torvalds case ARGP_WORDDATA: 3821da177e4SLinus Torvalds 3831da177e4SLinus Torvalds /* Get 2 bytes from the AML stream */ 3841da177e4SLinus Torvalds 385c51a4de8SBob Moore opcode = AML_WORD_OP; 386c51a4de8SBob Moore ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml); 387c51a4de8SBob Moore length = 2; 3881da177e4SLinus Torvalds break; 3891da177e4SLinus Torvalds 3901da177e4SLinus Torvalds case ARGP_DWORDDATA: 3911da177e4SLinus Torvalds 3921da177e4SLinus Torvalds /* Get 4 bytes from the AML stream */ 3931da177e4SLinus Torvalds 394c51a4de8SBob Moore opcode = AML_DWORD_OP; 395c51a4de8SBob Moore ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml); 396c51a4de8SBob Moore length = 4; 3971da177e4SLinus Torvalds break; 3981da177e4SLinus Torvalds 3991da177e4SLinus Torvalds case ARGP_QWORDDATA: 4001da177e4SLinus Torvalds 4011da177e4SLinus Torvalds /* Get 8 bytes from the AML stream */ 4021da177e4SLinus Torvalds 403c51a4de8SBob Moore opcode = AML_QWORD_OP; 404c51a4de8SBob Moore ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml); 405c51a4de8SBob Moore length = 8; 4061da177e4SLinus Torvalds break; 4071da177e4SLinus Torvalds 4081da177e4SLinus Torvalds case ARGP_CHARLIST: 4091da177e4SLinus Torvalds 410c51a4de8SBob Moore /* Get a pointer to the string, point past the string */ 4111da177e4SLinus Torvalds 412c51a4de8SBob Moore opcode = AML_STRING_OP; 413c51a4de8SBob Moore arg->common.value.string = ACPI_CAST_PTR(char, aml); 414c51a4de8SBob Moore 415c51a4de8SBob Moore /* Find the null terminator */ 416c51a4de8SBob Moore 417c51a4de8SBob Moore length = 0; 418c51a4de8SBob Moore while (aml[length]) { 419c51a4de8SBob Moore length++; 4201da177e4SLinus Torvalds } 421c51a4de8SBob Moore length++; 4221da177e4SLinus Torvalds break; 4231da177e4SLinus Torvalds 4241da177e4SLinus Torvalds case ARGP_NAME: 4251da177e4SLinus Torvalds case ARGP_NAMESTRING: 4261da177e4SLinus Torvalds 4271da177e4SLinus Torvalds acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); 4284be44fcdSLen Brown arg->common.value.name = 4294be44fcdSLen Brown acpi_ps_get_next_namestring(parser_state); 430c51a4de8SBob Moore return_VOID; 4311da177e4SLinus Torvalds 4321da177e4SLinus Torvalds default: 4331da177e4SLinus Torvalds 434f6a22b0bSBob Moore ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type)); 435c51a4de8SBob Moore return_VOID; 4361da177e4SLinus Torvalds } 4371da177e4SLinus Torvalds 438c51a4de8SBob Moore acpi_ps_init_op(arg, opcode); 439c51a4de8SBob Moore parser_state->aml += length; 4401da177e4SLinus Torvalds return_VOID; 4411da177e4SLinus Torvalds } 4421da177e4SLinus Torvalds 4431da177e4SLinus Torvalds /******************************************************************************* 4441da177e4SLinus Torvalds * 4451da177e4SLinus Torvalds * FUNCTION: acpi_ps_get_next_field 4461da177e4SLinus Torvalds * 4471da177e4SLinus Torvalds * PARAMETERS: parser_state - Current parser state object 4481da177e4SLinus Torvalds * 4491da177e4SLinus Torvalds * RETURN: A newly allocated FIELD op 4501da177e4SLinus Torvalds * 4511da177e4SLinus Torvalds * DESCRIPTION: Get next field (named_field, reserved_field, or access_field) 4521da177e4SLinus Torvalds * 4531da177e4SLinus Torvalds ******************************************************************************/ 4541da177e4SLinus Torvalds 4554be44fcdSLen Brown static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state 4564be44fcdSLen Brown *parser_state) 4571da177e4SLinus Torvalds { 458950a429cSLv Zheng u8 *aml; 4591da177e4SLinus Torvalds union acpi_parse_object *field; 4609ce81784SBob Moore union acpi_parse_object *arg = NULL; 4611da177e4SLinus Torvalds u16 opcode; 4621da177e4SLinus Torvalds u32 name; 4639ce81784SBob Moore u8 access_type; 4649ce81784SBob Moore u8 access_attribute; 4659ce81784SBob Moore u8 access_length; 4669ce81784SBob Moore u32 pkg_length; 4679ce81784SBob Moore u8 *pkg_end; 4689ce81784SBob Moore u32 buffer_length; 4691da177e4SLinus Torvalds 470b229cf92SBob Moore ACPI_FUNCTION_TRACE(ps_get_next_field); 4711da177e4SLinus Torvalds 4729cf7adecSBob Moore ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 473950a429cSLv Zheng aml = parser_state->aml; 4749ce81784SBob Moore 47544f6c012SRobert Moore /* Determine field type */ 4761da177e4SLinus Torvalds 4771da177e4SLinus Torvalds switch (ACPI_GET8(parser_state->aml)) { 4789ce81784SBob Moore case AML_FIELD_OFFSET_OP: 4791da177e4SLinus Torvalds 4801da177e4SLinus Torvalds opcode = AML_INT_RESERVEDFIELD_OP; 4811da177e4SLinus Torvalds parser_state->aml++; 4821da177e4SLinus Torvalds break; 4831da177e4SLinus Torvalds 4849ce81784SBob Moore case AML_FIELD_ACCESS_OP: 4851da177e4SLinus Torvalds 4861da177e4SLinus Torvalds opcode = AML_INT_ACCESSFIELD_OP; 4871da177e4SLinus Torvalds parser_state->aml++; 4881da177e4SLinus Torvalds break; 4899ce81784SBob Moore 4909ce81784SBob Moore case AML_FIELD_CONNECTION_OP: 4919ce81784SBob Moore 4929ce81784SBob Moore opcode = AML_INT_CONNECTION_OP; 4939ce81784SBob Moore parser_state->aml++; 4949ce81784SBob Moore break; 4959ce81784SBob Moore 4969ce81784SBob Moore case AML_FIELD_EXT_ACCESS_OP: 4979ce81784SBob Moore 4989ce81784SBob Moore opcode = AML_INT_EXTACCESSFIELD_OP; 4999ce81784SBob Moore parser_state->aml++; 5009ce81784SBob Moore break; 5019ce81784SBob Moore 5029ce81784SBob Moore default: 5039ce81784SBob Moore 5049ce81784SBob Moore opcode = AML_INT_NAMEDFIELD_OP; 5059ce81784SBob Moore break; 5061da177e4SLinus Torvalds } 5071da177e4SLinus Torvalds 5081da177e4SLinus Torvalds /* Allocate a new field op */ 5091da177e4SLinus Torvalds 51062eb935bSLv Zheng field = acpi_ps_alloc_op(opcode, aml); 5111da177e4SLinus Torvalds if (!field) { 5121da177e4SLinus Torvalds return_PTR(NULL); 5131da177e4SLinus Torvalds } 5141da177e4SLinus Torvalds 5151da177e4SLinus Torvalds /* Decode the field type */ 5161da177e4SLinus Torvalds 5179cf7adecSBob Moore ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 5181da177e4SLinus Torvalds switch (opcode) { 5191da177e4SLinus Torvalds case AML_INT_NAMEDFIELD_OP: 5201da177e4SLinus Torvalds 5211da177e4SLinus Torvalds /* Get the 4-character name */ 5221da177e4SLinus Torvalds 5231da177e4SLinus Torvalds ACPI_MOVE_32_TO_32(&name, parser_state->aml); 5241da177e4SLinus Torvalds acpi_ps_set_name(field, name); 52532786755SBob Moore parser_state->aml += ACPI_NAMESEG_SIZE; 5261da177e4SLinus Torvalds 5279cf7adecSBob Moore ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 5289cf7adecSBob Moore 5299cf7adecSBob Moore #ifdef ACPI_ASL_COMPILER 5309cf7adecSBob Moore /* 5319cf7adecSBob Moore * Because the package length isn't represented as a parse tree object, 5329cf7adecSBob Moore * take comments surrounding this and add to the previously created 5339cf7adecSBob Moore * parse node. 5349cf7adecSBob Moore */ 5359cf7adecSBob Moore if (field->common.inline_comment) { 5369cf7adecSBob Moore field->common.name_comment = 5379cf7adecSBob Moore field->common.inline_comment; 5389cf7adecSBob Moore } 5399cf7adecSBob Moore field->common.inline_comment = acpi_gbl_current_inline_comment; 5409cf7adecSBob Moore acpi_gbl_current_inline_comment = NULL; 5419cf7adecSBob Moore #endif 5429cf7adecSBob Moore 5431da177e4SLinus Torvalds /* Get the length which is encoded as a package length */ 5441da177e4SLinus Torvalds 5454be44fcdSLen Brown field->common.value.size = 5464be44fcdSLen Brown acpi_ps_get_next_package_length(parser_state); 5471da177e4SLinus Torvalds break; 5481da177e4SLinus Torvalds 5491da177e4SLinus Torvalds case AML_INT_RESERVEDFIELD_OP: 5501da177e4SLinus Torvalds 5511da177e4SLinus Torvalds /* Get the length which is encoded as a package length */ 5521da177e4SLinus Torvalds 5534be44fcdSLen Brown field->common.value.size = 5544be44fcdSLen Brown acpi_ps_get_next_package_length(parser_state); 5551da177e4SLinus Torvalds break; 5561da177e4SLinus Torvalds 5571da177e4SLinus Torvalds case AML_INT_ACCESSFIELD_OP: 5589ce81784SBob Moore case AML_INT_EXTACCESSFIELD_OP: 5591da177e4SLinus Torvalds 5601da177e4SLinus Torvalds /* 5611da177e4SLinus Torvalds * Get access_type and access_attrib and merge into the field Op 5629ce81784SBob Moore * access_type is first operand, access_attribute is second. stuff 5639ce81784SBob Moore * these bytes into the node integer value for convenience. 5641da177e4SLinus Torvalds */ 5659ce81784SBob Moore 5669ce81784SBob Moore /* Get the two bytes (Type/Attribute) */ 5679ce81784SBob Moore 5689ce81784SBob Moore access_type = ACPI_GET8(parser_state->aml); 5691da177e4SLinus Torvalds parser_state->aml++; 5709ce81784SBob Moore access_attribute = ACPI_GET8(parser_state->aml); 5711da177e4SLinus Torvalds parser_state->aml++; 5729ce81784SBob Moore 5739ce81784SBob Moore field->common.value.integer = (u8)access_type; 5749ce81784SBob Moore field->common.value.integer |= (u16)(access_attribute << 8); 5759ce81784SBob Moore 5769ce81784SBob Moore /* This opcode has a third byte, access_length */ 5779ce81784SBob Moore 5789ce81784SBob Moore if (opcode == AML_INT_EXTACCESSFIELD_OP) { 5799ce81784SBob Moore access_length = ACPI_GET8(parser_state->aml); 5809ce81784SBob Moore parser_state->aml++; 5819ce81784SBob Moore 5829ce81784SBob Moore field->common.value.integer |= 5839ce81784SBob Moore (u32)(access_length << 16); 5849ce81784SBob Moore } 5859ce81784SBob Moore break; 5869ce81784SBob Moore 5879ce81784SBob Moore case AML_INT_CONNECTION_OP: 5889ce81784SBob Moore 5899ce81784SBob Moore /* 5909ce81784SBob Moore * Argument for Connection operator can be either a Buffer 5919ce81784SBob Moore * (resource descriptor), or a name_string. 5929ce81784SBob Moore */ 59362eb935bSLv Zheng aml = parser_state->aml; 5949ce81784SBob Moore if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) { 5959ce81784SBob Moore parser_state->aml++; 5969ce81784SBob Moore 5979cf7adecSBob Moore ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 5989ce81784SBob Moore pkg_end = parser_state->aml; 5999ce81784SBob Moore pkg_length = 6009ce81784SBob Moore acpi_ps_get_next_package_length(parser_state); 6019ce81784SBob Moore pkg_end += pkg_length; 6029ce81784SBob Moore 6039cf7adecSBob Moore ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 6049ce81784SBob Moore if (parser_state->aml < pkg_end) { 6059ce81784SBob Moore 6069ce81784SBob Moore /* Non-empty list */ 6079ce81784SBob Moore 60862eb935bSLv Zheng arg = 60962eb935bSLv Zheng acpi_ps_alloc_op(AML_INT_BYTELIST_OP, aml); 6109ce81784SBob Moore if (!arg) { 6116af1c4fcSJesper Juhl acpi_ps_free_op(field); 6129ce81784SBob Moore return_PTR(NULL); 6139ce81784SBob Moore } 6149ce81784SBob Moore 6159ce81784SBob Moore /* Get the actual buffer length argument */ 6169ce81784SBob Moore 6179ce81784SBob Moore opcode = ACPI_GET8(parser_state->aml); 6189ce81784SBob Moore parser_state->aml++; 6199ce81784SBob Moore 6209cf7adecSBob Moore ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 6219ce81784SBob Moore switch (opcode) { 6229ce81784SBob Moore case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 6231d1ea1b7SChao Guan 6249ce81784SBob Moore buffer_length = 6259ce81784SBob Moore ACPI_GET8(parser_state->aml); 6269ce81784SBob Moore parser_state->aml += 1; 6279ce81784SBob Moore break; 6289ce81784SBob Moore 6299ce81784SBob Moore case AML_WORD_OP: /* AML_WORDDATA_ARG */ 6301d1ea1b7SChao Guan 6319ce81784SBob Moore buffer_length = 6329ce81784SBob Moore ACPI_GET16(parser_state->aml); 6339ce81784SBob Moore parser_state->aml += 2; 6349ce81784SBob Moore break; 6359ce81784SBob Moore 6369ce81784SBob Moore case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 6371d1ea1b7SChao Guan 6389ce81784SBob Moore buffer_length = 6399ce81784SBob Moore ACPI_GET32(parser_state->aml); 6409ce81784SBob Moore parser_state->aml += 4; 6419ce81784SBob Moore break; 6429ce81784SBob Moore 6439ce81784SBob Moore default: 6441d1ea1b7SChao Guan 6459ce81784SBob Moore buffer_length = 0; 6469ce81784SBob Moore break; 6479ce81784SBob Moore } 6489ce81784SBob Moore 6499ce81784SBob Moore /* Fill in bytelist data */ 6509ce81784SBob Moore 6519cf7adecSBob Moore ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); 6529ce81784SBob Moore arg->named.value.size = buffer_length; 6539ce81784SBob Moore arg->named.data = parser_state->aml; 6549ce81784SBob Moore } 6559ce81784SBob Moore 6569ce81784SBob Moore /* Skip to End of byte data */ 6579ce81784SBob Moore 6589ce81784SBob Moore parser_state->aml = pkg_end; 6599ce81784SBob Moore } else { 66062eb935bSLv Zheng arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, aml); 6619ce81784SBob Moore if (!arg) { 6626af1c4fcSJesper Juhl acpi_ps_free_op(field); 6639ce81784SBob Moore return_PTR(NULL); 6649ce81784SBob Moore } 6659ce81784SBob Moore 6669ce81784SBob Moore /* Get the Namestring argument */ 6679ce81784SBob Moore 6689ce81784SBob Moore arg->common.value.name = 6699ce81784SBob Moore acpi_ps_get_next_namestring(parser_state); 6709ce81784SBob Moore } 6719ce81784SBob Moore 6729ce81784SBob Moore /* Link the buffer/namestring to parent (CONNECTION_OP) */ 6739ce81784SBob Moore 6749ce81784SBob Moore acpi_ps_append_arg(field, arg); 6751da177e4SLinus Torvalds break; 6761da177e4SLinus Torvalds 6771da177e4SLinus Torvalds default: 6781da177e4SLinus Torvalds 6791da177e4SLinus Torvalds /* Opcode was set in previous switch */ 6801da177e4SLinus Torvalds break; 6811da177e4SLinus Torvalds } 6821da177e4SLinus Torvalds 6831da177e4SLinus Torvalds return_PTR(field); 6841da177e4SLinus Torvalds } 6851da177e4SLinus Torvalds 6861da177e4SLinus Torvalds /******************************************************************************* 6871da177e4SLinus Torvalds * 6881da177e4SLinus Torvalds * FUNCTION: acpi_ps_get_next_arg 6891da177e4SLinus Torvalds * 69044f6c012SRobert Moore * PARAMETERS: walk_state - Current state 69144f6c012SRobert Moore * parser_state - Current parser state object 6920dda8851SBob Moore * arg_type - The argument type (AML_*_ARG) 69344f6c012SRobert Moore * return_arg - Where the next arg is returned 6941da177e4SLinus Torvalds * 6951da177e4SLinus Torvalds * RETURN: Status, and an op object containing the next argument. 6961da177e4SLinus Torvalds * 6971da177e4SLinus Torvalds * DESCRIPTION: Get next argument (including complex list arguments that require 6981da177e4SLinus Torvalds * pushing the parser stack) 6991da177e4SLinus Torvalds * 7001da177e4SLinus Torvalds ******************************************************************************/ 7011da177e4SLinus Torvalds 7021da177e4SLinus Torvalds acpi_status 7034be44fcdSLen Brown acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, 7041da177e4SLinus Torvalds struct acpi_parse_state *parser_state, 7054be44fcdSLen Brown u32 arg_type, union acpi_parse_object **return_arg) 7061da177e4SLinus Torvalds { 7071da177e4SLinus Torvalds union acpi_parse_object *arg = NULL; 7081da177e4SLinus Torvalds union acpi_parse_object *prev = NULL; 7091da177e4SLinus Torvalds union acpi_parse_object *field; 7101da177e4SLinus Torvalds u32 subop; 7111da177e4SLinus Torvalds acpi_status status = AE_OK; 7121da177e4SLinus Torvalds 713b229cf92SBob Moore ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state); 7141da177e4SLinus Torvalds 715ce87e09dSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 716ce87e09dSBob Moore "Expected argument type ARGP: %s (%2.2X)\n", 717ce87e09dSBob Moore acpi_ut_get_argument_type_name(arg_type), arg_type)); 718ce87e09dSBob Moore 7191da177e4SLinus Torvalds switch (arg_type) { 7201da177e4SLinus Torvalds case ARGP_BYTEDATA: 7211da177e4SLinus Torvalds case ARGP_WORDDATA: 7221da177e4SLinus Torvalds case ARGP_DWORDDATA: 7231da177e4SLinus Torvalds case ARGP_CHARLIST: 7241da177e4SLinus Torvalds case ARGP_NAME: 7251da177e4SLinus Torvalds case ARGP_NAMESTRING: 7261da177e4SLinus Torvalds 72744f6c012SRobert Moore /* Constants, strings, and namestrings are all the same size */ 7281da177e4SLinus Torvalds 72962eb935bSLv Zheng arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml); 7301da177e4SLinus Torvalds if (!arg) { 7311da177e4SLinus Torvalds return_ACPI_STATUS(AE_NO_MEMORY); 7321da177e4SLinus Torvalds } 7331fad8738SBob Moore 7341da177e4SLinus Torvalds acpi_ps_get_next_simple_arg(parser_state, arg_type, arg); 7351da177e4SLinus Torvalds break; 7361da177e4SLinus Torvalds 7371da177e4SLinus Torvalds case ARGP_PKGLENGTH: 7381da177e4SLinus Torvalds 7391da177e4SLinus Torvalds /* Package length, nothing returned */ 7401da177e4SLinus Torvalds 7414be44fcdSLen Brown parser_state->pkg_end = 7424be44fcdSLen Brown acpi_ps_get_next_package_end(parser_state); 7431da177e4SLinus Torvalds break; 7441da177e4SLinus Torvalds 7451da177e4SLinus Torvalds case ARGP_FIELDLIST: 7461da177e4SLinus Torvalds 7471da177e4SLinus Torvalds if (parser_state->aml < parser_state->pkg_end) { 74852fc0b02SBob Moore 7491da177e4SLinus Torvalds /* Non-empty list */ 7501da177e4SLinus Torvalds 7511da177e4SLinus Torvalds while (parser_state->aml < parser_state->pkg_end) { 7521da177e4SLinus Torvalds field = acpi_ps_get_next_field(parser_state); 7531da177e4SLinus Torvalds if (!field) { 7541da177e4SLinus Torvalds return_ACPI_STATUS(AE_NO_MEMORY); 7551da177e4SLinus Torvalds } 7561da177e4SLinus Torvalds 7571da177e4SLinus Torvalds if (prev) { 7581da177e4SLinus Torvalds prev->common.next = field; 7594be44fcdSLen Brown } else { 7601da177e4SLinus Torvalds arg = field; 7611da177e4SLinus Torvalds } 7621da177e4SLinus Torvalds prev = field; 7631da177e4SLinus Torvalds } 7641da177e4SLinus Torvalds 7651da177e4SLinus Torvalds /* Skip to End of byte data */ 7661da177e4SLinus Torvalds 7671da177e4SLinus Torvalds parser_state->aml = parser_state->pkg_end; 7681da177e4SLinus Torvalds } 7691da177e4SLinus Torvalds break; 7701da177e4SLinus Torvalds 7711da177e4SLinus Torvalds case ARGP_BYTELIST: 7721da177e4SLinus Torvalds 7731da177e4SLinus Torvalds if (parser_state->aml < parser_state->pkg_end) { 77452fc0b02SBob Moore 7751da177e4SLinus Torvalds /* Non-empty list */ 7761da177e4SLinus Torvalds 77762eb935bSLv Zheng arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP, 77862eb935bSLv Zheng parser_state->aml); 7791da177e4SLinus Torvalds if (!arg) { 7801da177e4SLinus Torvalds return_ACPI_STATUS(AE_NO_MEMORY); 7811da177e4SLinus Torvalds } 7821da177e4SLinus Torvalds 7831da177e4SLinus Torvalds /* Fill in bytelist data */ 7841da177e4SLinus Torvalds 78544f6c012SRobert Moore arg->common.value.size = (u32) 7864be44fcdSLen Brown ACPI_PTR_DIFF(parser_state->pkg_end, 7874be44fcdSLen Brown parser_state->aml); 7881da177e4SLinus Torvalds arg->named.data = parser_state->aml; 7891da177e4SLinus Torvalds 7901da177e4SLinus Torvalds /* Skip to End of byte data */ 7911da177e4SLinus Torvalds 7921da177e4SLinus Torvalds parser_state->aml = parser_state->pkg_end; 7931da177e4SLinus Torvalds } 7941da177e4SLinus Torvalds break; 7951da177e4SLinus Torvalds 7961da177e4SLinus Torvalds case ARGP_SIMPLENAME: 797cca7a6eaSBob Moore case ARGP_NAME_OR_REF: 7981da177e4SLinus Torvalds 799ce87e09dSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 800ce87e09dSBob Moore "**** SimpleName/NameOrRef: %s (%2.2X)\n", 801ce87e09dSBob Moore acpi_ut_get_argument_type_name(arg_type), 802ce87e09dSBob Moore arg_type)); 803ce87e09dSBob Moore 8041da177e4SLinus Torvalds subop = acpi_ps_peek_opcode(parser_state); 8051da177e4SLinus Torvalds if (subop == 0 || 8061da177e4SLinus Torvalds acpi_ps_is_leading_char(subop) || 80704a81dceSBob Moore ACPI_IS_ROOT_PREFIX(subop) || 80804a81dceSBob Moore ACPI_IS_PARENT_PREFIX(subop)) { 80952fc0b02SBob Moore 8101da177e4SLinus Torvalds /* null_name or name_string */ 8111da177e4SLinus Torvalds 81262eb935bSLv Zheng arg = 81362eb935bSLv Zheng acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, 81462eb935bSLv Zheng parser_state->aml); 8151da177e4SLinus Torvalds if (!arg) { 8161da177e4SLinus Torvalds return_ACPI_STATUS(AE_NO_MEMORY); 8171da177e4SLinus Torvalds } 8181da177e4SLinus Torvalds 8194be44fcdSLen Brown status = 820ce87e09dSBob Moore acpi_ps_get_next_namepath(walk_state, parser_state, 821ce87e09dSBob Moore arg, 82289438f96SBob Moore ACPI_NOT_METHOD_CALL); 823ce87e09dSBob Moore } else { 824ce87e09dSBob Moore /* Single complex argument, nothing returned */ 825ce87e09dSBob Moore 826ce87e09dSBob Moore walk_state->arg_count = 1; 827bc7a36abSLin Ming } 828ce87e09dSBob Moore break; 829ce87e09dSBob Moore 830ce87e09dSBob Moore case ARGP_TARGET: 831ce87e09dSBob Moore case ARGP_SUPERNAME: 832ce87e09dSBob Moore 833ce87e09dSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 834ce87e09dSBob Moore "**** Target/Supername: %s (%2.2X)\n", 835ce87e09dSBob Moore acpi_ut_get_argument_type_name(arg_type), 836ce87e09dSBob Moore arg_type)); 837ce87e09dSBob Moore 838ce87e09dSBob Moore subop = acpi_ps_peek_opcode(parser_state); 8399a947291SBob Moore if (subop == 0 || 8409a947291SBob Moore acpi_ps_is_leading_char(subop) || 8419a947291SBob Moore ACPI_IS_ROOT_PREFIX(subop) || 8429a947291SBob Moore ACPI_IS_PARENT_PREFIX(subop)) { 843ce87e09dSBob Moore 844ce87e09dSBob Moore /* NULL target (zero). Convert to a NULL namepath */ 845ce87e09dSBob Moore 846ce87e09dSBob Moore arg = 847ce87e09dSBob Moore acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, 848ce87e09dSBob Moore parser_state->aml); 849ce87e09dSBob Moore if (!arg) { 850ce87e09dSBob Moore return_ACPI_STATUS(AE_NO_MEMORY); 851ce87e09dSBob Moore } 852ce87e09dSBob Moore 853ce87e09dSBob Moore status = 854ce87e09dSBob Moore acpi_ps_get_next_namepath(walk_state, parser_state, 855ce87e09dSBob Moore arg, 856ce87e09dSBob Moore ACPI_POSSIBLE_METHOD_CALL); 8579a947291SBob Moore 8589a947291SBob Moore if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) { 8591c29c372SBob Moore 8601c29c372SBob Moore /* Free method call op and corresponding namestring sub-ob */ 8611c29c372SBob Moore 8621c29c372SBob Moore acpi_ps_free_op(arg->common.value.arg); 8639a947291SBob Moore acpi_ps_free_op(arg); 8649a947291SBob Moore arg = NULL; 8659a947291SBob Moore walk_state->arg_count = 1; 8669a947291SBob Moore } 8674be44fcdSLen Brown } else { 86844f6c012SRobert Moore /* Single complex argument, nothing returned */ 8691da177e4SLinus Torvalds 8701da177e4SLinus Torvalds walk_state->arg_count = 1; 8711da177e4SLinus Torvalds } 8721da177e4SLinus Torvalds break; 8731da177e4SLinus Torvalds 8741da177e4SLinus Torvalds case ARGP_DATAOBJ: 8751da177e4SLinus Torvalds case ARGP_TERMARG: 8761da177e4SLinus Torvalds 877ce87e09dSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 878ce87e09dSBob Moore "**** TermArg/DataObj: %s (%2.2X)\n", 879ce87e09dSBob Moore acpi_ut_get_argument_type_name(arg_type), 880ce87e09dSBob Moore arg_type)); 881ce87e09dSBob Moore 88244f6c012SRobert Moore /* Single complex argument, nothing returned */ 8831da177e4SLinus Torvalds 8841da177e4SLinus Torvalds walk_state->arg_count = 1; 8851da177e4SLinus Torvalds break; 8861da177e4SLinus Torvalds 8871da177e4SLinus Torvalds case ARGP_DATAOBJLIST: 8881da177e4SLinus Torvalds case ARGP_TERMLIST: 8891da177e4SLinus Torvalds case ARGP_OBJLIST: 8901da177e4SLinus Torvalds 8911da177e4SLinus Torvalds if (parser_state->aml < parser_state->pkg_end) { 89252fc0b02SBob Moore 89344f6c012SRobert Moore /* Non-empty list of variable arguments, nothing returned */ 8941da177e4SLinus Torvalds 8951da177e4SLinus Torvalds walk_state->arg_count = ACPI_VAR_ARGS; 8961da177e4SLinus Torvalds } 8971da177e4SLinus Torvalds break; 8981da177e4SLinus Torvalds 8991da177e4SLinus Torvalds default: 9001da177e4SLinus Torvalds 901f6a22b0bSBob Moore ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type)); 9021da177e4SLinus Torvalds status = AE_AML_OPERAND_TYPE; 9031da177e4SLinus Torvalds break; 9041da177e4SLinus Torvalds } 9051da177e4SLinus Torvalds 9061da177e4SLinus Torvalds *return_arg = arg; 9071da177e4SLinus Torvalds return_ACPI_STATUS(status); 9081da177e4SLinus Torvalds } 909