xref: /openbmc/linux/drivers/acpi/acpica/dsfield.c (revision 612c2932)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown  *
495b482a8SLen Brown  * Module Name: dsfield - Dispatcher field routines
595b482a8SLen Brown  *
6*612c2932SBob Moore  * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown  *
895857638SErik Schmauss  *****************************************************************************/
995b482a8SLen Brown 
1095b482a8SLen Brown #include <acpi/acpi.h>
11e2f7a777SLen Brown #include "accommon.h"
12e2f7a777SLen Brown #include "amlcode.h"
13e2f7a777SLen Brown #include "acdispat.h"
14e2f7a777SLen Brown #include "acinterp.h"
15e2f7a777SLen Brown #include "acnamesp.h"
16e2f7a777SLen Brown #include "acparser.h"
1795b482a8SLen Brown 
1877d4e096SErik Schmauss #ifdef ACPI_EXEC_APP
1977d4e096SErik Schmauss #include "aecommon.h"
2077d4e096SErik Schmauss #endif
2177d4e096SErik Schmauss 
2295b482a8SLen Brown #define _COMPONENT          ACPI_DISPATCHER
2395b482a8SLen Brown ACPI_MODULE_NAME("dsfield")
2495b482a8SLen Brown 
2595b482a8SLen Brown /* Local prototypes */
266ccd7b5aSBob Moore #ifdef ACPI_ASL_COMPILER
276ccd7b5aSBob Moore #include "acdisasm.h"
286ccd7b5aSBob Moore static acpi_status
296ccd7b5aSBob Moore acpi_ds_create_external_region(acpi_status lookup_status,
306ccd7b5aSBob Moore 			       union acpi_parse_object *op,
316ccd7b5aSBob Moore 			       char *path,
326ccd7b5aSBob Moore 			       struct acpi_walk_state *walk_state,
336ccd7b5aSBob Moore 			       struct acpi_namespace_node **node);
346ccd7b5aSBob Moore #endif
356ccd7b5aSBob Moore 
3695b482a8SLen Brown static acpi_status
3795b482a8SLen Brown acpi_ds_get_field_names(struct acpi_create_field_info *info,
3895b482a8SLen Brown 			struct acpi_walk_state *walk_state,
3995b482a8SLen Brown 			union acpi_parse_object *arg);
4095b482a8SLen Brown 
416ccd7b5aSBob Moore #ifdef ACPI_ASL_COMPILER
426ccd7b5aSBob Moore /*******************************************************************************
436ccd7b5aSBob Moore  *
44ba494beeSBob Moore  * FUNCTION:    acpi_ds_create_external_region (iASL Disassembler only)
456ccd7b5aSBob Moore  *
466ccd7b5aSBob Moore  * PARAMETERS:  lookup_status   - Status from ns_lookup operation
47ba494beeSBob Moore  *              op              - Op containing the Field definition and args
48ba494beeSBob Moore  *              path            - Pathname of the region
496ccd7b5aSBob Moore  *  `           walk_state      - Current method state
50ba494beeSBob Moore  *              node            - Where the new region node is returned
516ccd7b5aSBob Moore  *
526ccd7b5aSBob Moore  * RETURN:      Status
536ccd7b5aSBob Moore  *
546ccd7b5aSBob Moore  * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
556ccd7b5aSBob Moore  *              region node/object.
566ccd7b5aSBob Moore  *
576ccd7b5aSBob Moore  ******************************************************************************/
586ccd7b5aSBob Moore 
596ccd7b5aSBob Moore static acpi_status
acpi_ds_create_external_region(acpi_status lookup_status,union acpi_parse_object * op,char * path,struct acpi_walk_state * walk_state,struct acpi_namespace_node ** node)606ccd7b5aSBob Moore acpi_ds_create_external_region(acpi_status lookup_status,
616ccd7b5aSBob Moore 			       union acpi_parse_object *op,
626ccd7b5aSBob Moore 			       char *path,
636ccd7b5aSBob Moore 			       struct acpi_walk_state *walk_state,
646ccd7b5aSBob Moore 			       struct acpi_namespace_node **node)
656ccd7b5aSBob Moore {
666ccd7b5aSBob Moore 	acpi_status status;
676ccd7b5aSBob Moore 	union acpi_operand_object *obj_desc;
686ccd7b5aSBob Moore 
696ccd7b5aSBob Moore 	if (lookup_status != AE_NOT_FOUND) {
706ccd7b5aSBob Moore 		return (lookup_status);
716ccd7b5aSBob Moore 	}
726ccd7b5aSBob Moore 
736ccd7b5aSBob Moore 	/*
746ccd7b5aSBob Moore 	 * Table disassembly:
756ccd7b5aSBob Moore 	 * operation_region not found. Generate an External for it, and
766ccd7b5aSBob Moore 	 * insert the name into the namespace.
776ccd7b5aSBob Moore 	 */
785af2b635SBob Moore 	acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
791fad8738SBob Moore 
806ccd7b5aSBob Moore 	status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
816ccd7b5aSBob Moore 				ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
826ccd7b5aSBob Moore 				walk_state, node);
836ccd7b5aSBob Moore 	if (ACPI_FAILURE(status)) {
846ccd7b5aSBob Moore 		return (status);
856ccd7b5aSBob Moore 	}
866ccd7b5aSBob Moore 
876ccd7b5aSBob Moore 	/* Must create and install a region object for the new node */
886ccd7b5aSBob Moore 
896ccd7b5aSBob Moore 	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
906ccd7b5aSBob Moore 	if (!obj_desc) {
916ccd7b5aSBob Moore 		return (AE_NO_MEMORY);
926ccd7b5aSBob Moore 	}
936ccd7b5aSBob Moore 
946ccd7b5aSBob Moore 	obj_desc->region.node = *node;
956ccd7b5aSBob Moore 	status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
966ccd7b5aSBob Moore 	return (status);
976ccd7b5aSBob Moore }
986ccd7b5aSBob Moore #endif
996ccd7b5aSBob Moore 
10095b482a8SLen Brown /*******************************************************************************
10195b482a8SLen Brown  *
10295b482a8SLen Brown  * FUNCTION:    acpi_ds_create_buffer_field
10395b482a8SLen Brown  *
104ba494beeSBob Moore  * PARAMETERS:  op                  - Current parse op (create_XXField)
10595b482a8SLen Brown  *              walk_state          - Current state
10695b482a8SLen Brown  *
10795b482a8SLen Brown  * RETURN:      Status
10895b482a8SLen Brown  *
10995b482a8SLen Brown  * DESCRIPTION: Execute the create_field operators:
11095b482a8SLen Brown  *              create_bit_field_op,
11195b482a8SLen Brown  *              create_byte_field_op,
11295b482a8SLen Brown  *              create_word_field_op,
11395b482a8SLen Brown  *              create_dword_field_op,
11495b482a8SLen Brown  *              create_qword_field_op,
11595b482a8SLen Brown  *              create_field_op     (all of which define a field in a buffer)
11695b482a8SLen Brown  *
11795b482a8SLen Brown  ******************************************************************************/
11895b482a8SLen Brown 
11995b482a8SLen Brown acpi_status
acpi_ds_create_buffer_field(union acpi_parse_object * op,struct acpi_walk_state * walk_state)12095b482a8SLen Brown acpi_ds_create_buffer_field(union acpi_parse_object *op,
12195b482a8SLen Brown 			    struct acpi_walk_state *walk_state)
12295b482a8SLen Brown {
12395b482a8SLen Brown 	union acpi_parse_object *arg;
12495b482a8SLen Brown 	struct acpi_namespace_node *node;
12595b482a8SLen Brown 	acpi_status status;
12695b482a8SLen Brown 	union acpi_operand_object *obj_desc;
12795b482a8SLen Brown 	union acpi_operand_object *second_desc = NULL;
12895b482a8SLen Brown 	u32 flags;
12995b482a8SLen Brown 
13095b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ds_create_buffer_field);
13195b482a8SLen Brown 
13295b482a8SLen Brown 	/*
13395b482a8SLen Brown 	 * Get the name_string argument (name of the new buffer_field)
13495b482a8SLen Brown 	 */
13595b482a8SLen Brown 	if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
13695b482a8SLen Brown 
13795b482a8SLen Brown 		/* For create_field, name is the 4th argument */
13895b482a8SLen Brown 
13995b482a8SLen Brown 		arg = acpi_ps_get_arg(op, 3);
14095b482a8SLen Brown 	} else {
141ba494beeSBob Moore 		/* For all other create_XXXField operators, name is the 3rd argument */
14295b482a8SLen Brown 
14395b482a8SLen Brown 		arg = acpi_ps_get_arg(op, 2);
14495b482a8SLen Brown 	}
14595b482a8SLen Brown 
14695b482a8SLen Brown 	if (!arg) {
14795b482a8SLen Brown 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
14895b482a8SLen Brown 	}
14995b482a8SLen Brown 
15095b482a8SLen Brown 	if (walk_state->deferred_node) {
15195b482a8SLen Brown 		node = walk_state->deferred_node;
15295b482a8SLen Brown 	} else {
15395b482a8SLen Brown 		/* Execute flag should always be set when this function is entered */
15495b482a8SLen Brown 
15595b482a8SLen Brown 		if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
156376a588cSBob Moore 			ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
15795b482a8SLen Brown 			return_ACPI_STATUS(AE_AML_INTERNAL);
15895b482a8SLen Brown 		}
15995b482a8SLen Brown 
16095b482a8SLen Brown 		/* Creating new namespace node, should not already exist */
16195b482a8SLen Brown 
16295b482a8SLen Brown 		flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
16395b482a8SLen Brown 		    ACPI_NS_ERROR_IF_FOUND;
16495b482a8SLen Brown 
1657f0c826aSLin Ming 		/*
1667f0c826aSLin Ming 		 * Mark node temporary if we are executing a normal control
1677f0c826aSLin Ming 		 * method. (Don't mark if this is a module-level code method)
1687f0c826aSLin Ming 		 */
1697f0c826aSLin Ming 		if (walk_state->method_node &&
1707f0c826aSLin Ming 		    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
17195b482a8SLen Brown 			flags |= ACPI_NS_TEMPORARY;
17295b482a8SLen Brown 		}
17395b482a8SLen Brown 
17495b482a8SLen Brown 		/* Enter the name_string into the namespace */
17595b482a8SLen Brown 
1761fad8738SBob Moore 		status = acpi_ns_lookup(walk_state->scope_info,
17795b482a8SLen Brown 					arg->common.value.string, ACPI_TYPE_ANY,
1781fad8738SBob Moore 					ACPI_IMODE_LOAD_PASS1, flags,
1791fad8738SBob Moore 					walk_state, &node);
180034fdaa5SErik Kaneda 		if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE)
181034fdaa5SErik Kaneda 		    && status == AE_ALREADY_EXISTS) {
182034fdaa5SErik Kaneda 			status = AE_OK;
183034fdaa5SErik Kaneda 		} else if (ACPI_FAILURE(status)) {
18416ccf829SBob Moore 			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
18516ccf829SBob Moore 					     arg->common.value.string, status);
18695b482a8SLen Brown 			return_ACPI_STATUS(status);
18795b482a8SLen Brown 		}
18895b482a8SLen Brown 	}
18995b482a8SLen Brown 
19095b482a8SLen Brown 	/*
19195b482a8SLen Brown 	 * We could put the returned object (Node) on the object stack for later,
19295b482a8SLen Brown 	 * but for now, we will put it in the "op" object that the parser uses,
19395b482a8SLen Brown 	 * so we can get it again at the end of this scope.
19495b482a8SLen Brown 	 */
19595b482a8SLen Brown 	op->common.node = node;
19695b482a8SLen Brown 
19795b482a8SLen Brown 	/*
19895b482a8SLen Brown 	 * If there is no object attached to the node, this node was just created
19995b482a8SLen Brown 	 * and we need to create the field object. Otherwise, this was a lookup
20095b482a8SLen Brown 	 * of an existing node and we don't want to create the field object again.
20195b482a8SLen Brown 	 */
20295b482a8SLen Brown 	obj_desc = acpi_ns_get_attached_object(node);
20395b482a8SLen Brown 	if (obj_desc) {
20495b482a8SLen Brown 		return_ACPI_STATUS(AE_OK);
20595b482a8SLen Brown 	}
20695b482a8SLen Brown 
20795b482a8SLen Brown 	/*
20895b482a8SLen Brown 	 * The Field definition is not fully parsed at this time.
20995b482a8SLen Brown 	 * (We must save the address of the AML for the buffer and index operands)
21095b482a8SLen Brown 	 */
21195b482a8SLen Brown 
21295b482a8SLen Brown 	/* Create the buffer field object */
21395b482a8SLen Brown 
21495b482a8SLen Brown 	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
21595b482a8SLen Brown 	if (!obj_desc) {
21695b482a8SLen Brown 		status = AE_NO_MEMORY;
21795b482a8SLen Brown 		goto cleanup;
21895b482a8SLen Brown 	}
21995b482a8SLen Brown 
22095b482a8SLen Brown 	/*
2211fad8738SBob Moore 	 * Remember location in AML stream of the field unit opcode and operands
2221fad8738SBob Moore 	 * -- since the buffer and index operands must be evaluated.
22395b482a8SLen Brown 	 */
22495b482a8SLen Brown 	second_desc = obj_desc->common.next_object;
22595b482a8SLen Brown 	second_desc->extra.aml_start = op->named.data;
22695b482a8SLen Brown 	second_desc->extra.aml_length = op->named.length;
22795b482a8SLen Brown 	obj_desc->buffer_field.node = node;
22895b482a8SLen Brown 
22995b482a8SLen Brown 	/* Attach constructed field descriptors to parent node */
23095b482a8SLen Brown 
23195b482a8SLen Brown 	status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
23295b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
23395b482a8SLen Brown 		goto cleanup;
23495b482a8SLen Brown 	}
23595b482a8SLen Brown 
23695b482a8SLen Brown cleanup:
23795b482a8SLen Brown 
23895b482a8SLen Brown 	/* Remove local reference to the object */
23995b482a8SLen Brown 
24095b482a8SLen Brown 	acpi_ut_remove_reference(obj_desc);
24195b482a8SLen Brown 	return_ACPI_STATUS(status);
24295b482a8SLen Brown }
24395b482a8SLen Brown 
24495b482a8SLen Brown /*******************************************************************************
24595b482a8SLen Brown  *
24695b482a8SLen Brown  * FUNCTION:    acpi_ds_get_field_names
24795b482a8SLen Brown  *
248ba494beeSBob Moore  * PARAMETERS:  info            - create_field info structure
2495ddbd771SErik Kaneda  *              walk_state      - Current method state
250ba494beeSBob Moore  *              arg             - First parser arg for the field name list
25195b482a8SLen Brown  *
25295b482a8SLen Brown  * RETURN:      Status
25395b482a8SLen Brown  *
25495b482a8SLen Brown  * DESCRIPTION: Process all named fields in a field declaration. Names are
25595b482a8SLen Brown  *              entered into the namespace.
25695b482a8SLen Brown  *
25795b482a8SLen Brown  ******************************************************************************/
25895b482a8SLen Brown 
25995b482a8SLen Brown static acpi_status
acpi_ds_get_field_names(struct acpi_create_field_info * info,struct acpi_walk_state * walk_state,union acpi_parse_object * arg)26095b482a8SLen Brown acpi_ds_get_field_names(struct acpi_create_field_info *info,
26195b482a8SLen Brown 			struct acpi_walk_state *walk_state,
26295b482a8SLen Brown 			union acpi_parse_object *arg)
26395b482a8SLen Brown {
26495b482a8SLen Brown 	acpi_status status;
2655df7e6cbSBob Moore 	u64 position;
2669ce81784SBob Moore 	union acpi_parse_object *child;
26795b482a8SLen Brown 
26877d4e096SErik Schmauss #ifdef ACPI_EXEC_APP
26977d4e096SErik Schmauss 	union acpi_operand_object *result_desc;
27077d4e096SErik Schmauss 	union acpi_operand_object *obj_desc;
27177d4e096SErik Schmauss 	char *name_path;
27277d4e096SErik Schmauss #endif
27377d4e096SErik Schmauss 
27495b482a8SLen Brown 	ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
27595b482a8SLen Brown 
27695b482a8SLen Brown 	/* First field starts at bit zero */
27795b482a8SLen Brown 
27895b482a8SLen Brown 	info->field_bit_position = 0;
27995b482a8SLen Brown 
28095b482a8SLen Brown 	/* Process all elements in the field list (of parse nodes) */
28195b482a8SLen Brown 
28295b482a8SLen Brown 	while (arg) {
28395b482a8SLen Brown 		/*
2849ce81784SBob Moore 		 * Four types of field elements are handled:
285ba494beeSBob Moore 		 * 1) name - Enters a new named field into the namespace
286ba494beeSBob Moore 		 * 2) offset - specifies a bit offset
2879ce81784SBob Moore 		 * 3) access_as - changes the access mode/attributes
288ba494beeSBob Moore 		 * 4) connection - Associate a resource template with the field
28995b482a8SLen Brown 		 */
29095b482a8SLen Brown 		switch (arg->common.aml_opcode) {
29195b482a8SLen Brown 		case AML_INT_RESERVEDFIELD_OP:
29295b482a8SLen Brown 
2931fad8738SBob Moore 			position = (u64)info->field_bit_position +
2941fad8738SBob Moore 			    (u64)arg->common.value.size;
29595b482a8SLen Brown 
29695b482a8SLen Brown 			if (position > ACPI_UINT32_MAX) {
29795b482a8SLen Brown 				ACPI_ERROR((AE_INFO,
29895b482a8SLen Brown 					    "Bit offset within field too large (> 0xFFFFFFFF)"));
29995b482a8SLen Brown 				return_ACPI_STATUS(AE_SUPPORT);
30095b482a8SLen Brown 			}
30195b482a8SLen Brown 
30295b482a8SLen Brown 			info->field_bit_position = (u32) position;
30395b482a8SLen Brown 			break;
30495b482a8SLen Brown 
30595b482a8SLen Brown 		case AML_INT_ACCESSFIELD_OP:
3069ce81784SBob Moore 		case AML_INT_EXTACCESSFIELD_OP:
30795b482a8SLen Brown 			/*
3089ce81784SBob Moore 			 * Get new access_type, access_attribute, and access_length fields
3099ce81784SBob Moore 			 * -- to be used for all field units that follow, until the
3109ce81784SBob Moore 			 * end-of-field or another access_as keyword is encountered.
3119ce81784SBob Moore 			 * NOTE. These three bytes are encoded in the integer value
3129ce81784SBob Moore 			 * of the parseop for convenience.
31395b482a8SLen Brown 			 *
31495b482a8SLen Brown 			 * In field_flags, preserve the flag bits other than the
3159ce81784SBob Moore 			 * ACCESS_TYPE bits.
31695b482a8SLen Brown 			 */
3179ce81784SBob Moore 
3189ce81784SBob Moore 			/* access_type (byte_acc, word_acc, etc.) */
3199ce81784SBob Moore 
32095b482a8SLen Brown 			info->field_flags = (u8)
32195b482a8SLen Brown 			    ((info->
32295b482a8SLen Brown 			      field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
3239ce81784SBob Moore 			     ((u8)((u32)(arg->common.value.integer & 0x07))));
32495b482a8SLen Brown 
3259ce81784SBob Moore 			/* access_attribute (attrib_quick, attrib_byte, etc.) */
3269ce81784SBob Moore 
3271fad8738SBob Moore 			info->attribute = (u8)
3281fad8738SBob Moore 			    ((arg->common.value.integer >> 8) & 0xFF);
3299ce81784SBob Moore 
3309ce81784SBob Moore 			/* access_length (for serial/buffer protocols) */
3319ce81784SBob Moore 
3321fad8738SBob Moore 			info->access_length = (u8)
3331fad8738SBob Moore 			    ((arg->common.value.integer >> 16) & 0xFF);
3349ce81784SBob Moore 			break;
3359ce81784SBob Moore 
3369ce81784SBob Moore 		case AML_INT_CONNECTION_OP:
3379ce81784SBob Moore 			/*
3389ce81784SBob Moore 			 * Clear any previous connection. New connection is used for all
3399ce81784SBob Moore 			 * fields that follow, similar to access_as
3409ce81784SBob Moore 			 */
3419ce81784SBob Moore 			info->resource_buffer = NULL;
3429ce81784SBob Moore 			info->connection_node = NULL;
34375ec6e55SBob Moore 			info->pin_number_index = 0;
3449ce81784SBob Moore 
3459ce81784SBob Moore 			/*
3469ce81784SBob Moore 			 * A Connection() is either an actual resource descriptor (buffer)
3479ce81784SBob Moore 			 * or a named reference to a resource template
3489ce81784SBob Moore 			 */
3499ce81784SBob Moore 			child = arg->common.value.arg;
3509ce81784SBob Moore 			if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
3519ce81784SBob Moore 				info->resource_buffer = child->named.data;
3529ce81784SBob Moore 				info->resource_length =
3539ce81784SBob Moore 				    (u16)child->named.value.integer;
3549ce81784SBob Moore 			} else {
3559ce81784SBob Moore 				/* Lookup the Connection() namepath, it should already exist */
3569ce81784SBob Moore 
3579ce81784SBob Moore 				status = acpi_ns_lookup(walk_state->scope_info,
3589ce81784SBob Moore 							child->common.value.
3599ce81784SBob Moore 							name, ACPI_TYPE_ANY,
3609ce81784SBob Moore 							ACPI_IMODE_EXECUTE,
3619ce81784SBob Moore 							ACPI_NS_DONT_OPEN_SCOPE,
3629ce81784SBob Moore 							walk_state,
3639ce81784SBob Moore 							&info->connection_node);
3649ce81784SBob Moore 				if (ACPI_FAILURE(status)) {
36516ccf829SBob Moore 					ACPI_ERROR_NAMESPACE(walk_state->
36616ccf829SBob Moore 							     scope_info,
36716ccf829SBob Moore 							     child->common.
3689ce81784SBob Moore 							     value.name,
3699ce81784SBob Moore 							     status);
3709ce81784SBob Moore 					return_ACPI_STATUS(status);
3719ce81784SBob Moore 				}
3729ce81784SBob Moore 			}
37395b482a8SLen Brown 			break;
37495b482a8SLen Brown 
37595b482a8SLen Brown 		case AML_INT_NAMEDFIELD_OP:
37695b482a8SLen Brown 
37795b482a8SLen Brown 			/* Lookup the name, it should already exist */
37895b482a8SLen Brown 
37995b482a8SLen Brown 			status = acpi_ns_lookup(walk_state->scope_info,
38095b482a8SLen Brown 						(char *)&arg->named.name,
38195b482a8SLen Brown 						info->field_type,
38295b482a8SLen Brown 						ACPI_IMODE_EXECUTE,
38395b482a8SLen Brown 						ACPI_NS_DONT_OPEN_SCOPE,
38495b482a8SLen Brown 						walk_state, &info->field_node);
38595b482a8SLen Brown 			if (ACPI_FAILURE(status)) {
38616ccf829SBob Moore 				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
38716ccf829SBob Moore 						     (char *)&arg->named.name,
38895b482a8SLen Brown 						     status);
38995b482a8SLen Brown 				return_ACPI_STATUS(status);
39095b482a8SLen Brown 			} else {
39195b482a8SLen Brown 				arg->common.node = info->field_node;
39295b482a8SLen Brown 				info->field_bit_length = arg->common.value.size;
39395b482a8SLen Brown 
39495b482a8SLen Brown 				/*
39595b482a8SLen Brown 				 * If there is no object attached to the node, this node was
39695b482a8SLen Brown 				 * just created and we need to create the field object.
39795b482a8SLen Brown 				 * Otherwise, this was a lookup of an existing node and we
39895b482a8SLen Brown 				 * don't want to create the field object again.
39995b482a8SLen Brown 				 */
40095b482a8SLen Brown 				if (!acpi_ns_get_attached_object
40195b482a8SLen Brown 				    (info->field_node)) {
40295b482a8SLen Brown 					status = acpi_ex_prep_field_value(info);
40395b482a8SLen Brown 					if (ACPI_FAILURE(status)) {
40495b482a8SLen Brown 						return_ACPI_STATUS(status);
40595b482a8SLen Brown 					}
40677d4e096SErik Schmauss #ifdef ACPI_EXEC_APP
40777d4e096SErik Schmauss 					name_path =
40877d4e096SErik Schmauss 					    acpi_ns_get_external_pathname(info->
40977d4e096SErik Schmauss 									  field_node);
41077d4e096SErik Schmauss 					if (ACPI_SUCCESS
41177d4e096SErik Schmauss 					    (ae_lookup_init_file_entry
41202b04f10SErik Schmauss 					     (name_path, &obj_desc))) {
41377d4e096SErik Schmauss 						acpi_ex_write_data_to_field
41477d4e096SErik Schmauss 						    (obj_desc,
41577d4e096SErik Schmauss 						     acpi_ns_get_attached_object
41677d4e096SErik Schmauss 						     (info->field_node),
41777d4e096SErik Schmauss 						     &result_desc);
41802b04f10SErik Schmauss 						acpi_ut_remove_reference
41902b04f10SErik Schmauss 						    (obj_desc);
42077d4e096SErik Schmauss 					}
4218b66fcfdSBob Moore 					ACPI_FREE(name_path);
42277d4e096SErik Schmauss #endif
42395b482a8SLen Brown 				}
42495b482a8SLen Brown 			}
42595b482a8SLen Brown 
42695b482a8SLen Brown 			/* Keep track of bit position for the next field */
42795b482a8SLen Brown 
4281fad8738SBob Moore 			position = (u64)info->field_bit_position +
4291fad8738SBob Moore 			    (u64)arg->common.value.size;
43095b482a8SLen Brown 
43195b482a8SLen Brown 			if (position > ACPI_UINT32_MAX) {
43295b482a8SLen Brown 				ACPI_ERROR((AE_INFO,
43395b482a8SLen Brown 					    "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
43495b482a8SLen Brown 					    ACPI_CAST_PTR(char,
43595b482a8SLen Brown 							  &info->field_node->
43695b482a8SLen Brown 							  name)));
43795b482a8SLen Brown 				return_ACPI_STATUS(AE_SUPPORT);
43895b482a8SLen Brown 			}
43995b482a8SLen Brown 
44095b482a8SLen Brown 			info->field_bit_position += info->field_bit_length;
44175ec6e55SBob Moore 			info->pin_number_index++;	/* Index relative to previous Connection() */
44295b482a8SLen Brown 			break;
44395b482a8SLen Brown 
44495b482a8SLen Brown 		default:
44595b482a8SLen Brown 
44695b482a8SLen Brown 			ACPI_ERROR((AE_INFO,
447f6a22b0bSBob Moore 				    "Invalid opcode in field list: 0x%X",
44895b482a8SLen Brown 				    arg->common.aml_opcode));
44995b482a8SLen Brown 			return_ACPI_STATUS(AE_AML_BAD_OPCODE);
45095b482a8SLen Brown 		}
45195b482a8SLen Brown 
45295b482a8SLen Brown 		arg = arg->common.next;
45395b482a8SLen Brown 	}
45495b482a8SLen Brown 
45595b482a8SLen Brown 	return_ACPI_STATUS(AE_OK);
45695b482a8SLen Brown }
45795b482a8SLen Brown 
45895b482a8SLen Brown /*******************************************************************************
45995b482a8SLen Brown  *
46095b482a8SLen Brown  * FUNCTION:    acpi_ds_create_field
46195b482a8SLen Brown  *
462ba494beeSBob Moore  * PARAMETERS:  op              - Op containing the Field definition and args
46395b482a8SLen Brown  *              region_node     - Object for the containing Operation Region
46495b482a8SLen Brown  *  `           walk_state      - Current method state
46595b482a8SLen Brown  *
46695b482a8SLen Brown  * RETURN:      Status
46795b482a8SLen Brown  *
46895b482a8SLen Brown  * DESCRIPTION: Create a new field in the specified operation region
46995b482a8SLen Brown  *
47095b482a8SLen Brown  ******************************************************************************/
47195b482a8SLen Brown 
47295b482a8SLen Brown acpi_status
acpi_ds_create_field(union acpi_parse_object * op,struct acpi_namespace_node * region_node,struct acpi_walk_state * walk_state)47395b482a8SLen Brown acpi_ds_create_field(union acpi_parse_object *op,
47495b482a8SLen Brown 		     struct acpi_namespace_node *region_node,
47595b482a8SLen Brown 		     struct acpi_walk_state *walk_state)
47695b482a8SLen Brown {
47795b482a8SLen Brown 	acpi_status status;
47895b482a8SLen Brown 	union acpi_parse_object *arg;
47995b482a8SLen Brown 	struct acpi_create_field_info info;
48095b482a8SLen Brown 
48195b482a8SLen Brown 	ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
48295b482a8SLen Brown 
48395b482a8SLen Brown 	/* First arg is the name of the parent op_region (must already exist) */
48495b482a8SLen Brown 
48595b482a8SLen Brown 	arg = op->common.value.arg;
4866ccd7b5aSBob Moore 
48795b482a8SLen Brown 	if (!region_node) {
48895b482a8SLen Brown 		status =
48995b482a8SLen Brown 		    acpi_ns_lookup(walk_state->scope_info,
49095b482a8SLen Brown 				   arg->common.value.name, ACPI_TYPE_REGION,
49195b482a8SLen Brown 				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
49295b482a8SLen Brown 				   walk_state, &region_node);
4936ccd7b5aSBob Moore #ifdef ACPI_ASL_COMPILER
4946ccd7b5aSBob Moore 		status = acpi_ds_create_external_region(status, arg,
4956ccd7b5aSBob Moore 							arg->common.value.name,
4966ccd7b5aSBob Moore 							walk_state,
4976ccd7b5aSBob Moore 							&region_node);
4986ccd7b5aSBob Moore #endif
49995b482a8SLen Brown 		if (ACPI_FAILURE(status)) {
50016ccf829SBob Moore 			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
50116ccf829SBob Moore 					     arg->common.value.name, status);
50295b482a8SLen Brown 			return_ACPI_STATUS(status);
50395b482a8SLen Brown 		}
50495b482a8SLen Brown 	}
50595b482a8SLen Brown 
5064fa4616eSBob Moore 	memset(&info, 0, sizeof(struct acpi_create_field_info));
5079ce81784SBob Moore 
50895b482a8SLen Brown 	/* Second arg is the field flags */
50995b482a8SLen Brown 
51095b482a8SLen Brown 	arg = arg->common.next;
51195b482a8SLen Brown 	info.field_flags = (u8) arg->common.value.integer;
51295b482a8SLen Brown 	info.attribute = 0;
51395b482a8SLen Brown 
51495b482a8SLen Brown 	/* Each remaining arg is a Named Field */
51595b482a8SLen Brown 
51695b482a8SLen Brown 	info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
51795b482a8SLen Brown 	info.region_node = region_node;
51895b482a8SLen Brown 
51995b482a8SLen Brown 	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
5206bfe5344SErik Kaneda 	if (ACPI_FAILURE(status)) {
5216bfe5344SErik Kaneda 		return_ACPI_STATUS(status);
5226bfe5344SErik Kaneda 	}
5236bfe5344SErik Kaneda 
524aa6ec56bSErik Schmauss 	if (info.region_node->object->region.space_id ==
5256bfe5344SErik Kaneda 	    ACPI_ADR_SPACE_PLATFORM_COMM) {
5266bfe5344SErik Kaneda 		region_node->object->field.internal_pcc_buffer =
527aa6ec56bSErik Schmauss 		    ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
5286bfe5344SErik Kaneda 					 length);
5296bfe5344SErik Kaneda 		if (!region_node->object->field.internal_pcc_buffer) {
530aa6ec56bSErik Schmauss 			return_ACPI_STATUS(AE_NO_MEMORY);
531aa6ec56bSErik Schmauss 		}
5326bfe5344SErik Kaneda 	}
5336bfe5344SErik Kaneda 
53495b482a8SLen Brown 	return_ACPI_STATUS(status);
53595b482a8SLen Brown }
53695b482a8SLen Brown 
53795b482a8SLen Brown /*******************************************************************************
53895b482a8SLen Brown  *
53995b482a8SLen Brown  * FUNCTION:    acpi_ds_init_field_objects
54095b482a8SLen Brown  *
541ba494beeSBob Moore  * PARAMETERS:  op              - Op containing the Field definition and args
54295b482a8SLen Brown  *  `           walk_state      - Current method state
54395b482a8SLen Brown  *
54495b482a8SLen Brown  * RETURN:      Status
54595b482a8SLen Brown  *
54695b482a8SLen Brown  * DESCRIPTION: For each "Field Unit" name in the argument list that is
54795b482a8SLen Brown  *              part of the field declaration, enter the name into the
54895b482a8SLen Brown  *              namespace.
54995b482a8SLen Brown  *
55095b482a8SLen Brown  ******************************************************************************/
55195b482a8SLen Brown 
55295b482a8SLen Brown acpi_status
acpi_ds_init_field_objects(union acpi_parse_object * op,struct acpi_walk_state * walk_state)55395b482a8SLen Brown acpi_ds_init_field_objects(union acpi_parse_object *op,
55495b482a8SLen Brown 			   struct acpi_walk_state *walk_state)
55595b482a8SLen Brown {
55695b482a8SLen Brown 	acpi_status status;
55795b482a8SLen Brown 	union acpi_parse_object *arg = NULL;
55895b482a8SLen Brown 	struct acpi_namespace_node *node;
55995b482a8SLen Brown 	u8 type = 0;
56095b482a8SLen Brown 	u32 flags;
56195b482a8SLen Brown 
56295b482a8SLen Brown 	ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
56395b482a8SLen Brown 
56495b482a8SLen Brown 	/* Execute flag should always be set when this function is entered */
56595b482a8SLen Brown 
56695b482a8SLen Brown 	if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
56795b482a8SLen Brown 		if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
56895b482a8SLen Brown 
56995b482a8SLen Brown 			/* bank_field Op is deferred, just return OK */
57095b482a8SLen Brown 
57195b482a8SLen Brown 			return_ACPI_STATUS(AE_OK);
57295b482a8SLen Brown 		}
57395b482a8SLen Brown 
574376a588cSBob Moore 		ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
57595b482a8SLen Brown 		return_ACPI_STATUS(AE_AML_INTERNAL);
57695b482a8SLen Brown 	}
57795b482a8SLen Brown 
57895b482a8SLen Brown 	/*
57995b482a8SLen Brown 	 * Get the field_list argument for this opcode. This is the start of the
58095b482a8SLen Brown 	 * list of field elements.
58195b482a8SLen Brown 	 */
58295b482a8SLen Brown 	switch (walk_state->opcode) {
58395b482a8SLen Brown 	case AML_FIELD_OP:
5841d1ea1b7SChao Guan 
58595b482a8SLen Brown 		arg = acpi_ps_get_arg(op, 2);
58695b482a8SLen Brown 		type = ACPI_TYPE_LOCAL_REGION_FIELD;
58795b482a8SLen Brown 		break;
58895b482a8SLen Brown 
58995b482a8SLen Brown 	case AML_BANK_FIELD_OP:
5901d1ea1b7SChao Guan 
59195b482a8SLen Brown 		arg = acpi_ps_get_arg(op, 4);
59295b482a8SLen Brown 		type = ACPI_TYPE_LOCAL_BANK_FIELD;
59395b482a8SLen Brown 		break;
59495b482a8SLen Brown 
59595b482a8SLen Brown 	case AML_INDEX_FIELD_OP:
5961d1ea1b7SChao Guan 
59795b482a8SLen Brown 		arg = acpi_ps_get_arg(op, 3);
59895b482a8SLen Brown 		type = ACPI_TYPE_LOCAL_INDEX_FIELD;
59995b482a8SLen Brown 		break;
60095b482a8SLen Brown 
60195b482a8SLen Brown 	default:
6021d1ea1b7SChao Guan 
60395b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
60495b482a8SLen Brown 	}
60595b482a8SLen Brown 
60695b482a8SLen Brown 	/* Creating new namespace node(s), should not already exist */
60795b482a8SLen Brown 
60895b482a8SLen Brown 	flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
60995b482a8SLen Brown 	    ACPI_NS_ERROR_IF_FOUND;
61095b482a8SLen Brown 
6117f0c826aSLin Ming 	/*
6127f0c826aSLin Ming 	 * Mark node(s) temporary if we are executing a normal control
6137f0c826aSLin Ming 	 * method. (Don't mark if this is a module-level code method)
6147f0c826aSLin Ming 	 */
6157f0c826aSLin Ming 	if (walk_state->method_node &&
6167f0c826aSLin Ming 	    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
61795b482a8SLen Brown 		flags |= ACPI_NS_TEMPORARY;
61895b482a8SLen Brown 	}
61977d4e096SErik Schmauss #ifdef ACPI_EXEC_APP
62077d4e096SErik Schmauss 	flags |= ACPI_NS_OVERRIDE_IF_FOUND;
62177d4e096SErik Schmauss #endif
62295b482a8SLen Brown 	/*
62395b482a8SLen Brown 	 * Walk the list of entries in the field_list
62495b482a8SLen Brown 	 * Note: field_list can be of zero length. In this case, Arg will be NULL.
62595b482a8SLen Brown 	 */
62695b482a8SLen Brown 	while (arg) {
62795b482a8SLen Brown 		/*
6289ce81784SBob Moore 		 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
6299ce81784SBob Moore 		 * in the field names in order to enter them into the namespace.
63095b482a8SLen Brown 		 */
63195b482a8SLen Brown 		if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
63295b482a8SLen Brown 			status = acpi_ns_lookup(walk_state->scope_info,
63395b482a8SLen Brown 						(char *)&arg->named.name, type,
63495b482a8SLen Brown 						ACPI_IMODE_LOAD_PASS1, flags,
63595b482a8SLen Brown 						walk_state, &node);
63695b482a8SLen Brown 			if (ACPI_FAILURE(status)) {
63716ccf829SBob Moore 				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
63816ccf829SBob Moore 						     (char *)&arg->named.name,
63995b482a8SLen Brown 						     status);
64095b482a8SLen Brown 				if (status != AE_ALREADY_EXISTS) {
64195b482a8SLen Brown 					return_ACPI_STATUS(status);
64295b482a8SLen Brown 				}
64395b482a8SLen Brown 
64495b482a8SLen Brown 				/* Name already exists, just ignore this error */
64595b482a8SLen Brown 			}
64695b482a8SLen Brown 
64795b482a8SLen Brown 			arg->common.node = node;
64895b482a8SLen Brown 		}
64995b482a8SLen Brown 
65095b482a8SLen Brown 		/* Get the next field element in the list */
65195b482a8SLen Brown 
65295b482a8SLen Brown 		arg = arg->common.next;
65395b482a8SLen Brown 	}
65495b482a8SLen Brown 
65595b482a8SLen Brown 	return_ACPI_STATUS(AE_OK);
65695b482a8SLen Brown }
65795b482a8SLen Brown 
65895b482a8SLen Brown /*******************************************************************************
65995b482a8SLen Brown  *
66095b482a8SLen Brown  * FUNCTION:    acpi_ds_create_bank_field
66195b482a8SLen Brown  *
662ba494beeSBob Moore  * PARAMETERS:  op              - Op containing the Field definition and args
66395b482a8SLen Brown  *              region_node     - Object for the containing Operation Region
66495b482a8SLen Brown  *              walk_state      - Current method state
66595b482a8SLen Brown  *
66695b482a8SLen Brown  * RETURN:      Status
66795b482a8SLen Brown  *
66895b482a8SLen Brown  * DESCRIPTION: Create a new bank field in the specified operation region
66995b482a8SLen Brown  *
67095b482a8SLen Brown  ******************************************************************************/
67195b482a8SLen Brown 
67295b482a8SLen Brown acpi_status
acpi_ds_create_bank_field(union acpi_parse_object * op,struct acpi_namespace_node * region_node,struct acpi_walk_state * walk_state)67395b482a8SLen Brown acpi_ds_create_bank_field(union acpi_parse_object *op,
67495b482a8SLen Brown 			  struct acpi_namespace_node *region_node,
67595b482a8SLen Brown 			  struct acpi_walk_state *walk_state)
67695b482a8SLen Brown {
67795b482a8SLen Brown 	acpi_status status;
67895b482a8SLen Brown 	union acpi_parse_object *arg;
67995b482a8SLen Brown 	struct acpi_create_field_info info;
68095b482a8SLen Brown 
68195b482a8SLen Brown 	ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
68295b482a8SLen Brown 
68395b482a8SLen Brown 	/* First arg is the name of the parent op_region (must already exist) */
68495b482a8SLen Brown 
68595b482a8SLen Brown 	arg = op->common.value.arg;
68695b482a8SLen Brown 	if (!region_node) {
68795b482a8SLen Brown 		status =
68895b482a8SLen Brown 		    acpi_ns_lookup(walk_state->scope_info,
68995b482a8SLen Brown 				   arg->common.value.name, ACPI_TYPE_REGION,
69095b482a8SLen Brown 				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
69195b482a8SLen Brown 				   walk_state, &region_node);
6926ccd7b5aSBob Moore #ifdef ACPI_ASL_COMPILER
6936ccd7b5aSBob Moore 		status = acpi_ds_create_external_region(status, arg,
6946ccd7b5aSBob Moore 							arg->common.value.name,
6956ccd7b5aSBob Moore 							walk_state,
6966ccd7b5aSBob Moore 							&region_node);
6976ccd7b5aSBob Moore #endif
69895b482a8SLen Brown 		if (ACPI_FAILURE(status)) {
69916ccf829SBob Moore 			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
70016ccf829SBob Moore 					     arg->common.value.name, status);
70195b482a8SLen Brown 			return_ACPI_STATUS(status);
70295b482a8SLen Brown 		}
70395b482a8SLen Brown 	}
70495b482a8SLen Brown 
70595b482a8SLen Brown 	/* Second arg is the Bank Register (Field) (must already exist) */
70695b482a8SLen Brown 
70795b482a8SLen Brown 	arg = arg->common.next;
70895b482a8SLen Brown 	status =
70995b482a8SLen Brown 	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
71095b482a8SLen Brown 			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
71195b482a8SLen Brown 			   ACPI_NS_SEARCH_PARENT, walk_state,
71295b482a8SLen Brown 			   &info.register_node);
71395b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
71416ccf829SBob Moore 		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
71516ccf829SBob Moore 				     arg->common.value.string, status);
71695b482a8SLen Brown 		return_ACPI_STATUS(status);
71795b482a8SLen Brown 	}
71895b482a8SLen Brown 
71995b482a8SLen Brown 	/*
72095b482a8SLen Brown 	 * Third arg is the bank_value
72195b482a8SLen Brown 	 * This arg is a term_arg, not a constant
72295b482a8SLen Brown 	 * It will be evaluated later, by acpi_ds_eval_bank_field_operands
72395b482a8SLen Brown 	 */
72495b482a8SLen Brown 	arg = arg->common.next;
72595b482a8SLen Brown 
72695b482a8SLen Brown 	/* Fourth arg is the field flags */
72795b482a8SLen Brown 
72895b482a8SLen Brown 	arg = arg->common.next;
72995b482a8SLen Brown 	info.field_flags = (u8) arg->common.value.integer;
73095b482a8SLen Brown 
73195b482a8SLen Brown 	/* Each remaining arg is a Named Field */
73295b482a8SLen Brown 
73395b482a8SLen Brown 	info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
73495b482a8SLen Brown 	info.region_node = region_node;
73595b482a8SLen Brown 
73695b482a8SLen Brown 	/*
73795b482a8SLen Brown 	 * Use Info.data_register_node to store bank_field Op
7381fad8738SBob Moore 	 * It's safe because data_register_node will never be used when create
7391fad8738SBob Moore 	 * bank field \we store aml_start and aml_length in the bank_field Op for
7401fad8738SBob Moore 	 * late evaluation. Used in acpi_ex_prep_field_value(Info)
74195b482a8SLen Brown 	 *
7421fad8738SBob Moore 	 * TBD: Or, should we add a field in struct acpi_create_field_info, like
7431fad8738SBob Moore 	 * "void *ParentOp"?
74495b482a8SLen Brown 	 */
74595b482a8SLen Brown 	info.data_register_node = (struct acpi_namespace_node *)op;
74695b482a8SLen Brown 
74795b482a8SLen Brown 	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
74895b482a8SLen Brown 	return_ACPI_STATUS(status);
74995b482a8SLen Brown }
75095b482a8SLen Brown 
75195b482a8SLen Brown /*******************************************************************************
75295b482a8SLen Brown  *
75395b482a8SLen Brown  * FUNCTION:    acpi_ds_create_index_field
75495b482a8SLen Brown  *
755ba494beeSBob Moore  * PARAMETERS:  op              - Op containing the Field definition and args
75695b482a8SLen Brown  *              region_node     - Object for the containing Operation Region
75795b482a8SLen Brown  *  `           walk_state      - Current method state
75895b482a8SLen Brown  *
75995b482a8SLen Brown  * RETURN:      Status
76095b482a8SLen Brown  *
76195b482a8SLen Brown  * DESCRIPTION: Create a new index field in the specified operation region
76295b482a8SLen Brown  *
76395b482a8SLen Brown  ******************************************************************************/
76495b482a8SLen Brown 
76595b482a8SLen Brown acpi_status
acpi_ds_create_index_field(union acpi_parse_object * op,struct acpi_namespace_node * region_node,struct acpi_walk_state * walk_state)76695b482a8SLen Brown acpi_ds_create_index_field(union acpi_parse_object *op,
76795b482a8SLen Brown 			   struct acpi_namespace_node *region_node,
76895b482a8SLen Brown 			   struct acpi_walk_state *walk_state)
76995b482a8SLen Brown {
77095b482a8SLen Brown 	acpi_status status;
77195b482a8SLen Brown 	union acpi_parse_object *arg;
77295b482a8SLen Brown 	struct acpi_create_field_info info;
77395b482a8SLen Brown 
77495b482a8SLen Brown 	ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
77595b482a8SLen Brown 
77695b482a8SLen Brown 	/* First arg is the name of the Index register (must already exist) */
77795b482a8SLen Brown 
77895b482a8SLen Brown 	arg = op->common.value.arg;
77995b482a8SLen Brown 	status =
78095b482a8SLen Brown 	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
78195b482a8SLen Brown 			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
78295b482a8SLen Brown 			   ACPI_NS_SEARCH_PARENT, walk_state,
78395b482a8SLen Brown 			   &info.register_node);
78495b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
78516ccf829SBob Moore 		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
78616ccf829SBob Moore 				     arg->common.value.string, status);
78795b482a8SLen Brown 		return_ACPI_STATUS(status);
78895b482a8SLen Brown 	}
78995b482a8SLen Brown 
79095b482a8SLen Brown 	/* Second arg is the data register (must already exist) */
79195b482a8SLen Brown 
79295b482a8SLen Brown 	arg = arg->common.next;
79395b482a8SLen Brown 	status =
79495b482a8SLen Brown 	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
79595b482a8SLen Brown 			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
79695b482a8SLen Brown 			   ACPI_NS_SEARCH_PARENT, walk_state,
79795b482a8SLen Brown 			   &info.data_register_node);
79895b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
79916ccf829SBob Moore 		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
80016ccf829SBob Moore 				     arg->common.value.string, status);
80195b482a8SLen Brown 		return_ACPI_STATUS(status);
80295b482a8SLen Brown 	}
80395b482a8SLen Brown 
80495b482a8SLen Brown 	/* Next arg is the field flags */
80595b482a8SLen Brown 
80695b482a8SLen Brown 	arg = arg->common.next;
80795b482a8SLen Brown 	info.field_flags = (u8) arg->common.value.integer;
80895b482a8SLen Brown 
80995b482a8SLen Brown 	/* Each remaining arg is a Named Field */
81095b482a8SLen Brown 
81195b482a8SLen Brown 	info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
81295b482a8SLen Brown 	info.region_node = region_node;
81395b482a8SLen Brown 
81495b482a8SLen Brown 	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
81595b482a8SLen Brown 	return_ACPI_STATUS(status);
81695b482a8SLen Brown }
817