1 /******************************************************************************
2  *
3  * Module Name: aslrestype2s - Serial Large resource descriptors
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include "aslcompiler.h"
153 #include "aslcompiler.y.h"
154 #include "amlcode.h"
155 
156 #define _COMPONENT          ACPI_COMPILER
157         ACPI_MODULE_NAME    ("aslrestype2s")
158 
159 
160 static UINT16
161 RsGetBufferDataLength (
162     ACPI_PARSE_OBJECT       *InitializerOp);
163 
164 static UINT16
165 RsGetInterruptDataLength (
166     ACPI_PARSE_OBJECT       *InitializerOp,
167     UINT32                  StartIndex);
168 
169 static BOOLEAN
170 RsGetVendorData (
171     ACPI_PARSE_OBJECT       *InitializerOp,
172     UINT8                   *VendorData,
173     ACPI_SIZE               DescriptorOffset);
174 
175 static UINT16
176 RsGetStringDataLengthAt (
177     ACPI_PARSE_OBJECT       *InitializerOp,
178     UINT32                  StartIndex);
179 
180 /*
181  * This module contains descriptors for serial buses and GPIO:
182  *
183  * GpioInt
184  * GpioIo
185  * I2cSerialBus
186  * SpiSerialBus
187  * UartSerialBus
188  * PinFunction
189  * PinConfig
190  * PinGroup
191  * PinGroupFunction
192  * PinGroupConfig
193  */
194 
195 
196 /*******************************************************************************
197  *
198  * FUNCTION:    RsGetBufferDataLength
199  *
200  * PARAMETERS:  InitializerOp       - Current parse op, start of the resource
201  *                                    descriptor
202  *
203  * RETURN:      Length of the data buffer
204  *
205  * DESCRIPTION: Get the length of a RawDataBuffer, used for vendor data.
206  *
207  ******************************************************************************/
208 
209 static UINT16
210 RsGetBufferDataLength (
211     ACPI_PARSE_OBJECT       *InitializerOp)
212 {
213     UINT16                  ExtraDataSize = 0;
214     ACPI_PARSE_OBJECT       *DataList;
215 
216 
217     /* Find the byte-initializer list */
218 
219     while (InitializerOp)
220     {
221         if (InitializerOp->Asl.ParseOpcode == PARSEOP_DATABUFFER)
222         {
223             /* First child is the optional length (ignore it here) */
224 
225             DataList = InitializerOp->Asl.Child;
226             DataList = ASL_GET_PEER_NODE (DataList);
227 
228             /* Count the data items (each one is a byte of data) */
229 
230             while (DataList)
231             {
232                 ExtraDataSize++;
233                 DataList = ASL_GET_PEER_NODE (DataList);
234             }
235 
236             return (ExtraDataSize);
237         }
238 
239         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
240     }
241 
242     return (ExtraDataSize);
243 }
244 
245 
246 /*******************************************************************************
247  *
248  * FUNCTION:    RsGetInterruptDataLength
249  *
250  * PARAMETERS:  InitializerOp       - Current parse op, start of the resource
251  *                                    descriptor
252  *              StartIndex          - Start index of interrupt/pin list
253  *
254  * RETURN:      Length of the interrupt data list
255  *
256  * DESCRIPTION: Get the length of a list of interrupt DWORDs for the GPIO
257  *              descriptors.
258  *
259  ******************************************************************************/
260 
261 static UINT16
262 RsGetInterruptDataLength (
263     ACPI_PARSE_OBJECT       *InitializerOp,
264     UINT32                  StartIndex)
265 {
266     UINT16                  InterruptLength;
267     UINT32                  i;
268 
269 
270     /* Count the interrupt numbers */
271 
272     InterruptLength = 0;
273     for (i = 0; InitializerOp; i++)
274     {
275         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
276 
277         /* Interrupt list starts at offset StartIndex (Gpio descriptors) */
278 
279         if (i >= StartIndex)
280         {
281             InterruptLength += 2;
282         }
283     }
284 
285     return (InterruptLength);
286 }
287 
288 
289 /*******************************************************************************
290  *
291  * FUNCTION:    RsGetVendorData
292  *
293  * PARAMETERS:  InitializerOp       - Current parse op, start of the resource
294  *                                    descriptor.
295  *              VendorData          - Where the vendor data is returned
296  *              DescriptorOffset    - Where vendor data begins in descriptor
297  *
298  * RETURN:      TRUE if valid vendor data was returned, FALSE otherwise.
299  *
300  * DESCRIPTION: Extract the vendor data and construct a vendor data buffer.
301  *
302  ******************************************************************************/
303 
304 static BOOLEAN
305 RsGetVendorData (
306     ACPI_PARSE_OBJECT       *InitializerOp,
307     UINT8                   *VendorData,
308     ACPI_SIZE               DescriptorOffset)
309 {
310     ACPI_PARSE_OBJECT       *BufferOp;
311     UINT32                  SpecifiedLength = ACPI_UINT32_MAX;
312     UINT16                  ActualLength = 0;
313 
314 
315     /* Vendor Data field is always optional */
316 
317     if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
318     {
319         return (FALSE);
320     }
321 
322     BufferOp = InitializerOp->Asl.Child;
323     if (!BufferOp)
324     {
325         AslError (ASL_ERROR, ASL_MSG_SYNTAX, InitializerOp, "");
326         return (FALSE);
327     }
328 
329     /* First child is the optional buffer length (WORD) */
330 
331     if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
332     {
333         SpecifiedLength = (UINT16) BufferOp->Asl.Value.Integer;
334     }
335 
336     /* Insert field tag _VEN */
337 
338     RsCreateByteField (InitializerOp, ACPI_RESTAG_VENDORDATA,
339         (UINT16) DescriptorOffset);
340 
341     /* Walk the list of buffer initializers (each is one byte) */
342 
343     BufferOp = RsCompleteNodeAndGetNext (BufferOp);
344     if (BufferOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
345     {
346         while (BufferOp)
347         {
348             *VendorData = (UINT8) BufferOp->Asl.Value.Integer;
349             VendorData++;
350             ActualLength++;
351             BufferOp = RsCompleteNodeAndGetNext (BufferOp);
352         }
353     }
354 
355     /* Length validation. Buffer cannot be of zero length */
356 
357     if ((SpecifiedLength == 0) ||
358         ((SpecifiedLength == ACPI_UINT32_MAX) && (ActualLength == 0)))
359     {
360         AslError (ASL_ERROR, ASL_MSG_BUFFER_LENGTH, InitializerOp, NULL);
361         return (FALSE);
362     }
363 
364     if (SpecifiedLength != ACPI_UINT32_MAX)
365     {
366         /* ActualLength > SpecifiedLength -> error */
367 
368         if (ActualLength > SpecifiedLength)
369         {
370             AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG, InitializerOp, NULL);
371             return (FALSE);
372         }
373 
374         /* ActualLength < SpecifiedLength -> remark */
375 
376         else if (ActualLength < SpecifiedLength)
377         {
378             AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT, InitializerOp, NULL);
379             return (FALSE);
380         }
381     }
382 
383     return (TRUE);
384 }
385 
386 
387 /*******************************************************************************
388  *
389  * FUNCTION:    RsGetStringDataLengthAt
390  *
391  * PARAMETERS:  InitializerOp     - Start of a subtree of init nodes
392  *              StartIndex        - Starting index of the string node
393  *
394  * RETURN:      Valid string length if a string node is found at given
395  *               StartIndex or 0 otherwise.
396  *
397  * DESCRIPTION: In a list of peer nodes, find the first one at given index
398  *              that contains a string and return length.
399  *
400  ******************************************************************************/
401 
402 static UINT16
403 RsGetStringDataLengthAt (
404     ACPI_PARSE_OBJECT       *InitializerOp,
405     UINT32                  StartIndex)
406 {
407     UINT32 i;
408 
409     for (i = 0; InitializerOp; i++)
410     {
411         if (i == StartIndex &&
412             InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
413         {
414             return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
415         }
416 
417         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
418     }
419 
420     return (0);
421 }
422 
423 
424 /*******************************************************************************
425  *
426  * FUNCTION:    RsDoGpioIntDescriptor
427  *
428  * PARAMETERS:  Info                - Parse Op and resource template offset
429  *
430  * RETURN:      Completed resource node
431  *
432  * DESCRIPTION: Construct a long "GpioInt" descriptor
433  *
434  ******************************************************************************/
435 
436 ASL_RESOURCE_NODE *
437 RsDoGpioIntDescriptor (
438     ASL_RESOURCE_INFO       *Info)
439 {
440     AML_RESOURCE            *Descriptor;
441     ACPI_PARSE_OBJECT       *InitializerOp;
442     ASL_RESOURCE_NODE       *Rnode;
443     char                    *ResourceSource = NULL;
444     UINT8                   *VendorData = NULL;
445     UINT16                  *InterruptList = NULL;
446     UINT16                  *PinList = NULL;
447     UINT16                  ResSourceLength;
448     UINT16                  VendorLength;
449     UINT16                  InterruptLength;
450     UINT16                  DescriptorSize;
451     UINT32                  CurrentByteOffset;
452     UINT32                  PinCount = 0;
453     UINT32                  i;
454 
455 
456     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
457     CurrentByteOffset = Info->CurrentByteOffset;
458 
459     /*
460      * Calculate lengths for fields that have variable length:
461      * 1) Resource Source string
462      * 2) Vendor Data buffer
463      * 3) PIN (interrupt) list
464      */
465     ResSourceLength = RsGetStringDataLength (InitializerOp);
466     VendorLength = RsGetBufferDataLength (InitializerOp);
467     InterruptLength = RsGetInterruptDataLength (InitializerOp, 10);
468 
469     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) +
470         ResSourceLength + VendorLength + InterruptLength;
471 
472     /* Allocate the local resource node and initialize */
473 
474     Rnode = RsAllocateResourceNode (DescriptorSize +
475         sizeof (AML_RESOURCE_LARGE_HEADER));
476 
477     Descriptor = Rnode->Buffer;
478     Descriptor->Gpio.ResourceLength = DescriptorSize;
479     Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO;
480     Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION;
481     Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_INT;
482 
483     /* Build pointers to optional areas */
484 
485     InterruptList = ACPI_ADD_PTR (UINT16, Descriptor,
486         sizeof (AML_RESOURCE_GPIO));
487     PinList = InterruptList;
488     ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength);
489     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
490 
491     /* Setup offsets within the descriptor */
492 
493     Descriptor->Gpio.PinTableOffset = (UINT16)
494         ACPI_PTR_DIFF (InterruptList, Descriptor);
495 
496     Descriptor->Gpio.ResSourceOffset = (UINT16)
497         ACPI_PTR_DIFF (ResourceSource, Descriptor);
498 
499     /* Process all child initialization nodes */
500 
501     for (i = 0; InitializerOp; i++)
502     {
503         switch (i)
504         {
505         case 0: /* Interrupt Mode - edge/level [Flag] (_MOD) */
506 
507             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0);
508             RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
509                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0);
510             break;
511 
512         case 1: /* Interrupt Polarity - Active high/low [Flags] (_POL) */
513 
514             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 1, 0);
515             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_POLARITY,
516                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 1, 2);
517             break;
518 
519         case 2: /* Share Type - Default: exclusive (0) [Flags] (_SHR) */
520 
521             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0);
522             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
523                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3, 2);
524             break;
525 
526         case 3: /* Pin Config [BYTE] (_PPI) */
527 
528             Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
529             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
530                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig));
531             break;
532 
533         case 4: /* Debounce Timeout [WORD] (_DBT) */
534 
535             Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer;
536             RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME,
537                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout));
538             break;
539 
540         case 5: /* ResSource [Optional Field - STRING] */
541 
542             if (ResSourceLength)
543             {
544                 /* Copy string to the descriptor */
545 
546                 strcpy (ResourceSource,
547                     InitializerOp->Asl.Value.String);
548             }
549             break;
550 
551         case 6: /* Resource Index */
552 
553             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
554             {
555                 Descriptor->Gpio.ResSourceIndex =
556                     (UINT8) InitializerOp->Asl.Value.Integer;
557             }
558             break;
559 
560         case 7: /* Resource Usage (consumer/producer) */
561 
562             RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1);
563             break;
564 
565         case 8: /* Resource Tag (Descriptor Name) */
566 
567             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
568             break;
569 
570         case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
571 
572             /*
573              * Always set the VendorOffset even if there is no Vendor Data.
574              * This field is required in order to calculate the length
575              * of the ResourceSource at runtime.
576              */
577             Descriptor->Gpio.VendorOffset = (UINT16)
578                 ACPI_PTR_DIFF (VendorData, Descriptor);
579 
580             if (RsGetVendorData (InitializerOp, VendorData,
581                 (CurrentByteOffset +  Descriptor->Gpio.VendorOffset)))
582             {
583                 Descriptor->Gpio.VendorLength = VendorLength;
584             }
585             break;
586 
587         default:
588             /*
589              * PINs come through here, repeatedly. Each PIN must be a WORD.
590              * NOTE: there is no "length" field for this, so from ACPI spec:
591              *  The number of pins in the table can be calculated from:
592              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
593              *  (implies resource source must immediately follow the pin list.)
594              *  Name: _PIN
595              */
596             *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer;
597             InterruptList++;
598             PinCount++;
599 
600             /* Case 10: First interrupt number in list */
601 
602             if (i == 10)
603             {
604                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
605                 {
606                     /* Must be at least one interrupt */
607 
608                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
609                         InitializerOp, NULL);
610                 }
611 
612                 /* Check now for duplicates in list */
613 
614                 RsCheckListForDuplicates (InitializerOp);
615 
616                 /* Create a named field at the start of the list */
617 
618                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
619                     CurrentByteOffset + Descriptor->Gpio.PinTableOffset);
620             }
621             break;
622         }
623 
624         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
625     }
626 
627     MpSaveGpioInfo (Info->MappingOp, Descriptor,
628         PinCount, PinList, ResourceSource);
629     return (Rnode);
630 }
631 
632 
633 /*******************************************************************************
634  *
635  * FUNCTION:    RsDoGpioIoDescriptor
636  *
637  * PARAMETERS:  Info                - Parse Op and resource template offset
638  *
639  * RETURN:      Completed resource node
640  *
641  * DESCRIPTION: Construct a long "GpioIo" descriptor
642  *
643  ******************************************************************************/
644 
645 ASL_RESOURCE_NODE *
646 RsDoGpioIoDescriptor (
647     ASL_RESOURCE_INFO       *Info)
648 {
649     AML_RESOURCE            *Descriptor;
650     ACPI_PARSE_OBJECT       *InitializerOp;
651     ASL_RESOURCE_NODE       *Rnode;
652     char                    *ResourceSource = NULL;
653     UINT8                   *VendorData = NULL;
654     UINT16                  *InterruptList = NULL;
655     UINT16                  *PinList = NULL;
656     UINT16                  ResSourceLength;
657     UINT16                  VendorLength;
658     UINT16                  InterruptLength;
659     UINT16                  DescriptorSize;
660     UINT32                  CurrentByteOffset;
661     UINT32                  PinCount = 0;
662     UINT32                  i;
663 
664 
665     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
666     CurrentByteOffset = Info->CurrentByteOffset;
667 
668     /*
669      * Calculate lengths for fields that have variable length:
670      * 1) Resource Source string
671      * 2) Vendor Data buffer
672      * 3) PIN (interrupt) list
673      */
674     ResSourceLength = RsGetStringDataLength (InitializerOp);
675     VendorLength = RsGetBufferDataLength (InitializerOp);
676     InterruptLength = RsGetInterruptDataLength (InitializerOp, 10);
677 
678     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) +
679         ResSourceLength + VendorLength + InterruptLength;
680 
681     /* Allocate the local resource node and initialize */
682 
683     Rnode = RsAllocateResourceNode (DescriptorSize +
684         sizeof (AML_RESOURCE_LARGE_HEADER));
685 
686     Descriptor = Rnode->Buffer;
687     Descriptor->Gpio.ResourceLength = DescriptorSize;
688     Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO;
689     Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION;
690     Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_IO;
691 
692     /* Build pointers to optional areas */
693 
694     InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO));
695     PinList = InterruptList;
696     ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength);
697     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
698 
699     /* Setup offsets within the descriptor */
700 
701     Descriptor->Gpio.PinTableOffset = (UINT16)
702         ACPI_PTR_DIFF (InterruptList, Descriptor);
703 
704     Descriptor->Gpio.ResSourceOffset = (UINT16)
705         ACPI_PTR_DIFF (ResourceSource, Descriptor);
706 
707     /* Process all child initialization nodes */
708 
709     for (i = 0; InitializerOp; i++)
710     {
711         switch (i)
712         {
713         case 0: /* Share Type [Flags] (_SHR) */
714 
715             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0);
716             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
717                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3);
718             break;
719 
720         case 1: /* Pin Config [BYTE] (_PPI) */
721 
722             Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
723             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
724                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig));
725             break;
726 
727         case 2: /* Debounce Timeout [WORD] (_DBT) */
728 
729             Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer;
730             RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME,
731                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout));
732             break;
733 
734         case 3: /* Drive Strength [WORD] (_DRS) */
735 
736             Descriptor->Gpio.DriveStrength = (UINT16) InitializerOp->Asl.Value.Integer;
737             RsCreateWordField (InitializerOp, ACPI_RESTAG_DRIVESTRENGTH,
738                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DriveStrength));
739             break;
740 
741         case 4: /* I/O Restriction [Flag] (_IOR) */
742 
743             RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0);
744             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_IORESTRICTION,
745                 CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0, 2);
746             break;
747 
748         case 5: /* ResSource [Optional Field - STRING] */
749 
750             if (ResSourceLength)
751             {
752                 /* Copy string to the descriptor */
753 
754                 strcpy (ResourceSource,
755                     InitializerOp->Asl.Value.String);
756             }
757             break;
758 
759         case 6: /* Resource Index */
760 
761             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
762             {
763                 Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
764             }
765             break;
766 
767         case 7: /* Resource Usage (consumer/producer) */
768 
769             RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1);
770             break;
771 
772         case 8: /* Resource Tag (Descriptor Name) */
773 
774             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
775             break;
776 
777         case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
778             /*
779              * Always set the VendorOffset even if there is no Vendor Data.
780              * This field is required in order to calculate the length
781              * of the ResourceSource at runtime.
782              */
783             Descriptor->Gpio.VendorOffset = (UINT16)
784                 ACPI_PTR_DIFF (VendorData, Descriptor);
785 
786             if (RsGetVendorData (InitializerOp, VendorData,
787                 (CurrentByteOffset + Descriptor->Gpio.VendorOffset)))
788             {
789                 Descriptor->Gpio.VendorLength = VendorLength;
790             }
791             break;
792 
793         default:
794             /*
795              * PINs come through here, repeatedly. Each PIN must be a WORD.
796              * NOTE: there is no "length" field for this, so from ACPI spec:
797              *  The number of pins in the table can be calculated from:
798              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
799              *  (implies resource source must immediately follow the pin list.)
800              *  Name: _PIN
801              */
802             *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer;
803             InterruptList++;
804             PinCount++;
805 
806             /* Case 10: First interrupt number in list */
807 
808             if (i == 10)
809             {
810                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
811                 {
812                     /* Must be at least one interrupt */
813 
814                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
815                         InitializerOp, NULL);
816                 }
817 
818                 /* Check now for duplicates in list */
819 
820                 RsCheckListForDuplicates (InitializerOp);
821 
822                 /* Create a named field at the start of the list */
823 
824                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
825                     CurrentByteOffset + Descriptor->Gpio.PinTableOffset);
826             }
827             break;
828         }
829 
830         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
831     }
832 
833     MpSaveGpioInfo (Info->MappingOp, Descriptor,
834         PinCount, PinList, ResourceSource);
835     return (Rnode);
836 }
837 
838 
839 /*******************************************************************************
840  *
841  * FUNCTION:    RsDoI2cSerialBusDescriptor
842  *
843  * PARAMETERS:  Info                - Parse Op and resource template offset
844  *
845  * RETURN:      Completed resource node
846  *
847  * DESCRIPTION: Construct a long "I2cSerialBus" descriptor
848  *
849  ******************************************************************************/
850 
851 ASL_RESOURCE_NODE *
852 RsDoI2cSerialBusDescriptor (
853     ASL_RESOURCE_INFO       *Info)
854 {
855     AML_RESOURCE            *Descriptor;
856     ACPI_PARSE_OBJECT       *InitializerOp;
857     ASL_RESOURCE_NODE       *Rnode;
858     char                    *ResourceSource = NULL;
859     UINT8                   *VendorData = NULL;
860     UINT16                  ResSourceLength;
861     UINT16                  VendorLength;
862     UINT16                  DescriptorSize;
863     UINT32                  CurrentByteOffset;
864     UINT32                  i;
865 
866 
867     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
868     CurrentByteOffset = Info->CurrentByteOffset;
869 
870     /*
871      * Calculate lengths for fields that have variable length:
872      * 1) Resource Source string
873      * 2) Vendor Data buffer
874      */
875     ResSourceLength = RsGetStringDataLength (InitializerOp);
876     VendorLength = RsGetBufferDataLength (InitializerOp);
877 
878     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS) +
879         ResSourceLength + VendorLength;
880 
881     /* Allocate the local resource node and initialize */
882 
883     Rnode = RsAllocateResourceNode (DescriptorSize +
884         sizeof (AML_RESOURCE_LARGE_HEADER));
885 
886     Descriptor = Rnode->Buffer;
887     Descriptor->I2cSerialBus.ResourceLength = DescriptorSize;
888     Descriptor->I2cSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
889     Descriptor->I2cSerialBus.RevisionId = AML_RESOURCE_I2C_REVISION;
890     Descriptor->I2cSerialBus.TypeRevisionId = AML_RESOURCE_I2C_TYPE_REVISION;
891     Descriptor->I2cSerialBus.Type = AML_RESOURCE_I2C_SERIALBUSTYPE;
892     Descriptor->I2cSerialBus.TypeDataLength = AML_RESOURCE_I2C_MIN_DATA_LEN + VendorLength;
893 
894     if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_I2C_SERIALBUS_V2)
895     {
896         Descriptor->I2cSerialBus.RevisionId = 2;
897     }
898 
899     /* Build pointers to optional areas */
900 
901     VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_I2C_SERIALBUS));
902     ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
903 
904     /* Process all child initialization nodes */
905 
906     for (i = 0; InitializerOp; i++)
907     {
908         switch (i)
909         {
910         case 0: /* Slave Address [WORD] (_ADR) */
911 
912             Descriptor->I2cSerialBus.SlaveAddress = (UINT16) InitializerOp->Asl.Value.Integer;
913             RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
914                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.SlaveAddress));
915             break;
916 
917         case 1: /* Slave Mode [Flag] (_SLV) */
918 
919             RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 0, 0);
920             RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
921                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0);
922             break;
923 
924         case 2: /* Connection Speed [DWORD] (_SPE) */
925 
926             Descriptor->I2cSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
927             RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
928                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.ConnectionSpeed));
929             break;
930 
931         case 3: /* Addressing Mode [Flag] (_MOD) */
932 
933             RsSetFlagBits16 (&Descriptor->I2cSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
934             RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
935                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.TypeSpecificFlags), 0);
936             break;
937 
938         case 4: /* ResSource [Optional Field - STRING] */
939 
940             if (ResSourceLength)
941             {
942                 /* Copy string to the descriptor */
943 
944                 strcpy (ResourceSource,
945                     InitializerOp->Asl.Value.String);
946             }
947             break;
948 
949         case 5: /* Resource Index */
950 
951             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
952             {
953                 Descriptor->I2cSerialBus.ResSourceIndex =
954                     (UINT8) InitializerOp->Asl.Value.Integer;
955             }
956             break;
957 
958         case 6: /* Resource Usage (consumer/producer) */
959 
960             RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 1, 1);
961             break;
962 
963         case 7: /* Resource Tag (Descriptor Name) */
964 
965             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
966             break;
967 
968         case 8:
969             /*
970              * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
971              * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
972              * the ASL parser)
973              */
974             RsSetFlagBits (&Descriptor->I2cSerialBus.Flags, InitializerOp, 2, 0);
975             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
976                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 2);
977             break;
978 
979         case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
980 
981             RsGetVendorData (InitializerOp, VendorData,
982                 CurrentByteOffset + sizeof (AML_RESOURCE_I2C_SERIALBUS));
983             break;
984 
985         default:    /* Ignore any extra nodes */
986 
987             break;
988         }
989 
990         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
991     }
992 
993     MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
994     return (Rnode);
995 }
996 
997 
998 /*******************************************************************************
999  *
1000  * FUNCTION:    RsDoSpiSerialBusDescriptor
1001  *
1002  * PARAMETERS:  Info                - Parse Op and resource template offset
1003  *
1004  * RETURN:      Completed resource node
1005  *
1006  * DESCRIPTION: Construct a long "SPI Serial Bus" descriptor
1007  *
1008  ******************************************************************************/
1009 
1010 ASL_RESOURCE_NODE *
1011 RsDoSpiSerialBusDescriptor (
1012     ASL_RESOURCE_INFO       *Info)
1013 {
1014     AML_RESOURCE            *Descriptor;
1015     ACPI_PARSE_OBJECT       *InitializerOp;
1016     ASL_RESOURCE_NODE       *Rnode;
1017     char                    *ResourceSource = NULL;
1018     UINT8                   *VendorData = NULL;
1019     UINT16                  ResSourceLength;
1020     UINT16                  VendorLength;
1021     UINT16                  DescriptorSize;
1022     UINT32                  CurrentByteOffset;
1023     UINT32                  i;
1024 
1025 
1026     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1027     CurrentByteOffset = Info->CurrentByteOffset;
1028 
1029     /*
1030      * Calculate lengths for fields that have variable length:
1031      * 1) Resource Source string
1032      * 2) Vendor Data buffer
1033      */
1034     ResSourceLength = RsGetStringDataLength (InitializerOp);
1035     VendorLength = RsGetBufferDataLength (InitializerOp);
1036 
1037     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS) +
1038         ResSourceLength + VendorLength;
1039 
1040     /* Allocate the local resource node and initialize */
1041 
1042     Rnode = RsAllocateResourceNode (DescriptorSize +
1043         sizeof (AML_RESOURCE_LARGE_HEADER));
1044 
1045     Descriptor = Rnode->Buffer;
1046     Descriptor->SpiSerialBus.ResourceLength = DescriptorSize;
1047     Descriptor->SpiSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
1048     Descriptor->SpiSerialBus.RevisionId = AML_RESOURCE_SPI_REVISION;
1049     Descriptor->SpiSerialBus.TypeRevisionId = AML_RESOURCE_SPI_TYPE_REVISION;
1050     Descriptor->SpiSerialBus.Type = AML_RESOURCE_SPI_SERIALBUSTYPE;
1051     Descriptor->SpiSerialBus.TypeDataLength = AML_RESOURCE_SPI_MIN_DATA_LEN + VendorLength;
1052 
1053     if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_SPI_SERIALBUS_V2)
1054     {
1055         Descriptor->I2cSerialBus.RevisionId = 2;
1056     }
1057 
1058     /* Build pointers to optional areas */
1059 
1060     VendorData = ACPI_ADD_PTR (UINT8, Descriptor,
1061         sizeof (AML_RESOURCE_SPI_SERIALBUS));
1062     ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
1063 
1064     /* Process all child initialization nodes */
1065 
1066     for (i = 0; InitializerOp; i++)
1067     {
1068         switch (i)
1069         {
1070         case 0: /* Device Selection [WORD] (_ADR) */
1071 
1072             Descriptor->SpiSerialBus.DeviceSelection = (UINT16) InitializerOp->Asl.Value.Integer;
1073             RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS,
1074                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DeviceSelection));
1075             break;
1076 
1077         case 1: /* Device Polarity [Flag] (_DPL) */
1078 
1079             RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 1, 0);
1080             RsCreateBitField (InitializerOp, ACPI_RESTAG_DEVICEPOLARITY,
1081                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 1);
1082             break;
1083 
1084         case 2: /* Wire Mode [Flag] (_MOD) */
1085 
1086             RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1087             RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE,
1088                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 0);
1089             break;
1090 
1091         case 3: /* Device Bit Length [BYTE] (_LEN) */
1092 
1093             Descriptor->SpiSerialBus.DataBitLength = (UINT8) InitializerOp->Asl.Value.Integer;
1094             RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
1095                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DataBitLength));
1096             break;
1097 
1098         case 4: /* Slave Mode [Flag] (_SLV) */
1099 
1100             RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 0, 0);
1101             RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
1102                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 0);
1103             break;
1104 
1105         case 5: /* Connection Speed [DWORD] (_SPE) */
1106 
1107             Descriptor->SpiSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer;
1108             RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
1109                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ConnectionSpeed));
1110             break;
1111 
1112         case 6: /* Clock Polarity [BYTE] (_POL) */
1113 
1114             Descriptor->SpiSerialBus.ClockPolarity = (UINT8) InitializerOp->Asl.Value.Integer;
1115             RsCreateByteField (InitializerOp, ACPI_RESTAG_POLARITY,
1116                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPolarity));
1117             break;
1118 
1119         case 7: /* Clock Phase [BYTE] (_PHA) */
1120 
1121             Descriptor->SpiSerialBus.ClockPhase = (UINT8) InitializerOp->Asl.Value.Integer;
1122             RsCreateByteField (InitializerOp, ACPI_RESTAG_PHASE,
1123                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPhase));
1124             break;
1125 
1126         case 8: /* ResSource [Optional Field - STRING] */
1127 
1128             if (ResSourceLength)
1129             {
1130                 /* Copy string to the descriptor */
1131 
1132                 strcpy (ResourceSource,
1133                     InitializerOp->Asl.Value.String);
1134             }
1135             break;
1136 
1137         case 9: /* Resource Index */
1138 
1139             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1140             {
1141                 Descriptor->SpiSerialBus.ResSourceIndex =
1142                     (UINT8) InitializerOp->Asl.Value.Integer;
1143             }
1144             break;
1145 
1146         case 10: /* Resource Usage (consumer/producer) */
1147 
1148             RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 1, 1);
1149             break;
1150 
1151         case 11: /* Resource Tag (Descriptor Name) */
1152 
1153             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1154             break;
1155 
1156         case 12:
1157             /*
1158              * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
1159              * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
1160              * the ASL parser)
1161              */
1162             RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 2, 0);
1163             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1164                 CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 2);
1165             break;
1166 
1167         case 13: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1168 
1169             RsGetVendorData (InitializerOp, VendorData,
1170                 CurrentByteOffset + sizeof (AML_RESOURCE_SPI_SERIALBUS));
1171             break;
1172 
1173         default:    /* Ignore any extra nodes */
1174 
1175             break;
1176         }
1177 
1178         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1179     }
1180 
1181     MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
1182     return (Rnode);
1183 }
1184 
1185 
1186 /*******************************************************************************
1187  *
1188  * FUNCTION:    RsDoUartSerialBusDescriptor
1189  *
1190  * PARAMETERS:  Info                - Parse Op and resource template offset
1191  *
1192  * RETURN:      Completed resource node
1193  *
1194  * DESCRIPTION: Construct a long "UART Serial Bus" descriptor
1195  *
1196  ******************************************************************************/
1197 
1198 ASL_RESOURCE_NODE *
1199 RsDoUartSerialBusDescriptor (
1200     ASL_RESOURCE_INFO       *Info)
1201 {
1202     AML_RESOURCE            *Descriptor;
1203     ACPI_PARSE_OBJECT       *InitializerOp;
1204     ASL_RESOURCE_NODE       *Rnode;
1205     char                    *ResourceSource = NULL;
1206     UINT8                   *VendorData = NULL;
1207     UINT16                  ResSourceLength;
1208     UINT16                  VendorLength;
1209     UINT16                  DescriptorSize;
1210     UINT32                  CurrentByteOffset;
1211     UINT32                  i;
1212 
1213 
1214     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1215     CurrentByteOffset = Info->CurrentByteOffset;
1216 
1217     /*
1218      * Calculate lengths for fields that have variable length:
1219      * 1) Resource Source string
1220      * 2) Vendor Data buffer
1221      */
1222     ResSourceLength = RsGetStringDataLength (InitializerOp);
1223     VendorLength = RsGetBufferDataLength (InitializerOp);
1224 
1225     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS) +
1226         ResSourceLength + VendorLength;
1227 
1228     /* Allocate the local resource node and initialize */
1229 
1230     Rnode = RsAllocateResourceNode (DescriptorSize +
1231         sizeof (AML_RESOURCE_LARGE_HEADER));
1232 
1233     Descriptor = Rnode->Buffer;
1234     Descriptor->UartSerialBus.ResourceLength = DescriptorSize;
1235     Descriptor->UartSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
1236     Descriptor->UartSerialBus.RevisionId = AML_RESOURCE_UART_REVISION;
1237     Descriptor->UartSerialBus.TypeRevisionId = AML_RESOURCE_UART_TYPE_REVISION;
1238     Descriptor->UartSerialBus.Type = AML_RESOURCE_UART_SERIALBUSTYPE;
1239     Descriptor->UartSerialBus.TypeDataLength = AML_RESOURCE_UART_MIN_DATA_LEN + VendorLength;
1240 
1241     if (Info->DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_UART_SERIALBUS_V2)
1242     {
1243         Descriptor->I2cSerialBus.RevisionId = 2;
1244     }
1245 
1246     /* Build pointers to optional areas */
1247 
1248     VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_UART_SERIALBUS));
1249     ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
1250 
1251     /* Process all child initialization nodes */
1252 
1253     for (i = 0; InitializerOp; i++)
1254     {
1255         switch (i)
1256         {
1257         case 0: /* Connection Speed (Baud Rate) [DWORD] (_SPE) */
1258 
1259             Descriptor->UartSerialBus.DefaultBaudRate = (UINT32) InitializerOp->Asl.Value.Integer;
1260             RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED,
1261                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.DefaultBaudRate));
1262             break;
1263 
1264         case 1: /* Bits Per Byte [Flags] (_LEN) */
1265 
1266             RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 4, 3);
1267             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LENGTH,
1268                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 4, 3);
1269             break;
1270 
1271         case 2: /* Stop Bits [Flags] (_STB) */
1272 
1273             RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 2, 1);
1274             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_STOPBITS,
1275                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 2, 2);
1276             break;
1277 
1278         case 3: /* Lines In Use [BYTE] (_LIN) */
1279 
1280             Descriptor->UartSerialBus.LinesEnabled = (UINT8) InitializerOp->Asl.Value.Integer;
1281             RsCreateByteField (InitializerOp, ACPI_RESTAG_LINE,
1282                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.LinesEnabled));
1283             break;
1284 
1285         case 4: /* Endianness [Flag] (_END) */
1286 
1287             RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 7, 0);
1288             RsCreateBitField (InitializerOp, ACPI_RESTAG_ENDIANNESS,
1289                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 7);
1290             break;
1291 
1292         case 5: /* Parity [BYTE] (_PAR) */
1293 
1294             Descriptor->UartSerialBus.Parity = (UINT8) InitializerOp->Asl.Value.Integer;
1295             RsCreateByteField (InitializerOp, ACPI_RESTAG_PARITY,
1296                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Parity));
1297             break;
1298 
1299         case 6: /* Flow Control [Flags] (_FLC) */
1300 
1301             RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1302             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_FLOWCONTROL,
1303                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 0, 2);
1304             break;
1305 
1306         case 7: /* Rx Buffer Size [WORD] (_RXL) */
1307 
1308             Descriptor->UartSerialBus.RxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
1309             RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_RX,
1310                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.RxFifoSize));
1311             break;
1312 
1313         case 8: /* Tx Buffer Size [WORD] (_TXL) */
1314 
1315             Descriptor->UartSerialBus.TxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer;
1316             RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_TX,
1317                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TxFifoSize));
1318             break;
1319 
1320         case 9: /* ResSource [Optional Field - STRING] */
1321 
1322             if (ResSourceLength)
1323             {
1324                 /* Copy string to the descriptor */
1325 
1326                 strcpy (ResourceSource,
1327                     InitializerOp->Asl.Value.String);
1328             }
1329             break;
1330 
1331         case 10: /* Resource Index */
1332 
1333             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1334             {
1335                 Descriptor->UartSerialBus.ResSourceIndex =
1336                     (UINT8) InitializerOp->Asl.Value.Integer;
1337             }
1338             break;
1339 
1340         case 11: /* Resource Usage (consumer/producer) */
1341 
1342             RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 1, 1);
1343 
1344             /*
1345              * Slave Mode [Flag] (_SLV)
1346              *
1347              * Note: There is no SlaveMode argument to the UartSerialBus macro, but
1348              * we add this name anyway to allow the flag to be set by ASL in the
1349              * rare case where there is a slave mode associated with the UART.
1350              */
1351             RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
1352                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 0);
1353             break;
1354 
1355         case 12: /* Resource Tag (Descriptor Name) */
1356 
1357             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1358             break;
1359 
1360         case 13:
1361             /*
1362              * Connection Share - Added for V2 (ACPI 6.0) version of the descriptor
1363              * Note: For V1, the share bit will be zero (Op is DEFAULT_ARG from
1364              * the ASL parser)
1365              */
1366             RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 2, 0);
1367             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1368                 CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 2);
1369             break;
1370 
1371         case 14: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1372 
1373             RsGetVendorData (InitializerOp, VendorData,
1374                 CurrentByteOffset + sizeof (AML_RESOURCE_UART_SERIALBUS));
1375             break;
1376 
1377         default:    /* Ignore any extra nodes */
1378 
1379             break;
1380         }
1381 
1382         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1383     }
1384 
1385     MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
1386     return (Rnode);
1387 }
1388 
1389 
1390 /*******************************************************************************
1391  *
1392  * FUNCTION:    RsDoPinFunctionDescriptor
1393  *
1394  * PARAMETERS:  Info                - Parse Op and resource template offset
1395  *
1396  * RETURN:      Completed resource node
1397  *
1398  * DESCRIPTION: Construct a long "PinFunction" descriptor
1399  *
1400  ******************************************************************************/
1401 
1402 ASL_RESOURCE_NODE *
1403 RsDoPinFunctionDescriptor (
1404     ASL_RESOURCE_INFO       *Info)
1405 {
1406     AML_RESOURCE            *Descriptor;
1407     ACPI_PARSE_OBJECT       *InitializerOp;
1408     ASL_RESOURCE_NODE       *Rnode;
1409     char                    *ResourceSource = NULL;
1410     UINT8                   *VendorData = NULL;
1411     UINT16                  *PinList = NULL;
1412     UINT16                  ResSourceLength;
1413     UINT16                  VendorLength;
1414     UINT16                  PinListLength;
1415     UINT16                  DescriptorSize;
1416     UINT32                  CurrentByteOffset;
1417     UINT32                  PinCount = 0;
1418     UINT32                  i;
1419 
1420     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1421     CurrentByteOffset = Info->CurrentByteOffset;
1422 
1423     /*
1424      * Calculate lengths for fields that have variable length:
1425      * 1) Resource Source string
1426      * 2) Vendor Data buffer
1427      * 3) PIN (interrupt) list
1428      */
1429     ResSourceLength = RsGetStringDataLength (InitializerOp);
1430     VendorLength = RsGetBufferDataLength (InitializerOp);
1431     PinListLength = RsGetInterruptDataLength (InitializerOp, 8);
1432 
1433     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_FUNCTION) +
1434         ResSourceLength + VendorLength + PinListLength;
1435 
1436     /* Allocate the local resource node and initialize */
1437 
1438     Rnode = RsAllocateResourceNode (DescriptorSize +
1439         sizeof (AML_RESOURCE_LARGE_HEADER));
1440 
1441     Descriptor = Rnode->Buffer;
1442     Descriptor->PinFunction.ResourceLength = DescriptorSize;
1443     Descriptor->PinFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_FUNCTION;
1444     Descriptor->PinFunction.RevisionId = AML_RESOURCE_PIN_FUNCTION_REVISION;
1445 
1446     /* Build pointers to optional areas */
1447 
1448     PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_FUNCTION));
1449     ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength);
1450     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
1451 
1452     /* Setup offsets within the descriptor */
1453 
1454     Descriptor->PinFunction.PinTableOffset = (UINT16)
1455         ACPI_PTR_DIFF (PinList, Descriptor);
1456 
1457     Descriptor->PinFunction.ResSourceOffset = (UINT16)
1458         ACPI_PTR_DIFF (ResourceSource, Descriptor);
1459 
1460     /* Process all child initialization nodes */
1461 
1462     for (i = 0; InitializerOp; i++)
1463     {
1464         switch (i)
1465         {
1466         case 0: /* Share Type [Flags] (_SHR) */
1467 
1468             RsSetFlagBits16 (&Descriptor->PinFunction.Flags, InitializerOp, 0, 0);
1469             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1470                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.Flags), 0);
1471             break;
1472 
1473         case 1: /* Pin Config [BYTE] (_PPI) */
1474 
1475             Descriptor->PinFunction.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
1476             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
1477                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.PinConfig));
1478             break;
1479 
1480         case 2: /* Function Number [WORD] (_FUN) */
1481 
1482             Descriptor->PinFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer;
1483             RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION,
1484                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.FunctionNumber));
1485             break;
1486 
1487         case 3: /* ResSource [Optional Field - STRING] */
1488 
1489             if (ResSourceLength)
1490             {
1491                 /* Copy string to the descriptor */
1492 
1493                 strcpy (ResourceSource, InitializerOp->Asl.Value.String);
1494             }
1495             break;
1496 
1497         case 4: /* Resource Index */
1498 
1499             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1500             {
1501                 Descriptor->PinFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
1502             }
1503             break;
1504 
1505         case 5: /* Resource Usage (consumer/producer) */
1506 
1507             /* Assumed to be consumer */
1508 
1509             break;
1510 
1511         case 6: /* Resource Tag (Descriptor Name) */
1512 
1513             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1514             break;
1515 
1516         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1517             /*
1518              * Always set the VendorOffset even if there is no Vendor Data.
1519              * This field is required in order to calculate the length
1520              * of the ResourceSource at runtime.
1521              */
1522             Descriptor->PinFunction.VendorOffset = (UINT16)
1523                 ACPI_PTR_DIFF (VendorData, Descriptor);
1524 
1525             if (RsGetVendorData (InitializerOp, VendorData,
1526                 (CurrentByteOffset + Descriptor->PinFunction.VendorOffset)))
1527             {
1528                 Descriptor->PinFunction.VendorLength = VendorLength;
1529             }
1530             break;
1531 
1532         default:
1533             /*
1534              * PINs come through here, repeatedly. Each PIN must be a WORD.
1535              * NOTE: there is no "length" field for this, so from ACPI spec:
1536              *  The number of pins in the table can be calculated from:
1537              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
1538              *  (implies resource source must immediately follow the pin list.)
1539              *  Name: _PIN
1540              */
1541             *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1542             PinList++;
1543             PinCount++;
1544 
1545             /* Case 8: First pin number in list */
1546 
1547             if (i == 8)
1548             {
1549                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1550                 {
1551                     /* Must be at least one interrupt */
1552 
1553                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1554                         InitializerOp, NULL);
1555                 }
1556 
1557                 /* Check now for duplicates in list */
1558 
1559                 RsCheckListForDuplicates (InitializerOp);
1560 
1561                 /* Create a named field at the start of the list */
1562 
1563                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1564                     CurrentByteOffset + Descriptor->PinFunction.PinTableOffset);
1565             }
1566             break;
1567         }
1568 
1569         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1570     }
1571 
1572     return (Rnode);
1573 }
1574 
1575 
1576 /*******************************************************************************
1577  *
1578  * FUNCTION:    RsDoPinConfigDescriptor
1579  *
1580  * PARAMETERS:  Info                - Parse Op and resource template offset
1581  *
1582  * RETURN:      Completed resource node
1583  *
1584  * DESCRIPTION: Construct a long "PinConfig" descriptor
1585  *
1586  ******************************************************************************/
1587 
1588 ASL_RESOURCE_NODE *
1589 RsDoPinConfigDescriptor (
1590     ASL_RESOURCE_INFO       *Info)
1591 {
1592     AML_RESOURCE            *Descriptor;
1593     ACPI_PARSE_OBJECT       *InitializerOp;
1594     ASL_RESOURCE_NODE       *Rnode;
1595     char                    *ResourceSource = NULL;
1596     UINT8                   *VendorData = NULL;
1597     UINT16                  *PinList = NULL;
1598     UINT16                  ResSourceLength;
1599     UINT16                  VendorLength;
1600     UINT16                  PinListLength;
1601     UINT16                  DescriptorSize;
1602     UINT32                  CurrentByteOffset;
1603     UINT32                  PinCount = 0;
1604     UINT32                  i;
1605 
1606     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1607     CurrentByteOffset = Info->CurrentByteOffset;
1608 
1609     /*
1610      * Calculate lengths for fields that have variable length:
1611      * 1) Resource Source string
1612      * 2) Vendor Data buffer
1613      * 3) PIN (interrupt) list
1614      */
1615     ResSourceLength = RsGetStringDataLength (InitializerOp);
1616     VendorLength = RsGetBufferDataLength (InitializerOp);
1617     PinListLength = RsGetInterruptDataLength (InitializerOp, 8);
1618 
1619     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_CONFIG) +
1620         ResSourceLength + VendorLength + PinListLength;
1621 
1622     /* Allocate the local resource node and initialize */
1623 
1624     Rnode = RsAllocateResourceNode (DescriptorSize +
1625         sizeof (AML_RESOURCE_LARGE_HEADER));
1626 
1627     Descriptor = Rnode->Buffer;
1628     Descriptor->PinConfig.ResourceLength = DescriptorSize;
1629     Descriptor->PinConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_CONFIG;
1630     Descriptor->PinConfig.RevisionId = AML_RESOURCE_PIN_CONFIG_REVISION;
1631 
1632     /* Build pointers to optional areas */
1633 
1634     PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_CONFIG));
1635     ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength);
1636     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
1637 
1638     /* Setup offsets within the descriptor */
1639 
1640     Descriptor->PinConfig.PinTableOffset = (UINT16)
1641         ACPI_PTR_DIFF (PinList, Descriptor);
1642 
1643     Descriptor->PinConfig.ResSourceOffset = (UINT16)
1644         ACPI_PTR_DIFF (ResourceSource, Descriptor);
1645 
1646     /* Process all child initialization nodes */
1647 
1648     for (i = 0; InitializerOp; i++)
1649     {
1650         BOOLEAN isValid;
1651 
1652         switch (i)
1653         {
1654         case 0: /* Share Type [Flags] (_SHR) */
1655 
1656             RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 0, 0);
1657             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1658                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.Flags), 0);
1659             break;
1660 
1661         case 1: /* Pin Config Type [BYTE] (_TYP) */
1662 
1663             isValid = InitializerOp->Asl.Value.Integer <= 0x0d;
1664             if (!isValid)
1665             {
1666                 isValid = InitializerOp->Asl.Value.Integer >= 0x80 &&
1667                           InitializerOp->Asl.Value.Integer <= 0xff;
1668             }
1669             if (!isValid)
1670             {
1671                     AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL);
1672             }
1673 
1674             Descriptor->PinConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer;
1675             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE,
1676                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigType));
1677 
1678             break;
1679 
1680         case 2: /* Pin Config Value [DWORD] (_VAL) */
1681 
1682             Descriptor->PinConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer;
1683             RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE,
1684                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigValue));
1685             break;
1686 
1687         case 3: /* ResSource [Optional Field - STRING] */
1688 
1689             if (ResSourceLength)
1690             {
1691                 /* Copy string to the descriptor */
1692 
1693                 strcpy (ResourceSource, InitializerOp->Asl.Value.String);
1694             }
1695             break;
1696 
1697         case 4: /* Resource Index */
1698 
1699             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1700             {
1701                 Descriptor->PinConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
1702             }
1703             break;
1704 
1705         case 5: /* Resource Usage (consumer/producer) */
1706 
1707             RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 1, 1);
1708 
1709             break;
1710 
1711         case 6: /* Resource Tag (Descriptor Name) */
1712 
1713             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1714             break;
1715 
1716         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1717             /*
1718              * Always set the VendorOffset even if there is no Vendor Data.
1719              * This field is required in order to calculate the length
1720              * of the ResourceSource at runtime.
1721              */
1722             Descriptor->PinConfig.VendorOffset = (UINT16)
1723                 ACPI_PTR_DIFF (VendorData, Descriptor);
1724 
1725             if (RsGetVendorData (InitializerOp, VendorData,
1726                 (CurrentByteOffset + Descriptor->PinConfig.VendorOffset)))
1727             {
1728                 Descriptor->PinConfig.VendorLength = VendorLength;
1729             }
1730             break;
1731 
1732         default:
1733             /*
1734              * PINs come through here, repeatedly. Each PIN must be a WORD.
1735              * NOTE: there is no "length" field for this, so from ACPI spec:
1736              *  The number of pins in the table can be calculated from:
1737              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
1738              *  (implies resource source must immediately follow the pin list.)
1739              *  Name: _PIN
1740              */
1741             *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1742             PinList++;
1743             PinCount++;
1744 
1745             /* Case 8: First pin number in list */
1746 
1747             if (i == 8)
1748             {
1749                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1750                 {
1751                     /* Must be at least one interrupt */
1752 
1753                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1754                         InitializerOp, NULL);
1755                 }
1756 
1757                 /* Check now for duplicates in list */
1758 
1759                 RsCheckListForDuplicates (InitializerOp);
1760 
1761                 /* Create a named field at the start of the list */
1762 
1763                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1764                     CurrentByteOffset + Descriptor->PinConfig.PinTableOffset);
1765             }
1766             break;
1767         }
1768 
1769         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1770     }
1771 
1772     return (Rnode);
1773 }
1774 
1775 
1776 /*******************************************************************************
1777  *
1778  * FUNCTION:    RsDoPinGroupDescriptor
1779  *
1780  * PARAMETERS:  Info                - Parse Op and resource template offset
1781  *
1782  * RETURN:      Completed resource node
1783  *
1784  * DESCRIPTION: Construct a long "PinGroup" descriptor
1785  *
1786  ******************************************************************************/
1787 
1788 ASL_RESOURCE_NODE *
1789 RsDoPinGroupDescriptor (
1790     ASL_RESOURCE_INFO       *Info)
1791 {
1792     AML_RESOURCE            *Descriptor;
1793     ACPI_PARSE_OBJECT       *InitializerOp;
1794     ASL_RESOURCE_NODE       *Rnode;
1795     UINT8                   *VendorData = NULL;
1796     UINT16                  *PinList = NULL;
1797     char                    *Label = NULL;
1798     UINT16                  LabelLength;
1799     UINT16                  VendorLength;
1800     UINT16                  PinListLength;
1801     UINT16                  DescriptorSize;
1802     UINT32                  CurrentByteOffset;
1803     UINT32                  PinCount = 0;
1804     UINT32                  i;
1805 
1806     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1807     CurrentByteOffset = Info->CurrentByteOffset;
1808 
1809     /*
1810      * Calculate lengths for fields that have variable length:
1811      * 1) Label
1812      * 2) Vendor Data buffer
1813      * 3) PIN (interrupt) list
1814      */
1815     LabelLength = RsGetStringDataLength (InitializerOp);
1816     VendorLength = RsGetBufferDataLength (InitializerOp);
1817     PinListLength = RsGetInterruptDataLength (InitializerOp, 4);
1818 
1819     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP) +
1820         LabelLength + VendorLength + PinListLength;
1821 
1822     /* Allocate the local resource node and initialize */
1823 
1824     Rnode = RsAllocateResourceNode (DescriptorSize +
1825         sizeof (AML_RESOURCE_LARGE_HEADER));
1826 
1827     Descriptor = Rnode->Buffer;
1828     Descriptor->PinGroup.ResourceLength = DescriptorSize;
1829     Descriptor->PinGroup.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP;
1830     Descriptor->PinGroup.RevisionId = AML_RESOURCE_PIN_GROUP_REVISION;
1831 
1832     /* Build pointers to optional areas */
1833 
1834     PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP));
1835     Label = ACPI_ADD_PTR (char, PinList, PinListLength);
1836     VendorData = ACPI_ADD_PTR (UINT8, Label, LabelLength);
1837 
1838     /* Setup offsets within the descriptor */
1839 
1840     Descriptor->PinGroup.PinTableOffset = (UINT16) ACPI_PTR_DIFF (PinList, Descriptor);
1841     Descriptor->PinGroup.LabelOffset = (UINT16) ACPI_PTR_DIFF (Label, Descriptor);
1842 
1843     /* Process all child initialization nodes */
1844 
1845     for (i = 0; InitializerOp; i++)
1846     {
1847         switch (i)
1848         {
1849         case 0: /* Resource Label */
1850 
1851             if (LabelLength < 2)
1852             {
1853                 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
1854             }
1855             strcpy (Label, InitializerOp->Asl.Value.String);
1856 
1857             break;
1858 
1859         case 1: /* Resource Usage (consumer/producer) */
1860 
1861             RsSetFlagBits16 (&Descriptor->PinGroup.Flags, InitializerOp, 0, 0);
1862 
1863             break;
1864 
1865         case 2: /* Resource Tag (Descriptor Name) */
1866 
1867             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1868             break;
1869 
1870         case 3: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1871             /*
1872              * Always set the VendorOffset even if there is no Vendor Data.
1873              * This field is required in order to calculate the length
1874              * of the ResourceSource at runtime.
1875              */
1876             Descriptor->PinGroup.VendorOffset = (UINT16)
1877                 ACPI_PTR_DIFF (VendorData, Descriptor);
1878 
1879             if (RsGetVendorData (InitializerOp, VendorData,
1880                 (CurrentByteOffset + Descriptor->PinGroup.VendorOffset)))
1881             {
1882                 Descriptor->PinGroup.VendorLength = VendorLength;
1883             }
1884             break;
1885 
1886         default:
1887             /*
1888              * PINs come through here, repeatedly. Each PIN must be a WORD.
1889              * NOTE: there is no "length" field for this, so from ACPI spec:
1890              *  The number of pins in the table can be calculated from:
1891              *  PinCount = (Resource Source Name Offset - Pin Table Offset) / 2
1892              *  (implies resource source must immediately follow the pin list.)
1893              *  Name: _PIN
1894              */
1895             *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1896             PinList++;
1897             PinCount++;
1898 
1899             /* Case 3: First pin number in list */
1900 
1901             if (i == 4)
1902             {
1903                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1904                 {
1905                     /* Must be at least one interrupt */
1906 
1907                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1908                         InitializerOp, NULL);
1909                 }
1910 
1911                 /* Check now for duplicates in list */
1912 
1913                 RsCheckListForDuplicates (InitializerOp);
1914 
1915                 /* Create a named field at the start of the list */
1916 
1917                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1918                     CurrentByteOffset + Descriptor->PinGroup.PinTableOffset);
1919             }
1920             break;
1921         }
1922 
1923         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1924     }
1925 
1926     return (Rnode);
1927 }
1928 
1929 
1930 /*******************************************************************************
1931  *
1932  * FUNCTION:    RsDoPinGroupFunctionDescriptor
1933  *
1934  * PARAMETERS:  Info                - Parse Op and resource template offset
1935  *
1936  * RETURN:      Completed resource node
1937  *
1938  * DESCRIPTION: Construct a long "PinGroupFunction" descriptor
1939  *
1940  ******************************************************************************/
1941 
1942 ASL_RESOURCE_NODE *
1943 RsDoPinGroupFunctionDescriptor (
1944     ASL_RESOURCE_INFO       *Info)
1945 {
1946     AML_RESOURCE            *Descriptor;
1947     ACPI_PARSE_OBJECT       *InitializerOp;
1948     ASL_RESOURCE_NODE       *Rnode;
1949     char                    *ResourceSource = NULL;
1950     char                    *ResourceSourceLabel = NULL;
1951     UINT8                   *VendorData = NULL;
1952     UINT16                  ResSourceLength;
1953     UINT16                  ResSourceLabelLength;
1954     UINT16                  VendorLength;
1955     UINT16                  DescriptorSize;
1956     UINT32                  CurrentByteOffset;
1957     UINT32                  i;
1958 
1959     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1960     CurrentByteOffset = Info->CurrentByteOffset;
1961 
1962     /*
1963      * Calculate lengths for fields that have variable length:
1964      * 1) Resource Source string
1965      * 2) Resource Source Label string
1966      * 3) Vendor Data buffer
1967      */
1968     ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 2);
1969     ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 4);
1970     VendorLength = RsGetBufferDataLength (InitializerOp);
1971 
1972     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_FUNCTION) +
1973         ResSourceLength + ResSourceLabelLength + VendorLength;
1974 
1975     /* Allocate the local resource node and initialize */
1976 
1977     Rnode = RsAllocateResourceNode (DescriptorSize +
1978         sizeof (AML_RESOURCE_LARGE_HEADER));
1979 
1980     Descriptor = Rnode->Buffer;
1981     Descriptor->PinGroupFunction.ResourceLength = DescriptorSize;
1982     Descriptor->PinGroupFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION;
1983     Descriptor->PinGroupFunction.RevisionId = AML_RESOURCE_PIN_GROUP_FUNCTION_REVISION;
1984 
1985     /* Build pointers to optional areas */
1986 
1987     ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_FUNCTION));
1988     ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength);
1989     VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength);
1990 
1991     /* Setup offsets within the descriptor */
1992 
1993     Descriptor->PinGroupFunction.ResSourceOffset = (UINT16)
1994         ACPI_PTR_DIFF (ResourceSource, Descriptor);
1995     Descriptor->PinGroupFunction.ResSourceLabelOffset = (UINT16)
1996         ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor);
1997 
1998     /* Process all child initialization nodes */
1999 
2000     for (i = 0; InitializerOp; i++)
2001     {
2002         switch (i)
2003         {
2004         case 0: /* Share Type [Flags] (_SHR) */
2005 
2006             RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 0, 0);
2007             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
2008                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.Flags), 0);
2009             break;
2010 
2011         case 1: /* Function Number [WORD] */
2012 
2013             Descriptor->PinGroupFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer;
2014             RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION,
2015                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.FunctionNumber));
2016             break;
2017 
2018         case 2: /* ResourceSource [STRING] */
2019 
2020             strcpy (ResourceSource, InitializerOp->Asl.Value.String);
2021             break;
2022 
2023         case 3: /* Resource Index */
2024 
2025             Descriptor->PinGroupFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
2026             break;
2027 
2028         case 4: /* ResourceSourceLabel [STRING] */
2029 
2030             if (ResSourceLabelLength < 2)
2031             {
2032                 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
2033             }
2034 
2035             strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String);
2036             break;
2037 
2038         case 5: /* Resource Usage (consumer/producer) */
2039 
2040             RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 1, 1);
2041 
2042             break;
2043 
2044         case 6: /* Resource Tag (Descriptor Name) */
2045 
2046             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
2047             break;
2048 
2049         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
2050             /*
2051              * Always set the VendorOffset even if there is no Vendor Data.
2052              * This field is required in order to calculate the length
2053              * of the ResourceSource at runtime.
2054              */
2055             Descriptor->PinGroupFunction.VendorOffset = (UINT16)
2056                 ACPI_PTR_DIFF (VendorData, Descriptor);
2057 
2058             if (RsGetVendorData (InitializerOp, VendorData,
2059                 (CurrentByteOffset + Descriptor->PinGroupFunction.VendorOffset)))
2060             {
2061                 Descriptor->PinGroupFunction.VendorLength = VendorLength;
2062             }
2063             break;
2064 
2065         default:
2066             break;
2067         }
2068 
2069         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2070     }
2071 
2072     return (Rnode);
2073 }
2074 
2075 
2076 /*******************************************************************************
2077  *
2078  * FUNCTION:    RsDoPinGroupConfigDescriptor
2079  *
2080  * PARAMETERS:  Info                - Parse Op and resource template offset
2081  *
2082  * RETURN:      Completed resource node
2083  *
2084  * DESCRIPTION: Construct a long "PinGroupConfig" descriptor
2085  *
2086  ******************************************************************************/
2087 
2088 ASL_RESOURCE_NODE *
2089 RsDoPinGroupConfigDescriptor (
2090     ASL_RESOURCE_INFO       *Info)
2091 {
2092     AML_RESOURCE            *Descriptor;
2093     ACPI_PARSE_OBJECT       *InitializerOp;
2094     ASL_RESOURCE_NODE       *Rnode;
2095     char                    *ResourceSource = NULL;
2096     char                    *ResourceSourceLabel = NULL;
2097     UINT8                   *VendorData = NULL;
2098     UINT16                  ResSourceLength;
2099     UINT16                  ResSourceLabelLength;
2100     UINT16                  VendorLength;
2101     UINT16                  DescriptorSize;
2102     UINT32                  CurrentByteOffset;
2103     UINT32                  i;
2104 
2105     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
2106     CurrentByteOffset = Info->CurrentByteOffset;
2107 
2108     /*
2109      * Calculate lengths for fields that have variable length:
2110      * 1) Resource Source string
2111      * 2) Resource Source Label string
2112      * 3) Vendor Data buffer
2113      */
2114     ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 3);
2115     ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 5);
2116     VendorLength = RsGetBufferDataLength (InitializerOp);
2117 
2118     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_CONFIG) +
2119         ResSourceLength + ResSourceLabelLength + VendorLength;
2120 
2121     /* Allocate the local resource node and initialize */
2122 
2123     Rnode = RsAllocateResourceNode (DescriptorSize +
2124         sizeof (AML_RESOURCE_LARGE_HEADER));
2125 
2126     Descriptor = Rnode->Buffer;
2127     Descriptor->PinGroupConfig.ResourceLength = DescriptorSize;
2128     Descriptor->PinGroupConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG;
2129     Descriptor->PinGroupConfig.RevisionId = AML_RESOURCE_PIN_GROUP_CONFIG_REVISION;
2130 
2131     /* Build pointers to optional areas */
2132 
2133     ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_CONFIG));
2134     ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength);
2135     VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength);
2136 
2137     /* Setup offsets within the descriptor */
2138 
2139     Descriptor->PinGroupConfig.ResSourceOffset = (UINT16)
2140         ACPI_PTR_DIFF (ResourceSource, Descriptor);
2141     Descriptor->PinGroupConfig.ResSourceLabelOffset = (UINT16)
2142         ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor);
2143 
2144     /* Process all child initialization nodes */
2145 
2146     for (i = 0; InitializerOp; i++)
2147     {
2148         BOOLEAN isValid;
2149 
2150         switch (i)
2151         {
2152         case 0: /* Share Type [Flags] (_SHR) */
2153 
2154             RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 0, 0);
2155             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
2156                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.Flags), 0);
2157             break;
2158 
2159         case 1: /* Pin Config Type [BYTE] (_TYP) */
2160 
2161             isValid = InitializerOp->Asl.Value.Integer <= 0x0d;
2162             if (!isValid)
2163             {
2164                 isValid = InitializerOp->Asl.Value.Integer >= 0x80 &&
2165                           InitializerOp->Asl.Value.Integer <= 0xff;
2166             }
2167             if (!isValid)
2168             {
2169                     AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL);
2170             }
2171 
2172             Descriptor->PinGroupConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer;
2173             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE,
2174                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigType));
2175 
2176             break;
2177 
2178         case 2: /* Pin Config Value [DWORD] (_VAL) */
2179 
2180             Descriptor->PinGroupConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer;
2181             RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE,
2182                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigValue));
2183             break;
2184 
2185         case 3: /* ResourceSource [STRING] */
2186 
2187             /* Copy string to the descriptor */
2188 
2189             strcpy (ResourceSource, InitializerOp->Asl.Value.String);
2190             break;
2191 
2192         case 4: /* Resource Index */
2193 
2194             Descriptor->PinGroupConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
2195             break;
2196 
2197         case 5: /* ResourceSourceLabel [STRING] */
2198 
2199             if (ResSourceLabelLength < 2)
2200             {
2201                 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
2202             }
2203 
2204             strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String);
2205             break;
2206 
2207         case 6: /* Resource Usage (consumer/producer) */
2208 
2209             RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 1, 1);
2210 
2211             break;
2212 
2213         case 7: /* Resource Tag (Descriptor Name) */
2214 
2215             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
2216             break;
2217 
2218         case 8: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
2219             /*
2220              * Always set the VendorOffset even if there is no Vendor Data.
2221              * This field is required in order to calculate the length
2222              * of the ResourceSource at runtime.
2223              */
2224             Descriptor->PinGroupConfig.VendorOffset = (UINT16)
2225                 ACPI_PTR_DIFF (VendorData, Descriptor);
2226 
2227             if (RsGetVendorData (InitializerOp, VendorData,
2228                 (CurrentByteOffset + Descriptor->PinGroupConfig.VendorOffset)))
2229             {
2230                 Descriptor->PinGroupConfig.VendorLength = VendorLength;
2231             }
2232             break;
2233 
2234         default:
2235             break;
2236         }
2237 
2238         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2239     }
2240 
2241     return (Rnode);
2242 }
2243