nspredef.c revision 193341
1193267Sjkim/****************************************************************************** 2193267Sjkim * 3193267Sjkim * Module Name: nspredef - Validation of ACPI predefined methods and objects 4193267Sjkim * 5193267Sjkim *****************************************************************************/ 6193267Sjkim 7193267Sjkim/****************************************************************************** 8193267Sjkim * 9193267Sjkim * 1. Copyright Notice 10193267Sjkim * 11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 12193267Sjkim * All rights reserved. 13193267Sjkim * 14193267Sjkim * 2. License 15193267Sjkim * 16193267Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17193267Sjkim * rights. You may have additional license terms from the party that provided 18193267Sjkim * you this software, covering your right to use that party's intellectual 19193267Sjkim * property rights. 20193267Sjkim * 21193267Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22193267Sjkim * copy of the source code appearing in this file ("Covered Code") an 23193267Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24193267Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25193267Sjkim * make derivatives, distribute, use and display any portion of the Covered 26193267Sjkim * Code in any form, with the right to sublicense such rights; and 27193267Sjkim * 28193267Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29193267Sjkim * license (with the right to sublicense), under only those claims of Intel 30193267Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31193267Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32193267Sjkim * solely to the minimum extent necessary to exercise the above copyright 33193267Sjkim * license, and in no event shall the patent license extend to any additions 34193267Sjkim * to or modifications of the Original Intel Code. No other license or right 35193267Sjkim * is granted directly or by implication, estoppel or otherwise; 36193267Sjkim * 37193267Sjkim * The above copyright and patent license is granted only if the following 38193267Sjkim * conditions are met: 39193267Sjkim * 40193267Sjkim * 3. Conditions 41193267Sjkim * 42193267Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43193267Sjkim * Redistribution of source code of any substantial portion of the Covered 44193267Sjkim * Code or modification with rights to further distribute source must include 45193267Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46193267Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47193267Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48193267Sjkim * contain a file documenting the changes Licensee made to create that Covered 49193267Sjkim * Code and the date of any change. Licensee must include in that file the 50193267Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51193267Sjkim * must include a prominent statement that the modification is derived, 52193267Sjkim * directly or indirectly, from Original Intel Code. 53193267Sjkim * 54193267Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55193267Sjkim * Redistribution of source code of any substantial portion of the Covered 56193267Sjkim * Code or modification without rights to further distribute source must 57193267Sjkim * include the following Disclaimer and Export Compliance provision in the 58193267Sjkim * documentation and/or other materials provided with distribution. In 59193267Sjkim * addition, Licensee may not authorize further sublicense of source of any 60193267Sjkim * portion of the Covered Code, and must include terms to the effect that the 61193267Sjkim * license from Licensee to its licensee is limited to the intellectual 62193267Sjkim * property embodied in the software Licensee provides to its licensee, and 63193267Sjkim * not to intellectual property embodied in modifications its licensee may 64193267Sjkim * make. 65193267Sjkim * 66193267Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67193267Sjkim * substantial portion of the Covered Code or modification must reproduce the 68193267Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69193267Sjkim * provision in the documentation and/or other materials provided with the 70193267Sjkim * distribution. 71193267Sjkim * 72193267Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73193267Sjkim * Intel Code. 74193267Sjkim * 75193267Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76193267Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77193267Sjkim * other dealings in products derived from or relating to the Covered Code 78193267Sjkim * without prior written authorization from Intel. 79193267Sjkim * 80193267Sjkim * 4. Disclaimer and Export Compliance 81193267Sjkim * 82193267Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83193267Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84193267Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85193267Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86193267Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87193267Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88193267Sjkim * PARTICULAR PURPOSE. 89193267Sjkim * 90193267Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91193267Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92193267Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93193267Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94193267Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95193267Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96193267Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97193267Sjkim * LIMITED REMEDY. 98193267Sjkim * 99193267Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100193267Sjkim * software or system incorporating such software without first obtaining any 101193267Sjkim * required license or other approval from the U. S. Department of Commerce or 102193267Sjkim * any other agency or department of the United States Government. In the 103193267Sjkim * event Licensee exports any such software from the United States or 104193267Sjkim * re-exports any such software from a foreign destination, Licensee shall 105193267Sjkim * ensure that the distribution and export/re-export of the software is in 106193267Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107193267Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108193267Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109193267Sjkim * software, or service, directly or indirectly, to any country for which the 110193267Sjkim * United States government or any agency thereof requires an export license, 111193267Sjkim * other governmental approval, or letter of assurance, without first obtaining 112193267Sjkim * such license, approval or letter. 113193267Sjkim * 114193267Sjkim *****************************************************************************/ 115193267Sjkim 116193267Sjkim#define __NSPREDEF_C__ 117193267Sjkim 118193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 119193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 120193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 121193341Sjkim#include <contrib/dev/acpica/include/acpredef.h> 122193267Sjkim 123193267Sjkim 124193267Sjkim#define _COMPONENT ACPI_NAMESPACE 125193267Sjkim ACPI_MODULE_NAME ("nspredef") 126193267Sjkim 127193267Sjkim 128193267Sjkim/******************************************************************************* 129193267Sjkim * 130193267Sjkim * This module validates predefined ACPI objects that appear in the namespace, 131193267Sjkim * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this 132193267Sjkim * validation is to detect problems with BIOS-exposed predefined ACPI objects 133193267Sjkim * before the results are returned to the ACPI-related drivers. 134193267Sjkim * 135193267Sjkim * There are several areas that are validated: 136193267Sjkim * 137193267Sjkim * 1) The number of input arguments as defined by the method/object in the 138193267Sjkim * ASL is validated against the ACPI specification. 139193267Sjkim * 2) The type of the return object (if any) is validated against the ACPI 140193267Sjkim * specification. 141193267Sjkim * 3) For returned package objects, the count of package elements is 142193267Sjkim * validated, as well as the type of each package element. Nested 143193267Sjkim * packages are supported. 144193267Sjkim * 145193267Sjkim * For any problems found, a warning message is issued. 146193267Sjkim * 147193267Sjkim ******************************************************************************/ 148193267Sjkim 149193267Sjkim/* Local prototypes */ 150193267Sjkim 151193267Sjkimstatic ACPI_STATUS 152193267SjkimAcpiNsCheckPackage ( 153193267Sjkim char *Pathname, 154193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr, 155193267Sjkim const ACPI_PREDEFINED_INFO *Predefined); 156193267Sjkim 157193267Sjkimstatic ACPI_STATUS 158193267SjkimAcpiNsCheckPackageElements ( 159193267Sjkim char *Pathname, 160193267Sjkim ACPI_OPERAND_OBJECT **Elements, 161193267Sjkim UINT8 Type1, 162193267Sjkim UINT32 Count1, 163193267Sjkim UINT8 Type2, 164193267Sjkim UINT32 Count2, 165193267Sjkim UINT32 StartIndex); 166193267Sjkim 167193267Sjkimstatic ACPI_STATUS 168193267SjkimAcpiNsCheckObjectType ( 169193267Sjkim char *Pathname, 170193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr, 171193267Sjkim UINT32 ExpectedBtypes, 172193267Sjkim UINT32 PackageIndex); 173193267Sjkim 174193267Sjkimstatic ACPI_STATUS 175193267SjkimAcpiNsCheckReference ( 176193267Sjkim char *Pathname, 177193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject); 178193267Sjkim 179193267Sjkimstatic ACPI_STATUS 180193267SjkimAcpiNsRepairObject ( 181193267Sjkim UINT32 ExpectedBtypes, 182193267Sjkim UINT32 PackageIndex, 183193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 184193267Sjkim 185193267Sjkim/* 186193267Sjkim * Names for the types that can be returned by the predefined objects. 187193267Sjkim * Used for warning messages. Must be in the same order as the ACPI_RTYPEs 188193267Sjkim */ 189193267Sjkimstatic const char *AcpiRtypeNames[] = 190193267Sjkim{ 191193267Sjkim "/Integer", 192193267Sjkim "/String", 193193267Sjkim "/Buffer", 194193267Sjkim "/Package", 195193267Sjkim "/Reference", 196193267Sjkim}; 197193267Sjkim 198193267Sjkim#define ACPI_NOT_PACKAGE ACPI_UINT32_MAX 199193267Sjkim 200193267Sjkim 201193267Sjkim/******************************************************************************* 202193267Sjkim * 203193267Sjkim * FUNCTION: AcpiNsCheckPredefinedNames 204193267Sjkim * 205193267Sjkim * PARAMETERS: Node - Namespace node for the method/object 206193267Sjkim * ReturnObjectPtr - Pointer to the object returned from the 207193267Sjkim * evaluation of a method or object 208193267Sjkim * 209193267Sjkim * RETURN: Status 210193267Sjkim * 211193267Sjkim * DESCRIPTION: Check an ACPI name for a match in the predefined name list. 212193267Sjkim * 213193267Sjkim ******************************************************************************/ 214193267Sjkim 215193267SjkimACPI_STATUS 216193267SjkimAcpiNsCheckPredefinedNames ( 217193267Sjkim ACPI_NAMESPACE_NODE *Node, 218193267Sjkim UINT32 UserParamCount, 219193267Sjkim ACPI_STATUS ReturnStatus, 220193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 221193267Sjkim{ 222193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 223193267Sjkim ACPI_STATUS Status = AE_OK; 224193267Sjkim const ACPI_PREDEFINED_INFO *Predefined; 225193267Sjkim char *Pathname; 226193267Sjkim 227193267Sjkim 228193267Sjkim /* Match the name for this method/object against the predefined list */ 229193267Sjkim 230193267Sjkim Predefined = AcpiNsCheckForPredefinedName (Node); 231193267Sjkim 232193267Sjkim /* Get the full pathname to the object, for use in error messages */ 233193267Sjkim 234193267Sjkim Pathname = AcpiNsGetExternalPathname (Node); 235193267Sjkim if (!Pathname) 236193267Sjkim { 237193267Sjkim return (AE_OK); /* Could not get pathname, ignore */ 238193267Sjkim } 239193267Sjkim 240193267Sjkim /* 241193267Sjkim * Check that the parameter count for this method matches the ASL 242193267Sjkim * definition. For predefined names, ensure that both the caller and 243193267Sjkim * the method itself are in accordance with the ACPI specification. 244193267Sjkim */ 245193267Sjkim AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined); 246193267Sjkim 247193267Sjkim /* If not a predefined name, we cannot validate the return object */ 248193267Sjkim 249193267Sjkim if (!Predefined) 250193267Sjkim { 251193267Sjkim goto Exit; 252193267Sjkim } 253193267Sjkim 254193267Sjkim /* If the method failed, we cannot validate the return object */ 255193267Sjkim 256193267Sjkim if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE)) 257193267Sjkim { 258193267Sjkim goto Exit; 259193267Sjkim } 260193267Sjkim 261193267Sjkim /* 262193267Sjkim * Only validate the return value on the first successful evaluation of 263193267Sjkim * the method. This ensures that any warnings will only be emitted during 264193267Sjkim * the very first evaluation of the method/object. 265193267Sjkim */ 266193267Sjkim if (Node->Flags & ANOBJ_EVALUATED) 267193267Sjkim { 268193267Sjkim goto Exit; 269193267Sjkim } 270193267Sjkim 271193267Sjkim /* Mark the node as having been successfully evaluated */ 272193267Sjkim 273193267Sjkim Node->Flags |= ANOBJ_EVALUATED; 274193267Sjkim 275193267Sjkim /* 276193267Sjkim * If there is no return value, check if we require a return value for 277193267Sjkim * this predefined name. Either one return value is expected, or none, 278193267Sjkim * for both methods and other objects. 279193267Sjkim * 280193267Sjkim * Exit now if there is no return object. Warning if one was expected. 281193267Sjkim */ 282193267Sjkim if (!ReturnObject) 283193267Sjkim { 284193267Sjkim if ((Predefined->Info.ExpectedBtypes) && 285193267Sjkim (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE))) 286193267Sjkim { 287193267Sjkim ACPI_ERROR ((AE_INFO, 288193267Sjkim "%s: Missing expected return value", Pathname)); 289193267Sjkim 290193267Sjkim Status = AE_AML_NO_RETURN_VALUE; 291193267Sjkim } 292193267Sjkim goto Exit; 293193267Sjkim } 294193267Sjkim 295193267Sjkim /* 296193267Sjkim * We have a return value, but if one wasn't expected, just exit, this is 297193267Sjkim * not a problem 298193267Sjkim * 299193267Sjkim * For example, if the "Implicit Return" feature is enabled, methods will 300193267Sjkim * always return a value 301193267Sjkim */ 302193267Sjkim if (!Predefined->Info.ExpectedBtypes) 303193267Sjkim { 304193267Sjkim goto Exit; 305193267Sjkim } 306193267Sjkim 307193267Sjkim /* 308193267Sjkim * Check that the type of the return object is what is expected for 309193267Sjkim * this predefined name 310193267Sjkim */ 311193267Sjkim Status = AcpiNsCheckObjectType (Pathname, ReturnObjectPtr, 312193267Sjkim Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE); 313193267Sjkim if (ACPI_FAILURE (Status)) 314193267Sjkim { 315193267Sjkim goto Exit; 316193267Sjkim } 317193267Sjkim 318193267Sjkim /* For returned Package objects, check the type of all sub-objects */ 319193267Sjkim 320193267Sjkim if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE) 321193267Sjkim { 322193267Sjkim Status = AcpiNsCheckPackage (Pathname, ReturnObjectPtr, Predefined); 323193267Sjkim } 324193267Sjkim 325193267SjkimExit: 326193267Sjkim ACPI_FREE (Pathname); 327193267Sjkim return (Status); 328193267Sjkim} 329193267Sjkim 330193267Sjkim 331193267Sjkim/******************************************************************************* 332193267Sjkim * 333193267Sjkim * FUNCTION: AcpiNsCheckParameterCount 334193267Sjkim * 335193267Sjkim * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 336193267Sjkim * Node - Namespace node for the method/object 337193267Sjkim * UserParamCount - Number of args passed in by the caller 338193267Sjkim * Predefined - Pointer to entry in predefined name table 339193267Sjkim * 340193267Sjkim * RETURN: None 341193267Sjkim * 342193267Sjkim * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a 343193267Sjkim * predefined name is what is expected (i.e., what is defined in 344193267Sjkim * the ACPI specification for this predefined name.) 345193267Sjkim * 346193267Sjkim ******************************************************************************/ 347193267Sjkim 348193267Sjkimvoid 349193267SjkimAcpiNsCheckParameterCount ( 350193267Sjkim char *Pathname, 351193267Sjkim ACPI_NAMESPACE_NODE *Node, 352193267Sjkim UINT32 UserParamCount, 353193267Sjkim const ACPI_PREDEFINED_INFO *Predefined) 354193267Sjkim{ 355193267Sjkim UINT32 ParamCount; 356193267Sjkim UINT32 RequiredParamsCurrent; 357193267Sjkim UINT32 RequiredParamsOld; 358193267Sjkim 359193267Sjkim 360193267Sjkim /* Methods have 0-7 parameters. All other types have zero. */ 361193267Sjkim 362193267Sjkim ParamCount = 0; 363193267Sjkim if (Node->Type == ACPI_TYPE_METHOD) 364193267Sjkim { 365193267Sjkim ParamCount = Node->Object->Method.ParamCount; 366193267Sjkim } 367193267Sjkim 368193267Sjkim /* Argument count check for non-predefined methods/objects */ 369193267Sjkim 370193267Sjkim if (!Predefined) 371193267Sjkim { 372193267Sjkim /* 373193267Sjkim * Warning if too few or too many arguments have been passed by the 374193267Sjkim * caller. An incorrect number of arguments may not cause the method 375193267Sjkim * to fail. However, the method will fail if there are too few 376193267Sjkim * arguments and the method attempts to use one of the missing ones. 377193267Sjkim */ 378193267Sjkim if (UserParamCount < ParamCount) 379193267Sjkim { 380193267Sjkim ACPI_WARNING ((AE_INFO, 381193267Sjkim "%s: Insufficient arguments - needs %d, found %d", 382193267Sjkim Pathname, ParamCount, UserParamCount)); 383193267Sjkim } 384193267Sjkim else if (UserParamCount > ParamCount) 385193267Sjkim { 386193267Sjkim ACPI_WARNING ((AE_INFO, 387193267Sjkim "%s: Excess arguments - needs %d, found %d", 388193267Sjkim Pathname, ParamCount, UserParamCount)); 389193267Sjkim } 390193267Sjkim return; 391193267Sjkim } 392193267Sjkim 393193267Sjkim /* Allow two different legal argument counts (_SCP, etc.) */ 394193267Sjkim 395193267Sjkim RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F; 396193267Sjkim RequiredParamsOld = Predefined->Info.ParamCount >> 4; 397193267Sjkim 398193267Sjkim if (UserParamCount != ACPI_UINT32_MAX) 399193267Sjkim { 400193267Sjkim /* Validate the user-supplied parameter count */ 401193267Sjkim 402193267Sjkim if ((UserParamCount != RequiredParamsCurrent) && 403193267Sjkim (UserParamCount != RequiredParamsOld)) 404193267Sjkim { 405193267Sjkim ACPI_WARNING ((AE_INFO, 406193267Sjkim "%s: Parameter count mismatch - " 407193267Sjkim "caller passed %d, ACPI requires %d", 408193267Sjkim Pathname, UserParamCount, RequiredParamsCurrent)); 409193267Sjkim } 410193267Sjkim } 411193267Sjkim 412193267Sjkim /* 413193267Sjkim * Only validate the argument count on the first successful evaluation of 414193267Sjkim * the method. This ensures that any warnings will only be emitted during 415193267Sjkim * the very first evaluation of the method/object. 416193267Sjkim */ 417193267Sjkim if (Node->Flags & ANOBJ_EVALUATED) 418193267Sjkim { 419193267Sjkim return; 420193267Sjkim } 421193267Sjkim 422193267Sjkim /* 423193267Sjkim * Check that the ASL-defined parameter count is what is expected for 424193267Sjkim * this predefined name. 425193267Sjkim */ 426193267Sjkim if ((ParamCount != RequiredParamsCurrent) && 427193267Sjkim (ParamCount != RequiredParamsOld)) 428193267Sjkim { 429193267Sjkim ACPI_WARNING ((AE_INFO, 430193267Sjkim "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", 431193267Sjkim Pathname, ParamCount, RequiredParamsCurrent)); 432193267Sjkim } 433193267Sjkim} 434193267Sjkim 435193267Sjkim 436193267Sjkim/******************************************************************************* 437193267Sjkim * 438193267Sjkim * FUNCTION: AcpiNsCheckForPredefinedName 439193267Sjkim * 440193267Sjkim * PARAMETERS: Node - Namespace node for the method/object 441193267Sjkim * 442193267Sjkim * RETURN: Pointer to entry in predefined table. NULL indicates not found. 443193267Sjkim * 444193267Sjkim * DESCRIPTION: Check an object name against the predefined object list. 445193267Sjkim * 446193267Sjkim ******************************************************************************/ 447193267Sjkim 448193267Sjkimconst ACPI_PREDEFINED_INFO * 449193267SjkimAcpiNsCheckForPredefinedName ( 450193267Sjkim ACPI_NAMESPACE_NODE *Node) 451193267Sjkim{ 452193267Sjkim const ACPI_PREDEFINED_INFO *ThisName; 453193267Sjkim 454193267Sjkim 455193267Sjkim /* Quick check for a predefined name, first character must be underscore */ 456193267Sjkim 457193267Sjkim if (Node->Name.Ascii[0] != '_') 458193267Sjkim { 459193267Sjkim return (NULL); 460193267Sjkim } 461193267Sjkim 462193267Sjkim /* Search info table for a predefined method/object name */ 463193267Sjkim 464193267Sjkim ThisName = PredefinedNames; 465193267Sjkim while (ThisName->Info.Name[0]) 466193267Sjkim { 467193267Sjkim if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name)) 468193267Sjkim { 469193267Sjkim /* Return pointer to this table entry */ 470193267Sjkim 471193267Sjkim return (ThisName); 472193267Sjkim } 473193267Sjkim 474193267Sjkim /* 475193267Sjkim * Skip next entry in the table if this name returns a Package 476193267Sjkim * (next entry contains the package info) 477193267Sjkim */ 478193267Sjkim if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) 479193267Sjkim { 480193267Sjkim ThisName++; 481193267Sjkim } 482193267Sjkim 483193267Sjkim ThisName++; 484193267Sjkim } 485193267Sjkim 486193267Sjkim return (NULL); 487193267Sjkim} 488193267Sjkim 489193267Sjkim 490193267Sjkim/******************************************************************************* 491193267Sjkim * 492193267Sjkim * FUNCTION: AcpiNsCheckPackage 493193267Sjkim * 494193267Sjkim * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 495193267Sjkim * ReturnObjectPtr - Pointer to the object returned from the 496193267Sjkim * evaluation of a method or object 497193267Sjkim * Predefined - Pointer to entry in predefined name table 498193267Sjkim * 499193267Sjkim * RETURN: Status 500193267Sjkim * 501193267Sjkim * DESCRIPTION: Check a returned package object for the correct count and 502193267Sjkim * correct type of all sub-objects. 503193267Sjkim * 504193267Sjkim ******************************************************************************/ 505193267Sjkim 506193267Sjkimstatic ACPI_STATUS 507193267SjkimAcpiNsCheckPackage ( 508193267Sjkim char *Pathname, 509193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr, 510193267Sjkim const ACPI_PREDEFINED_INFO *Predefined) 511193267Sjkim{ 512193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 513193267Sjkim const ACPI_PREDEFINED_INFO *Package; 514193267Sjkim ACPI_OPERAND_OBJECT *SubPackage; 515193267Sjkim ACPI_OPERAND_OBJECT **Elements; 516193267Sjkim ACPI_OPERAND_OBJECT **SubElements; 517193267Sjkim ACPI_STATUS Status; 518193267Sjkim UINT32 ExpectedCount; 519193267Sjkim UINT32 Count; 520193267Sjkim UINT32 i; 521193267Sjkim UINT32 j; 522193267Sjkim 523193267Sjkim 524193267Sjkim ACPI_FUNCTION_NAME (NsCheckPackage); 525193267Sjkim 526193267Sjkim 527193267Sjkim /* The package info for this name is in the next table entry */ 528193267Sjkim 529193267Sjkim Package = Predefined + 1; 530193267Sjkim 531193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 532193267Sjkim "%s Validating return Package of Type %X, Count %X\n", 533193267Sjkim Pathname, Package->RetInfo.Type, ReturnObject->Package.Count)); 534193267Sjkim 535193267Sjkim /* Extract package count and elements array */ 536193267Sjkim 537193267Sjkim Elements = ReturnObject->Package.Elements; 538193267Sjkim Count = ReturnObject->Package.Count; 539193267Sjkim 540193267Sjkim /* The package must have at least one element, else invalid */ 541193267Sjkim 542193267Sjkim if (!Count) 543193267Sjkim { 544193267Sjkim ACPI_WARNING ((AE_INFO, 545193267Sjkim "%s: Return Package has no elements (empty)", Pathname)); 546193267Sjkim 547193267Sjkim return (AE_AML_OPERAND_VALUE); 548193267Sjkim } 549193267Sjkim 550193267Sjkim /* 551193267Sjkim * Decode the type of the expected package contents 552193267Sjkim * 553193267Sjkim * PTYPE1 packages contain no subpackages 554193267Sjkim * PTYPE2 packages contain sub-packages 555193267Sjkim */ 556193267Sjkim switch (Package->RetInfo.Type) 557193267Sjkim { 558193267Sjkim case ACPI_PTYPE1_FIXED: 559193267Sjkim 560193267Sjkim /* 561193267Sjkim * The package count is fixed and there are no sub-packages 562193267Sjkim * 563193267Sjkim * If package is too small, exit. 564193267Sjkim * If package is larger than expected, issue warning but continue 565193267Sjkim */ 566193267Sjkim ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 567193267Sjkim if (Count < ExpectedCount) 568193267Sjkim { 569193267Sjkim goto PackageTooSmall; 570193267Sjkim } 571193267Sjkim else if (Count > ExpectedCount) 572193267Sjkim { 573193267Sjkim ACPI_WARNING ((AE_INFO, 574193267Sjkim "%s: Return Package is larger than needed - " 575193267Sjkim "found %u, expected %u", Pathname, Count, ExpectedCount)); 576193267Sjkim } 577193267Sjkim 578193267Sjkim /* Validate all elements of the returned package */ 579193267Sjkim 580193267Sjkim Status = AcpiNsCheckPackageElements (Pathname, Elements, 581193267Sjkim Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 582193267Sjkim Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0); 583193267Sjkim if (ACPI_FAILURE (Status)) 584193267Sjkim { 585193267Sjkim return (Status); 586193267Sjkim } 587193267Sjkim break; 588193267Sjkim 589193267Sjkim 590193267Sjkim case ACPI_PTYPE1_VAR: 591193267Sjkim 592193267Sjkim /* 593193267Sjkim * The package count is variable, there are no sub-packages, and all 594193267Sjkim * elements must be of the same type 595193267Sjkim */ 596193267Sjkim for (i = 0; i < Count; i++) 597193267Sjkim { 598193267Sjkim Status = AcpiNsCheckObjectType (Pathname, Elements, 599193267Sjkim Package->RetInfo.ObjectType1, i); 600193267Sjkim if (ACPI_FAILURE (Status)) 601193267Sjkim { 602193267Sjkim return (Status); 603193267Sjkim } 604193267Sjkim Elements++; 605193267Sjkim } 606193267Sjkim break; 607193267Sjkim 608193267Sjkim 609193267Sjkim case ACPI_PTYPE1_OPTION: 610193267Sjkim 611193267Sjkim /* 612193267Sjkim * The package count is variable, there are no sub-packages. There are 613193267Sjkim * a fixed number of required elements, and a variable number of 614193267Sjkim * optional elements. 615193267Sjkim * 616193267Sjkim * Check if package is at least as large as the minimum required 617193267Sjkim */ 618193267Sjkim ExpectedCount = Package->RetInfo3.Count; 619193267Sjkim if (Count < ExpectedCount) 620193267Sjkim { 621193267Sjkim goto PackageTooSmall; 622193267Sjkim } 623193267Sjkim 624193267Sjkim /* Variable number of sub-objects */ 625193267Sjkim 626193267Sjkim for (i = 0; i < Count; i++) 627193267Sjkim { 628193267Sjkim if (i < Package->RetInfo3.Count) 629193267Sjkim { 630193267Sjkim /* These are the required package elements (0, 1, or 2) */ 631193267Sjkim 632193267Sjkim Status = AcpiNsCheckObjectType (Pathname, Elements, 633193267Sjkim Package->RetInfo3.ObjectType[i], i); 634193267Sjkim if (ACPI_FAILURE (Status)) 635193267Sjkim { 636193267Sjkim return (Status); 637193267Sjkim } 638193267Sjkim } 639193267Sjkim else 640193267Sjkim { 641193267Sjkim /* These are the optional package elements */ 642193267Sjkim 643193267Sjkim Status = AcpiNsCheckObjectType (Pathname, Elements, 644193267Sjkim Package->RetInfo3.TailObjectType, i); 645193267Sjkim if (ACPI_FAILURE (Status)) 646193267Sjkim { 647193267Sjkim return (Status); 648193267Sjkim } 649193267Sjkim } 650193267Sjkim Elements++; 651193267Sjkim } 652193267Sjkim break; 653193267Sjkim 654193267Sjkim 655193267Sjkim case ACPI_PTYPE2_PKG_COUNT: 656193267Sjkim 657193267Sjkim /* First element is the (Integer) count of sub-packages to follow */ 658193267Sjkim 659193267Sjkim Status = AcpiNsCheckObjectType (Pathname, Elements, 660193267Sjkim ACPI_RTYPE_INTEGER, 0); 661193267Sjkim if (ACPI_FAILURE (Status)) 662193267Sjkim { 663193267Sjkim return (Status); 664193267Sjkim } 665193267Sjkim 666193267Sjkim /* 667193267Sjkim * Count cannot be larger than the parent package length, but allow it 668193267Sjkim * to be smaller. The >= accounts for the Integer above. 669193267Sjkim */ 670193267Sjkim ExpectedCount = (UINT32) (*Elements)->Integer.Value; 671193267Sjkim if (ExpectedCount >= Count) 672193267Sjkim { 673193267Sjkim goto PackageTooSmall; 674193267Sjkim } 675193267Sjkim 676193267Sjkim Count = ExpectedCount; 677193267Sjkim Elements++; 678193267Sjkim 679193267Sjkim /* Now we can walk the sub-packages */ 680193267Sjkim 681193267Sjkim /*lint -fallthrough */ 682193267Sjkim 683193267Sjkim 684193267Sjkim case ACPI_PTYPE2: 685193267Sjkim case ACPI_PTYPE2_FIXED: 686193267Sjkim case ACPI_PTYPE2_MIN: 687193267Sjkim case ACPI_PTYPE2_COUNT: 688193267Sjkim 689193267Sjkim /* 690193267Sjkim * These types all return a single package that consists of a variable 691193267Sjkim * number of sub-packages 692193267Sjkim */ 693193267Sjkim for (i = 0; i < Count; i++) 694193267Sjkim { 695193267Sjkim SubPackage = *Elements; 696193267Sjkim SubElements = SubPackage->Package.Elements; 697193267Sjkim 698193267Sjkim /* Each sub-object must be of type Package */ 699193267Sjkim 700193267Sjkim Status = AcpiNsCheckObjectType (Pathname, &SubPackage, 701193267Sjkim ACPI_RTYPE_PACKAGE, i); 702193267Sjkim if (ACPI_FAILURE (Status)) 703193267Sjkim { 704193267Sjkim return (Status); 705193267Sjkim } 706193267Sjkim 707193267Sjkim /* Examine the different types of sub-packages */ 708193267Sjkim 709193267Sjkim switch (Package->RetInfo.Type) 710193267Sjkim { 711193267Sjkim case ACPI_PTYPE2: 712193267Sjkim case ACPI_PTYPE2_PKG_COUNT: 713193267Sjkim 714193267Sjkim /* Each subpackage has a fixed number of elements */ 715193267Sjkim 716193267Sjkim ExpectedCount = 717193267Sjkim Package->RetInfo.Count1 + Package->RetInfo.Count2; 718193267Sjkim if (SubPackage->Package.Count != ExpectedCount) 719193267Sjkim { 720193267Sjkim Count = SubPackage->Package.Count; 721193267Sjkim goto PackageTooSmall; 722193267Sjkim } 723193267Sjkim 724193267Sjkim Status = AcpiNsCheckPackageElements (Pathname, SubElements, 725193267Sjkim Package->RetInfo.ObjectType1, 726193267Sjkim Package->RetInfo.Count1, 727193267Sjkim Package->RetInfo.ObjectType2, 728193267Sjkim Package->RetInfo.Count2, 0); 729193267Sjkim if (ACPI_FAILURE (Status)) 730193267Sjkim { 731193267Sjkim return (Status); 732193267Sjkim } 733193267Sjkim break; 734193267Sjkim 735193267Sjkim case ACPI_PTYPE2_FIXED: 736193267Sjkim 737193267Sjkim /* Each sub-package has a fixed length */ 738193267Sjkim 739193267Sjkim ExpectedCount = Package->RetInfo2.Count; 740193267Sjkim if (SubPackage->Package.Count < ExpectedCount) 741193267Sjkim { 742193267Sjkim Count = SubPackage->Package.Count; 743193267Sjkim goto PackageTooSmall; 744193267Sjkim } 745193267Sjkim 746193267Sjkim /* Check the type of each sub-package element */ 747193267Sjkim 748193267Sjkim for (j = 0; j < ExpectedCount; j++) 749193267Sjkim { 750193267Sjkim Status = AcpiNsCheckObjectType (Pathname, &SubElements[j], 751193267Sjkim Package->RetInfo2.ObjectType[j], j); 752193267Sjkim if (ACPI_FAILURE (Status)) 753193267Sjkim { 754193267Sjkim return (Status); 755193267Sjkim } 756193267Sjkim } 757193267Sjkim break; 758193267Sjkim 759193267Sjkim case ACPI_PTYPE2_MIN: 760193267Sjkim 761193267Sjkim /* Each sub-package has a variable but minimum length */ 762193267Sjkim 763193267Sjkim ExpectedCount = Package->RetInfo.Count1; 764193267Sjkim if (SubPackage->Package.Count < ExpectedCount) 765193267Sjkim { 766193267Sjkim Count = SubPackage->Package.Count; 767193267Sjkim goto PackageTooSmall; 768193267Sjkim } 769193267Sjkim 770193267Sjkim /* Check the type of each sub-package element */ 771193267Sjkim 772193267Sjkim Status = AcpiNsCheckPackageElements (Pathname, SubElements, 773193267Sjkim Package->RetInfo.ObjectType1, 774193267Sjkim SubPackage->Package.Count, 0, 0, 0); 775193267Sjkim if (ACPI_FAILURE (Status)) 776193267Sjkim { 777193267Sjkim return (Status); 778193267Sjkim } 779193267Sjkim break; 780193267Sjkim 781193267Sjkim case ACPI_PTYPE2_COUNT: 782193267Sjkim 783193267Sjkim /* First element is the (Integer) count of elements to follow */ 784193267Sjkim 785193267Sjkim Status = AcpiNsCheckObjectType (Pathname, SubElements, 786193267Sjkim ACPI_RTYPE_INTEGER, 0); 787193267Sjkim if (ACPI_FAILURE (Status)) 788193267Sjkim { 789193267Sjkim return (Status); 790193267Sjkim } 791193267Sjkim 792193267Sjkim /* Make sure package is large enough for the Count */ 793193267Sjkim 794193267Sjkim ExpectedCount = (UINT32) (*SubElements)->Integer.Value; 795193267Sjkim if (SubPackage->Package.Count < ExpectedCount) 796193267Sjkim { 797193267Sjkim Count = SubPackage->Package.Count; 798193267Sjkim goto PackageTooSmall; 799193267Sjkim } 800193267Sjkim 801193267Sjkim /* Check the type of each sub-package element */ 802193267Sjkim 803193267Sjkim Status = AcpiNsCheckPackageElements (Pathname, 804193267Sjkim (SubElements + 1), 805193267Sjkim Package->RetInfo.ObjectType1, 806193267Sjkim (ExpectedCount - 1), 0, 0, 1); 807193267Sjkim if (ACPI_FAILURE (Status)) 808193267Sjkim { 809193267Sjkim return (Status); 810193267Sjkim } 811193267Sjkim break; 812193267Sjkim 813193267Sjkim default: 814193267Sjkim break; 815193267Sjkim } 816193267Sjkim 817193267Sjkim Elements++; 818193267Sjkim } 819193267Sjkim break; 820193267Sjkim 821193267Sjkim 822193267Sjkim default: 823193267Sjkim 824193267Sjkim /* Should not get here if predefined info table is correct */ 825193267Sjkim 826193267Sjkim ACPI_WARNING ((AE_INFO, 827193267Sjkim "%s: Invalid internal return type in table entry: %X", 828193267Sjkim Pathname, Package->RetInfo.Type)); 829193267Sjkim 830193267Sjkim return (AE_AML_INTERNAL); 831193267Sjkim } 832193267Sjkim 833193267Sjkim return (AE_OK); 834193267Sjkim 835193267Sjkim 836193267SjkimPackageTooSmall: 837193267Sjkim 838193267Sjkim /* Error exit for the case with an incorrect package count */ 839193267Sjkim 840193267Sjkim ACPI_WARNING ((AE_INFO, "%s: Return Package is too small - " 841193267Sjkim "found %u, expected %u", Pathname, Count, ExpectedCount)); 842193267Sjkim 843193267Sjkim return (AE_AML_OPERAND_VALUE); 844193267Sjkim} 845193267Sjkim 846193267Sjkim 847193267Sjkim/******************************************************************************* 848193267Sjkim * 849193267Sjkim * FUNCTION: AcpiNsCheckPackageElements 850193267Sjkim * 851193267Sjkim * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 852193267Sjkim * Elements - Pointer to the package elements array 853193267Sjkim * Type1 - Object type for first group 854193267Sjkim * Count1 - Count for first group 855193267Sjkim * Type2 - Object type for second group 856193267Sjkim * Count2 - Count for second group 857193267Sjkim * StartIndex - Start of the first group of elements 858193267Sjkim * 859193267Sjkim * RETURN: Status 860193267Sjkim * 861193267Sjkim * DESCRIPTION: Check that all elements of a package are of the correct object 862193267Sjkim * type. Supports up to two groups of different object types. 863193267Sjkim * 864193267Sjkim ******************************************************************************/ 865193267Sjkim 866193267Sjkimstatic ACPI_STATUS 867193267SjkimAcpiNsCheckPackageElements ( 868193267Sjkim char *Pathname, 869193267Sjkim ACPI_OPERAND_OBJECT **Elements, 870193267Sjkim UINT8 Type1, 871193267Sjkim UINT32 Count1, 872193267Sjkim UINT8 Type2, 873193267Sjkim UINT32 Count2, 874193267Sjkim UINT32 StartIndex) 875193267Sjkim{ 876193267Sjkim ACPI_OPERAND_OBJECT **ThisElement = Elements; 877193267Sjkim ACPI_STATUS Status; 878193267Sjkim UINT32 i; 879193267Sjkim 880193267Sjkim 881193267Sjkim /* 882193267Sjkim * Up to two groups of package elements are supported by the data 883193267Sjkim * structure. All elements in each group must be of the same type. 884193267Sjkim * The second group can have a count of zero. 885193267Sjkim */ 886193267Sjkim for (i = 0; i < Count1; i++) 887193267Sjkim { 888193267Sjkim Status = AcpiNsCheckObjectType (Pathname, ThisElement, 889193267Sjkim Type1, i + StartIndex); 890193267Sjkim if (ACPI_FAILURE (Status)) 891193267Sjkim { 892193267Sjkim return (Status); 893193267Sjkim } 894193267Sjkim ThisElement++; 895193267Sjkim } 896193267Sjkim 897193267Sjkim for (i = 0; i < Count2; i++) 898193267Sjkim { 899193267Sjkim Status = AcpiNsCheckObjectType (Pathname, ThisElement, 900193267Sjkim Type2, (i + Count1 + StartIndex)); 901193267Sjkim if (ACPI_FAILURE (Status)) 902193267Sjkim { 903193267Sjkim return (Status); 904193267Sjkim } 905193267Sjkim ThisElement++; 906193267Sjkim } 907193267Sjkim 908193267Sjkim return (AE_OK); 909193267Sjkim} 910193267Sjkim 911193267Sjkim 912193267Sjkim/******************************************************************************* 913193267Sjkim * 914193267Sjkim * FUNCTION: AcpiNsCheckObjectType 915193267Sjkim * 916193267Sjkim * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 917193267Sjkim * ReturnObjectPtr - Pointer to the object returned from the 918193267Sjkim * evaluation of a method or object 919193267Sjkim * ExpectedBtypes - Bitmap of expected return type(s) 920193267Sjkim * PackageIndex - Index of object within parent package (if 921193267Sjkim * applicable - ACPI_NOT_PACKAGE otherwise) 922193267Sjkim * 923193267Sjkim * RETURN: Status 924193267Sjkim * 925193267Sjkim * DESCRIPTION: Check the type of the return object against the expected object 926193267Sjkim * type(s). Use of Btype allows multiple expected object types. 927193267Sjkim * 928193267Sjkim ******************************************************************************/ 929193267Sjkim 930193267Sjkimstatic ACPI_STATUS 931193267SjkimAcpiNsCheckObjectType ( 932193267Sjkim char *Pathname, 933193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr, 934193267Sjkim UINT32 ExpectedBtypes, 935193267Sjkim UINT32 PackageIndex) 936193267Sjkim{ 937193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 938193267Sjkim ACPI_STATUS Status = AE_OK; 939193267Sjkim UINT32 ReturnBtype; 940193267Sjkim char TypeBuffer[48]; /* Room for 5 types */ 941193267Sjkim UINT32 ThisRtype; 942193267Sjkim UINT32 i; 943193267Sjkim UINT32 j; 944193267Sjkim 945193267Sjkim 946193267Sjkim /* 947193267Sjkim * If we get a NULL ReturnObject here, it is a NULL package element, 948193267Sjkim * and this is always an error. 949193267Sjkim */ 950193267Sjkim if (!ReturnObject) 951193267Sjkim { 952193267Sjkim goto TypeErrorExit; 953193267Sjkim } 954193267Sjkim 955193267Sjkim /* A Namespace node should not get here, but make sure */ 956193267Sjkim 957193267Sjkim if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) 958193267Sjkim { 959193267Sjkim ACPI_WARNING ((AE_INFO, 960193267Sjkim "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", 961193267Sjkim Pathname, ReturnObject->Node.Name.Ascii, 962193267Sjkim AcpiUtGetTypeName (ReturnObject->Node.Type))); 963193267Sjkim return (AE_AML_OPERAND_TYPE); 964193267Sjkim } 965193267Sjkim 966193267Sjkim /* 967193267Sjkim * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. 968193267Sjkim * The bitmapped type allows multiple possible return types. 969193267Sjkim * 970193267Sjkim * Note, the cases below must handle all of the possible types returned 971193267Sjkim * from all of the predefined names (including elements of returned 972193267Sjkim * packages) 973193267Sjkim */ 974193267Sjkim switch (ReturnObject->Common.Type) 975193267Sjkim { 976193267Sjkim case ACPI_TYPE_INTEGER: 977193267Sjkim ReturnBtype = ACPI_RTYPE_INTEGER; 978193267Sjkim break; 979193267Sjkim 980193267Sjkim case ACPI_TYPE_BUFFER: 981193267Sjkim ReturnBtype = ACPI_RTYPE_BUFFER; 982193267Sjkim break; 983193267Sjkim 984193267Sjkim case ACPI_TYPE_STRING: 985193267Sjkim ReturnBtype = ACPI_RTYPE_STRING; 986193267Sjkim break; 987193267Sjkim 988193267Sjkim case ACPI_TYPE_PACKAGE: 989193267Sjkim ReturnBtype = ACPI_RTYPE_PACKAGE; 990193267Sjkim break; 991193267Sjkim 992193267Sjkim case ACPI_TYPE_LOCAL_REFERENCE: 993193267Sjkim ReturnBtype = ACPI_RTYPE_REFERENCE; 994193267Sjkim break; 995193267Sjkim 996193267Sjkim default: 997193267Sjkim /* Not one of the supported objects, must be incorrect */ 998193267Sjkim 999193267Sjkim goto TypeErrorExit; 1000193267Sjkim } 1001193267Sjkim 1002193267Sjkim /* Is the object one of the expected types? */ 1003193267Sjkim 1004193267Sjkim if (!(ReturnBtype & ExpectedBtypes)) 1005193267Sjkim { 1006193267Sjkim /* Type mismatch -- attempt repair of the returned object */ 1007193267Sjkim 1008193267Sjkim Status = AcpiNsRepairObject (ExpectedBtypes, PackageIndex, 1009193267Sjkim ReturnObjectPtr); 1010193267Sjkim if (ACPI_SUCCESS (Status)) 1011193267Sjkim { 1012193267Sjkim return (Status); 1013193267Sjkim } 1014193267Sjkim goto TypeErrorExit; 1015193267Sjkim } 1016193267Sjkim 1017193267Sjkim /* For reference objects, check that the reference type is correct */ 1018193267Sjkim 1019193267Sjkim if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) 1020193267Sjkim { 1021193267Sjkim Status = AcpiNsCheckReference (Pathname, ReturnObject); 1022193267Sjkim } 1023193267Sjkim 1024193267Sjkim return (Status); 1025193267Sjkim 1026193267Sjkim 1027193267SjkimTypeErrorExit: 1028193267Sjkim 1029193267Sjkim /* Create a string with all expected types for this predefined object */ 1030193267Sjkim 1031193267Sjkim j = 1; 1032193267Sjkim TypeBuffer[0] = 0; 1033193267Sjkim ThisRtype = ACPI_RTYPE_INTEGER; 1034193267Sjkim 1035193267Sjkim for (i = 0; i < ACPI_NUM_RTYPES; i++) 1036193267Sjkim { 1037193267Sjkim /* If one of the expected types, concatenate the name of this type */ 1038193267Sjkim 1039193267Sjkim if (ExpectedBtypes & ThisRtype) 1040193267Sjkim { 1041193267Sjkim ACPI_STRCAT (TypeBuffer, &AcpiRtypeNames[i][j]); 1042193267Sjkim j = 0; /* Use name separator from now on */ 1043193267Sjkim } 1044193267Sjkim ThisRtype <<= 1; /* Next Rtype */ 1045193267Sjkim } 1046193267Sjkim 1047193267Sjkim if (PackageIndex == ACPI_NOT_PACKAGE) 1048193267Sjkim { 1049193267Sjkim ACPI_WARNING ((AE_INFO, 1050193267Sjkim "%s: Return type mismatch - found %s, expected %s", 1051193267Sjkim Pathname, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 1052193267Sjkim } 1053193267Sjkim else 1054193267Sjkim { 1055193267Sjkim ACPI_WARNING ((AE_INFO, 1056193267Sjkim "%s: Return Package type mismatch at index %u - " 1057193267Sjkim "found %s, expected %s", Pathname, PackageIndex, 1058193267Sjkim AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 1059193267Sjkim } 1060193267Sjkim 1061193267Sjkim return (AE_AML_OPERAND_TYPE); 1062193267Sjkim} 1063193267Sjkim 1064193267Sjkim 1065193267Sjkim/******************************************************************************* 1066193267Sjkim * 1067193267Sjkim * FUNCTION: AcpiNsCheckReference 1068193267Sjkim * 1069193267Sjkim * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 1070193267Sjkim * ReturnObject - Object returned from the evaluation of a 1071193267Sjkim * method or object 1072193267Sjkim * 1073193267Sjkim * RETURN: Status 1074193267Sjkim * 1075193267Sjkim * DESCRIPTION: Check a returned reference object for the correct reference 1076193267Sjkim * type. The only reference type that can be returned from a 1077193267Sjkim * predefined method is a named reference. All others are invalid. 1078193267Sjkim * 1079193267Sjkim ******************************************************************************/ 1080193267Sjkim 1081193267Sjkimstatic ACPI_STATUS 1082193267SjkimAcpiNsCheckReference ( 1083193267Sjkim char *Pathname, 1084193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject) 1085193267Sjkim{ 1086193267Sjkim 1087193267Sjkim /* 1088193267Sjkim * Check the reference object for the correct reference type (opcode). 1089193267Sjkim * The only type of reference that can be converted to an ACPI_OBJECT is 1090193267Sjkim * a reference to a named object (reference class: NAME) 1091193267Sjkim */ 1092193267Sjkim if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME) 1093193267Sjkim { 1094193267Sjkim return (AE_OK); 1095193267Sjkim } 1096193267Sjkim 1097193267Sjkim ACPI_WARNING ((AE_INFO, 1098193267Sjkim "%s: Return type mismatch - " 1099193267Sjkim "unexpected reference object type [%s] %2.2X", 1100193267Sjkim Pathname, AcpiUtGetReferenceName (ReturnObject), 1101193267Sjkim ReturnObject->Reference.Class)); 1102193267Sjkim 1103193267Sjkim return (AE_AML_OPERAND_TYPE); 1104193267Sjkim} 1105193267Sjkim 1106193267Sjkim 1107193267Sjkim/******************************************************************************* 1108193267Sjkim * 1109193267Sjkim * FUNCTION: AcpiNsRepairObject 1110193267Sjkim * 1111193267Sjkim * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 1112193267Sjkim * PackageIndex - Used to determine if target is in a package 1113193267Sjkim * ReturnObjectPtr - Pointer to the object returned from the 1114193267Sjkim * evaluation of a method or object 1115193267Sjkim * 1116193267Sjkim * RETURN: Status. AE_OK if repair was successful. 1117193267Sjkim * 1118193267Sjkim * DESCRIPTION: Attempt to repair/convert a return object of a type that was 1119193267Sjkim * not expected. 1120193267Sjkim * 1121193267Sjkim ******************************************************************************/ 1122193267Sjkim 1123193267Sjkimstatic ACPI_STATUS 1124193267SjkimAcpiNsRepairObject ( 1125193267Sjkim UINT32 ExpectedBtypes, 1126193267Sjkim UINT32 PackageIndex, 1127193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 1128193267Sjkim{ 1129193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 1130193267Sjkim ACPI_OPERAND_OBJECT *NewObject; 1131193267Sjkim ACPI_SIZE Length; 1132193267Sjkim 1133193267Sjkim 1134193267Sjkim switch (ReturnObject->Common.Type) 1135193267Sjkim { 1136193267Sjkim case ACPI_TYPE_BUFFER: 1137193267Sjkim 1138193267Sjkim if (!(ExpectedBtypes & ACPI_RTYPE_STRING)) 1139193267Sjkim { 1140193267Sjkim return (AE_AML_OPERAND_TYPE); 1141193267Sjkim } 1142193267Sjkim 1143193267Sjkim /* 1144193267Sjkim * Have a Buffer, expected a String, convert. Use a ToString 1145193267Sjkim * conversion, no transform performed on the buffer data. The best 1146193267Sjkim * example of this is the _BIF method, where the string data from 1147193267Sjkim * the battery is often (incorrectly) returned as buffer object(s). 1148193267Sjkim */ 1149193267Sjkim Length = 0; 1150193267Sjkim while ((Length < ReturnObject->Buffer.Length) && 1151193267Sjkim (ReturnObject->Buffer.Pointer[Length])) 1152193267Sjkim { 1153193267Sjkim Length++; 1154193267Sjkim } 1155193267Sjkim 1156193267Sjkim /* Allocate a new string object */ 1157193267Sjkim 1158193267Sjkim NewObject = AcpiUtCreateStringObject (Length); 1159193267Sjkim if (!NewObject) 1160193267Sjkim { 1161193267Sjkim return (AE_NO_MEMORY); 1162193267Sjkim } 1163193267Sjkim 1164193267Sjkim /* 1165193267Sjkim * Copy the raw buffer data with no transform. String is already NULL 1166193267Sjkim * terminated at Length+1. 1167193267Sjkim */ 1168193267Sjkim ACPI_MEMCPY (NewObject->String.Pointer, 1169193267Sjkim ReturnObject->Buffer.Pointer, Length); 1170193267Sjkim 1171193267Sjkim /* Install the new return object */ 1172193267Sjkim 1173193267Sjkim AcpiUtRemoveReference (ReturnObject); 1174193267Sjkim *ReturnObjectPtr = NewObject; 1175193267Sjkim 1176193267Sjkim /* 1177193267Sjkim * If the object is a package element, we need to: 1178193267Sjkim * 1. Decrement the reference count of the orignal object, it was 1179193267Sjkim * incremented when building the package 1180193267Sjkim * 2. Increment the reference count of the new object, it will be 1181193267Sjkim * decremented when releasing the package 1182193267Sjkim */ 1183193267Sjkim if (PackageIndex != ACPI_NOT_PACKAGE) 1184193267Sjkim { 1185193267Sjkim AcpiUtRemoveReference (ReturnObject); 1186193267Sjkim AcpiUtAddReference (NewObject); 1187193267Sjkim } 1188193267Sjkim return (AE_OK); 1189193267Sjkim 1190193267Sjkim default: 1191193267Sjkim break; 1192193267Sjkim } 1193193267Sjkim 1194193267Sjkim return (AE_AML_OPERAND_TYPE); 1195193267Sjkim} 1196193267Sjkim 1197