1193267Sjkim/****************************************************************************** 2193267Sjkim * 3193267Sjkim * Module Name: nspredef - Validation of ACPI predefined methods and objects 4193267Sjkim * 5193267Sjkim *****************************************************************************/ 6193267Sjkim 7217365Sjkim/* 8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp. 9193267Sjkim * All rights reserved. 10193267Sjkim * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25193267Sjkim * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29193267Sjkim * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43193267Sjkim 44197104Sjkim#define ACPI_CREATE_PREDEFINED_TABLE 45193267Sjkim 46193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 47193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 49193341Sjkim#include <contrib/dev/acpica/include/acpredef.h> 50193267Sjkim 51193267Sjkim 52193267Sjkim#define _COMPONENT ACPI_NAMESPACE 53193267Sjkim ACPI_MODULE_NAME ("nspredef") 54193267Sjkim 55193267Sjkim 56193267Sjkim/******************************************************************************* 57193267Sjkim * 58193267Sjkim * This module validates predefined ACPI objects that appear in the namespace, 59193267Sjkim * at the time they are evaluated (via AcpiEvaluateObject). The purpose of this 60193267Sjkim * validation is to detect problems with BIOS-exposed predefined ACPI objects 61193267Sjkim * before the results are returned to the ACPI-related drivers. 62193267Sjkim * 63193267Sjkim * There are several areas that are validated: 64193267Sjkim * 65193267Sjkim * 1) The number of input arguments as defined by the method/object in the 66193267Sjkim * ASL is validated against the ACPI specification. 67193267Sjkim * 2) The type of the return object (if any) is validated against the ACPI 68193267Sjkim * specification. 69193267Sjkim * 3) For returned package objects, the count of package elements is 70193267Sjkim * validated, as well as the type of each package element. Nested 71193267Sjkim * packages are supported. 72193267Sjkim * 73193267Sjkim * For any problems found, a warning message is issued. 74193267Sjkim * 75193267Sjkim ******************************************************************************/ 76193267Sjkim 77197104Sjkim 78193267Sjkim/* Local prototypes */ 79193267Sjkim 80193267Sjkimstatic ACPI_STATUS 81193267SjkimAcpiNsCheckPackage ( 82197104Sjkim ACPI_PREDEFINED_DATA *Data, 83197104Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 84193267Sjkim 85193267Sjkimstatic ACPI_STATUS 86197104SjkimAcpiNsCheckPackageList ( 87197104Sjkim ACPI_PREDEFINED_DATA *Data, 88197104Sjkim const ACPI_PREDEFINED_INFO *Package, 89197104Sjkim ACPI_OPERAND_OBJECT **Elements, 90197104Sjkim UINT32 Count); 91197104Sjkim 92197104Sjkimstatic ACPI_STATUS 93193267SjkimAcpiNsCheckPackageElements ( 94197104Sjkim ACPI_PREDEFINED_DATA *Data, 95193267Sjkim ACPI_OPERAND_OBJECT **Elements, 96193267Sjkim UINT8 Type1, 97193267Sjkim UINT32 Count1, 98193267Sjkim UINT8 Type2, 99193267Sjkim UINT32 Count2, 100193267Sjkim UINT32 StartIndex); 101193267Sjkim 102193267Sjkimstatic ACPI_STATUS 103193267SjkimAcpiNsCheckObjectType ( 104197104Sjkim ACPI_PREDEFINED_DATA *Data, 105193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr, 106193267Sjkim UINT32 ExpectedBtypes, 107193267Sjkim UINT32 PackageIndex); 108193267Sjkim 109193267Sjkimstatic ACPI_STATUS 110193267SjkimAcpiNsCheckReference ( 111197104Sjkim ACPI_PREDEFINED_DATA *Data, 112193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject); 113193267Sjkim 114197104Sjkimstatic void 115197104SjkimAcpiNsGetExpectedTypes ( 116197104Sjkim char *Buffer, 117197104Sjkim UINT32 ExpectedBtypes); 118193267Sjkim 119193267Sjkim/* 120193267Sjkim * Names for the types that can be returned by the predefined objects. 121193267Sjkim * Used for warning messages. Must be in the same order as the ACPI_RTYPEs 122193267Sjkim */ 123193267Sjkimstatic const char *AcpiRtypeNames[] = 124193267Sjkim{ 125193267Sjkim "/Integer", 126193267Sjkim "/String", 127193267Sjkim "/Buffer", 128193267Sjkim "/Package", 129193267Sjkim "/Reference", 130193267Sjkim}; 131193267Sjkim 132193267Sjkim 133193267Sjkim/******************************************************************************* 134193267Sjkim * 135193267Sjkim * FUNCTION: AcpiNsCheckPredefinedNames 136193267Sjkim * 137193267Sjkim * PARAMETERS: Node - Namespace node for the method/object 138197104Sjkim * UserParamCount - Number of parameters actually passed 139197104Sjkim * ReturnStatus - Status from the object evaluation 140193267Sjkim * ReturnObjectPtr - Pointer to the object returned from the 141193267Sjkim * evaluation of a method or object 142193267Sjkim * 143193267Sjkim * RETURN: Status 144193267Sjkim * 145193267Sjkim * DESCRIPTION: Check an ACPI name for a match in the predefined name list. 146193267Sjkim * 147193267Sjkim ******************************************************************************/ 148193267Sjkim 149193267SjkimACPI_STATUS 150193267SjkimAcpiNsCheckPredefinedNames ( 151193267Sjkim ACPI_NAMESPACE_NODE *Node, 152193267Sjkim UINT32 UserParamCount, 153193267Sjkim ACPI_STATUS ReturnStatus, 154193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 155193267Sjkim{ 156193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 157193267Sjkim ACPI_STATUS Status = AE_OK; 158193267Sjkim const ACPI_PREDEFINED_INFO *Predefined; 159193267Sjkim char *Pathname; 160197104Sjkim ACPI_PREDEFINED_DATA *Data; 161193267Sjkim 162193267Sjkim 163193267Sjkim /* Match the name for this method/object against the predefined list */ 164193267Sjkim 165193267Sjkim Predefined = AcpiNsCheckForPredefinedName (Node); 166193267Sjkim 167197104Sjkim /* Get the full pathname to the object, for use in warning messages */ 168193267Sjkim 169193267Sjkim Pathname = AcpiNsGetExternalPathname (Node); 170193267Sjkim if (!Pathname) 171193267Sjkim { 172193267Sjkim return (AE_OK); /* Could not get pathname, ignore */ 173193267Sjkim } 174193267Sjkim 175193267Sjkim /* 176193267Sjkim * Check that the parameter count for this method matches the ASL 177193267Sjkim * definition. For predefined names, ensure that both the caller and 178193267Sjkim * the method itself are in accordance with the ACPI specification. 179193267Sjkim */ 180193267Sjkim AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined); 181193267Sjkim 182193267Sjkim /* If not a predefined name, we cannot validate the return object */ 183193267Sjkim 184193267Sjkim if (!Predefined) 185193267Sjkim { 186197104Sjkim goto Cleanup; 187193267Sjkim } 188193267Sjkim 189193267Sjkim /* 190197104Sjkim * If the method failed or did not actually return an object, we cannot 191197104Sjkim * validate the return object 192193267Sjkim */ 193197104Sjkim if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE)) 194193267Sjkim { 195197104Sjkim goto Cleanup; 196193267Sjkim } 197193267Sjkim 198193267Sjkim /* 199193267Sjkim * If there is no return value, check if we require a return value for 200193267Sjkim * this predefined name. Either one return value is expected, or none, 201193267Sjkim * for both methods and other objects. 202193267Sjkim * 203193267Sjkim * Exit now if there is no return object. Warning if one was expected. 204193267Sjkim */ 205193267Sjkim if (!ReturnObject) 206193267Sjkim { 207193267Sjkim if ((Predefined->Info.ExpectedBtypes) && 208193267Sjkim (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE))) 209193267Sjkim { 210197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 211197104Sjkim "Missing expected return value")); 212193267Sjkim 213193267Sjkim Status = AE_AML_NO_RETURN_VALUE; 214193267Sjkim } 215197104Sjkim goto Cleanup; 216193267Sjkim } 217193267Sjkim 218193267Sjkim /* 219197104Sjkim * 1) We have a return value, but if one wasn't expected, just exit, this is 220197104Sjkim * not a problem. For example, if the "Implicit Return" feature is 221197104Sjkim * enabled, methods will always return a value. 222193267Sjkim * 223197104Sjkim * 2) If the return value can be of any type, then we cannot perform any 224197104Sjkim * validation, exit. 225193267Sjkim */ 226197104Sjkim if ((!Predefined->Info.ExpectedBtypes) || 227197104Sjkim (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL)) 228193267Sjkim { 229197104Sjkim goto Cleanup; 230193267Sjkim } 231193267Sjkim 232197104Sjkim /* Create the parameter data block for object validation */ 233197104Sjkim 234197104Sjkim Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA)); 235197104Sjkim if (!Data) 236197104Sjkim { 237197104Sjkim goto Cleanup; 238197104Sjkim } 239197104Sjkim Data->Predefined = Predefined; 240197104Sjkim Data->NodeFlags = Node->Flags; 241197104Sjkim Data->Pathname = Pathname; 242197104Sjkim 243193267Sjkim /* 244200553Sjkim * Check that the type of the main return object is what is expected 245200553Sjkim * for this predefined name 246193267Sjkim */ 247197104Sjkim Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr, 248197104Sjkim Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT); 249193267Sjkim if (ACPI_FAILURE (Status)) 250193267Sjkim { 251200553Sjkim goto Exit; 252193267Sjkim } 253193267Sjkim 254200553Sjkim /* 255200553Sjkim * For returned Package objects, check the type of all sub-objects. 256200553Sjkim * Note: Package may have been newly created by call above. 257200553Sjkim */ 258200553Sjkim if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE) 259193267Sjkim { 260202771Sjkim Data->ParentPackage = *ReturnObjectPtr; 261197104Sjkim Status = AcpiNsCheckPackage (Data, ReturnObjectPtr); 262200553Sjkim if (ACPI_FAILURE (Status)) 263200553Sjkim { 264200553Sjkim goto Exit; 265200553Sjkim } 266193267Sjkim } 267193267Sjkim 268199337Sjkim /* 269200553Sjkim * The return object was OK, or it was successfully repaired above. 270200553Sjkim * Now make some additional checks such as verifying that package 271200553Sjkim * objects are sorted correctly (if required) or buffer objects have 272200553Sjkim * the correct data width (bytes vs. dwords). These repairs are 273200553Sjkim * performed on a per-name basis, i.e., the code is specific to 274200553Sjkim * particular predefined names. 275199337Sjkim */ 276199337Sjkim Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr); 277197104Sjkim 278200553SjkimExit: 279197104Sjkim /* 280197104Sjkim * If the object validation failed or if we successfully repaired one 281197104Sjkim * or more objects, mark the parent node to suppress further warning 282197104Sjkim * messages during the next evaluation of the same method/object. 283197104Sjkim */ 284197104Sjkim if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED)) 285197104Sjkim { 286197104Sjkim Node->Flags |= ANOBJ_EVALUATED; 287197104Sjkim } 288197104Sjkim ACPI_FREE (Data); 289197104Sjkim 290197104SjkimCleanup: 291193267Sjkim ACPI_FREE (Pathname); 292193267Sjkim return (Status); 293193267Sjkim} 294193267Sjkim 295193267Sjkim 296193267Sjkim/******************************************************************************* 297193267Sjkim * 298193267Sjkim * FUNCTION: AcpiNsCheckParameterCount 299193267Sjkim * 300193267Sjkim * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 301193267Sjkim * Node - Namespace node for the method/object 302193267Sjkim * UserParamCount - Number of args passed in by the caller 303193267Sjkim * Predefined - Pointer to entry in predefined name table 304193267Sjkim * 305193267Sjkim * RETURN: None 306193267Sjkim * 307193267Sjkim * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a 308193267Sjkim * predefined name is what is expected (i.e., what is defined in 309193267Sjkim * the ACPI specification for this predefined name.) 310193267Sjkim * 311193267Sjkim ******************************************************************************/ 312193267Sjkim 313193267Sjkimvoid 314193267SjkimAcpiNsCheckParameterCount ( 315193267Sjkim char *Pathname, 316193267Sjkim ACPI_NAMESPACE_NODE *Node, 317193267Sjkim UINT32 UserParamCount, 318193267Sjkim const ACPI_PREDEFINED_INFO *Predefined) 319193267Sjkim{ 320193267Sjkim UINT32 ParamCount; 321193267Sjkim UINT32 RequiredParamsCurrent; 322193267Sjkim UINT32 RequiredParamsOld; 323193267Sjkim 324193267Sjkim 325193267Sjkim /* Methods have 0-7 parameters. All other types have zero. */ 326193267Sjkim 327193267Sjkim ParamCount = 0; 328193267Sjkim if (Node->Type == ACPI_TYPE_METHOD) 329193267Sjkim { 330193267Sjkim ParamCount = Node->Object->Method.ParamCount; 331193267Sjkim } 332193267Sjkim 333193267Sjkim if (!Predefined) 334193267Sjkim { 335193267Sjkim /* 336197104Sjkim * Check the parameter count for non-predefined methods/objects. 337197104Sjkim * 338193267Sjkim * Warning if too few or too many arguments have been passed by the 339193267Sjkim * caller. An incorrect number of arguments may not cause the method 340193267Sjkim * to fail. However, the method will fail if there are too few 341193267Sjkim * arguments and the method attempts to use one of the missing ones. 342193267Sjkim */ 343193267Sjkim if (UserParamCount < ParamCount) 344193267Sjkim { 345197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 346197104Sjkim "Insufficient arguments - needs %u, found %u", 347197104Sjkim ParamCount, UserParamCount)); 348193267Sjkim } 349193267Sjkim else if (UserParamCount > ParamCount) 350193267Sjkim { 351197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 352197104Sjkim "Excess arguments - needs %u, found %u", 353197104Sjkim ParamCount, UserParamCount)); 354193267Sjkim } 355193267Sjkim return; 356193267Sjkim } 357193267Sjkim 358197104Sjkim /* 359197104Sjkim * Validate the user-supplied parameter count. 360197104Sjkim * Allow two different legal argument counts (_SCP, etc.) 361197104Sjkim */ 362193267Sjkim RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F; 363193267Sjkim RequiredParamsOld = Predefined->Info.ParamCount >> 4; 364193267Sjkim 365193267Sjkim if (UserParamCount != ACPI_UINT32_MAX) 366193267Sjkim { 367193267Sjkim if ((UserParamCount != RequiredParamsCurrent) && 368193267Sjkim (UserParamCount != RequiredParamsOld)) 369193267Sjkim { 370197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 371197104Sjkim "Parameter count mismatch - " 372197104Sjkim "caller passed %u, ACPI requires %u", 373197104Sjkim UserParamCount, RequiredParamsCurrent)); 374193267Sjkim } 375193267Sjkim } 376193267Sjkim 377193267Sjkim /* 378193267Sjkim * Check that the ASL-defined parameter count is what is expected for 379197104Sjkim * this predefined name (parameter count as defined by the ACPI 380197104Sjkim * specification) 381193267Sjkim */ 382193267Sjkim if ((ParamCount != RequiredParamsCurrent) && 383193267Sjkim (ParamCount != RequiredParamsOld)) 384193267Sjkim { 385197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags, 386197104Sjkim "Parameter count mismatch - ASL declared %u, ACPI requires %u", 387197104Sjkim ParamCount, RequiredParamsCurrent)); 388193267Sjkim } 389193267Sjkim} 390193267Sjkim 391193267Sjkim 392193267Sjkim/******************************************************************************* 393193267Sjkim * 394193267Sjkim * FUNCTION: AcpiNsCheckForPredefinedName 395193267Sjkim * 396193267Sjkim * PARAMETERS: Node - Namespace node for the method/object 397193267Sjkim * 398193267Sjkim * RETURN: Pointer to entry in predefined table. NULL indicates not found. 399193267Sjkim * 400193267Sjkim * DESCRIPTION: Check an object name against the predefined object list. 401193267Sjkim * 402193267Sjkim ******************************************************************************/ 403193267Sjkim 404193267Sjkimconst ACPI_PREDEFINED_INFO * 405193267SjkimAcpiNsCheckForPredefinedName ( 406193267Sjkim ACPI_NAMESPACE_NODE *Node) 407193267Sjkim{ 408193267Sjkim const ACPI_PREDEFINED_INFO *ThisName; 409193267Sjkim 410193267Sjkim 411193267Sjkim /* Quick check for a predefined name, first character must be underscore */ 412193267Sjkim 413193267Sjkim if (Node->Name.Ascii[0] != '_') 414193267Sjkim { 415193267Sjkim return (NULL); 416193267Sjkim } 417193267Sjkim 418193267Sjkim /* Search info table for a predefined method/object name */ 419193267Sjkim 420193267Sjkim ThisName = PredefinedNames; 421193267Sjkim while (ThisName->Info.Name[0]) 422193267Sjkim { 423193267Sjkim if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name)) 424193267Sjkim { 425193267Sjkim return (ThisName); 426193267Sjkim } 427193267Sjkim 428193267Sjkim /* 429193267Sjkim * Skip next entry in the table if this name returns a Package 430193267Sjkim * (next entry contains the package info) 431193267Sjkim */ 432193267Sjkim if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) 433193267Sjkim { 434193267Sjkim ThisName++; 435193267Sjkim } 436193267Sjkim 437193267Sjkim ThisName++; 438193267Sjkim } 439193267Sjkim 440197104Sjkim return (NULL); /* Not found */ 441193267Sjkim} 442193267Sjkim 443193267Sjkim 444193267Sjkim/******************************************************************************* 445193267Sjkim * 446193267Sjkim * FUNCTION: AcpiNsCheckPackage 447193267Sjkim * 448197104Sjkim * PARAMETERS: Data - Pointer to validation data structure 449193267Sjkim * ReturnObjectPtr - Pointer to the object returned from the 450193267Sjkim * evaluation of a method or object 451193267Sjkim * 452193267Sjkim * RETURN: Status 453193267Sjkim * 454193267Sjkim * DESCRIPTION: Check a returned package object for the correct count and 455193267Sjkim * correct type of all sub-objects. 456193267Sjkim * 457193267Sjkim ******************************************************************************/ 458193267Sjkim 459193267Sjkimstatic ACPI_STATUS 460193267SjkimAcpiNsCheckPackage ( 461197104Sjkim ACPI_PREDEFINED_DATA *Data, 462197104Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 463193267Sjkim{ 464193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 465193267Sjkim const ACPI_PREDEFINED_INFO *Package; 466193267Sjkim ACPI_OPERAND_OBJECT **Elements; 467197104Sjkim ACPI_STATUS Status = AE_OK; 468193267Sjkim UINT32 ExpectedCount; 469193267Sjkim UINT32 Count; 470193267Sjkim UINT32 i; 471193267Sjkim 472193267Sjkim 473193267Sjkim ACPI_FUNCTION_NAME (NsCheckPackage); 474193267Sjkim 475193267Sjkim 476193267Sjkim /* The package info for this name is in the next table entry */ 477193267Sjkim 478197104Sjkim Package = Data->Predefined + 1; 479193267Sjkim 480193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 481193267Sjkim "%s Validating return Package of Type %X, Count %X\n", 482197104Sjkim Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count)); 483193267Sjkim 484200553Sjkim /* 485200553Sjkim * For variable-length Packages, we can safely remove all embedded 486200553Sjkim * and trailing NULL package elements 487200553Sjkim */ 488200553Sjkim AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject); 489200553Sjkim 490193267Sjkim /* Extract package count and elements array */ 491193267Sjkim 492193267Sjkim Elements = ReturnObject->Package.Elements; 493193267Sjkim Count = ReturnObject->Package.Count; 494193267Sjkim 495193267Sjkim /* The package must have at least one element, else invalid */ 496193267Sjkim 497193267Sjkim if (!Count) 498193267Sjkim { 499197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 500197104Sjkim "Return Package has no elements (empty)")); 501193267Sjkim 502193267Sjkim return (AE_AML_OPERAND_VALUE); 503193267Sjkim } 504193267Sjkim 505193267Sjkim /* 506193267Sjkim * Decode the type of the expected package contents 507193267Sjkim * 508193267Sjkim * PTYPE1 packages contain no subpackages 509193267Sjkim * PTYPE2 packages contain sub-packages 510193267Sjkim */ 511193267Sjkim switch (Package->RetInfo.Type) 512193267Sjkim { 513193267Sjkim case ACPI_PTYPE1_FIXED: 514193267Sjkim 515193267Sjkim /* 516193267Sjkim * The package count is fixed and there are no sub-packages 517193267Sjkim * 518193267Sjkim * If package is too small, exit. 519193267Sjkim * If package is larger than expected, issue warning but continue 520193267Sjkim */ 521193267Sjkim ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 522193267Sjkim if (Count < ExpectedCount) 523193267Sjkim { 524193267Sjkim goto PackageTooSmall; 525193267Sjkim } 526193267Sjkim else if (Count > ExpectedCount) 527193267Sjkim { 528200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 529200553Sjkim "%s: Return Package is larger than needed - " 530200553Sjkim "found %u, expected %u\n", 531200553Sjkim Data->Pathname, Count, ExpectedCount)); 532193267Sjkim } 533193267Sjkim 534193267Sjkim /* Validate all elements of the returned package */ 535193267Sjkim 536197104Sjkim Status = AcpiNsCheckPackageElements (Data, Elements, 537193267Sjkim Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 538193267Sjkim Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0); 539193267Sjkim break; 540193267Sjkim 541193267Sjkim 542193267Sjkim case ACPI_PTYPE1_VAR: 543193267Sjkim 544193267Sjkim /* 545193267Sjkim * The package count is variable, there are no sub-packages, and all 546193267Sjkim * elements must be of the same type 547193267Sjkim */ 548193267Sjkim for (i = 0; i < Count; i++) 549193267Sjkim { 550197104Sjkim Status = AcpiNsCheckObjectType (Data, Elements, 551193267Sjkim Package->RetInfo.ObjectType1, i); 552193267Sjkim if (ACPI_FAILURE (Status)) 553193267Sjkim { 554193267Sjkim return (Status); 555193267Sjkim } 556193267Sjkim Elements++; 557193267Sjkim } 558193267Sjkim break; 559193267Sjkim 560193267Sjkim 561193267Sjkim case ACPI_PTYPE1_OPTION: 562193267Sjkim 563193267Sjkim /* 564193267Sjkim * The package count is variable, there are no sub-packages. There are 565193267Sjkim * a fixed number of required elements, and a variable number of 566193267Sjkim * optional elements. 567193267Sjkim * 568193267Sjkim * Check if package is at least as large as the minimum required 569193267Sjkim */ 570193267Sjkim ExpectedCount = Package->RetInfo3.Count; 571193267Sjkim if (Count < ExpectedCount) 572193267Sjkim { 573193267Sjkim goto PackageTooSmall; 574193267Sjkim } 575193267Sjkim 576193267Sjkim /* Variable number of sub-objects */ 577193267Sjkim 578193267Sjkim for (i = 0; i < Count; i++) 579193267Sjkim { 580193267Sjkim if (i < Package->RetInfo3.Count) 581193267Sjkim { 582193267Sjkim /* These are the required package elements (0, 1, or 2) */ 583193267Sjkim 584197104Sjkim Status = AcpiNsCheckObjectType (Data, Elements, 585193267Sjkim Package->RetInfo3.ObjectType[i], i); 586193267Sjkim if (ACPI_FAILURE (Status)) 587193267Sjkim { 588193267Sjkim return (Status); 589193267Sjkim } 590193267Sjkim } 591193267Sjkim else 592193267Sjkim { 593193267Sjkim /* These are the optional package elements */ 594193267Sjkim 595197104Sjkim Status = AcpiNsCheckObjectType (Data, Elements, 596193267Sjkim Package->RetInfo3.TailObjectType, i); 597193267Sjkim if (ACPI_FAILURE (Status)) 598193267Sjkim { 599193267Sjkim return (Status); 600193267Sjkim } 601193267Sjkim } 602193267Sjkim Elements++; 603193267Sjkim } 604193267Sjkim break; 605193267Sjkim 606193267Sjkim 607197104Sjkim case ACPI_PTYPE2_REV_FIXED: 608197104Sjkim 609197104Sjkim /* First element is the (Integer) revision */ 610197104Sjkim 611197104Sjkim Status = AcpiNsCheckObjectType (Data, Elements, 612197104Sjkim ACPI_RTYPE_INTEGER, 0); 613197104Sjkim if (ACPI_FAILURE (Status)) 614197104Sjkim { 615197104Sjkim return (Status); 616197104Sjkim } 617197104Sjkim 618197104Sjkim Elements++; 619197104Sjkim Count--; 620197104Sjkim 621197104Sjkim /* Examine the sub-packages */ 622197104Sjkim 623197104Sjkim Status = AcpiNsCheckPackageList (Data, Package, Elements, Count); 624197104Sjkim break; 625197104Sjkim 626197104Sjkim 627193267Sjkim case ACPI_PTYPE2_PKG_COUNT: 628193267Sjkim 629193267Sjkim /* First element is the (Integer) count of sub-packages to follow */ 630193267Sjkim 631197104Sjkim Status = AcpiNsCheckObjectType (Data, Elements, 632193267Sjkim ACPI_RTYPE_INTEGER, 0); 633193267Sjkim if (ACPI_FAILURE (Status)) 634193267Sjkim { 635193267Sjkim return (Status); 636193267Sjkim } 637193267Sjkim 638193267Sjkim /* 639193267Sjkim * Count cannot be larger than the parent package length, but allow it 640193267Sjkim * to be smaller. The >= accounts for the Integer above. 641193267Sjkim */ 642193267Sjkim ExpectedCount = (UINT32) (*Elements)->Integer.Value; 643193267Sjkim if (ExpectedCount >= Count) 644193267Sjkim { 645193267Sjkim goto PackageTooSmall; 646193267Sjkim } 647193267Sjkim 648193267Sjkim Count = ExpectedCount; 649193267Sjkim Elements++; 650193267Sjkim 651197104Sjkim /* Examine the sub-packages */ 652193267Sjkim 653197104Sjkim Status = AcpiNsCheckPackageList (Data, Package, Elements, Count); 654197104Sjkim break; 655193267Sjkim 656193267Sjkim 657193267Sjkim case ACPI_PTYPE2: 658193267Sjkim case ACPI_PTYPE2_FIXED: 659193267Sjkim case ACPI_PTYPE2_MIN: 660193267Sjkim case ACPI_PTYPE2_COUNT: 661193267Sjkim 662193267Sjkim /* 663197104Sjkim * These types all return a single Package that consists of a 664197104Sjkim * variable number of sub-Packages. 665197104Sjkim * 666197104Sjkim * First, ensure that the first element is a sub-Package. If not, 667197104Sjkim * the BIOS may have incorrectly returned the object as a single 668197104Sjkim * package instead of a Package of Packages (a common error if 669197104Sjkim * there is only one entry). We may be able to repair this by 670197104Sjkim * wrapping the returned Package with a new outer Package. 671193267Sjkim */ 672199337Sjkim if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE)) 673193267Sjkim { 674197104Sjkim /* Create the new outer package and populate it */ 675193267Sjkim 676197104Sjkim Status = AcpiNsRepairPackageList (Data, ReturnObjectPtr); 677193267Sjkim if (ACPI_FAILURE (Status)) 678193267Sjkim { 679193267Sjkim return (Status); 680193267Sjkim } 681193267Sjkim 682197104Sjkim /* Update locals to point to the new package (of 1 element) */ 683193267Sjkim 684197104Sjkim ReturnObject = *ReturnObjectPtr; 685197104Sjkim Elements = ReturnObject->Package.Elements; 686197104Sjkim Count = 1; 687197104Sjkim } 688193267Sjkim 689197104Sjkim /* Examine the sub-packages */ 690193267Sjkim 691197104Sjkim Status = AcpiNsCheckPackageList (Data, Package, Elements, Count); 692197104Sjkim break; 693193267Sjkim 694193267Sjkim 695197104Sjkim default: 696193267Sjkim 697197104Sjkim /* Should not get here if predefined info table is correct */ 698193267Sjkim 699197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 700197104Sjkim "Invalid internal return type in table entry: %X", 701197104Sjkim Package->RetInfo.Type)); 702193267Sjkim 703197104Sjkim return (AE_AML_INTERNAL); 704197104Sjkim } 705193267Sjkim 706197104Sjkim return (Status); 707193267Sjkim 708193267Sjkim 709197104SjkimPackageTooSmall: 710193267Sjkim 711197104Sjkim /* Error exit for the case with an incorrect package count */ 712193267Sjkim 713197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 714197104Sjkim "Return Package is too small - found %u elements, expected %u", 715197104Sjkim Count, ExpectedCount)); 716193267Sjkim 717197104Sjkim return (AE_AML_OPERAND_VALUE); 718197104Sjkim} 719193267Sjkim 720193267Sjkim 721197104Sjkim/******************************************************************************* 722197104Sjkim * 723197104Sjkim * FUNCTION: AcpiNsCheckPackageList 724197104Sjkim * 725197104Sjkim * PARAMETERS: Data - Pointer to validation data structure 726197104Sjkim * Package - Pointer to package-specific info for method 727197104Sjkim * Elements - Element list of parent package. All elements 728197104Sjkim * of this list should be of type Package. 729197104Sjkim * Count - Count of subpackages 730197104Sjkim * 731197104Sjkim * RETURN: Status 732197104Sjkim * 733197104Sjkim * DESCRIPTION: Examine a list of subpackages 734197104Sjkim * 735197104Sjkim ******************************************************************************/ 736193267Sjkim 737197104Sjkimstatic ACPI_STATUS 738197104SjkimAcpiNsCheckPackageList ( 739197104Sjkim ACPI_PREDEFINED_DATA *Data, 740197104Sjkim const ACPI_PREDEFINED_INFO *Package, 741197104Sjkim ACPI_OPERAND_OBJECT **Elements, 742197104Sjkim UINT32 Count) 743197104Sjkim{ 744197104Sjkim ACPI_OPERAND_OBJECT *SubPackage; 745197104Sjkim ACPI_OPERAND_OBJECT **SubElements; 746197104Sjkim ACPI_STATUS Status; 747197104Sjkim UINT32 ExpectedCount; 748197104Sjkim UINT32 i; 749197104Sjkim UINT32 j; 750193267Sjkim 751193267Sjkim 752200553Sjkim /* 753200553Sjkim * Validate each sub-Package in the parent Package 754200553Sjkim * 755200553Sjkim * NOTE: assumes list of sub-packages contains no NULL elements. 756200553Sjkim * Any NULL elements should have been removed by earlier call 757200553Sjkim * to AcpiNsRemoveNullElements. 758200553Sjkim */ 759197104Sjkim for (i = 0; i < Count; i++) 760197104Sjkim { 761197104Sjkim SubPackage = *Elements; 762197104Sjkim SubElements = SubPackage->Package.Elements; 763202771Sjkim Data->ParentPackage = SubPackage; 764193267Sjkim 765197104Sjkim /* Each sub-object must be of type Package */ 766197104Sjkim 767197104Sjkim Status = AcpiNsCheckObjectType (Data, &SubPackage, 768197104Sjkim ACPI_RTYPE_PACKAGE, i); 769197104Sjkim if (ACPI_FAILURE (Status)) 770197104Sjkim { 771197104Sjkim return (Status); 772197104Sjkim } 773197104Sjkim 774197104Sjkim /* Examine the different types of expected sub-packages */ 775197104Sjkim 776202771Sjkim Data->ParentPackage = SubPackage; 777197104Sjkim switch (Package->RetInfo.Type) 778197104Sjkim { 779197104Sjkim case ACPI_PTYPE2: 780197104Sjkim case ACPI_PTYPE2_PKG_COUNT: 781197104Sjkim case ACPI_PTYPE2_REV_FIXED: 782197104Sjkim 783197104Sjkim /* Each subpackage has a fixed number of elements */ 784197104Sjkim 785197104Sjkim ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 786197104Sjkim if (SubPackage->Package.Count < ExpectedCount) 787197104Sjkim { 788197104Sjkim goto PackageTooSmall; 789197104Sjkim } 790197104Sjkim 791197104Sjkim Status = AcpiNsCheckPackageElements (Data, SubElements, 792197104Sjkim Package->RetInfo.ObjectType1, 793197104Sjkim Package->RetInfo.Count1, 794197104Sjkim Package->RetInfo.ObjectType2, 795197104Sjkim Package->RetInfo.Count2, 0); 796197104Sjkim if (ACPI_FAILURE (Status)) 797197104Sjkim { 798197104Sjkim return (Status); 799197104Sjkim } 800197104Sjkim break; 801197104Sjkim 802197104Sjkim 803197104Sjkim case ACPI_PTYPE2_FIXED: 804197104Sjkim 805197104Sjkim /* Each sub-package has a fixed length */ 806197104Sjkim 807197104Sjkim ExpectedCount = Package->RetInfo2.Count; 808197104Sjkim if (SubPackage->Package.Count < ExpectedCount) 809197104Sjkim { 810197104Sjkim goto PackageTooSmall; 811197104Sjkim } 812197104Sjkim 813197104Sjkim /* Check the type of each sub-package element */ 814197104Sjkim 815197104Sjkim for (j = 0; j < ExpectedCount; j++) 816197104Sjkim { 817197104Sjkim Status = AcpiNsCheckObjectType (Data, &SubElements[j], 818197104Sjkim Package->RetInfo2.ObjectType[j], j); 819193267Sjkim if (ACPI_FAILURE (Status)) 820193267Sjkim { 821193267Sjkim return (Status); 822193267Sjkim } 823197104Sjkim } 824197104Sjkim break; 825193267Sjkim 826197104Sjkim 827197104Sjkim case ACPI_PTYPE2_MIN: 828197104Sjkim 829197104Sjkim /* Each sub-package has a variable but minimum length */ 830197104Sjkim 831197104Sjkim ExpectedCount = Package->RetInfo.Count1; 832197104Sjkim if (SubPackage->Package.Count < ExpectedCount) 833197104Sjkim { 834197104Sjkim goto PackageTooSmall; 835193267Sjkim } 836193267Sjkim 837197104Sjkim /* Check the type of each sub-package element */ 838193267Sjkim 839197104Sjkim Status = AcpiNsCheckPackageElements (Data, SubElements, 840197104Sjkim Package->RetInfo.ObjectType1, 841197104Sjkim SubPackage->Package.Count, 0, 0, 0); 842197104Sjkim if (ACPI_FAILURE (Status)) 843197104Sjkim { 844197104Sjkim return (Status); 845197104Sjkim } 846197104Sjkim break; 847193267Sjkim 848193267Sjkim 849197104Sjkim case ACPI_PTYPE2_COUNT: 850193267Sjkim 851197104Sjkim /* 852197104Sjkim * First element is the (Integer) count of elements, including 853202771Sjkim * the count field (the ACPI name is NumElements) 854197104Sjkim */ 855197104Sjkim Status = AcpiNsCheckObjectType (Data, SubElements, 856197104Sjkim ACPI_RTYPE_INTEGER, 0); 857197104Sjkim if (ACPI_FAILURE (Status)) 858197104Sjkim { 859197104Sjkim return (Status); 860197104Sjkim } 861193267Sjkim 862197104Sjkim /* 863197104Sjkim * Make sure package is large enough for the Count and is 864197104Sjkim * is as large as the minimum size 865197104Sjkim */ 866197104Sjkim ExpectedCount = (UINT32) (*SubElements)->Integer.Value; 867197104Sjkim if (SubPackage->Package.Count < ExpectedCount) 868197104Sjkim { 869197104Sjkim goto PackageTooSmall; 870197104Sjkim } 871197104Sjkim if (SubPackage->Package.Count < Package->RetInfo.Count1) 872197104Sjkim { 873197104Sjkim ExpectedCount = Package->RetInfo.Count1; 874197104Sjkim goto PackageTooSmall; 875197104Sjkim } 876202771Sjkim if (ExpectedCount == 0) 877202771Sjkim { 878202771Sjkim /* 879202771Sjkim * Either the NumEntries element was originally zero or it was 880202771Sjkim * a NULL element and repaired to an Integer of value zero. 881202771Sjkim * In either case, repair it by setting NumEntries to be the 882202771Sjkim * actual size of the subpackage. 883202771Sjkim */ 884202771Sjkim ExpectedCount = SubPackage->Package.Count; 885202771Sjkim (*SubElements)->Integer.Value = ExpectedCount; 886202771Sjkim } 887197104Sjkim 888197104Sjkim /* Check the type of each sub-package element */ 889197104Sjkim 890197104Sjkim Status = AcpiNsCheckPackageElements (Data, (SubElements + 1), 891197104Sjkim Package->RetInfo.ObjectType1, 892197104Sjkim (ExpectedCount - 1), 0, 0, 1); 893197104Sjkim if (ACPI_FAILURE (Status)) 894197104Sjkim { 895197104Sjkim return (Status); 896197104Sjkim } 897197104Sjkim break; 898197104Sjkim 899197104Sjkim 900197104Sjkim default: /* Should not get here, type was validated by caller */ 901197104Sjkim 902197104Sjkim return (AE_AML_INTERNAL); 903197104Sjkim } 904197104Sjkim 905197104Sjkim Elements++; 906193267Sjkim } 907193267Sjkim 908193267Sjkim return (AE_OK); 909193267Sjkim 910193267Sjkim 911193267SjkimPackageTooSmall: 912193267Sjkim 913197104Sjkim /* The sub-package count was smaller than required */ 914193267Sjkim 915197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 916197104Sjkim "Return Sub-Package[%u] is too small - found %u elements, expected %u", 917197104Sjkim i, SubPackage->Package.Count, ExpectedCount)); 918193267Sjkim 919193267Sjkim return (AE_AML_OPERAND_VALUE); 920193267Sjkim} 921193267Sjkim 922193267Sjkim 923193267Sjkim/******************************************************************************* 924193267Sjkim * 925193267Sjkim * FUNCTION: AcpiNsCheckPackageElements 926193267Sjkim * 927197104Sjkim * PARAMETERS: Data - Pointer to validation data structure 928193267Sjkim * Elements - Pointer to the package elements array 929193267Sjkim * Type1 - Object type for first group 930193267Sjkim * Count1 - Count for first group 931193267Sjkim * Type2 - Object type for second group 932193267Sjkim * Count2 - Count for second group 933193267Sjkim * StartIndex - Start of the first group of elements 934193267Sjkim * 935193267Sjkim * RETURN: Status 936193267Sjkim * 937193267Sjkim * DESCRIPTION: Check that all elements of a package are of the correct object 938193267Sjkim * type. Supports up to two groups of different object types. 939193267Sjkim * 940193267Sjkim ******************************************************************************/ 941193267Sjkim 942193267Sjkimstatic ACPI_STATUS 943193267SjkimAcpiNsCheckPackageElements ( 944197104Sjkim ACPI_PREDEFINED_DATA *Data, 945193267Sjkim ACPI_OPERAND_OBJECT **Elements, 946193267Sjkim UINT8 Type1, 947193267Sjkim UINT32 Count1, 948193267Sjkim UINT8 Type2, 949193267Sjkim UINT32 Count2, 950193267Sjkim UINT32 StartIndex) 951193267Sjkim{ 952193267Sjkim ACPI_OPERAND_OBJECT **ThisElement = Elements; 953193267Sjkim ACPI_STATUS Status; 954193267Sjkim UINT32 i; 955193267Sjkim 956193267Sjkim 957193267Sjkim /* 958193267Sjkim * Up to two groups of package elements are supported by the data 959193267Sjkim * structure. All elements in each group must be of the same type. 960193267Sjkim * The second group can have a count of zero. 961193267Sjkim */ 962193267Sjkim for (i = 0; i < Count1; i++) 963193267Sjkim { 964197104Sjkim Status = AcpiNsCheckObjectType (Data, ThisElement, 965193267Sjkim Type1, i + StartIndex); 966193267Sjkim if (ACPI_FAILURE (Status)) 967193267Sjkim { 968193267Sjkim return (Status); 969193267Sjkim } 970193267Sjkim ThisElement++; 971193267Sjkim } 972193267Sjkim 973193267Sjkim for (i = 0; i < Count2; i++) 974193267Sjkim { 975197104Sjkim Status = AcpiNsCheckObjectType (Data, ThisElement, 976193267Sjkim Type2, (i + Count1 + StartIndex)); 977193267Sjkim if (ACPI_FAILURE (Status)) 978193267Sjkim { 979193267Sjkim return (Status); 980193267Sjkim } 981193267Sjkim ThisElement++; 982193267Sjkim } 983193267Sjkim 984193267Sjkim return (AE_OK); 985193267Sjkim} 986193267Sjkim 987193267Sjkim 988193267Sjkim/******************************************************************************* 989193267Sjkim * 990193267Sjkim * FUNCTION: AcpiNsCheckObjectType 991193267Sjkim * 992197104Sjkim * PARAMETERS: Data - Pointer to validation data structure 993193267Sjkim * ReturnObjectPtr - Pointer to the object returned from the 994193267Sjkim * evaluation of a method or object 995193267Sjkim * ExpectedBtypes - Bitmap of expected return type(s) 996193267Sjkim * PackageIndex - Index of object within parent package (if 997197104Sjkim * applicable - ACPI_NOT_PACKAGE_ELEMENT 998197104Sjkim * otherwise) 999193267Sjkim * 1000193267Sjkim * RETURN: Status 1001193267Sjkim * 1002193267Sjkim * DESCRIPTION: Check the type of the return object against the expected object 1003193267Sjkim * type(s). Use of Btype allows multiple expected object types. 1004193267Sjkim * 1005193267Sjkim ******************************************************************************/ 1006193267Sjkim 1007193267Sjkimstatic ACPI_STATUS 1008193267SjkimAcpiNsCheckObjectType ( 1009197104Sjkim ACPI_PREDEFINED_DATA *Data, 1010193267Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr, 1011193267Sjkim UINT32 ExpectedBtypes, 1012193267Sjkim UINT32 PackageIndex) 1013193267Sjkim{ 1014193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 1015193267Sjkim ACPI_STATUS Status = AE_OK; 1016193267Sjkim UINT32 ReturnBtype; 1017193267Sjkim char TypeBuffer[48]; /* Room for 5 types */ 1018193267Sjkim 1019193267Sjkim 1020193267Sjkim /* 1021202771Sjkim * If we get a NULL ReturnObject here, it is a NULL package element. 1022202771Sjkim * Since all extraneous NULL package elements were removed earlier by a 1023202771Sjkim * call to AcpiNsRemoveNullElements, this is an unexpected NULL element. 1024202771Sjkim * We will attempt to repair it. 1025193267Sjkim */ 1026193267Sjkim if (!ReturnObject) 1027193267Sjkim { 1028202771Sjkim Status = AcpiNsRepairNullElement (Data, ExpectedBtypes, 1029202771Sjkim PackageIndex, ReturnObjectPtr); 1030202771Sjkim if (ACPI_SUCCESS (Status)) 1031202771Sjkim { 1032202771Sjkim return (AE_OK); /* Repair was successful */ 1033202771Sjkim } 1034193267Sjkim goto TypeErrorExit; 1035193267Sjkim } 1036193267Sjkim 1037193267Sjkim /* A Namespace node should not get here, but make sure */ 1038193267Sjkim 1039193267Sjkim if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED) 1040193267Sjkim { 1041197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 1042197104Sjkim "Invalid return type - Found a Namespace node [%4.4s] type %s", 1043197104Sjkim ReturnObject->Node.Name.Ascii, 1044193267Sjkim AcpiUtGetTypeName (ReturnObject->Node.Type))); 1045193267Sjkim return (AE_AML_OPERAND_TYPE); 1046193267Sjkim } 1047193267Sjkim 1048193267Sjkim /* 1049193267Sjkim * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. 1050193267Sjkim * The bitmapped type allows multiple possible return types. 1051193267Sjkim * 1052193267Sjkim * Note, the cases below must handle all of the possible types returned 1053193267Sjkim * from all of the predefined names (including elements of returned 1054193267Sjkim * packages) 1055193267Sjkim */ 1056193267Sjkim switch (ReturnObject->Common.Type) 1057193267Sjkim { 1058193267Sjkim case ACPI_TYPE_INTEGER: 1059193267Sjkim ReturnBtype = ACPI_RTYPE_INTEGER; 1060193267Sjkim break; 1061193267Sjkim 1062193267Sjkim case ACPI_TYPE_BUFFER: 1063193267Sjkim ReturnBtype = ACPI_RTYPE_BUFFER; 1064193267Sjkim break; 1065193267Sjkim 1066193267Sjkim case ACPI_TYPE_STRING: 1067193267Sjkim ReturnBtype = ACPI_RTYPE_STRING; 1068193267Sjkim break; 1069193267Sjkim 1070193267Sjkim case ACPI_TYPE_PACKAGE: 1071193267Sjkim ReturnBtype = ACPI_RTYPE_PACKAGE; 1072193267Sjkim break; 1073193267Sjkim 1074193267Sjkim case ACPI_TYPE_LOCAL_REFERENCE: 1075193267Sjkim ReturnBtype = ACPI_RTYPE_REFERENCE; 1076193267Sjkim break; 1077193267Sjkim 1078193267Sjkim default: 1079193267Sjkim /* Not one of the supported objects, must be incorrect */ 1080193267Sjkim 1081193267Sjkim goto TypeErrorExit; 1082193267Sjkim } 1083193267Sjkim 1084193267Sjkim /* Is the object one of the expected types? */ 1085193267Sjkim 1086202771Sjkim if (ReturnBtype & ExpectedBtypes) 1087193267Sjkim { 1088202771Sjkim /* For reference objects, check that the reference type is correct */ 1089193267Sjkim 1090202771Sjkim if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) 1091193267Sjkim { 1092202771Sjkim Status = AcpiNsCheckReference (Data, ReturnObject); 1093193267Sjkim } 1094202771Sjkim 1095202771Sjkim return (Status); 1096193267Sjkim } 1097193267Sjkim 1098202771Sjkim /* Type mismatch -- attempt repair of the returned object */ 1099193267Sjkim 1100202771Sjkim Status = AcpiNsRepairObject (Data, ExpectedBtypes, 1101202771Sjkim PackageIndex, ReturnObjectPtr); 1102202771Sjkim if (ACPI_SUCCESS (Status)) 1103193267Sjkim { 1104202771Sjkim return (AE_OK); /* Repair was successful */ 1105193267Sjkim } 1106193267Sjkim 1107193267Sjkim 1108193267SjkimTypeErrorExit: 1109193267Sjkim 1110193267Sjkim /* Create a string with all expected types for this predefined object */ 1111193267Sjkim 1112197104Sjkim AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes); 1113193267Sjkim 1114197104Sjkim if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) 1115193267Sjkim { 1116197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 1117197104Sjkim "Return type mismatch - found %s, expected %s", 1118197104Sjkim AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 1119193267Sjkim } 1120193267Sjkim else 1121193267Sjkim { 1122197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 1123197104Sjkim "Return Package type mismatch at index %u - " 1124197104Sjkim "found %s, expected %s", PackageIndex, 1125193267Sjkim AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer)); 1126193267Sjkim } 1127193267Sjkim 1128193267Sjkim return (AE_AML_OPERAND_TYPE); 1129193267Sjkim} 1130193267Sjkim 1131193267Sjkim 1132193267Sjkim/******************************************************************************* 1133193267Sjkim * 1134193267Sjkim * FUNCTION: AcpiNsCheckReference 1135193267Sjkim * 1136197104Sjkim * PARAMETERS: Data - Pointer to validation data structure 1137193267Sjkim * ReturnObject - Object returned from the evaluation of a 1138193267Sjkim * method or object 1139193267Sjkim * 1140193267Sjkim * RETURN: Status 1141193267Sjkim * 1142193267Sjkim * DESCRIPTION: Check a returned reference object for the correct reference 1143193267Sjkim * type. The only reference type that can be returned from a 1144193267Sjkim * predefined method is a named reference. All others are invalid. 1145193267Sjkim * 1146193267Sjkim ******************************************************************************/ 1147193267Sjkim 1148193267Sjkimstatic ACPI_STATUS 1149193267SjkimAcpiNsCheckReference ( 1150197104Sjkim ACPI_PREDEFINED_DATA *Data, 1151193267Sjkim ACPI_OPERAND_OBJECT *ReturnObject) 1152193267Sjkim{ 1153193267Sjkim 1154193267Sjkim /* 1155193267Sjkim * Check the reference object for the correct reference type (opcode). 1156193267Sjkim * The only type of reference that can be converted to an ACPI_OBJECT is 1157193267Sjkim * a reference to a named object (reference class: NAME) 1158193267Sjkim */ 1159193267Sjkim if (ReturnObject->Reference.Class == ACPI_REFCLASS_NAME) 1160193267Sjkim { 1161193267Sjkim return (AE_OK); 1162193267Sjkim } 1163193267Sjkim 1164197104Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 1165197104Sjkim "Return type mismatch - unexpected reference object type [%s] %2.2X", 1166197104Sjkim AcpiUtGetReferenceName (ReturnObject), 1167193267Sjkim ReturnObject->Reference.Class)); 1168193267Sjkim 1169193267Sjkim return (AE_AML_OPERAND_TYPE); 1170193267Sjkim} 1171193267Sjkim 1172193267Sjkim 1173193267Sjkim/******************************************************************************* 1174193267Sjkim * 1175197104Sjkim * FUNCTION: AcpiNsGetExpectedTypes 1176193267Sjkim * 1177197104Sjkim * PARAMETERS: Buffer - Pointer to where the string is returned 1178197104Sjkim * ExpectedBtypes - Bitmap of expected return type(s) 1179193267Sjkim * 1180197104Sjkim * RETURN: Buffer is populated with type names. 1181193267Sjkim * 1182197104Sjkim * DESCRIPTION: Translate the expected types bitmap into a string of ascii 1183197104Sjkim * names of expected types, for use in warning messages. 1184193267Sjkim * 1185193267Sjkim ******************************************************************************/ 1186193267Sjkim 1187197104Sjkimstatic void 1188197104SjkimAcpiNsGetExpectedTypes ( 1189197104Sjkim char *Buffer, 1190197104Sjkim UINT32 ExpectedBtypes) 1191193267Sjkim{ 1192197104Sjkim UINT32 ThisRtype; 1193197104Sjkim UINT32 i; 1194197104Sjkim UINT32 j; 1195193267Sjkim 1196193267Sjkim 1197197104Sjkim j = 1; 1198197104Sjkim Buffer[0] = 0; 1199197104Sjkim ThisRtype = ACPI_RTYPE_INTEGER; 1200197104Sjkim 1201197104Sjkim for (i = 0; i < ACPI_NUM_RTYPES; i++) 1202193267Sjkim { 1203197104Sjkim /* If one of the expected types, concatenate the name of this type */ 1204193267Sjkim 1205197104Sjkim if (ExpectedBtypes & ThisRtype) 1206193267Sjkim { 1207197104Sjkim ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]); 1208197104Sjkim j = 0; /* Use name separator from now on */ 1209193267Sjkim } 1210197104Sjkim ThisRtype <<= 1; /* Next Rtype */ 1211193267Sjkim } 1212193267Sjkim} 1213