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