1 /******************************************************************************
2  *
3  * Module Name: dsfield - Dispatcher field routines
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2011, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #define __DSFIELD_C__
45 
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "amlcode.h"
49 #include "acdispat.h"
50 #include "acinterp.h"
51 #include "acnamesp.h"
52 #include "acparser.h"
53 
54 
55 #define _COMPONENT          ACPI_DISPATCHER
56         ACPI_MODULE_NAME    ("dsfield")
57 
58 /* Local prototypes */
59 
60 static ACPI_STATUS
61 AcpiDsGetFieldNames (
62     ACPI_CREATE_FIELD_INFO  *Info,
63     ACPI_WALK_STATE         *WalkState,
64     ACPI_PARSE_OBJECT       *Arg);
65 
66 
67 /*******************************************************************************
68  *
69  * FUNCTION:    AcpiDsCreateBufferField
70  *
71  * PARAMETERS:  Op                  - Current parse op (CreateXXField)
72  *              WalkState           - Current state
73  *
74  * RETURN:      Status
75  *
76  * DESCRIPTION: Execute the CreateField operators:
77  *              CreateBitFieldOp,
78  *              CreateByteFieldOp,
79  *              CreateWordFieldOp,
80  *              CreateDWordFieldOp,
81  *              CreateQWordFieldOp,
82  *              CreateFieldOp       (all of which define a field in a buffer)
83  *
84  ******************************************************************************/
85 
86 ACPI_STATUS
87 AcpiDsCreateBufferField (
88     ACPI_PARSE_OBJECT       *Op,
89     ACPI_WALK_STATE         *WalkState)
90 {
91     ACPI_PARSE_OBJECT       *Arg;
92     ACPI_NAMESPACE_NODE     *Node;
93     ACPI_STATUS             Status;
94     ACPI_OPERAND_OBJECT     *ObjDesc;
95     ACPI_OPERAND_OBJECT     *SecondDesc = NULL;
96     UINT32                  Flags;
97 
98 
99     ACPI_FUNCTION_TRACE (DsCreateBufferField);
100 
101 
102     /*
103      * Get the NameString argument (name of the new BufferField)
104      */
105     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
106     {
107         /* For CreateField, name is the 4th argument */
108 
109         Arg = AcpiPsGetArg (Op, 3);
110     }
111     else
112     {
113         /* For all other CreateXXXField operators, name is the 3rd argument */
114 
115         Arg = AcpiPsGetArg (Op, 2);
116     }
117 
118     if (!Arg)
119     {
120         return_ACPI_STATUS (AE_AML_NO_OPERAND);
121     }
122 
123     if (WalkState->DeferredNode)
124     {
125         Node = WalkState->DeferredNode;
126         Status = AE_OK;
127     }
128     else
129     {
130         /* Execute flag should always be set when this function is entered */
131 
132         if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
133         {
134             return_ACPI_STATUS (AE_AML_INTERNAL);
135         }
136 
137         /* Creating new namespace node, should not already exist */
138 
139         Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
140                 ACPI_NS_ERROR_IF_FOUND;
141 
142         /*
143          * Mark node temporary if we are executing a normal control
144          * method. (Don't mark if this is a module-level code method)
145          */
146         if (WalkState->MethodNode &&
147             !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
148         {
149             Flags |= ACPI_NS_TEMPORARY;
150         }
151 
152         /* Enter the NameString into the namespace */
153 
154         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
155                     ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
156                     Flags, WalkState, &Node);
157         if (ACPI_FAILURE (Status))
158         {
159             ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
160             return_ACPI_STATUS (Status);
161         }
162     }
163 
164     /*
165      * We could put the returned object (Node) on the object stack for later,
166      * but for now, we will put it in the "op" object that the parser uses,
167      * so we can get it again at the end of this scope.
168      */
169     Op->Common.Node = Node;
170 
171     /*
172      * If there is no object attached to the node, this node was just created
173      * and we need to create the field object. Otherwise, this was a lookup
174      * of an existing node and we don't want to create the field object again.
175      */
176     ObjDesc = AcpiNsGetAttachedObject (Node);
177     if (ObjDesc)
178     {
179         return_ACPI_STATUS (AE_OK);
180     }
181 
182     /*
183      * The Field definition is not fully parsed at this time.
184      * (We must save the address of the AML for the buffer and index operands)
185      */
186 
187     /* Create the buffer field object */
188 
189     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
190     if (!ObjDesc)
191     {
192         Status = AE_NO_MEMORY;
193         goto Cleanup;
194     }
195 
196     /*
197      * Remember location in AML stream of the field unit opcode and operands --
198      * since the buffer and index operands must be evaluated.
199      */
200     SecondDesc                  = ObjDesc->Common.NextObject;
201     SecondDesc->Extra.AmlStart  = Op->Named.Data;
202     SecondDesc->Extra.AmlLength = Op->Named.Length;
203     ObjDesc->BufferField.Node   = Node;
204 
205     /* Attach constructed field descriptors to parent node */
206 
207     Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
208     if (ACPI_FAILURE (Status))
209     {
210         goto Cleanup;
211     }
212 
213 
214 Cleanup:
215 
216     /* Remove local reference to the object */
217 
218     AcpiUtRemoveReference (ObjDesc);
219     return_ACPI_STATUS (Status);
220 }
221 
222 
223 /*******************************************************************************
224  *
225  * FUNCTION:    AcpiDsGetFieldNames
226  *
227  * PARAMETERS:  Info            - CreateField info structure
228  *  `           WalkState       - Current method state
229  *              Arg             - First parser arg for the field name list
230  *
231  * RETURN:      Status
232  *
233  * DESCRIPTION: Process all named fields in a field declaration.  Names are
234  *              entered into the namespace.
235  *
236  ******************************************************************************/
237 
238 static ACPI_STATUS
239 AcpiDsGetFieldNames (
240     ACPI_CREATE_FIELD_INFO  *Info,
241     ACPI_WALK_STATE         *WalkState,
242     ACPI_PARSE_OBJECT       *Arg)
243 {
244     ACPI_STATUS             Status;
245     UINT64                  Position;
246 
247 
248     ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
249 
250 
251     /* First field starts at bit zero */
252 
253     Info->FieldBitPosition = 0;
254 
255     /* Process all elements in the field list (of parse nodes) */
256 
257     while (Arg)
258     {
259         /*
260          * Three types of field elements are handled:
261          * 1) Offset - specifies a bit offset
262          * 2) AccessAs - changes the access mode
263          * 3) Name - Enters a new named field into the namespace
264          */
265         switch (Arg->Common.AmlOpcode)
266         {
267         case AML_INT_RESERVEDFIELD_OP:
268 
269             Position = (UINT64) Info->FieldBitPosition
270                         + (UINT64) Arg->Common.Value.Size;
271 
272             if (Position > ACPI_UINT32_MAX)
273             {
274                 ACPI_ERROR ((AE_INFO,
275                     "Bit offset within field too large (> 0xFFFFFFFF)"));
276                 return_ACPI_STATUS (AE_SUPPORT);
277             }
278 
279             Info->FieldBitPosition = (UINT32) Position;
280             break;
281 
282 
283         case AML_INT_ACCESSFIELD_OP:
284 
285             /*
286              * Get a new AccessType and AccessAttribute -- to be used for all
287              * field units that follow, until field end or another AccessAs
288              * keyword.
289              *
290              * In FieldFlags, preserve the flag bits other than the
291              * ACCESS_TYPE bits
292              */
293             Info->FieldFlags = (UINT8)
294                 ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
295                 ((UINT8) ((UINT32) Arg->Common.Value.Integer >> 8)));
296 
297             Info->Attribute = (UINT8) (Arg->Common.Value.Integer);
298             break;
299 
300 
301         case AML_INT_NAMEDFIELD_OP:
302 
303             /* Lookup the name, it should already exist */
304 
305             Status = AcpiNsLookup (WalkState->ScopeInfo,
306                         (char *) &Arg->Named.Name, Info->FieldType,
307                         ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
308                         WalkState, &Info->FieldNode);
309             if (ACPI_FAILURE (Status))
310             {
311                 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
312                 return_ACPI_STATUS (Status);
313             }
314             else
315             {
316                 Arg->Common.Node = Info->FieldNode;
317                 Info->FieldBitLength = Arg->Common.Value.Size;
318 
319                 /*
320                  * If there is no object attached to the node, this node was
321                  * just created and we need to create the field object.
322                  * Otherwise, this was a lookup of an existing node and we
323                  * don't want to create the field object again.
324                  */
325                 if (!AcpiNsGetAttachedObject (Info->FieldNode))
326                 {
327                     Status = AcpiExPrepFieldValue (Info);
328                     if (ACPI_FAILURE (Status))
329                     {
330                         return_ACPI_STATUS (Status);
331                     }
332                 }
333             }
334 
335             /* Keep track of bit position for the next field */
336 
337             Position = (UINT64) Info->FieldBitPosition
338                         + (UINT64) Arg->Common.Value.Size;
339 
340             if (Position > ACPI_UINT32_MAX)
341             {
342                 ACPI_ERROR ((AE_INFO,
343                     "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
344                     ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
345                 return_ACPI_STATUS (AE_SUPPORT);
346             }
347 
348             Info->FieldBitPosition += Info->FieldBitLength;
349             break;
350 
351 
352         default:
353 
354             ACPI_ERROR ((AE_INFO,
355                 "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode));
356             return_ACPI_STATUS (AE_AML_BAD_OPCODE);
357         }
358 
359         Arg = Arg->Common.Next;
360     }
361 
362     return_ACPI_STATUS (AE_OK);
363 }
364 
365 
366 /*******************************************************************************
367  *
368  * FUNCTION:    AcpiDsCreateField
369  *
370  * PARAMETERS:  Op              - Op containing the Field definition and args
371  *              RegionNode      - Object for the containing Operation Region
372  *  `           WalkState       - Current method state
373  *
374  * RETURN:      Status
375  *
376  * DESCRIPTION: Create a new field in the specified operation region
377  *
378  ******************************************************************************/
379 
380 ACPI_STATUS
381 AcpiDsCreateField (
382     ACPI_PARSE_OBJECT       *Op,
383     ACPI_NAMESPACE_NODE     *RegionNode,
384     ACPI_WALK_STATE         *WalkState)
385 {
386     ACPI_STATUS             Status;
387     ACPI_PARSE_OBJECT       *Arg;
388     ACPI_CREATE_FIELD_INFO  Info;
389 
390 
391     ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
392 
393 
394     /* First arg is the name of the parent OpRegion (must already exist) */
395 
396     Arg = Op->Common.Value.Arg;
397     if (!RegionNode)
398     {
399         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
400                         ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
401                         ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
402         if (ACPI_FAILURE (Status))
403         {
404             ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
405             return_ACPI_STATUS (Status);
406         }
407     }
408 
409     /* Second arg is the field flags */
410 
411     Arg = Arg->Common.Next;
412     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
413     Info.Attribute = 0;
414 
415     /* Each remaining arg is a Named Field */
416 
417     Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
418     Info.RegionNode = RegionNode;
419 
420     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
421 
422     return_ACPI_STATUS (Status);
423 }
424 
425 
426 /*******************************************************************************
427  *
428  * FUNCTION:    AcpiDsInitFieldObjects
429  *
430  * PARAMETERS:  Op              - Op containing the Field definition and args
431  *  `           WalkState       - Current method state
432  *
433  * RETURN:      Status
434  *
435  * DESCRIPTION: For each "Field Unit" name in the argument list that is
436  *              part of the field declaration, enter the name into the
437  *              namespace.
438  *
439  ******************************************************************************/
440 
441 ACPI_STATUS
442 AcpiDsInitFieldObjects (
443     ACPI_PARSE_OBJECT       *Op,
444     ACPI_WALK_STATE         *WalkState)
445 {
446     ACPI_STATUS             Status;
447     ACPI_PARSE_OBJECT       *Arg = NULL;
448     ACPI_NAMESPACE_NODE     *Node;
449     UINT8                   Type = 0;
450     UINT32                  Flags;
451 
452 
453     ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
454 
455 
456     /* Execute flag should always be set when this function is entered */
457 
458     if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
459     {
460         if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
461         {
462             /* BankField Op is deferred, just return OK */
463 
464             return_ACPI_STATUS (AE_OK);
465         }
466 
467         return_ACPI_STATUS (AE_AML_INTERNAL);
468     }
469 
470     /*
471      * Get the FieldList argument for this opcode. This is the start of the
472      * list of field elements.
473      */
474     switch (WalkState->Opcode)
475     {
476     case AML_FIELD_OP:
477         Arg = AcpiPsGetArg (Op, 2);
478         Type = ACPI_TYPE_LOCAL_REGION_FIELD;
479         break;
480 
481     case AML_BANK_FIELD_OP:
482         Arg = AcpiPsGetArg (Op, 4);
483         Type = ACPI_TYPE_LOCAL_BANK_FIELD;
484         break;
485 
486     case AML_INDEX_FIELD_OP:
487         Arg = AcpiPsGetArg (Op, 3);
488         Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
489         break;
490 
491     default:
492         return_ACPI_STATUS (AE_BAD_PARAMETER);
493     }
494 
495     /* Creating new namespace node(s), should not already exist */
496 
497     Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
498             ACPI_NS_ERROR_IF_FOUND;
499 
500     /*
501      * Mark node(s) temporary if we are executing a normal control
502      * method. (Don't mark if this is a module-level code method)
503      */
504     if (WalkState->MethodNode &&
505         !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
506     {
507         Flags |= ACPI_NS_TEMPORARY;
508     }
509 
510     /*
511      * Walk the list of entries in the FieldList
512      * Note: FieldList can be of zero length. In this case, Arg will be NULL.
513      */
514     while (Arg)
515     {
516         /*
517          * Ignore OFFSET and ACCESSAS terms here; we are only interested in the
518          * field names in order to enter them into the namespace.
519          */
520         if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
521         {
522             Status = AcpiNsLookup (WalkState->ScopeInfo,
523                         (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
524                         Flags, WalkState, &Node);
525             if (ACPI_FAILURE (Status))
526             {
527                 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
528                 if (Status != AE_ALREADY_EXISTS)
529                 {
530                     return_ACPI_STATUS (Status);
531                 }
532 
533                 /* Name already exists, just ignore this error */
534 
535                 Status = AE_OK;
536             }
537 
538             Arg->Common.Node = Node;
539         }
540 
541         /* Get the next field element in the list */
542 
543         Arg = Arg->Common.Next;
544     }
545 
546     return_ACPI_STATUS (AE_OK);
547 }
548 
549 
550 /*******************************************************************************
551  *
552  * FUNCTION:    AcpiDsCreateBankField
553  *
554  * PARAMETERS:  Op              - Op containing the Field definition and args
555  *              RegionNode      - Object for the containing Operation Region
556  *              WalkState       - Current method state
557  *
558  * RETURN:      Status
559  *
560  * DESCRIPTION: Create a new bank field in the specified operation region
561  *
562  ******************************************************************************/
563 
564 ACPI_STATUS
565 AcpiDsCreateBankField (
566     ACPI_PARSE_OBJECT       *Op,
567     ACPI_NAMESPACE_NODE     *RegionNode,
568     ACPI_WALK_STATE         *WalkState)
569 {
570     ACPI_STATUS             Status;
571     ACPI_PARSE_OBJECT       *Arg;
572     ACPI_CREATE_FIELD_INFO  Info;
573 
574 
575     ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
576 
577 
578     /* First arg is the name of the parent OpRegion (must already exist) */
579 
580     Arg = Op->Common.Value.Arg;
581     if (!RegionNode)
582     {
583         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
584                         ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
585                         ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
586         if (ACPI_FAILURE (Status))
587         {
588             ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
589             return_ACPI_STATUS (Status);
590         }
591     }
592 
593     /* Second arg is the Bank Register (Field) (must already exist) */
594 
595     Arg = Arg->Common.Next;
596     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
597                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
598                     ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
599     if (ACPI_FAILURE (Status))
600     {
601         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
602         return_ACPI_STATUS (Status);
603     }
604 
605     /*
606      * Third arg is the BankValue
607      * This arg is a TermArg, not a constant
608      * It will be evaluated later, by AcpiDsEvalBankFieldOperands
609      */
610     Arg = Arg->Common.Next;
611 
612     /* Fourth arg is the field flags */
613 
614     Arg = Arg->Common.Next;
615     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
616 
617     /* Each remaining arg is a Named Field */
618 
619     Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
620     Info.RegionNode = RegionNode;
621 
622     /*
623      * Use Info.DataRegisterNode to store BankField Op
624      * It's safe because DataRegisterNode will never be used when create bank field
625      * We store AmlStart and AmlLength in the BankField Op for late evaluation
626      * Used in AcpiExPrepFieldValue(Info)
627      *
628      * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like "void *ParentOp"?
629      */
630     Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
631 
632     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
633     return_ACPI_STATUS (Status);
634 }
635 
636 
637 /*******************************************************************************
638  *
639  * FUNCTION:    AcpiDsCreateIndexField
640  *
641  * PARAMETERS:  Op              - Op containing the Field definition and args
642  *              RegionNode      - Object for the containing Operation Region
643  *  `           WalkState       - Current method state
644  *
645  * RETURN:      Status
646  *
647  * DESCRIPTION: Create a new index field in the specified operation region
648  *
649  ******************************************************************************/
650 
651 ACPI_STATUS
652 AcpiDsCreateIndexField (
653     ACPI_PARSE_OBJECT       *Op,
654     ACPI_NAMESPACE_NODE     *RegionNode,
655     ACPI_WALK_STATE         *WalkState)
656 {
657     ACPI_STATUS             Status;
658     ACPI_PARSE_OBJECT       *Arg;
659     ACPI_CREATE_FIELD_INFO  Info;
660 
661 
662     ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
663 
664 
665     /* First arg is the name of the Index register (must already exist) */
666 
667     Arg = Op->Common.Value.Arg;
668     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
669                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
670                     ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
671     if (ACPI_FAILURE (Status))
672     {
673         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
674         return_ACPI_STATUS (Status);
675     }
676 
677     /* Second arg is the data register (must already exist) */
678 
679     Arg = Arg->Common.Next;
680     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
681                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
682                     ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
683     if (ACPI_FAILURE (Status))
684     {
685         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
686         return_ACPI_STATUS (Status);
687     }
688 
689     /* Next arg is the field flags */
690 
691     Arg = Arg->Common.Next;
692     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
693 
694     /* Each remaining arg is a Named Field */
695 
696     Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
697     Info.RegionNode = RegionNode;
698 
699     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
700 
701     return_ACPI_STATUS (Status);
702 }
703 
704 
705