xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/dsfield.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Module Name: dsfield - Dispatcher field routines
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2000 - 2020, Intel Corp.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *****************************************************************************/
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <acpi/acpi.h>
11*4882a593Smuzhiyun #include "accommon.h"
12*4882a593Smuzhiyun #include "amlcode.h"
13*4882a593Smuzhiyun #include "acdispat.h"
14*4882a593Smuzhiyun #include "acinterp.h"
15*4882a593Smuzhiyun #include "acnamesp.h"
16*4882a593Smuzhiyun #include "acparser.h"
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #ifdef ACPI_EXEC_APP
19*4882a593Smuzhiyun #include "aecommon.h"
20*4882a593Smuzhiyun #endif
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define _COMPONENT          ACPI_DISPATCHER
23*4882a593Smuzhiyun ACPI_MODULE_NAME("dsfield")
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /* Local prototypes */
26*4882a593Smuzhiyun #ifdef ACPI_ASL_COMPILER
27*4882a593Smuzhiyun #include "acdisasm.h"
28*4882a593Smuzhiyun static acpi_status
29*4882a593Smuzhiyun acpi_ds_create_external_region(acpi_status lookup_status,
30*4882a593Smuzhiyun 			       union acpi_parse_object *op,
31*4882a593Smuzhiyun 			       char *path,
32*4882a593Smuzhiyun 			       struct acpi_walk_state *walk_state,
33*4882a593Smuzhiyun 			       struct acpi_namespace_node **node);
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun static acpi_status
37*4882a593Smuzhiyun acpi_ds_get_field_names(struct acpi_create_field_info *info,
38*4882a593Smuzhiyun 			struct acpi_walk_state *walk_state,
39*4882a593Smuzhiyun 			union acpi_parse_object *arg);
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #ifdef ACPI_ASL_COMPILER
42*4882a593Smuzhiyun /*******************************************************************************
43*4882a593Smuzhiyun  *
44*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_create_external_region (iASL Disassembler only)
45*4882a593Smuzhiyun  *
46*4882a593Smuzhiyun  * PARAMETERS:  lookup_status   - Status from ns_lookup operation
47*4882a593Smuzhiyun  *              op              - Op containing the Field definition and args
48*4882a593Smuzhiyun  *              path            - Pathname of the region
49*4882a593Smuzhiyun  *  `           walk_state      - Current method state
50*4882a593Smuzhiyun  *              node            - Where the new region node is returned
51*4882a593Smuzhiyun  *
52*4882a593Smuzhiyun  * RETURN:      Status
53*4882a593Smuzhiyun  *
54*4882a593Smuzhiyun  * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
55*4882a593Smuzhiyun  *              region node/object.
56*4882a593Smuzhiyun  *
57*4882a593Smuzhiyun  ******************************************************************************/
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 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)60*4882a593Smuzhiyun acpi_ds_create_external_region(acpi_status lookup_status,
61*4882a593Smuzhiyun 			       union acpi_parse_object *op,
62*4882a593Smuzhiyun 			       char *path,
63*4882a593Smuzhiyun 			       struct acpi_walk_state *walk_state,
64*4882a593Smuzhiyun 			       struct acpi_namespace_node **node)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	acpi_status status;
67*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	if (lookup_status != AE_NOT_FOUND) {
70*4882a593Smuzhiyun 		return (lookup_status);
71*4882a593Smuzhiyun 	}
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	/*
74*4882a593Smuzhiyun 	 * Table disassembly:
75*4882a593Smuzhiyun 	 * operation_region not found. Generate an External for it, and
76*4882a593Smuzhiyun 	 * insert the name into the namespace.
77*4882a593Smuzhiyun 	 */
78*4882a593Smuzhiyun 	acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
81*4882a593Smuzhiyun 				ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
82*4882a593Smuzhiyun 				walk_state, node);
83*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
84*4882a593Smuzhiyun 		return (status);
85*4882a593Smuzhiyun 	}
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/* Must create and install a region object for the new node */
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
90*4882a593Smuzhiyun 	if (!obj_desc) {
91*4882a593Smuzhiyun 		return (AE_NO_MEMORY);
92*4882a593Smuzhiyun 	}
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	obj_desc->region.node = *node;
95*4882a593Smuzhiyun 	status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
96*4882a593Smuzhiyun 	return (status);
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun #endif
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun /*******************************************************************************
101*4882a593Smuzhiyun  *
102*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_create_buffer_field
103*4882a593Smuzhiyun  *
104*4882a593Smuzhiyun  * PARAMETERS:  op                  - Current parse op (create_XXField)
105*4882a593Smuzhiyun  *              walk_state          - Current state
106*4882a593Smuzhiyun  *
107*4882a593Smuzhiyun  * RETURN:      Status
108*4882a593Smuzhiyun  *
109*4882a593Smuzhiyun  * DESCRIPTION: Execute the create_field operators:
110*4882a593Smuzhiyun  *              create_bit_field_op,
111*4882a593Smuzhiyun  *              create_byte_field_op,
112*4882a593Smuzhiyun  *              create_word_field_op,
113*4882a593Smuzhiyun  *              create_dword_field_op,
114*4882a593Smuzhiyun  *              create_qword_field_op,
115*4882a593Smuzhiyun  *              create_field_op     (all of which define a field in a buffer)
116*4882a593Smuzhiyun  *
117*4882a593Smuzhiyun  ******************************************************************************/
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun acpi_status
acpi_ds_create_buffer_field(union acpi_parse_object * op,struct acpi_walk_state * walk_state)120*4882a593Smuzhiyun acpi_ds_create_buffer_field(union acpi_parse_object *op,
121*4882a593Smuzhiyun 			    struct acpi_walk_state *walk_state)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun 	union acpi_parse_object *arg;
124*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
125*4882a593Smuzhiyun 	acpi_status status;
126*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
127*4882a593Smuzhiyun 	union acpi_operand_object *second_desc = NULL;
128*4882a593Smuzhiyun 	u32 flags;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ds_create_buffer_field);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	/*
133*4882a593Smuzhiyun 	 * Get the name_string argument (name of the new buffer_field)
134*4882a593Smuzhiyun 	 */
135*4882a593Smuzhiyun 	if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 		/* For create_field, name is the 4th argument */
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 		arg = acpi_ps_get_arg(op, 3);
140*4882a593Smuzhiyun 	} else {
141*4882a593Smuzhiyun 		/* For all other create_XXXField operators, name is the 3rd argument */
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 		arg = acpi_ps_get_arg(op, 2);
144*4882a593Smuzhiyun 	}
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	if (!arg) {
147*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
148*4882a593Smuzhiyun 	}
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	if (walk_state->deferred_node) {
151*4882a593Smuzhiyun 		node = walk_state->deferred_node;
152*4882a593Smuzhiyun 	} else {
153*4882a593Smuzhiyun 		/* Execute flag should always be set when this function is entered */
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 		if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
156*4882a593Smuzhiyun 			ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
157*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_AML_INTERNAL);
158*4882a593Smuzhiyun 		}
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 		/* Creating new namespace node, should not already exist */
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 		flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
163*4882a593Smuzhiyun 		    ACPI_NS_ERROR_IF_FOUND;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 		/*
166*4882a593Smuzhiyun 		 * Mark node temporary if we are executing a normal control
167*4882a593Smuzhiyun 		 * method. (Don't mark if this is a module-level code method)
168*4882a593Smuzhiyun 		 */
169*4882a593Smuzhiyun 		if (walk_state->method_node &&
170*4882a593Smuzhiyun 		    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
171*4882a593Smuzhiyun 			flags |= ACPI_NS_TEMPORARY;
172*4882a593Smuzhiyun 		}
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 		/* Enter the name_string into the namespace */
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 		status = acpi_ns_lookup(walk_state->scope_info,
177*4882a593Smuzhiyun 					arg->common.value.string, ACPI_TYPE_ANY,
178*4882a593Smuzhiyun 					ACPI_IMODE_LOAD_PASS1, flags,
179*4882a593Smuzhiyun 					walk_state, &node);
180*4882a593Smuzhiyun 		if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE)
181*4882a593Smuzhiyun 		    && status == AE_ALREADY_EXISTS) {
182*4882a593Smuzhiyun 			status = AE_OK;
183*4882a593Smuzhiyun 		} else if (ACPI_FAILURE(status)) {
184*4882a593Smuzhiyun 			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
185*4882a593Smuzhiyun 					     arg->common.value.string, status);
186*4882a593Smuzhiyun 			return_ACPI_STATUS(status);
187*4882a593Smuzhiyun 		}
188*4882a593Smuzhiyun 	}
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	/*
191*4882a593Smuzhiyun 	 * We could put the returned object (Node) on the object stack for later,
192*4882a593Smuzhiyun 	 * but for now, we will put it in the "op" object that the parser uses,
193*4882a593Smuzhiyun 	 * so we can get it again at the end of this scope.
194*4882a593Smuzhiyun 	 */
195*4882a593Smuzhiyun 	op->common.node = node;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	/*
198*4882a593Smuzhiyun 	 * If there is no object attached to the node, this node was just created
199*4882a593Smuzhiyun 	 * and we need to create the field object. Otherwise, this was a lookup
200*4882a593Smuzhiyun 	 * of an existing node and we don't want to create the field object again.
201*4882a593Smuzhiyun 	 */
202*4882a593Smuzhiyun 	obj_desc = acpi_ns_get_attached_object(node);
203*4882a593Smuzhiyun 	if (obj_desc) {
204*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_OK);
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	/*
208*4882a593Smuzhiyun 	 * The Field definition is not fully parsed at this time.
209*4882a593Smuzhiyun 	 * (We must save the address of the AML for the buffer and index operands)
210*4882a593Smuzhiyun 	 */
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	/* Create the buffer field object */
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
215*4882a593Smuzhiyun 	if (!obj_desc) {
216*4882a593Smuzhiyun 		status = AE_NO_MEMORY;
217*4882a593Smuzhiyun 		goto cleanup;
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	/*
221*4882a593Smuzhiyun 	 * Remember location in AML stream of the field unit opcode and operands
222*4882a593Smuzhiyun 	 * -- since the buffer and index operands must be evaluated.
223*4882a593Smuzhiyun 	 */
224*4882a593Smuzhiyun 	second_desc = obj_desc->common.next_object;
225*4882a593Smuzhiyun 	second_desc->extra.aml_start = op->named.data;
226*4882a593Smuzhiyun 	second_desc->extra.aml_length = op->named.length;
227*4882a593Smuzhiyun 	obj_desc->buffer_field.node = node;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	/* Attach constructed field descriptors to parent node */
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
232*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
233*4882a593Smuzhiyun 		goto cleanup;
234*4882a593Smuzhiyun 	}
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun cleanup:
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	/* Remove local reference to the object */
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	acpi_ut_remove_reference(obj_desc);
241*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun /*******************************************************************************
245*4882a593Smuzhiyun  *
246*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_get_field_names
247*4882a593Smuzhiyun  *
248*4882a593Smuzhiyun  * PARAMETERS:  info            - create_field info structure
249*4882a593Smuzhiyun  *              walk_state      - Current method state
250*4882a593Smuzhiyun  *              arg             - First parser arg for the field name list
251*4882a593Smuzhiyun  *
252*4882a593Smuzhiyun  * RETURN:      Status
253*4882a593Smuzhiyun  *
254*4882a593Smuzhiyun  * DESCRIPTION: Process all named fields in a field declaration. Names are
255*4882a593Smuzhiyun  *              entered into the namespace.
256*4882a593Smuzhiyun  *
257*4882a593Smuzhiyun  ******************************************************************************/
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 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)260*4882a593Smuzhiyun acpi_ds_get_field_names(struct acpi_create_field_info *info,
261*4882a593Smuzhiyun 			struct acpi_walk_state *walk_state,
262*4882a593Smuzhiyun 			union acpi_parse_object *arg)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun 	acpi_status status;
265*4882a593Smuzhiyun 	u64 position;
266*4882a593Smuzhiyun 	union acpi_parse_object *child;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun #ifdef ACPI_EXEC_APP
269*4882a593Smuzhiyun 	union acpi_operand_object *result_desc;
270*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
271*4882a593Smuzhiyun 	char *name_path;
272*4882a593Smuzhiyun #endif
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	/* First field starts at bit zero */
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	info->field_bit_position = 0;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	/* Process all elements in the field list (of parse nodes) */
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	while (arg) {
283*4882a593Smuzhiyun 		/*
284*4882a593Smuzhiyun 		 * Four types of field elements are handled:
285*4882a593Smuzhiyun 		 * 1) name - Enters a new named field into the namespace
286*4882a593Smuzhiyun 		 * 2) offset - specifies a bit offset
287*4882a593Smuzhiyun 		 * 3) access_as - changes the access mode/attributes
288*4882a593Smuzhiyun 		 * 4) connection - Associate a resource template with the field
289*4882a593Smuzhiyun 		 */
290*4882a593Smuzhiyun 		switch (arg->common.aml_opcode) {
291*4882a593Smuzhiyun 		case AML_INT_RESERVEDFIELD_OP:
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 			position = (u64)info->field_bit_position +
294*4882a593Smuzhiyun 			    (u64)arg->common.value.size;
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 			if (position > ACPI_UINT32_MAX) {
297*4882a593Smuzhiyun 				ACPI_ERROR((AE_INFO,
298*4882a593Smuzhiyun 					    "Bit offset within field too large (> 0xFFFFFFFF)"));
299*4882a593Smuzhiyun 				return_ACPI_STATUS(AE_SUPPORT);
300*4882a593Smuzhiyun 			}
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 			info->field_bit_position = (u32) position;
303*4882a593Smuzhiyun 			break;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 		case AML_INT_ACCESSFIELD_OP:
306*4882a593Smuzhiyun 		case AML_INT_EXTACCESSFIELD_OP:
307*4882a593Smuzhiyun 			/*
308*4882a593Smuzhiyun 			 * Get new access_type, access_attribute, and access_length fields
309*4882a593Smuzhiyun 			 * -- to be used for all field units that follow, until the
310*4882a593Smuzhiyun 			 * end-of-field or another access_as keyword is encountered.
311*4882a593Smuzhiyun 			 * NOTE. These three bytes are encoded in the integer value
312*4882a593Smuzhiyun 			 * of the parseop for convenience.
313*4882a593Smuzhiyun 			 *
314*4882a593Smuzhiyun 			 * In field_flags, preserve the flag bits other than the
315*4882a593Smuzhiyun 			 * ACCESS_TYPE bits.
316*4882a593Smuzhiyun 			 */
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 			/* access_type (byte_acc, word_acc, etc.) */
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 			info->field_flags = (u8)
321*4882a593Smuzhiyun 			    ((info->
322*4882a593Smuzhiyun 			      field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
323*4882a593Smuzhiyun 			     ((u8)((u32)(arg->common.value.integer & 0x07))));
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 			/* access_attribute (attrib_quick, attrib_byte, etc.) */
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 			info->attribute = (u8)
328*4882a593Smuzhiyun 			    ((arg->common.value.integer >> 8) & 0xFF);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 			/* access_length (for serial/buffer protocols) */
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 			info->access_length = (u8)
333*4882a593Smuzhiyun 			    ((arg->common.value.integer >> 16) & 0xFF);
334*4882a593Smuzhiyun 			break;
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 		case AML_INT_CONNECTION_OP:
337*4882a593Smuzhiyun 			/*
338*4882a593Smuzhiyun 			 * Clear any previous connection. New connection is used for all
339*4882a593Smuzhiyun 			 * fields that follow, similar to access_as
340*4882a593Smuzhiyun 			 */
341*4882a593Smuzhiyun 			info->resource_buffer = NULL;
342*4882a593Smuzhiyun 			info->connection_node = NULL;
343*4882a593Smuzhiyun 			info->pin_number_index = 0;
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 			/*
346*4882a593Smuzhiyun 			 * A Connection() is either an actual resource descriptor (buffer)
347*4882a593Smuzhiyun 			 * or a named reference to a resource template
348*4882a593Smuzhiyun 			 */
349*4882a593Smuzhiyun 			child = arg->common.value.arg;
350*4882a593Smuzhiyun 			if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
351*4882a593Smuzhiyun 				info->resource_buffer = child->named.data;
352*4882a593Smuzhiyun 				info->resource_length =
353*4882a593Smuzhiyun 				    (u16)child->named.value.integer;
354*4882a593Smuzhiyun 			} else {
355*4882a593Smuzhiyun 				/* Lookup the Connection() namepath, it should already exist */
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 				status = acpi_ns_lookup(walk_state->scope_info,
358*4882a593Smuzhiyun 							child->common.value.
359*4882a593Smuzhiyun 							name, ACPI_TYPE_ANY,
360*4882a593Smuzhiyun 							ACPI_IMODE_EXECUTE,
361*4882a593Smuzhiyun 							ACPI_NS_DONT_OPEN_SCOPE,
362*4882a593Smuzhiyun 							walk_state,
363*4882a593Smuzhiyun 							&info->connection_node);
364*4882a593Smuzhiyun 				if (ACPI_FAILURE(status)) {
365*4882a593Smuzhiyun 					ACPI_ERROR_NAMESPACE(walk_state->
366*4882a593Smuzhiyun 							     scope_info,
367*4882a593Smuzhiyun 							     child->common.
368*4882a593Smuzhiyun 							     value.name,
369*4882a593Smuzhiyun 							     status);
370*4882a593Smuzhiyun 					return_ACPI_STATUS(status);
371*4882a593Smuzhiyun 				}
372*4882a593Smuzhiyun 			}
373*4882a593Smuzhiyun 			break;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 		case AML_INT_NAMEDFIELD_OP:
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 			/* Lookup the name, it should already exist */
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 			status = acpi_ns_lookup(walk_state->scope_info,
380*4882a593Smuzhiyun 						(char *)&arg->named.name,
381*4882a593Smuzhiyun 						info->field_type,
382*4882a593Smuzhiyun 						ACPI_IMODE_EXECUTE,
383*4882a593Smuzhiyun 						ACPI_NS_DONT_OPEN_SCOPE,
384*4882a593Smuzhiyun 						walk_state, &info->field_node);
385*4882a593Smuzhiyun 			if (ACPI_FAILURE(status)) {
386*4882a593Smuzhiyun 				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
387*4882a593Smuzhiyun 						     (char *)&arg->named.name,
388*4882a593Smuzhiyun 						     status);
389*4882a593Smuzhiyun 				return_ACPI_STATUS(status);
390*4882a593Smuzhiyun 			} else {
391*4882a593Smuzhiyun 				arg->common.node = info->field_node;
392*4882a593Smuzhiyun 				info->field_bit_length = arg->common.value.size;
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 				/*
395*4882a593Smuzhiyun 				 * If there is no object attached to the node, this node was
396*4882a593Smuzhiyun 				 * just created and we need to create the field object.
397*4882a593Smuzhiyun 				 * Otherwise, this was a lookup of an existing node and we
398*4882a593Smuzhiyun 				 * don't want to create the field object again.
399*4882a593Smuzhiyun 				 */
400*4882a593Smuzhiyun 				if (!acpi_ns_get_attached_object
401*4882a593Smuzhiyun 				    (info->field_node)) {
402*4882a593Smuzhiyun 					status = acpi_ex_prep_field_value(info);
403*4882a593Smuzhiyun 					if (ACPI_FAILURE(status)) {
404*4882a593Smuzhiyun 						return_ACPI_STATUS(status);
405*4882a593Smuzhiyun 					}
406*4882a593Smuzhiyun #ifdef ACPI_EXEC_APP
407*4882a593Smuzhiyun 					name_path =
408*4882a593Smuzhiyun 					    acpi_ns_get_external_pathname(info->
409*4882a593Smuzhiyun 									  field_node);
410*4882a593Smuzhiyun 					if (ACPI_SUCCESS
411*4882a593Smuzhiyun 					    (ae_lookup_init_file_entry
412*4882a593Smuzhiyun 					     (name_path, &obj_desc))) {
413*4882a593Smuzhiyun 						acpi_ex_write_data_to_field
414*4882a593Smuzhiyun 						    (obj_desc,
415*4882a593Smuzhiyun 						     acpi_ns_get_attached_object
416*4882a593Smuzhiyun 						     (info->field_node),
417*4882a593Smuzhiyun 						     &result_desc);
418*4882a593Smuzhiyun 						acpi_ut_remove_reference
419*4882a593Smuzhiyun 						    (obj_desc);
420*4882a593Smuzhiyun 					}
421*4882a593Smuzhiyun 					ACPI_FREE(name_path);
422*4882a593Smuzhiyun #endif
423*4882a593Smuzhiyun 				}
424*4882a593Smuzhiyun 			}
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 			/* Keep track of bit position for the next field */
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 			position = (u64)info->field_bit_position +
429*4882a593Smuzhiyun 			    (u64)arg->common.value.size;
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 			if (position > ACPI_UINT32_MAX) {
432*4882a593Smuzhiyun 				ACPI_ERROR((AE_INFO,
433*4882a593Smuzhiyun 					    "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
434*4882a593Smuzhiyun 					    ACPI_CAST_PTR(char,
435*4882a593Smuzhiyun 							  &info->field_node->
436*4882a593Smuzhiyun 							  name)));
437*4882a593Smuzhiyun 				return_ACPI_STATUS(AE_SUPPORT);
438*4882a593Smuzhiyun 			}
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 			info->field_bit_position += info->field_bit_length;
441*4882a593Smuzhiyun 			info->pin_number_index++;	/* Index relative to previous Connection() */
442*4882a593Smuzhiyun 			break;
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 		default:
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 			ACPI_ERROR((AE_INFO,
447*4882a593Smuzhiyun 				    "Invalid opcode in field list: 0x%X",
448*4882a593Smuzhiyun 				    arg->common.aml_opcode));
449*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_AML_BAD_OPCODE);
450*4882a593Smuzhiyun 		}
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 		arg = arg->common.next;
453*4882a593Smuzhiyun 	}
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	return_ACPI_STATUS(AE_OK);
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun /*******************************************************************************
459*4882a593Smuzhiyun  *
460*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_create_field
461*4882a593Smuzhiyun  *
462*4882a593Smuzhiyun  * PARAMETERS:  op              - Op containing the Field definition and args
463*4882a593Smuzhiyun  *              region_node     - Object for the containing Operation Region
464*4882a593Smuzhiyun  *  `           walk_state      - Current method state
465*4882a593Smuzhiyun  *
466*4882a593Smuzhiyun  * RETURN:      Status
467*4882a593Smuzhiyun  *
468*4882a593Smuzhiyun  * DESCRIPTION: Create a new field in the specified operation region
469*4882a593Smuzhiyun  *
470*4882a593Smuzhiyun  ******************************************************************************/
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun acpi_status
acpi_ds_create_field(union acpi_parse_object * op,struct acpi_namespace_node * region_node,struct acpi_walk_state * walk_state)473*4882a593Smuzhiyun acpi_ds_create_field(union acpi_parse_object *op,
474*4882a593Smuzhiyun 		     struct acpi_namespace_node *region_node,
475*4882a593Smuzhiyun 		     struct acpi_walk_state *walk_state)
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun 	acpi_status status;
478*4882a593Smuzhiyun 	union acpi_parse_object *arg;
479*4882a593Smuzhiyun 	struct acpi_create_field_info info;
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	/* First arg is the name of the parent op_region (must already exist) */
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	arg = op->common.value.arg;
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	if (!region_node) {
488*4882a593Smuzhiyun 		status =
489*4882a593Smuzhiyun 		    acpi_ns_lookup(walk_state->scope_info,
490*4882a593Smuzhiyun 				   arg->common.value.name, ACPI_TYPE_REGION,
491*4882a593Smuzhiyun 				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
492*4882a593Smuzhiyun 				   walk_state, &region_node);
493*4882a593Smuzhiyun #ifdef ACPI_ASL_COMPILER
494*4882a593Smuzhiyun 		status = acpi_ds_create_external_region(status, arg,
495*4882a593Smuzhiyun 							arg->common.value.name,
496*4882a593Smuzhiyun 							walk_state,
497*4882a593Smuzhiyun 							&region_node);
498*4882a593Smuzhiyun #endif
499*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
500*4882a593Smuzhiyun 			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
501*4882a593Smuzhiyun 					     arg->common.value.name, status);
502*4882a593Smuzhiyun 			return_ACPI_STATUS(status);
503*4882a593Smuzhiyun 		}
504*4882a593Smuzhiyun 	}
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun 	memset(&info, 0, sizeof(struct acpi_create_field_info));
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	/* Second arg is the field flags */
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	arg = arg->common.next;
511*4882a593Smuzhiyun 	info.field_flags = (u8) arg->common.value.integer;
512*4882a593Smuzhiyun 	info.attribute = 0;
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	/* Each remaining arg is a Named Field */
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
517*4882a593Smuzhiyun 	info.region_node = region_node;
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
520*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
521*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
522*4882a593Smuzhiyun 	}
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	if (info.region_node->object->region.space_id ==
525*4882a593Smuzhiyun 	    ACPI_ADR_SPACE_PLATFORM_COMM) {
526*4882a593Smuzhiyun 		region_node->object->field.internal_pcc_buffer =
527*4882a593Smuzhiyun 		    ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
528*4882a593Smuzhiyun 					 length);
529*4882a593Smuzhiyun 		if (!region_node->object->field.internal_pcc_buffer) {
530*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_NO_MEMORY);
531*4882a593Smuzhiyun 		}
532*4882a593Smuzhiyun 	}
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun /*******************************************************************************
538*4882a593Smuzhiyun  *
539*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_init_field_objects
540*4882a593Smuzhiyun  *
541*4882a593Smuzhiyun  * PARAMETERS:  op              - Op containing the Field definition and args
542*4882a593Smuzhiyun  *  `           walk_state      - Current method state
543*4882a593Smuzhiyun  *
544*4882a593Smuzhiyun  * RETURN:      Status
545*4882a593Smuzhiyun  *
546*4882a593Smuzhiyun  * DESCRIPTION: For each "Field Unit" name in the argument list that is
547*4882a593Smuzhiyun  *              part of the field declaration, enter the name into the
548*4882a593Smuzhiyun  *              namespace.
549*4882a593Smuzhiyun  *
550*4882a593Smuzhiyun  ******************************************************************************/
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun acpi_status
acpi_ds_init_field_objects(union acpi_parse_object * op,struct acpi_walk_state * walk_state)553*4882a593Smuzhiyun acpi_ds_init_field_objects(union acpi_parse_object *op,
554*4882a593Smuzhiyun 			   struct acpi_walk_state *walk_state)
555*4882a593Smuzhiyun {
556*4882a593Smuzhiyun 	acpi_status status;
557*4882a593Smuzhiyun 	union acpi_parse_object *arg = NULL;
558*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
559*4882a593Smuzhiyun 	u8 type = 0;
560*4882a593Smuzhiyun 	u32 flags;
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	/* Execute flag should always be set when this function is entered */
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
567*4882a593Smuzhiyun 		if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 			/* bank_field Op is deferred, just return OK */
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_OK);
572*4882a593Smuzhiyun 		}
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
575*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_AML_INTERNAL);
576*4882a593Smuzhiyun 	}
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	/*
579*4882a593Smuzhiyun 	 * Get the field_list argument for this opcode. This is the start of the
580*4882a593Smuzhiyun 	 * list of field elements.
581*4882a593Smuzhiyun 	 */
582*4882a593Smuzhiyun 	switch (walk_state->opcode) {
583*4882a593Smuzhiyun 	case AML_FIELD_OP:
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 		arg = acpi_ps_get_arg(op, 2);
586*4882a593Smuzhiyun 		type = ACPI_TYPE_LOCAL_REGION_FIELD;
587*4882a593Smuzhiyun 		break;
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	case AML_BANK_FIELD_OP:
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 		arg = acpi_ps_get_arg(op, 4);
592*4882a593Smuzhiyun 		type = ACPI_TYPE_LOCAL_BANK_FIELD;
593*4882a593Smuzhiyun 		break;
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 	case AML_INDEX_FIELD_OP:
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 		arg = acpi_ps_get_arg(op, 3);
598*4882a593Smuzhiyun 		type = ACPI_TYPE_LOCAL_INDEX_FIELD;
599*4882a593Smuzhiyun 		break;
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 	default:
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_BAD_PARAMETER);
604*4882a593Smuzhiyun 	}
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	/* Creating new namespace node(s), should not already exist */
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun 	flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
609*4882a593Smuzhiyun 	    ACPI_NS_ERROR_IF_FOUND;
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 	/*
612*4882a593Smuzhiyun 	 * Mark node(s) temporary if we are executing a normal control
613*4882a593Smuzhiyun 	 * method. (Don't mark if this is a module-level code method)
614*4882a593Smuzhiyun 	 */
615*4882a593Smuzhiyun 	if (walk_state->method_node &&
616*4882a593Smuzhiyun 	    !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
617*4882a593Smuzhiyun 		flags |= ACPI_NS_TEMPORARY;
618*4882a593Smuzhiyun 	}
619*4882a593Smuzhiyun #ifdef ACPI_EXEC_APP
620*4882a593Smuzhiyun 	flags |= ACPI_NS_OVERRIDE_IF_FOUND;
621*4882a593Smuzhiyun #endif
622*4882a593Smuzhiyun 	/*
623*4882a593Smuzhiyun 	 * Walk the list of entries in the field_list
624*4882a593Smuzhiyun 	 * Note: field_list can be of zero length. In this case, Arg will be NULL.
625*4882a593Smuzhiyun 	 */
626*4882a593Smuzhiyun 	while (arg) {
627*4882a593Smuzhiyun 		/*
628*4882a593Smuzhiyun 		 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
629*4882a593Smuzhiyun 		 * in the field names in order to enter them into the namespace.
630*4882a593Smuzhiyun 		 */
631*4882a593Smuzhiyun 		if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
632*4882a593Smuzhiyun 			status = acpi_ns_lookup(walk_state->scope_info,
633*4882a593Smuzhiyun 						(char *)&arg->named.name, type,
634*4882a593Smuzhiyun 						ACPI_IMODE_LOAD_PASS1, flags,
635*4882a593Smuzhiyun 						walk_state, &node);
636*4882a593Smuzhiyun 			if (ACPI_FAILURE(status)) {
637*4882a593Smuzhiyun 				ACPI_ERROR_NAMESPACE(walk_state->scope_info,
638*4882a593Smuzhiyun 						     (char *)&arg->named.name,
639*4882a593Smuzhiyun 						     status);
640*4882a593Smuzhiyun 				if (status != AE_ALREADY_EXISTS) {
641*4882a593Smuzhiyun 					return_ACPI_STATUS(status);
642*4882a593Smuzhiyun 				}
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 				/* Name already exists, just ignore this error */
645*4882a593Smuzhiyun 			}
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 			arg->common.node = node;
648*4882a593Smuzhiyun 		}
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 		/* Get the next field element in the list */
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 		arg = arg->common.next;
653*4882a593Smuzhiyun 	}
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	return_ACPI_STATUS(AE_OK);
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun /*******************************************************************************
659*4882a593Smuzhiyun  *
660*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_create_bank_field
661*4882a593Smuzhiyun  *
662*4882a593Smuzhiyun  * PARAMETERS:  op              - Op containing the Field definition and args
663*4882a593Smuzhiyun  *              region_node     - Object for the containing Operation Region
664*4882a593Smuzhiyun  *              walk_state      - Current method state
665*4882a593Smuzhiyun  *
666*4882a593Smuzhiyun  * RETURN:      Status
667*4882a593Smuzhiyun  *
668*4882a593Smuzhiyun  * DESCRIPTION: Create a new bank field in the specified operation region
669*4882a593Smuzhiyun  *
670*4882a593Smuzhiyun  ******************************************************************************/
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun acpi_status
acpi_ds_create_bank_field(union acpi_parse_object * op,struct acpi_namespace_node * region_node,struct acpi_walk_state * walk_state)673*4882a593Smuzhiyun acpi_ds_create_bank_field(union acpi_parse_object *op,
674*4882a593Smuzhiyun 			  struct acpi_namespace_node *region_node,
675*4882a593Smuzhiyun 			  struct acpi_walk_state *walk_state)
676*4882a593Smuzhiyun {
677*4882a593Smuzhiyun 	acpi_status status;
678*4882a593Smuzhiyun 	union acpi_parse_object *arg;
679*4882a593Smuzhiyun 	struct acpi_create_field_info info;
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	/* First arg is the name of the parent op_region (must already exist) */
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 	arg = op->common.value.arg;
686*4882a593Smuzhiyun 	if (!region_node) {
687*4882a593Smuzhiyun 		status =
688*4882a593Smuzhiyun 		    acpi_ns_lookup(walk_state->scope_info,
689*4882a593Smuzhiyun 				   arg->common.value.name, ACPI_TYPE_REGION,
690*4882a593Smuzhiyun 				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
691*4882a593Smuzhiyun 				   walk_state, &region_node);
692*4882a593Smuzhiyun #ifdef ACPI_ASL_COMPILER
693*4882a593Smuzhiyun 		status = acpi_ds_create_external_region(status, arg,
694*4882a593Smuzhiyun 							arg->common.value.name,
695*4882a593Smuzhiyun 							walk_state,
696*4882a593Smuzhiyun 							&region_node);
697*4882a593Smuzhiyun #endif
698*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
699*4882a593Smuzhiyun 			ACPI_ERROR_NAMESPACE(walk_state->scope_info,
700*4882a593Smuzhiyun 					     arg->common.value.name, status);
701*4882a593Smuzhiyun 			return_ACPI_STATUS(status);
702*4882a593Smuzhiyun 		}
703*4882a593Smuzhiyun 	}
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	/* Second arg is the Bank Register (Field) (must already exist) */
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	arg = arg->common.next;
708*4882a593Smuzhiyun 	status =
709*4882a593Smuzhiyun 	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
710*4882a593Smuzhiyun 			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
711*4882a593Smuzhiyun 			   ACPI_NS_SEARCH_PARENT, walk_state,
712*4882a593Smuzhiyun 			   &info.register_node);
713*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
714*4882a593Smuzhiyun 		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
715*4882a593Smuzhiyun 				     arg->common.value.string, status);
716*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
717*4882a593Smuzhiyun 	}
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun 	/*
720*4882a593Smuzhiyun 	 * Third arg is the bank_value
721*4882a593Smuzhiyun 	 * This arg is a term_arg, not a constant
722*4882a593Smuzhiyun 	 * It will be evaluated later, by acpi_ds_eval_bank_field_operands
723*4882a593Smuzhiyun 	 */
724*4882a593Smuzhiyun 	arg = arg->common.next;
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun 	/* Fourth arg is the field flags */
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	arg = arg->common.next;
729*4882a593Smuzhiyun 	info.field_flags = (u8) arg->common.value.integer;
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun 	/* Each remaining arg is a Named Field */
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
734*4882a593Smuzhiyun 	info.region_node = region_node;
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun 	/*
737*4882a593Smuzhiyun 	 * Use Info.data_register_node to store bank_field Op
738*4882a593Smuzhiyun 	 * It's safe because data_register_node will never be used when create
739*4882a593Smuzhiyun 	 * bank field \we store aml_start and aml_length in the bank_field Op for
740*4882a593Smuzhiyun 	 * late evaluation. Used in acpi_ex_prep_field_value(Info)
741*4882a593Smuzhiyun 	 *
742*4882a593Smuzhiyun 	 * TBD: Or, should we add a field in struct acpi_create_field_info, like
743*4882a593Smuzhiyun 	 * "void *ParentOp"?
744*4882a593Smuzhiyun 	 */
745*4882a593Smuzhiyun 	info.data_register_node = (struct acpi_namespace_node *)op;
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
748*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun /*******************************************************************************
752*4882a593Smuzhiyun  *
753*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_create_index_field
754*4882a593Smuzhiyun  *
755*4882a593Smuzhiyun  * PARAMETERS:  op              - Op containing the Field definition and args
756*4882a593Smuzhiyun  *              region_node     - Object for the containing Operation Region
757*4882a593Smuzhiyun  *  `           walk_state      - Current method state
758*4882a593Smuzhiyun  *
759*4882a593Smuzhiyun  * RETURN:      Status
760*4882a593Smuzhiyun  *
761*4882a593Smuzhiyun  * DESCRIPTION: Create a new index field in the specified operation region
762*4882a593Smuzhiyun  *
763*4882a593Smuzhiyun  ******************************************************************************/
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun acpi_status
acpi_ds_create_index_field(union acpi_parse_object * op,struct acpi_namespace_node * region_node,struct acpi_walk_state * walk_state)766*4882a593Smuzhiyun acpi_ds_create_index_field(union acpi_parse_object *op,
767*4882a593Smuzhiyun 			   struct acpi_namespace_node *region_node,
768*4882a593Smuzhiyun 			   struct acpi_walk_state *walk_state)
769*4882a593Smuzhiyun {
770*4882a593Smuzhiyun 	acpi_status status;
771*4882a593Smuzhiyun 	union acpi_parse_object *arg;
772*4882a593Smuzhiyun 	struct acpi_create_field_info info;
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
775*4882a593Smuzhiyun 
776*4882a593Smuzhiyun 	/* First arg is the name of the Index register (must already exist) */
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun 	arg = op->common.value.arg;
779*4882a593Smuzhiyun 	status =
780*4882a593Smuzhiyun 	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
781*4882a593Smuzhiyun 			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
782*4882a593Smuzhiyun 			   ACPI_NS_SEARCH_PARENT, walk_state,
783*4882a593Smuzhiyun 			   &info.register_node);
784*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
785*4882a593Smuzhiyun 		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
786*4882a593Smuzhiyun 				     arg->common.value.string, status);
787*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
788*4882a593Smuzhiyun 	}
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun 	/* Second arg is the data register (must already exist) */
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 	arg = arg->common.next;
793*4882a593Smuzhiyun 	status =
794*4882a593Smuzhiyun 	    acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
795*4882a593Smuzhiyun 			   ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
796*4882a593Smuzhiyun 			   ACPI_NS_SEARCH_PARENT, walk_state,
797*4882a593Smuzhiyun 			   &info.data_register_node);
798*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
799*4882a593Smuzhiyun 		ACPI_ERROR_NAMESPACE(walk_state->scope_info,
800*4882a593Smuzhiyun 				     arg->common.value.string, status);
801*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
802*4882a593Smuzhiyun 	}
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun 	/* Next arg is the field flags */
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 	arg = arg->common.next;
807*4882a593Smuzhiyun 	info.field_flags = (u8) arg->common.value.integer;
808*4882a593Smuzhiyun 
809*4882a593Smuzhiyun 	/* Each remaining arg is a Named Field */
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun 	info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
812*4882a593Smuzhiyun 	info.region_node = region_node;
813*4882a593Smuzhiyun 
814*4882a593Smuzhiyun 	status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
815*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
816*4882a593Smuzhiyun }
817