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, ®ion_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 ®ion_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, ®ion_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 ®ion_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