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 - 2023, 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
RsGetBufferDataLength(ACPI_PARSE_OBJECT * InitializerOp)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
RsGetInterruptDataLength(ACPI_PARSE_OBJECT * InitializerOp,UINT32 StartIndex)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
RsGetVendorData(ACPI_PARSE_OBJECT * InitializerOp,UINT8 * VendorData,ACPI_SIZE DescriptorOffset)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
RsGetStringDataLengthAt(ACPI_PARSE_OBJECT * InitializerOp,UINT32 StartIndex)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 *
RsDoGpioIntDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoGpioIoDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoI2cSerialBusDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoSpiSerialBusDescriptor(ASL_RESOURCE_INFO * Info)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 *
RsDoUartSerialBusDescriptor(ASL_RESOURCE_INFO * Info)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:    RsDoCsi2SerialBusDescriptor
1393  *
1394  * PARAMETERS:  Info                - Parse Op and resource template offset
1395  *
1396  * RETURN:      Completed resource node
1397  *
1398  * DESCRIPTION: Construct a long "Csi2SerialBus" descriptor
1399  *
1400  ******************************************************************************/
1401 
1402 ASL_RESOURCE_NODE *
RsDoCsi2SerialBusDescriptor(ASL_RESOURCE_INFO * Info)1403 RsDoCsi2SerialBusDescriptor (
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                  ResSourceLength;
1412     UINT16                  VendorLength;
1413     UINT16                  DescriptorSize;
1414     UINT32                  CurrentByteOffset;
1415     UINT32                  i;
1416 
1417 
1418     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1419     CurrentByteOffset = Info->CurrentByteOffset;
1420 
1421     /*
1422      * Calculate lengths for fields that have variable length:
1423      * 1) Resource Source string
1424      * 2) Vendor Data buffer
1425      */
1426     ResSourceLength = RsGetStringDataLength (InitializerOp);
1427     VendorLength = RsGetBufferDataLength (InitializerOp);
1428 
1429     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_CSI2_SERIALBUS) +
1430         ResSourceLength + VendorLength;
1431 
1432     /* Allocate the local resource node and initialize */
1433 
1434     Rnode = RsAllocateResourceNode (DescriptorSize +
1435         sizeof (AML_RESOURCE_LARGE_HEADER));
1436 
1437     Descriptor = Rnode->Buffer;
1438     Descriptor->Csi2SerialBus.ResourceLength = DescriptorSize;
1439     Descriptor->Csi2SerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS;
1440     Descriptor->Csi2SerialBus.RevisionId = AML_RESOURCE_CSI2_REVISION;
1441     Descriptor->Csi2SerialBus.TypeRevisionId = AML_RESOURCE_CSI2_TYPE_REVISION;
1442     Descriptor->Csi2SerialBus.Type = AML_RESOURCE_CSI2_SERIALBUSTYPE;
1443     Descriptor->Csi2SerialBus.TypeDataLength = AML_RESOURCE_CSI2_MIN_DATA_LEN + VendorLength;
1444 
1445     /* Build pointers to optional areas */
1446 
1447     VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_CSI2_SERIALBUS));
1448     ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength);
1449 
1450     /* Process all child initialization nodes */
1451 
1452     for (i = 0; InitializerOp; i++)
1453     {
1454         switch (i)
1455         {
1456         case 0: /* Slave Mode [Flag] (_SLV) */
1457 
1458             RsSetFlagBits (&Descriptor->Csi2SerialBus.Flags, InitializerOp, 0, 0);
1459             RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE,
1460                 CurrentByteOffset + ASL_RESDESC_OFFSET (I2cSerialBus.Flags), 0);
1461             break;
1462 
1463         case 1: /* Phy Type [Flag] (_PHY) */
1464 
1465             RsSetFlagBits16 ((UINT16 *) &Descriptor->Csi2SerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1466             RsCreateBitField (InitializerOp, ACPI_RESTAG_PHYTYPE,
1467                 CurrentByteOffset + ASL_RESDESC_OFFSET (Csi2SerialBus.TypeSpecificFlags), 0);
1468             break;
1469 
1470         case 2: /* Local Port Instance [Integer] (_PRT) */
1471 
1472             RsSetFlagBits16 ((UINT16 *) &Descriptor->Csi2SerialBus.TypeSpecificFlags, InitializerOp, 0, 0);
1473             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LOCALPORT,
1474                 CurrentByteOffset + ASL_RESDESC_OFFSET (Csi2SerialBus.TypeSpecificFlags), 2, 6);
1475             break;
1476 
1477         case 3: /* ResSource [Optional Field - STRING] */
1478 
1479             if (ResSourceLength)
1480             {
1481                 /* Copy string to the descriptor */
1482 
1483                 strcpy (ResourceSource,
1484                     InitializerOp->Asl.Value.String);
1485             }
1486             break;
1487 
1488         case 4: /* Resource Index */
1489 
1490             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1491             {
1492                 Descriptor->Csi2SerialBus.ResSourceIndex =
1493                     (UINT8) InitializerOp->Asl.Value.Integer;
1494             }
1495             break;
1496 
1497         case 5: /* Resource Usage (consumer/producer) */
1498 
1499             RsSetFlagBits (&Descriptor->Csi2SerialBus.Flags, InitializerOp, 1, 1);
1500             break;
1501 
1502         case 6: /* Resource Tag (Descriptor Name) */
1503 
1504             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1505             break;
1506 
1507         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1508 
1509             RsGetVendorData (InitializerOp, VendorData,
1510                 CurrentByteOffset + sizeof (AML_RESOURCE_CSI2_SERIALBUS));
1511             break;
1512 
1513         default:    /* Ignore any extra nodes */
1514 
1515             break;
1516         }
1517 
1518         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1519     }
1520 
1521     MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource);
1522     return (Rnode);
1523 }
1524 
1525 
1526 /*******************************************************************************
1527  *
1528  * FUNCTION:    RsDoPinFunctionDescriptor
1529  *
1530  * PARAMETERS:  Info                - Parse Op and resource template offset
1531  *
1532  * RETURN:      Completed resource node
1533  *
1534  * DESCRIPTION: Construct a long "PinFunction" descriptor
1535  *
1536  ******************************************************************************/
1537 
1538 ASL_RESOURCE_NODE *
RsDoPinFunctionDescriptor(ASL_RESOURCE_INFO * Info)1539 RsDoPinFunctionDescriptor (
1540     ASL_RESOURCE_INFO       *Info)
1541 {
1542     AML_RESOURCE            *Descriptor;
1543     ACPI_PARSE_OBJECT       *InitializerOp;
1544     ASL_RESOURCE_NODE       *Rnode;
1545     char                    *ResourceSource = NULL;
1546     UINT8                   *VendorData = NULL;
1547     UINT16                  *PinList = NULL;
1548     UINT16                  ResSourceLength;
1549     UINT16                  VendorLength;
1550     UINT16                  PinListLength;
1551     UINT16                  DescriptorSize;
1552     UINT32                  CurrentByteOffset;
1553     UINT32                  i;
1554 
1555     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1556     CurrentByteOffset = Info->CurrentByteOffset;
1557 
1558     /*
1559      * Calculate lengths for fields that have variable length:
1560      * 1) Resource Source string
1561      * 2) Vendor Data buffer
1562      * 3) PIN (interrupt) list
1563      */
1564     ResSourceLength = RsGetStringDataLength (InitializerOp);
1565     VendorLength = RsGetBufferDataLength (InitializerOp);
1566     PinListLength = RsGetInterruptDataLength (InitializerOp, 8);
1567 
1568     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_FUNCTION) +
1569         ResSourceLength + VendorLength + PinListLength;
1570 
1571     /* Allocate the local resource node and initialize */
1572 
1573     Rnode = RsAllocateResourceNode (DescriptorSize +
1574         sizeof (AML_RESOURCE_LARGE_HEADER));
1575 
1576     Descriptor = Rnode->Buffer;
1577     Descriptor->PinFunction.ResourceLength = DescriptorSize;
1578     Descriptor->PinFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_FUNCTION;
1579     Descriptor->PinFunction.RevisionId = AML_RESOURCE_PIN_FUNCTION_REVISION;
1580 
1581     /* Build pointers to optional areas */
1582 
1583     PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_FUNCTION));
1584     ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength);
1585     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
1586 
1587     /* Setup offsets within the descriptor */
1588 
1589     Descriptor->PinFunction.PinTableOffset = (UINT16)
1590         ACPI_PTR_DIFF (PinList, Descriptor);
1591 
1592     Descriptor->PinFunction.ResSourceOffset = (UINT16)
1593         ACPI_PTR_DIFF (ResourceSource, Descriptor);
1594 
1595     /* Process all child initialization nodes */
1596 
1597     for (i = 0; InitializerOp; i++)
1598     {
1599         switch (i)
1600         {
1601         case 0: /* Share Type [Flags] (_SHR) */
1602 
1603             RsSetFlagBits16 (&Descriptor->PinFunction.Flags, InitializerOp, 0, 0);
1604             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1605                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.Flags), 0);
1606             break;
1607 
1608         case 1: /* Pin Config [BYTE] (_PPI) */
1609 
1610             Descriptor->PinFunction.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer;
1611             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG,
1612                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.PinConfig));
1613             break;
1614 
1615         case 2: /* Function Number [WORD] (_FUN) */
1616 
1617             Descriptor->PinFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer;
1618             RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION,
1619                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinFunction.FunctionNumber));
1620             break;
1621 
1622         case 3: /* ResSource [Optional Field - STRING] */
1623 
1624             if (ResSourceLength)
1625             {
1626                 /* Copy string to the descriptor */
1627 
1628                 strcpy (ResourceSource, InitializerOp->Asl.Value.String);
1629             }
1630             break;
1631 
1632         case 4: /* Resource Index */
1633 
1634             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1635             {
1636                 Descriptor->PinFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
1637             }
1638             break;
1639 
1640         case 5: /* Resource Usage (consumer/producer) */
1641 
1642             /* Assumed to be consumer */
1643 
1644             break;
1645 
1646         case 6: /* Resource Tag (Descriptor Name) */
1647 
1648             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1649             break;
1650 
1651         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1652             /*
1653              * Always set the VendorOffset even if there is no Vendor Data.
1654              * This field is required in order to calculate the length
1655              * of the ResourceSource at runtime.
1656              */
1657             Descriptor->PinFunction.VendorOffset = (UINT16)
1658                 ACPI_PTR_DIFF (VendorData, Descriptor);
1659 
1660             if (RsGetVendorData (InitializerOp, VendorData,
1661                 (CurrentByteOffset + Descriptor->PinFunction.VendorOffset)))
1662             {
1663                 Descriptor->PinFunction.VendorLength = VendorLength;
1664             }
1665             break;
1666 
1667         default:
1668             /*
1669              * PINs come through here, repeatedly. Each PIN must be a WORD.
1670              *  Name: _PIN
1671              */
1672             *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1673             PinList++;
1674 
1675             /* Case 8: First pin number in list */
1676 
1677             if (i == 8)
1678             {
1679                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1680                 {
1681                     /* Must be at least one interrupt */
1682 
1683                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1684                         InitializerOp, NULL);
1685                 }
1686 
1687                 /* Check now for duplicates in list */
1688 
1689                 RsCheckListForDuplicates (InitializerOp);
1690 
1691                 /* Create a named field at the start of the list */
1692 
1693                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1694                     CurrentByteOffset + Descriptor->PinFunction.PinTableOffset);
1695             }
1696             break;
1697         }
1698 
1699         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1700     }
1701 
1702     return (Rnode);
1703 }
1704 
1705 /*******************************************************************************
1706  *
1707  * FUNCTION:    RsDoClockInputDescriptor
1708  *
1709  * PARAMETERS:  Info                - Parse Op and resource template offset
1710  *
1711  * RETURN:      Completed resource node
1712  *
1713  * DESCRIPTION: Construct a long "ClockInput" descriptor
1714  *
1715  ******************************************************************************/
1716 
1717 ASL_RESOURCE_NODE *
RsDoClockInputDescriptor(ASL_RESOURCE_INFO * Info)1718 RsDoClockInputDescriptor (
1719     ASL_RESOURCE_INFO       *Info)
1720 {
1721     AML_RESOURCE            *Descriptor;
1722     ACPI_PARSE_OBJECT       *InitializerOp;
1723     ASL_RESOURCE_NODE       *Rnode;
1724     char                    *ResourceSourceString = NULL;
1725     UINT8                   *ResourceSourceIndex = NULL;
1726     UINT16                  ResSourceLength;
1727     UINT16                  DescriptorSize;
1728     UINT32                  i;
1729     UINT32                  CurrentByteOffset;
1730 
1731     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1732     CurrentByteOffset = Info->CurrentByteOffset;
1733 
1734     /*
1735      * Calculate lengths for fields that have variable length:
1736      * 1) Resource Source string
1737      */
1738     ResSourceLength = RsGetStringDataLength (InitializerOp);
1739 
1740     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_CLOCK_INPUT) + ResSourceLength + 1;
1741 
1742     /* Allocate the local resource node and initialize */
1743 
1744     Rnode = RsAllocateResourceNode (DescriptorSize +
1745         sizeof (AML_RESOURCE_LARGE_HEADER));
1746 
1747     Descriptor = Rnode->Buffer;
1748     Descriptor->ClockInput.ResourceLength = DescriptorSize;
1749     Descriptor->ClockInput.DescriptorType = ACPI_RESOURCE_NAME_CLOCK_INPUT;
1750     Descriptor->ClockInput.RevisionId = AML_RESOURCE_CLOCK_INPUT_REVISION;
1751 
1752     /* Build pointers to optional areas */
1753 
1754     if (ResSourceLength){
1755         ResourceSourceIndex = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_CLOCK_INPUT));
1756         ResourceSourceString = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_CLOCK_INPUT) + 1);
1757     }
1758 
1759     /* Process all child initialization nodes */
1760 
1761     for (i = 0; InitializerOp; i++)
1762     {
1763         switch (i)
1764         {
1765         case 0:
1766             Descriptor->ClockInput.FrequencyNumerator = (UINT32)InitializerOp->Asl.Value.Integer;
1767             RsCreateDwordField (InitializerOp, ACPI_RESTAG_FQN,
1768                 CurrentByteOffset + ASL_RESDESC_OFFSET (ClockInput.FrequencyNumerator));
1769 
1770             break;
1771 
1772         case 1:
1773             Descriptor->ClockInput.FrequencyDivisor = (UINT16)InitializerOp->Asl.Value.Integer;
1774             RsCreateWordField (InitializerOp, ACPI_RESTAG_FQD,
1775                 CurrentByteOffset + ASL_RESDESC_OFFSET (ClockInput.FrequencyDivisor));
1776 
1777             break;
1778 
1779         case 2:
1780             RsSetFlagBits16 (&Descriptor->ClockInput.Flags, InitializerOp, 1, 0);
1781             break;
1782 
1783         case 3:
1784             RsSetFlagBits16 (&Descriptor->ClockInput.Flags, InitializerOp, 0, 0);
1785             break;
1786 
1787         case 4: /* ResSource String [Optional Field] */
1788 
1789             if (ResourceSourceString)
1790             {
1791                 /* Copy string to the descriptor */
1792 
1793                 strcpy (ResourceSourceString, InitializerOp->Asl.Value.String);
1794             }
1795             break;
1796 
1797         case 5: /* ResSource Index [Optional Field] */
1798             if (ResourceSourceIndex)
1799             {
1800                 *ResourceSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
1801             }
1802             break;
1803 
1804         default:
1805             break;
1806         }
1807 
1808         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
1809     }
1810 
1811     return (Rnode);
1812 }
1813 
1814 
1815 /*******************************************************************************
1816  *
1817  * FUNCTION:    RsDoPinConfigDescriptor
1818  *
1819  * PARAMETERS:  Info                - Parse Op and resource template offset
1820  *
1821  * RETURN:      Completed resource node
1822  *
1823  * DESCRIPTION: Construct a long "PinConfig" descriptor
1824  *
1825  ******************************************************************************/
1826 
1827 ASL_RESOURCE_NODE *
RsDoPinConfigDescriptor(ASL_RESOURCE_INFO * Info)1828 RsDoPinConfigDescriptor (
1829     ASL_RESOURCE_INFO       *Info)
1830 {
1831     AML_RESOURCE            *Descriptor;
1832     ACPI_PARSE_OBJECT       *InitializerOp;
1833     ASL_RESOURCE_NODE       *Rnode;
1834     char                    *ResourceSource = NULL;
1835     UINT8                   *VendorData = NULL;
1836     UINT16                  *PinList = NULL;
1837     UINT16                  ResSourceLength;
1838     UINT16                  VendorLength;
1839     UINT16                  PinListLength;
1840     UINT16                  DescriptorSize;
1841     UINT32                  CurrentByteOffset;
1842     UINT32                  i;
1843 
1844     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
1845     CurrentByteOffset = Info->CurrentByteOffset;
1846 
1847     /*
1848      * Calculate lengths for fields that have variable length:
1849      * 1) Resource Source string
1850      * 2) Vendor Data buffer
1851      * 3) PIN (interrupt) list
1852      */
1853     ResSourceLength = RsGetStringDataLength (InitializerOp);
1854     VendorLength = RsGetBufferDataLength (InitializerOp);
1855     PinListLength = RsGetInterruptDataLength (InitializerOp, 8);
1856 
1857     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_CONFIG) +
1858         ResSourceLength + VendorLength + PinListLength;
1859 
1860     /* Allocate the local resource node and initialize */
1861 
1862     Rnode = RsAllocateResourceNode (DescriptorSize +
1863         sizeof (AML_RESOURCE_LARGE_HEADER));
1864 
1865     Descriptor = Rnode->Buffer;
1866     Descriptor->PinConfig.ResourceLength = DescriptorSize;
1867     Descriptor->PinConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_CONFIG;
1868     Descriptor->PinConfig.RevisionId = AML_RESOURCE_PIN_CONFIG_REVISION;
1869 
1870     /* Build pointers to optional areas */
1871 
1872     PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_CONFIG));
1873     ResourceSource = ACPI_ADD_PTR (char, PinList, PinListLength);
1874     VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength);
1875 
1876     /* Setup offsets within the descriptor */
1877 
1878     Descriptor->PinConfig.PinTableOffset = (UINT16)
1879         ACPI_PTR_DIFF (PinList, Descriptor);
1880 
1881     Descriptor->PinConfig.ResSourceOffset = (UINT16)
1882         ACPI_PTR_DIFF (ResourceSource, Descriptor);
1883 
1884     /* Process all child initialization nodes */
1885 
1886     for (i = 0; InitializerOp; i++)
1887     {
1888         BOOLEAN isValid;
1889 
1890         switch (i)
1891         {
1892         case 0: /* Share Type [Flags] (_SHR) */
1893 
1894             RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 0, 0);
1895             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
1896                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.Flags), 0);
1897             break;
1898 
1899         case 1: /* Pin Config Type [BYTE] (_TYP) */
1900 
1901             isValid = InitializerOp->Asl.Value.Integer <= 0x0d;
1902             if (!isValid)
1903             {
1904                 isValid = InitializerOp->Asl.Value.Integer >= 0x80 &&
1905                           InitializerOp->Asl.Value.Integer <= 0xff;
1906             }
1907             if (!isValid)
1908             {
1909                     AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL);
1910             }
1911 
1912             Descriptor->PinConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer;
1913             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE,
1914                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigType));
1915 
1916             break;
1917 
1918         case 2: /* Pin Config Value [DWORD] (_VAL) */
1919 
1920             Descriptor->PinConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer;
1921             RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE,
1922                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinConfig.PinConfigValue));
1923             break;
1924 
1925         case 3: /* ResSource [Optional Field - STRING] */
1926 
1927             if (ResSourceLength)
1928             {
1929                 /* Copy string to the descriptor */
1930 
1931                 strcpy (ResourceSource, InitializerOp->Asl.Value.String);
1932             }
1933             break;
1934 
1935         case 4: /* Resource Index */
1936 
1937             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
1938             {
1939                 Descriptor->PinConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
1940             }
1941             break;
1942 
1943         case 5: /* Resource Usage (consumer/producer) */
1944 
1945             RsSetFlagBits16 (&Descriptor->PinConfig.Flags, InitializerOp, 1, 1);
1946 
1947             break;
1948 
1949         case 6: /* Resource Tag (Descriptor Name) */
1950 
1951             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
1952             break;
1953 
1954         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
1955             /*
1956              * Always set the VendorOffset even if there is no Vendor Data.
1957              * This field is required in order to calculate the length
1958              * of the ResourceSource at runtime.
1959              */
1960             Descriptor->PinConfig.VendorOffset = (UINT16)
1961                 ACPI_PTR_DIFF (VendorData, Descriptor);
1962 
1963             if (RsGetVendorData (InitializerOp, VendorData,
1964                 (CurrentByteOffset + Descriptor->PinConfig.VendorOffset)))
1965             {
1966                 Descriptor->PinConfig.VendorLength = VendorLength;
1967             }
1968             break;
1969 
1970         default:
1971             /*
1972              * PINs come through here, repeatedly. Each PIN must be a WORD.
1973              *  Name: _PIN
1974              */
1975             *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
1976             PinList++;
1977 
1978             /* Case 8: First pin number in list */
1979 
1980             if (i == 8)
1981             {
1982                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1983                 {
1984                     /* Must be at least one interrupt */
1985 
1986                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
1987                         InitializerOp, NULL);
1988                 }
1989 
1990                 /* Check now for duplicates in list */
1991 
1992                 RsCheckListForDuplicates (InitializerOp);
1993 
1994                 /* Create a named field at the start of the list */
1995 
1996                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
1997                     CurrentByteOffset + Descriptor->PinConfig.PinTableOffset);
1998             }
1999             break;
2000         }
2001 
2002         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2003     }
2004 
2005     return (Rnode);
2006 }
2007 
2008 
2009 /*******************************************************************************
2010  *
2011  * FUNCTION:    RsDoPinGroupDescriptor
2012  *
2013  * PARAMETERS:  Info                - Parse Op and resource template offset
2014  *
2015  * RETURN:      Completed resource node
2016  *
2017  * DESCRIPTION: Construct a long "PinGroup" descriptor
2018  *
2019  ******************************************************************************/
2020 
2021 ASL_RESOURCE_NODE *
RsDoPinGroupDescriptor(ASL_RESOURCE_INFO * Info)2022 RsDoPinGroupDescriptor (
2023     ASL_RESOURCE_INFO       *Info)
2024 {
2025     AML_RESOURCE            *Descriptor;
2026     ACPI_PARSE_OBJECT       *InitializerOp;
2027     ASL_RESOURCE_NODE       *Rnode;
2028     UINT8                   *VendorData = NULL;
2029     UINT16                  *PinList = NULL;
2030     char                    *Label = NULL;
2031     UINT16                  LabelLength;
2032     UINT16                  VendorLength;
2033     UINT16                  PinListLength;
2034     UINT16                  DescriptorSize;
2035     UINT32                  CurrentByteOffset;
2036     UINT32                  i;
2037 
2038     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
2039     CurrentByteOffset = Info->CurrentByteOffset;
2040 
2041     /*
2042      * Calculate lengths for fields that have variable length:
2043      * 1) Label
2044      * 2) Vendor Data buffer
2045      * 3) PIN (interrupt) list
2046      */
2047     LabelLength = RsGetStringDataLength (InitializerOp);
2048     VendorLength = RsGetBufferDataLength (InitializerOp);
2049     PinListLength = RsGetInterruptDataLength (InitializerOp, 4);
2050 
2051     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP) +
2052         LabelLength + VendorLength + PinListLength;
2053 
2054     /* Allocate the local resource node and initialize */
2055 
2056     Rnode = RsAllocateResourceNode (DescriptorSize +
2057         sizeof (AML_RESOURCE_LARGE_HEADER));
2058 
2059     Descriptor = Rnode->Buffer;
2060     Descriptor->PinGroup.ResourceLength = DescriptorSize;
2061     Descriptor->PinGroup.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP;
2062     Descriptor->PinGroup.RevisionId = AML_RESOURCE_PIN_GROUP_REVISION;
2063 
2064     /* Build pointers to optional areas */
2065 
2066     PinList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP));
2067     Label = ACPI_ADD_PTR (char, PinList, PinListLength);
2068     VendorData = ACPI_ADD_PTR (UINT8, Label, LabelLength);
2069 
2070     /* Setup offsets within the descriptor */
2071 
2072     Descriptor->PinGroup.PinTableOffset = (UINT16) ACPI_PTR_DIFF (PinList, Descriptor);
2073     Descriptor->PinGroup.LabelOffset = (UINT16) ACPI_PTR_DIFF (Label, Descriptor);
2074 
2075     /* Process all child initialization nodes */
2076 
2077     for (i = 0; InitializerOp; i++)
2078     {
2079         switch (i)
2080         {
2081         case 0: /* Resource Label */
2082 
2083             if (LabelLength < 2)
2084             {
2085                 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
2086             }
2087             strcpy (Label, InitializerOp->Asl.Value.String);
2088 
2089             break;
2090 
2091         case 1: /* Resource Usage (consumer/producer) */
2092 
2093             RsSetFlagBits16 (&Descriptor->PinGroup.Flags, InitializerOp, 0, 0);
2094 
2095             break;
2096 
2097         case 2: /* Resource Tag (Descriptor Name) */
2098 
2099             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
2100             break;
2101 
2102         case 3: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
2103             /*
2104              * Always set the VendorOffset even if there is no Vendor Data.
2105              * This field is required in order to calculate the length
2106              * of the ResourceSource at runtime.
2107              */
2108             Descriptor->PinGroup.VendorOffset = (UINT16)
2109                 ACPI_PTR_DIFF (VendorData, Descriptor);
2110 
2111             if (RsGetVendorData (InitializerOp, VendorData,
2112                 (CurrentByteOffset + Descriptor->PinGroup.VendorOffset)))
2113             {
2114                 Descriptor->PinGroup.VendorLength = VendorLength;
2115             }
2116             break;
2117 
2118         default:
2119             /*
2120              * PINs come through here, repeatedly. Each PIN must be a WORD.
2121              *  Name: _PIN
2122              */
2123             *PinList = (UINT16) InitializerOp->Asl.Value.Integer;
2124             PinList++;
2125 
2126             /* Case 3: First pin number in list */
2127 
2128             if (i == 4)
2129             {
2130                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
2131                 {
2132                     /* Must be at least one interrupt */
2133 
2134                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
2135                         InitializerOp, NULL);
2136                 }
2137 
2138                 /* Check now for duplicates in list */
2139 
2140                 RsCheckListForDuplicates (InitializerOp);
2141 
2142                 /* Create a named field at the start of the list */
2143 
2144                 RsCreateWordField (InitializerOp, ACPI_RESTAG_PIN,
2145                     CurrentByteOffset + Descriptor->PinGroup.PinTableOffset);
2146             }
2147             break;
2148         }
2149 
2150         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2151     }
2152 
2153     return (Rnode);
2154 }
2155 
2156 
2157 /*******************************************************************************
2158  *
2159  * FUNCTION:    RsDoPinGroupFunctionDescriptor
2160  *
2161  * PARAMETERS:  Info                - Parse Op and resource template offset
2162  *
2163  * RETURN:      Completed resource node
2164  *
2165  * DESCRIPTION: Construct a long "PinGroupFunction" descriptor
2166  *
2167  ******************************************************************************/
2168 
2169 ASL_RESOURCE_NODE *
RsDoPinGroupFunctionDescriptor(ASL_RESOURCE_INFO * Info)2170 RsDoPinGroupFunctionDescriptor (
2171     ASL_RESOURCE_INFO       *Info)
2172 {
2173     AML_RESOURCE            *Descriptor;
2174     ACPI_PARSE_OBJECT       *InitializerOp;
2175     ASL_RESOURCE_NODE       *Rnode;
2176     char                    *ResourceSource = NULL;
2177     char                    *ResourceSourceLabel = NULL;
2178     UINT8                   *VendorData = NULL;
2179     UINT16                  ResSourceLength;
2180     UINT16                  ResSourceLabelLength;
2181     UINT16                  VendorLength;
2182     UINT16                  DescriptorSize;
2183     UINT32                  CurrentByteOffset;
2184     UINT32                  i;
2185 
2186     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
2187     CurrentByteOffset = Info->CurrentByteOffset;
2188 
2189     /*
2190      * Calculate lengths for fields that have variable length:
2191      * 1) Resource Source string
2192      * 2) Resource Source Label string
2193      * 3) Vendor Data buffer
2194      */
2195     ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 2);
2196     ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 4);
2197     VendorLength = RsGetBufferDataLength (InitializerOp);
2198 
2199     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_FUNCTION) +
2200         ResSourceLength + ResSourceLabelLength + VendorLength;
2201 
2202     /* Allocate the local resource node and initialize */
2203 
2204     Rnode = RsAllocateResourceNode (DescriptorSize +
2205         sizeof (AML_RESOURCE_LARGE_HEADER));
2206 
2207     Descriptor = Rnode->Buffer;
2208     Descriptor->PinGroupFunction.ResourceLength = DescriptorSize;
2209     Descriptor->PinGroupFunction.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION;
2210     Descriptor->PinGroupFunction.RevisionId = AML_RESOURCE_PIN_GROUP_FUNCTION_REVISION;
2211 
2212     /* Build pointers to optional areas */
2213 
2214     ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_FUNCTION));
2215     ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength);
2216     VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength);
2217 
2218     /* Setup offsets within the descriptor */
2219 
2220     Descriptor->PinGroupFunction.ResSourceOffset = (UINT16)
2221         ACPI_PTR_DIFF (ResourceSource, Descriptor);
2222     Descriptor->PinGroupFunction.ResSourceLabelOffset = (UINT16)
2223         ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor);
2224 
2225     /* Process all child initialization nodes */
2226 
2227     for (i = 0; InitializerOp; i++)
2228     {
2229         switch (i)
2230         {
2231         case 0: /* Share Type [Flags] (_SHR) */
2232 
2233             RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 0, 0);
2234             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
2235                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.Flags), 0);
2236             break;
2237 
2238         case 1: /* Function Number [WORD] */
2239 
2240             Descriptor->PinGroupFunction.FunctionNumber = (UINT16) InitializerOp->Asl.Value.Integer;
2241             RsCreateDwordField (InitializerOp, ACPI_RESTAG_FUNCTION,
2242                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupFunction.FunctionNumber));
2243             break;
2244 
2245         case 2: /* ResourceSource [STRING] */
2246 
2247             strcpy (ResourceSource, InitializerOp->Asl.Value.String);
2248             break;
2249 
2250         case 3: /* Resource Index */
2251 
2252             Descriptor->PinGroupFunction.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
2253             break;
2254 
2255         case 4: /* ResourceSourceLabel [STRING] */
2256 
2257             if (ResSourceLabelLength < 2)
2258             {
2259                 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
2260             }
2261 
2262             strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String);
2263             break;
2264 
2265         case 5: /* Resource Usage (consumer/producer) */
2266 
2267             RsSetFlagBits16 (&Descriptor->PinGroupFunction.Flags, InitializerOp, 1, 1);
2268 
2269             break;
2270 
2271         case 6: /* Resource Tag (Descriptor Name) */
2272 
2273             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
2274             break;
2275 
2276         case 7: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
2277             /*
2278              * Always set the VendorOffset even if there is no Vendor Data.
2279              * This field is required in order to calculate the length
2280              * of the ResourceSource at runtime.
2281              */
2282             Descriptor->PinGroupFunction.VendorOffset = (UINT16)
2283                 ACPI_PTR_DIFF (VendorData, Descriptor);
2284 
2285             if (RsGetVendorData (InitializerOp, VendorData,
2286                 (CurrentByteOffset + Descriptor->PinGroupFunction.VendorOffset)))
2287             {
2288                 Descriptor->PinGroupFunction.VendorLength = VendorLength;
2289             }
2290             break;
2291 
2292         default:
2293             break;
2294         }
2295 
2296         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2297     }
2298 
2299     return (Rnode);
2300 }
2301 
2302 
2303 /*******************************************************************************
2304  *
2305  * FUNCTION:    RsDoPinGroupConfigDescriptor
2306  *
2307  * PARAMETERS:  Info                - Parse Op and resource template offset
2308  *
2309  * RETURN:      Completed resource node
2310  *
2311  * DESCRIPTION: Construct a long "PinGroupConfig" descriptor
2312  *
2313  ******************************************************************************/
2314 
2315 ASL_RESOURCE_NODE *
RsDoPinGroupConfigDescriptor(ASL_RESOURCE_INFO * Info)2316 RsDoPinGroupConfigDescriptor (
2317     ASL_RESOURCE_INFO       *Info)
2318 {
2319     AML_RESOURCE            *Descriptor;
2320     ACPI_PARSE_OBJECT       *InitializerOp;
2321     ASL_RESOURCE_NODE       *Rnode;
2322     char                    *ResourceSource = NULL;
2323     char                    *ResourceSourceLabel = NULL;
2324     UINT8                   *VendorData = NULL;
2325     UINT16                  ResSourceLength;
2326     UINT16                  ResSourceLabelLength;
2327     UINT16                  VendorLength;
2328     UINT16                  DescriptorSize;
2329     UINT32                  CurrentByteOffset;
2330     UINT32                  i;
2331 
2332     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
2333     CurrentByteOffset = Info->CurrentByteOffset;
2334 
2335     /*
2336      * Calculate lengths for fields that have variable length:
2337      * 1) Resource Source string
2338      * 2) Resource Source Label string
2339      * 3) Vendor Data buffer
2340      */
2341     ResSourceLength = RsGetStringDataLengthAt (InitializerOp, 3);
2342     ResSourceLabelLength = RsGetStringDataLengthAt (InitializerOp, 5);
2343     VendorLength = RsGetBufferDataLength (InitializerOp);
2344 
2345     DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_PIN_GROUP_CONFIG) +
2346         ResSourceLength + ResSourceLabelLength + VendorLength;
2347 
2348     /* Allocate the local resource node and initialize */
2349 
2350     Rnode = RsAllocateResourceNode (DescriptorSize +
2351         sizeof (AML_RESOURCE_LARGE_HEADER));
2352 
2353     Descriptor = Rnode->Buffer;
2354     Descriptor->PinGroupConfig.ResourceLength = DescriptorSize;
2355     Descriptor->PinGroupConfig.DescriptorType = ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG;
2356     Descriptor->PinGroupConfig.RevisionId = AML_RESOURCE_PIN_GROUP_CONFIG_REVISION;
2357 
2358     /* Build pointers to optional areas */
2359 
2360     ResourceSource = ACPI_ADD_PTR (char, Descriptor, sizeof (AML_RESOURCE_PIN_GROUP_CONFIG));
2361     ResourceSourceLabel = ACPI_ADD_PTR (char, ResourceSource, ResSourceLength);
2362     VendorData = ACPI_ADD_PTR (UINT8, ResourceSourceLabel, ResSourceLabelLength);
2363 
2364     /* Setup offsets within the descriptor */
2365 
2366     Descriptor->PinGroupConfig.ResSourceOffset = (UINT16)
2367         ACPI_PTR_DIFF (ResourceSource, Descriptor);
2368     Descriptor->PinGroupConfig.ResSourceLabelOffset = (UINT16)
2369         ACPI_PTR_DIFF (ResourceSourceLabel, Descriptor);
2370 
2371     /* Process all child initialization nodes */
2372 
2373     for (i = 0; InitializerOp; i++)
2374     {
2375         BOOLEAN isValid;
2376 
2377         switch (i)
2378         {
2379         case 0: /* Share Type [Flags] (_SHR) */
2380 
2381             RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 0, 0);
2382             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
2383                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.Flags), 0);
2384             break;
2385 
2386         case 1: /* Pin Config Type [BYTE] (_TYP) */
2387 
2388             isValid = InitializerOp->Asl.Value.Integer <= 0x0d;
2389             if (!isValid)
2390             {
2391                 isValid = InitializerOp->Asl.Value.Integer >= 0x80 &&
2392                           InitializerOp->Asl.Value.Integer <= 0xff;
2393             }
2394             if (!isValid)
2395             {
2396                     AslError (ASL_ERROR, ASL_MSG_RANGE, InitializerOp, NULL);
2397             }
2398 
2399             Descriptor->PinGroupConfig.PinConfigType = (UINT8) InitializerOp->Asl.Value.Integer;
2400             RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG_TYPE,
2401                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigType));
2402 
2403             break;
2404 
2405         case 2: /* Pin Config Value [DWORD] (_VAL) */
2406 
2407             Descriptor->PinGroupConfig.PinConfigValue = (UINT32) InitializerOp->Asl.Value.Integer;
2408             RsCreateDwordField (InitializerOp, ACPI_RESTAG_PINCONFIG_VALUE,
2409                 CurrentByteOffset + ASL_RESDESC_OFFSET (PinGroupConfig.PinConfigValue));
2410             break;
2411 
2412         case 3: /* ResourceSource [STRING] */
2413 
2414             /* Copy string to the descriptor */
2415 
2416             strcpy (ResourceSource, InitializerOp->Asl.Value.String);
2417             break;
2418 
2419         case 4: /* Resource Index */
2420 
2421             Descriptor->PinGroupConfig.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
2422             break;
2423 
2424         case 5: /* ResourceSourceLabel [STRING] */
2425 
2426             if (ResSourceLabelLength < 2)
2427             {
2428                 AslError(ASL_WARNING, ASL_MSG_NULL_STRING, InitializerOp, NULL);
2429             }
2430 
2431             strcpy (ResourceSourceLabel, InitializerOp->Asl.Value.String);
2432             break;
2433 
2434         case 6: /* Resource Usage (consumer/producer) */
2435 
2436             RsSetFlagBits16 (&Descriptor->PinGroupConfig.Flags, InitializerOp, 1, 1);
2437 
2438             break;
2439 
2440         case 7: /* Resource Tag (Descriptor Name) */
2441 
2442             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
2443             break;
2444 
2445         case 8: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */
2446             /*
2447              * Always set the VendorOffset even if there is no Vendor Data.
2448              * This field is required in order to calculate the length
2449              * of the ResourceSource at runtime.
2450              */
2451             Descriptor->PinGroupConfig.VendorOffset = (UINT16)
2452                 ACPI_PTR_DIFF (VendorData, Descriptor);
2453 
2454             if (RsGetVendorData (InitializerOp, VendorData,
2455                 (CurrentByteOffset + Descriptor->PinGroupConfig.VendorOffset)))
2456             {
2457                 Descriptor->PinGroupConfig.VendorLength = VendorLength;
2458             }
2459             break;
2460 
2461         default:
2462             break;
2463         }
2464 
2465         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
2466     }
2467 
2468     return (Rnode);
2469 }
2470