xref: /titanic_50/usr/src/uts/intel/io/acpica/namespace/nspredef.c (revision 5face7b240cd471c2e641bc011daacc1996afc41)
1 /******************************************************************************
2  *
3  * Module Name: nspredef - Validation of ACPI predefined methods and objects
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2009, 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 #define __NSPREDEF_C__
117 
118 #include "acpi.h"
119 #include "accommon.h"
120 #include "acnamesp.h"
121 #include "acpredef.h"
122 
123 
124 #define _COMPONENT          ACPI_NAMESPACE
125         ACPI_MODULE_NAME    ("nspredef")
126 
127 
128 /*******************************************************************************
129  *
130  * This module validates predefined ACPI objects that appear in the namespace,
131  * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this
132  * validation is to detect problems with BIOS-exposed predefined ACPI objects
133  * before the results are returned to the ACPI-related drivers.
134  *
135  * There are several areas that are validated:
136  *
137  *  1) The number of input arguments as defined by the method/object in the
138  *      ASL is validated against the ACPI specification.
139  *  2) The type of the return object (if any) is validated against the ACPI
140  *      specification.
141  *  3) For returned package objects, the count of package elements is
142  *      validated, as well as the type of each package element. Nested
143  *      packages are supported.
144  *
145  * For any problems found, a warning message is issued.
146  *
147  ******************************************************************************/
148 
149 /* Local prototypes */
150 
151 static ACPI_STATUS
152 AcpiNsCheckPackage (
153     char                        *Pathname,
154     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
155     const ACPI_PREDEFINED_INFO  *Predefined);
156 
157 static ACPI_STATUS
158 AcpiNsCheckPackageElements (
159     char                        *Pathname,
160     ACPI_OPERAND_OBJECT         **Elements,
161     UINT8                       Type1,
162     UINT32                      Count1,
163     UINT8                       Type2,
164     UINT32                      Count2,
165     UINT32                      StartIndex);
166 
167 static ACPI_STATUS
168 AcpiNsCheckObjectType (
169     char                        *Pathname,
170     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
171     UINT32                      ExpectedBtypes,
172     UINT32                      PackageIndex);
173 
174 static ACPI_STATUS
175 AcpiNsCheckReference (
176     char                        *Pathname,
177     ACPI_OPERAND_OBJECT         *ReturnObject);
178 
179 static ACPI_STATUS
180 AcpiNsRepairObject (
181     UINT32                      ExpectedBtypes,
182     UINT32                      PackageIndex,
183     ACPI_OPERAND_OBJECT         **ReturnObjectPtr);
184 
185 /*
186  * Names for the types that can be returned by the predefined objects.
187  * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
188  */
189 static const char   *AcpiRtypeNames[] =
190 {
191     "/Integer",
192     "/String",
193     "/Buffer",
194     "/Package",
195     "/Reference",
196 };
197 
198 #define ACPI_NOT_PACKAGE    ACPI_UINT32_MAX
199 
200 
201 /*******************************************************************************
202  *
203  * FUNCTION:    AcpiNsCheckPredefinedNames
204  *
205  * PARAMETERS:  Node            - Namespace node for the method/object
206  *              ReturnObjectPtr - Pointer to the object returned from the
207  *                                evaluation of a method or object
208  *
209  * RETURN:      Status
210  *
211  * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
212  *
213  ******************************************************************************/
214 
215 ACPI_STATUS
216 AcpiNsCheckPredefinedNames (
217     ACPI_NAMESPACE_NODE         *Node,
218     UINT32                      UserParamCount,
219     ACPI_STATUS                 ReturnStatus,
220     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
221 {
222     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
223     ACPI_STATUS                 Status = AE_OK;
224     const ACPI_PREDEFINED_INFO  *Predefined;
225     char                        *Pathname;
226 
227 
228     /* Match the name for this method/object against the predefined list */
229 
230     Predefined = AcpiNsCheckForPredefinedName (Node);
231 
232     /* Get the full pathname to the object, for use in error messages */
233 
234     Pathname = AcpiNsGetExternalPathname (Node);
235     if (!Pathname)
236     {
237         return (AE_OK); /* Could not get pathname, ignore */
238     }
239 
240     /*
241      * Check that the parameter count for this method matches the ASL
242      * definition. For predefined names, ensure that both the caller and
243      * the method itself are in accordance with the ACPI specification.
244      */
245     AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined);
246 
247     /* If not a predefined name, we cannot validate the return object */
248 
249     if (!Predefined)
250     {
251         goto Exit;
252     }
253 
254     /* If the method failed, we cannot validate the return object */
255 
256     if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
257     {
258         goto Exit;
259     }
260 
261     /*
262      * Only validate the return value on the first successful evaluation of
263      * the method. This ensures that any warnings will only be emitted during
264      * the very first evaluation of the method/object.
265      */
266     if (Node->Flags & ANOBJ_EVALUATED)
267     {
268         goto Exit;
269     }
270 
271     /* Mark the node as having been successfully evaluated */
272 
273     Node->Flags |= ANOBJ_EVALUATED;
274 
275     /*
276      * If there is no return value, check if we require a return value for
277      * this predefined name. Either one return value is expected, or none,
278      * for both methods and other objects.
279      *
280      * Exit now if there is no return object. Warning if one was expected.
281      */
282     if (!ReturnObject)
283     {
284         if ((Predefined->Info.ExpectedBtypes) &&
285             (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
286         {
287             ACPI_ERROR ((AE_INFO,
288                 "%s: Missing expected return value", Pathname));
289 
290             Status = AE_AML_NO_RETURN_VALUE;
291         }
292         goto Exit;
293     }
294 
295     /*
296      * We have a return value, but if one wasn't expected, just exit, this is
297      * not a problem
298      *
299      * For example, if the "Implicit Return" feature is enabled, methods will
300      * always return a value
301      */
302     if (!Predefined->Info.ExpectedBtypes)
303     {
304         goto Exit;
305     }
306 
307     /*
308      * Check that the type of the return object is what is expected for
309      * this predefined name
310      */
311     Status = AcpiNsCheckObjectType (Pathname, ReturnObjectPtr,
312                 Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE);
313     if (ACPI_FAILURE (Status))
314     {
315         goto Exit;
316     }
317 
318     /* For returned Package objects, check the type of all sub-objects */
319 
320     if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE)
321     {
322         Status = AcpiNsCheckPackage (Pathname, ReturnObjectPtr, Predefined);
323     }
324 
325 Exit:
326     ACPI_FREE (Pathname);
327     return (Status);
328 }
329 
330 
331 /*******************************************************************************
332  *
333  * FUNCTION:    AcpiNsCheckParameterCount
334  *
335  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
336  *              Node            - Namespace node for the method/object
337  *              UserParamCount  - Number of args passed in by the caller
338  *              Predefined      - Pointer to entry in predefined name table
339  *
340  * RETURN:      None
341  *
342  * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
343  *              predefined name is what is expected (i.e., what is defined in
344  *              the ACPI specification for this predefined name.)
345  *
346  ******************************************************************************/
347 
348 void
349 AcpiNsCheckParameterCount (
350     char                        *Pathname,
351     ACPI_NAMESPACE_NODE         *Node,
352     UINT32                      UserParamCount,
353     const ACPI_PREDEFINED_INFO  *Predefined)
354 {
355     UINT32                      ParamCount;
356     UINT32                      RequiredParamsCurrent;
357     UINT32                      RequiredParamsOld;
358 
359 
360     /* Methods have 0-7 parameters. All other types have zero. */
361 
362     ParamCount = 0;
363     if (Node->Type == ACPI_TYPE_METHOD)
364     {
365         ParamCount = Node->Object->Method.ParamCount;
366     }
367 
368     /* Argument count check for non-predefined methods/objects */
369 
370     if (!Predefined)
371     {
372         /*
373          * Warning if too few or too many arguments have been passed by the
374          * caller. An incorrect number of arguments may not cause the method
375          * to fail. However, the method will fail if there are too few
376          * arguments and the method attempts to use one of the missing ones.
377          */
378         if (UserParamCount < ParamCount)
379         {
380             ACPI_WARNING ((AE_INFO,
381                 "%s: Insufficient arguments - needs %d, found %d",
382                 Pathname, ParamCount, UserParamCount));
383         }
384         else if (UserParamCount > ParamCount)
385         {
386             ACPI_WARNING ((AE_INFO,
387                 "%s: Excess arguments - needs %d, found %d",
388                 Pathname, ParamCount, UserParamCount));
389         }
390         return;
391     }
392 
393     /* Allow two different legal argument counts (_SCP, etc.) */
394 
395     RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
396     RequiredParamsOld = Predefined->Info.ParamCount >> 4;
397 
398     if (UserParamCount != ACPI_UINT32_MAX)
399     {
400         /* Validate the user-supplied parameter count */
401 
402         if ((UserParamCount != RequiredParamsCurrent) &&
403             (UserParamCount != RequiredParamsOld))
404         {
405             ACPI_WARNING ((AE_INFO,
406                 "%s: Parameter count mismatch - "
407                 "caller passed %d, ACPI requires %d",
408                 Pathname, UserParamCount, RequiredParamsCurrent));
409         }
410     }
411 
412     /*
413      * Only validate the argument count on the first successful evaluation of
414      * the method. This ensures that any warnings will only be emitted during
415      * the very first evaluation of the method/object.
416      */
417     if (Node->Flags & ANOBJ_EVALUATED)
418     {
419         return;
420     }
421 
422     /*
423      * Check that the ASL-defined parameter count is what is expected for
424      * this predefined name.
425      */
426     if ((ParamCount != RequiredParamsCurrent) &&
427         (ParamCount != RequiredParamsOld))
428     {
429         ACPI_WARNING ((AE_INFO,
430             "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d",
431             Pathname, ParamCount, RequiredParamsCurrent));
432     }
433 }
434 
435 
436 /*******************************************************************************
437  *
438  * FUNCTION:    AcpiNsCheckForPredefinedName
439  *
440  * PARAMETERS:  Node            - Namespace node for the method/object
441  *
442  * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
443  *
444  * DESCRIPTION: Check an object name against the predefined object list.
445  *
446  ******************************************************************************/
447 
448 const ACPI_PREDEFINED_INFO *
449 AcpiNsCheckForPredefinedName (
450     ACPI_NAMESPACE_NODE         *Node)
451 {
452     const ACPI_PREDEFINED_INFO  *ThisName;
453 
454 
455     /* Quick check for a predefined name, first character must be underscore */
456 
457     if (Node->Name.Ascii[0] != '_')
458     {
459         return (NULL);
460     }
461 
462     /* Search info table for a predefined method/object name */
463 
464     ThisName = PredefinedNames;
465     while (ThisName->Info.Name[0])
466     {
467         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
468         {
469             /* Return pointer to this table entry */
470 
471             return (ThisName);
472         }
473 
474         /*
475          * Skip next entry in the table if this name returns a Package
476          * (next entry contains the package info)
477          */
478         if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
479         {
480             ThisName++;
481         }
482 
483         ThisName++;
484     }
485 
486     return (NULL);
487 }
488 
489 
490 /*******************************************************************************
491  *
492  * FUNCTION:    AcpiNsCheckPackage
493  *
494  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
495  *              ReturnObjectPtr - Pointer to the object returned from the
496  *                                evaluation of a method or object
497  *              Predefined      - Pointer to entry in predefined name table
498  *
499  * RETURN:      Status
500  *
501  * DESCRIPTION: Check a returned package object for the correct count and
502  *              correct type of all sub-objects.
503  *
504  ******************************************************************************/
505 
506 static ACPI_STATUS
507 AcpiNsCheckPackage (
508     char                        *Pathname,
509     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
510     const ACPI_PREDEFINED_INFO  *Predefined)
511 {
512     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
513     const ACPI_PREDEFINED_INFO  *Package;
514     ACPI_OPERAND_OBJECT         *SubPackage;
515     ACPI_OPERAND_OBJECT         **Elements;
516     ACPI_OPERAND_OBJECT         **SubElements;
517     ACPI_STATUS                 Status;
518     UINT32                      ExpectedCount;
519     UINT32                      Count;
520     UINT32                      i;
521     UINT32                      j;
522 
523 
524     ACPI_FUNCTION_NAME (NsCheckPackage);
525 
526 
527     /* The package info for this name is in the next table entry */
528 
529     Package = Predefined + 1;
530 
531     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
532         "%s Validating return Package of Type %X, Count %X\n",
533         Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
534 
535     /* Extract package count and elements array */
536 
537     Elements = ReturnObject->Package.Elements;
538     Count = ReturnObject->Package.Count;
539 
540     /* The package must have at least one element, else invalid */
541 
542     if (!Count)
543     {
544         ACPI_WARNING ((AE_INFO,
545             "%s: Return Package has no elements (empty)", Pathname));
546 
547         return (AE_AML_OPERAND_VALUE);
548     }
549 
550     /*
551      * Decode the type of the expected package contents
552      *
553      * PTYPE1 packages contain no subpackages
554      * PTYPE2 packages contain sub-packages
555      */
556     switch (Package->RetInfo.Type)
557     {
558     case ACPI_PTYPE1_FIXED:
559 
560         /*
561          * The package count is fixed and there are no sub-packages
562          *
563          * If package is too small, exit.
564          * If package is larger than expected, issue warning but continue
565          */
566         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
567         if (Count < ExpectedCount)
568         {
569             goto PackageTooSmall;
570         }
571         else if (Count > ExpectedCount)
572         {
573             ACPI_WARNING ((AE_INFO,
574                 "%s: Return Package is larger than needed - "
575                 "found %u, expected %u", Pathname, Count, ExpectedCount));
576         }
577 
578         /* Validate all elements of the returned package */
579 
580         Status = AcpiNsCheckPackageElements (Pathname, Elements,
581                     Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
582                     Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
583         if (ACPI_FAILURE (Status))
584         {
585             return (Status);
586         }
587         break;
588 
589 
590     case ACPI_PTYPE1_VAR:
591 
592         /*
593          * The package count is variable, there are no sub-packages, and all
594          * elements must be of the same type
595          */
596         for (i = 0; i < Count; i++)
597         {
598             Status = AcpiNsCheckObjectType (Pathname, Elements,
599                         Package->RetInfo.ObjectType1, i);
600             if (ACPI_FAILURE (Status))
601             {
602                 return (Status);
603             }
604             Elements++;
605         }
606         break;
607 
608 
609     case ACPI_PTYPE1_OPTION:
610 
611         /*
612          * The package count is variable, there are no sub-packages. There are
613          * a fixed number of required elements, and a variable number of
614          * optional elements.
615          *
616          * Check if package is at least as large as the minimum required
617          */
618         ExpectedCount = Package->RetInfo3.Count;
619         if (Count < ExpectedCount)
620         {
621             goto PackageTooSmall;
622         }
623 
624         /* Variable number of sub-objects */
625 
626         for (i = 0; i < Count; i++)
627         {
628             if (i < Package->RetInfo3.Count)
629             {
630                 /* These are the required package elements (0, 1, or 2) */
631 
632                 Status = AcpiNsCheckObjectType (Pathname, Elements,
633                             Package->RetInfo3.ObjectType[i], i);
634                 if (ACPI_FAILURE (Status))
635                 {
636                     return (Status);
637                 }
638             }
639             else
640             {
641                 /* These are the optional package elements */
642 
643                 Status = AcpiNsCheckObjectType (Pathname, Elements,
644                             Package->RetInfo3.TailObjectType, i);
645                 if (ACPI_FAILURE (Status))
646                 {
647                     return (Status);
648                 }
649             }
650             Elements++;
651         }
652         break;
653 
654 
655     case ACPI_PTYPE2_PKG_COUNT:
656 
657         /* First element is the (Integer) count of sub-packages to follow */
658 
659         Status = AcpiNsCheckObjectType (Pathname, Elements,
660                     ACPI_RTYPE_INTEGER, 0);
661         if (ACPI_FAILURE (Status))
662         {
663             return (Status);
664         }
665 
666         /*
667          * Count cannot be larger than the parent package length, but allow it
668          * to be smaller. The >= accounts for the Integer above.
669          */
670         ExpectedCount = (UINT32) (*Elements)->Integer.Value;
671         if (ExpectedCount >= Count)
672         {
673             goto PackageTooSmall;
674         }
675 
676         Count = ExpectedCount;
677         Elements++;
678 
679         /* Now we can walk the sub-packages */
680 
681         /*lint -fallthrough */
682 
683 
684     case ACPI_PTYPE2:
685     case ACPI_PTYPE2_FIXED:
686     case ACPI_PTYPE2_MIN:
687     case ACPI_PTYPE2_COUNT:
688 
689         /*
690          * These types all return a single package that consists of a variable
691          * number of sub-packages
692          */
693         for (i = 0; i < Count; i++)
694         {
695             SubPackage = *Elements;
696             SubElements = SubPackage->Package.Elements;
697 
698             /* Each sub-object must be of type Package */
699 
700             Status = AcpiNsCheckObjectType (Pathname, &SubPackage,
701                         ACPI_RTYPE_PACKAGE, i);
702             if (ACPI_FAILURE (Status))
703             {
704                 return (Status);
705             }
706 
707             /* Examine the different types of sub-packages */
708 
709             switch (Package->RetInfo.Type)
710             {
711             case ACPI_PTYPE2:
712             case ACPI_PTYPE2_PKG_COUNT:
713 
714                 /* Each subpackage has a fixed number of elements */
715 
716                 ExpectedCount =
717                     Package->RetInfo.Count1 + Package->RetInfo.Count2;
718                 if (SubPackage->Package.Count != ExpectedCount)
719                 {
720                     Count = SubPackage->Package.Count;
721                     goto PackageTooSmall;
722                 }
723 
724                 Status = AcpiNsCheckPackageElements (Pathname, SubElements,
725                             Package->RetInfo.ObjectType1,
726                             Package->RetInfo.Count1,
727                             Package->RetInfo.ObjectType2,
728                             Package->RetInfo.Count2, 0);
729                 if (ACPI_FAILURE (Status))
730                 {
731                     return (Status);
732                 }
733                 break;
734 
735             case ACPI_PTYPE2_FIXED:
736 
737                 /* Each sub-package has a fixed length */
738 
739                 ExpectedCount = Package->RetInfo2.Count;
740                 if (SubPackage->Package.Count < ExpectedCount)
741                 {
742                     Count = SubPackage->Package.Count;
743                     goto PackageTooSmall;
744                 }
745 
746                 /* Check the type of each sub-package element */
747 
748                 for (j = 0; j < ExpectedCount; j++)
749                 {
750                     Status = AcpiNsCheckObjectType (Pathname, &SubElements[j],
751                                 Package->RetInfo2.ObjectType[j], j);
752                     if (ACPI_FAILURE (Status))
753                     {
754                         return (Status);
755                     }
756                 }
757                 break;
758 
759             case ACPI_PTYPE2_MIN:
760 
761                 /* Each sub-package has a variable but minimum length */
762 
763                 ExpectedCount = Package->RetInfo.Count1;
764                 if (SubPackage->Package.Count < ExpectedCount)
765                 {
766                     Count = SubPackage->Package.Count;
767                     goto PackageTooSmall;
768                 }
769 
770                 /* Check the type of each sub-package element */
771 
772                 Status = AcpiNsCheckPackageElements (Pathname, SubElements,
773                             Package->RetInfo.ObjectType1,
774                             SubPackage->Package.Count, 0, 0, 0);
775                 if (ACPI_FAILURE (Status))
776                 {
777                     return (Status);
778                 }
779                 break;
780 
781             case ACPI_PTYPE2_COUNT:
782 
783                 /* First element is the (Integer) count of elements to follow */
784 
785                 Status = AcpiNsCheckObjectType (Pathname, SubElements,
786                             ACPI_RTYPE_INTEGER, 0);
787                 if (ACPI_FAILURE (Status))
788                 {
789                     return (Status);
790                 }
791 
792                 /* Make sure package is large enough for the Count */
793 
794                 ExpectedCount = (UINT32) (*SubElements)->Integer.Value;
795                 if (SubPackage->Package.Count < ExpectedCount)
796                 {
797                     Count = SubPackage->Package.Count;
798                     goto PackageTooSmall;
799                 }
800 
801                 /* Check the type of each sub-package element */
802 
803                 Status = AcpiNsCheckPackageElements (Pathname,
804                             (SubElements + 1),
805                             Package->RetInfo.ObjectType1,
806                             (ExpectedCount - 1), 0, 0, 1);
807                 if (ACPI_FAILURE (Status))
808                 {
809                     return (Status);
810                 }
811                 break;
812 
813             default:
814                 break;
815             }
816 
817             Elements++;
818         }
819         break;
820 
821 
822     default:
823 
824         /* Should not get here if predefined info table is correct */
825 
826         ACPI_WARNING ((AE_INFO,
827             "%s: Invalid internal return type in table entry: %X",
828             Pathname, Package->RetInfo.Type));
829 
830         return (AE_AML_INTERNAL);
831     }
832 
833     return (AE_OK);
834 
835 
836 PackageTooSmall:
837 
838     /* Error exit for the case with an incorrect package count */
839 
840     ACPI_WARNING ((AE_INFO, "%s: Return Package is too small - "
841         "found %u, expected %u", Pathname, Count, ExpectedCount));
842 
843     return (AE_AML_OPERAND_VALUE);
844 }
845 
846 
847 /*******************************************************************************
848  *
849  * FUNCTION:    AcpiNsCheckPackageElements
850  *
851  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
852  *              Elements        - Pointer to the package elements array
853  *              Type1           - Object type for first group
854  *              Count1          - Count for first group
855  *              Type2           - Object type for second group
856  *              Count2          - Count for second group
857  *              StartIndex      - Start of the first group of elements
858  *
859  * RETURN:      Status
860  *
861  * DESCRIPTION: Check that all elements of a package are of the correct object
862  *              type. Supports up to two groups of different object types.
863  *
864  ******************************************************************************/
865 
866 static ACPI_STATUS
867 AcpiNsCheckPackageElements (
868     char                        *Pathname,
869     ACPI_OPERAND_OBJECT         **Elements,
870     UINT8                       Type1,
871     UINT32                      Count1,
872     UINT8                       Type2,
873     UINT32                      Count2,
874     UINT32                      StartIndex)
875 {
876     ACPI_OPERAND_OBJECT         **ThisElement = Elements;
877     ACPI_STATUS                 Status;
878     UINT32                      i;
879 
880 
881     /*
882      * Up to two groups of package elements are supported by the data
883      * structure. All elements in each group must be of the same type.
884      * The second group can have a count of zero.
885      */
886     for (i = 0; i < Count1; i++)
887     {
888         Status = AcpiNsCheckObjectType (Pathname, ThisElement,
889                     Type1, i + StartIndex);
890         if (ACPI_FAILURE (Status))
891         {
892             return (Status);
893         }
894         ThisElement++;
895     }
896 
897     for (i = 0; i < Count2; i++)
898     {
899         Status = AcpiNsCheckObjectType (Pathname, ThisElement,
900                     Type2, (i + Count1 + StartIndex));
901         if (ACPI_FAILURE (Status))
902         {
903             return (Status);
904         }
905         ThisElement++;
906     }
907 
908     return (AE_OK);
909 }
910 
911 
912 /*******************************************************************************
913  *
914  * FUNCTION:    AcpiNsCheckObjectType
915  *
916  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
917  *              ReturnObjectPtr - Pointer to the object returned from the
918  *                                evaluation of a method or object
919  *              ExpectedBtypes  - Bitmap of expected return type(s)
920  *              PackageIndex    - Index of object within parent package (if
921  *                                applicable - ACPI_NOT_PACKAGE otherwise)
922  *
923  * RETURN:      Status
924  *
925  * DESCRIPTION: Check the type of the return object against the expected object
926  *              type(s). Use of Btype allows multiple expected object types.
927  *
928  ******************************************************************************/
929 
930 static ACPI_STATUS
931 AcpiNsCheckObjectType (
932     char                        *Pathname,
933     ACPI_OPERAND_OBJECT         **ReturnObjectPtr,
934     UINT32                      ExpectedBtypes,
935     UINT32                      PackageIndex)
936 {
937     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
938     ACPI_STATUS                 Status = AE_OK;
939     UINT32                      ReturnBtype;
940     char                        TypeBuffer[48]; /* Room for 5 types */
941     UINT32                      ThisRtype;
942     UINT32                      i;
943     UINT32                      j;
944 
945 
946     /*
947      * If we get a NULL ReturnObject here, it is a NULL package element,
948      * and this is always an error.
949      */
950     if (!ReturnObject)
951     {
952         goto TypeErrorExit;
953     }
954 
955     /* A Namespace node should not get here, but make sure */
956 
957     if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
958     {
959         ACPI_WARNING ((AE_INFO,
960             "%s: Invalid return type - Found a Namespace node [%4.4s] type %s",
961             Pathname, ReturnObject->Node.Name.Ascii,
962             AcpiUtGetTypeName (ReturnObject->Node.Type)));
963         return (AE_AML_OPERAND_TYPE);
964     }
965 
966     /*
967      * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
968      * The bitmapped type allows multiple possible return types.
969      *
970      * Note, the cases below must handle all of the possible types returned
971      * from all of the predefined names (including elements of returned
972      * packages)
973      */
974     switch (ReturnObject->Common.Type)
975     {
976     case ACPI_TYPE_INTEGER:
977         ReturnBtype = ACPI_RTYPE_INTEGER;
978         break;
979 
980     case ACPI_TYPE_BUFFER:
981         ReturnBtype = ACPI_RTYPE_BUFFER;
982         break;
983 
984     case ACPI_TYPE_STRING:
985         ReturnBtype = ACPI_RTYPE_STRING;
986         break;
987 
988     case ACPI_TYPE_PACKAGE:
989         ReturnBtype = ACPI_RTYPE_PACKAGE;
990         break;
991 
992     case ACPI_TYPE_LOCAL_REFERENCE:
993         ReturnBtype = ACPI_RTYPE_REFERENCE;
994         break;
995 
996     default:
997         /* Not one of the supported objects, must be incorrect */
998 
999         goto TypeErrorExit;
1000     }
1001 
1002     /* Is the object one of the expected types? */
1003 
1004     if (!(ReturnBtype & ExpectedBtypes))
1005     {
1006         /* Type mismatch -- attempt repair of the returned object */
1007 
1008         Status = AcpiNsRepairObject (ExpectedBtypes, PackageIndex,
1009                     ReturnObjectPtr);
1010         if (ACPI_SUCCESS (Status))
1011         {
1012             return (Status);
1013         }
1014         goto TypeErrorExit;
1015     }
1016 
1017     /* For reference objects, check that the reference type is correct */
1018 
1019     if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
1020     {
1021         Status = AcpiNsCheckReference (Pathname, ReturnObject);
1022     }
1023 
1024     return (Status);
1025 
1026 
1027 TypeErrorExit:
1028 
1029     /* Create a string with all expected types for this predefined object */
1030 
1031     j = 1;
1032     TypeBuffer[0] = 0;
1033     ThisRtype = ACPI_RTYPE_INTEGER;
1034 
1035     for (i = 0; i < ACPI_NUM_RTYPES; i++)
1036     {
1037         /* If one of the expected types, concatenate the name of this type */
1038 
1039         if (ExpectedBtypes & ThisRtype)
1040         {
1041             ACPI_STRCAT (TypeBuffer, &AcpiRtypeNames[i][j]);
1042             j = 0;              /* Use name separator from now on */
1043         }
1044         ThisRtype <<= 1;    /* Next Rtype */
1045     }
1046 
1047     if (PackageIndex == ACPI_NOT_PACKAGE)
1048     {
1049         ACPI_WARNING ((AE_INFO,
1050             "%s: Return type mismatch - found %s, expected %s",
1051             Pathname, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1052     }
1053     else
1054     {
1055         ACPI_WARNING ((AE_INFO,
1056             "%s: Return Package type mismatch at index %u - "
1057             "found %s, expected %s", Pathname, PackageIndex,
1058             AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
1059     }
1060 
1061     return (AE_AML_OPERAND_TYPE);
1062 }
1063 
1064 
1065 /*******************************************************************************
1066  *
1067  * FUNCTION:    AcpiNsCheckReference
1068  *
1069  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
1070  *              ReturnObject    - Object returned from the evaluation of a
1071  *                                method or object
1072  *
1073  * RETURN:      Status
1074  *
1075  * DESCRIPTION: Check a returned reference object for the correct reference
1076  *              type. The only reference type that can be returned from a
1077  *              predefined method is a named reference. All others are invalid.
1078  *
1079  ******************************************************************************/
1080 
1081 static ACPI_STATUS
1082 AcpiNsCheckReference (
1083     char                        *Pathname,
1084     ACPI_OPERAND_OBJECT         *ReturnObject)
1085 {
1086 
1087     /*
1088      * Check the reference object for the correct reference type (opcode).
1089      * The only type of reference that can be converted to an ACPI_OBJECT is
1090      * a reference to a named object (reference class: NAME)
1091      */
1092     if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME)
1093     {
1094         return (AE_OK);
1095     }
1096 
1097     ACPI_WARNING ((AE_INFO,
1098         "%s: Return type mismatch - "
1099         "unexpected reference object type [%s] %2.2X",
1100         Pathname, AcpiUtGetReferenceName (ReturnObject),
1101         ReturnObject->Reference.Class));
1102 
1103     return (AE_AML_OPERAND_TYPE);
1104 }
1105 
1106 
1107 /*******************************************************************************
1108  *
1109  * FUNCTION:    AcpiNsRepairObject
1110  *
1111  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
1112  *              PackageIndex    - Used to determine if target is in a package
1113  *              ReturnObjectPtr - Pointer to the object returned from the
1114  *                                evaluation of a method or object
1115  *
1116  * RETURN:      Status. AE_OK if repair was successful.
1117  *
1118  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
1119  *              not expected.
1120  *
1121  ******************************************************************************/
1122 
1123 static ACPI_STATUS
1124 AcpiNsRepairObject (
1125     UINT32                      ExpectedBtypes,
1126     UINT32                      PackageIndex,
1127     ACPI_OPERAND_OBJECT         **ReturnObjectPtr)
1128 {
1129     ACPI_OPERAND_OBJECT         *ReturnObject = *ReturnObjectPtr;
1130     ACPI_OPERAND_OBJECT         *NewObject;
1131     ACPI_SIZE                   Length;
1132 
1133 
1134     switch (ReturnObject->Common.Type)
1135     {
1136     case ACPI_TYPE_BUFFER:
1137 
1138         if (!(ExpectedBtypes & ACPI_RTYPE_STRING))
1139         {
1140             return (AE_AML_OPERAND_TYPE);
1141         }
1142 
1143         /*
1144          * Have a Buffer, expected a String, convert. Use a ToString
1145          * conversion, no transform performed on the buffer data. The best
1146          * example of this is the _BIF method, where the string data from
1147          * the battery is often (incorrectly) returned as buffer object(s).
1148          */
1149         Length = 0;
1150         while ((Length < ReturnObject->Buffer.Length) &&
1151                 (ReturnObject->Buffer.Pointer[Length]))
1152         {
1153             Length++;
1154         }
1155 
1156         /* Allocate a new string object */
1157 
1158         NewObject = AcpiUtCreateStringObject (Length);
1159         if (!NewObject)
1160         {
1161             return (AE_NO_MEMORY);
1162         }
1163 
1164         /*
1165          * Copy the raw buffer data with no transform. String is already NULL
1166          * terminated at Length+1.
1167          */
1168         ACPI_MEMCPY (NewObject->String.Pointer,
1169             ReturnObject->Buffer.Pointer, Length);
1170 
1171         /* Install the new return object */
1172 
1173         AcpiUtRemoveReference (ReturnObject);
1174         *ReturnObjectPtr = NewObject;
1175 
1176         /*
1177          * If the object is a package element, we need to:
1178          * 1. Decrement the reference count of the orignal object, it was
1179          *    incremented when building the package
1180          * 2. Increment the reference count of the new object, it will be
1181          *    decremented when releasing the package
1182          */
1183         if (PackageIndex != ACPI_NOT_PACKAGE)
1184         {
1185             AcpiUtRemoveReference (ReturnObject);
1186             AcpiUtAddReference (NewObject);
1187         }
1188         return (AE_OK);
1189 
1190     default:
1191         break;
1192     }
1193 
1194     return (AE_AML_OPERAND_TYPE);
1195 }
1196 
1197