1196000Sjkim/****************************************************************************** 2196000Sjkim * 3196000Sjkim * Module Name: nsrepair - Repair for objects returned by predefined methods 4196000Sjkim * 5196000Sjkim *****************************************************************************/ 6196000Sjkim 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9196000Sjkim * All rights reserved. 10196000Sjkim * 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. 25196000Sjkim * 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. 29196000Sjkim * 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 */ 43196000Sjkim 44197107Sjkim#include <contrib/dev/acpica/include/acpi.h> 45197107Sjkim#include <contrib/dev/acpica/include/accommon.h> 46197107Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 47198237Sjkim#include <contrib/dev/acpica/include/acinterp.h> 48202773Sjkim#include <contrib/dev/acpica/include/acpredef.h> 49246849Sjkim#include <contrib/dev/acpica/include/amlresrc.h> 50196000Sjkim 51196000Sjkim#define _COMPONENT ACPI_NAMESPACE 52196000Sjkim ACPI_MODULE_NAME ("nsrepair") 53196000Sjkim 54196000Sjkim 55196000Sjkim/******************************************************************************* 56196000Sjkim * 57200553Sjkim * This module attempts to repair or convert objects returned by the 58200553Sjkim * predefined methods to an object type that is expected, as per the ACPI 59200553Sjkim * specification. The need for this code is dictated by the many machines that 60200553Sjkim * return incorrect types for the standard predefined methods. Performing these 61200553Sjkim * conversions here, in one place, eliminates the need for individual ACPI 62200553Sjkim * device drivers to do the same. Note: Most of these conversions are different 63200553Sjkim * than the internal object conversion routines used for implicit object 64200553Sjkim * conversion. 65200553Sjkim * 66200553Sjkim * The following conversions can be performed as necessary: 67200553Sjkim * 68200553Sjkim * Integer -> String 69200553Sjkim * Integer -> Buffer 70200553Sjkim * String -> Integer 71200553Sjkim * String -> Buffer 72200553Sjkim * Buffer -> Integer 73200553Sjkim * Buffer -> String 74200553Sjkim * Buffer -> Package of Integers 75200553Sjkim * Package -> Package of one Package 76246849Sjkim * 77246849Sjkim * Additional conversions that are available: 78246849Sjkim * Convert a null return or zero return value to an EndTag descriptor 79246849Sjkim * Convert an ASCII string to a Unicode buffer 80246849Sjkim * 81233617Sjkim * An incorrect standalone object is wrapped with required outer package 82200553Sjkim * 83202771Sjkim * Additional possible repairs: 84202771Sjkim * Required package elements that are NULL replaced by Integer/String/Buffer 85202771Sjkim * 86200553Sjkim ******************************************************************************/ 87200553Sjkim 88200553Sjkim 89200553Sjkim/* Local prototypes */ 90200553Sjkim 91246849Sjkimstatic const ACPI_SIMPLE_REPAIR_INFO * 92246849SjkimAcpiNsMatchSimpleRepair ( 93246849Sjkim ACPI_NAMESPACE_NODE *Node, 94246849Sjkim UINT32 ReturnBtype, 95246849Sjkim UINT32 PackageIndex); 96200553Sjkim 97200553Sjkim 98246849Sjkim/* 99246849Sjkim * Special but simple repairs for some names. 100246849Sjkim * 101246849Sjkim * 2nd argument: Unexpected types that can be repaired 102246849Sjkim */ 103246849Sjkimstatic const ACPI_SIMPLE_REPAIR_INFO AcpiObjectRepairInfo[] = 104246849Sjkim{ 105246849Sjkim /* Resource descriptor conversions */ 106200553Sjkim 107246849Sjkim { "_CRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, 108246849Sjkim ACPI_NOT_PACKAGE_ELEMENT, 109246849Sjkim AcpiNsConvertToResource }, 110246849Sjkim { "_DMA", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, 111246849Sjkim ACPI_NOT_PACKAGE_ELEMENT, 112246849Sjkim AcpiNsConvertToResource }, 113246849Sjkim { "_PRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, 114246849Sjkim ACPI_NOT_PACKAGE_ELEMENT, 115246849Sjkim AcpiNsConvertToResource }, 116200553Sjkim 117306536Sjkim /* Object reference conversions */ 118306536Sjkim 119306536Sjkim { "_DEP", ACPI_RTYPE_STRING, ACPI_ALL_PACKAGE_ELEMENTS, 120306536Sjkim AcpiNsConvertToReference }, 121306536Sjkim 122246849Sjkim /* Unicode conversions */ 123246849Sjkim 124246849Sjkim { "_MLS", ACPI_RTYPE_STRING, 1, 125246849Sjkim AcpiNsConvertToUnicode }, 126246849Sjkim { "_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 127246849Sjkim ACPI_NOT_PACKAGE_ELEMENT, 128246849Sjkim AcpiNsConvertToUnicode }, 129246849Sjkim { {0,0,0,0}, 0, 0, NULL } /* Table terminator */ 130246849Sjkim}; 131246849Sjkim 132246849Sjkim 133200553Sjkim/******************************************************************************* 134200553Sjkim * 135246849Sjkim * FUNCTION: AcpiNsSimpleRepair 136196000Sjkim * 137249663Sjkim * PARAMETERS: Info - Method execution information block 138196000Sjkim * ExpectedBtypes - Object types expected 139196000Sjkim * PackageIndex - Index of object within parent package (if 140196000Sjkim * applicable - ACPI_NOT_PACKAGE_ELEMENT 141196000Sjkim * otherwise) 142196000Sjkim * ReturnObjectPtr - Pointer to the object returned from the 143196000Sjkim * evaluation of a method or object 144196000Sjkim * 145196000Sjkim * RETURN: Status. AE_OK if repair was successful. 146196000Sjkim * 147196000Sjkim * DESCRIPTION: Attempt to repair/convert a return object of a type that was 148196000Sjkim * not expected. 149196000Sjkim * 150196000Sjkim ******************************************************************************/ 151196000Sjkim 152196000SjkimACPI_STATUS 153246849SjkimAcpiNsSimpleRepair ( 154249663Sjkim ACPI_EVALUATE_INFO *Info, 155196000Sjkim UINT32 ExpectedBtypes, 156196000Sjkim UINT32 PackageIndex, 157196000Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 158196000Sjkim{ 159196000Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 160246849Sjkim ACPI_OPERAND_OBJECT *NewObject = NULL; 161198237Sjkim ACPI_STATUS Status; 162246849Sjkim const ACPI_SIMPLE_REPAIR_INFO *Predefined; 163196000Sjkim 164196000Sjkim 165246849Sjkim ACPI_FUNCTION_NAME (NsSimpleRepair); 166200553Sjkim 167200553Sjkim 168198237Sjkim /* 169246849Sjkim * Special repairs for certain names that are in the repair table. 170246849Sjkim * Check if this name is in the list of repairable names. 171246849Sjkim */ 172249663Sjkim Predefined = AcpiNsMatchSimpleRepair (Info->Node, 173249663Sjkim Info->ReturnBtype, PackageIndex); 174246849Sjkim if (Predefined) 175246849Sjkim { 176246849Sjkim if (!ReturnObject) 177246849Sjkim { 178249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 179246849Sjkim ACPI_WARN_ALWAYS, "Missing expected return value")); 180246849Sjkim } 181246849Sjkim 182306536Sjkim Status = Predefined->ObjectConverter (Info->Node, ReturnObject, 183306536Sjkim &NewObject); 184246849Sjkim if (ACPI_FAILURE (Status)) 185246849Sjkim { 186246849Sjkim /* A fatal error occurred during a conversion */ 187246849Sjkim 188246849Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 189246849Sjkim "During return object analysis")); 190246849Sjkim return (Status); 191246849Sjkim } 192246849Sjkim if (NewObject) 193246849Sjkim { 194246849Sjkim goto ObjectRepaired; 195246849Sjkim } 196246849Sjkim } 197246849Sjkim 198246849Sjkim /* 199246849Sjkim * Do not perform simple object repair unless the return type is not 200246849Sjkim * expected. 201246849Sjkim */ 202249663Sjkim if (Info->ReturnBtype & ExpectedBtypes) 203246849Sjkim { 204246849Sjkim return (AE_OK); 205246849Sjkim } 206246849Sjkim 207246849Sjkim /* 208198237Sjkim * At this point, we know that the type of the returned object was not 209198237Sjkim * one of the expected types for this predefined name. Attempt to 210200553Sjkim * repair the object by converting it to one of the expected object 211200553Sjkim * types for this predefined name. 212198237Sjkim */ 213246849Sjkim 214246849Sjkim /* 215246849Sjkim * If there is no return value, check if we require a return value for 216246849Sjkim * this predefined name. Either one return value is expected, or none, 217246849Sjkim * for both methods and other objects. 218246849Sjkim * 219281075Sdim * Try to fix if there was no return object. Warning if failed to fix. 220246849Sjkim */ 221246849Sjkim if (!ReturnObject) 222246849Sjkim { 223246849Sjkim if (ExpectedBtypes && (!(ExpectedBtypes & ACPI_RTYPE_NONE))) 224246849Sjkim { 225281075Sdim if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) 226281075Sdim { 227281075Sdim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 228281075Sdim ACPI_WARN_ALWAYS, "Found unexpected NULL package element")); 229246849Sjkim 230281075Sdim Status = AcpiNsRepairNullElement (Info, ExpectedBtypes, 231306536Sjkim PackageIndex, ReturnObjectPtr); 232281075Sdim if (ACPI_SUCCESS (Status)) 233281075Sdim { 234281075Sdim return (AE_OK); /* Repair was successful */ 235281075Sdim } 236281075Sdim } 237281075Sdim else 238281075Sdim { 239281075Sdim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 240281075Sdim ACPI_WARN_ALWAYS, "Missing expected return value")); 241281075Sdim } 242281075Sdim 243246849Sjkim return (AE_AML_NO_RETURN_VALUE); 244246849Sjkim } 245246849Sjkim } 246246849Sjkim 247200553Sjkim if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 248196000Sjkim { 249200553Sjkim Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); 250200553Sjkim if (ACPI_SUCCESS (Status)) 251200553Sjkim { 252200553Sjkim goto ObjectRepaired; 253200553Sjkim } 254200553Sjkim } 255200553Sjkim if (ExpectedBtypes & ACPI_RTYPE_STRING) 256200553Sjkim { 257200553Sjkim Status = AcpiNsConvertToString (ReturnObject, &NewObject); 258200553Sjkim if (ACPI_SUCCESS (Status)) 259200553Sjkim { 260200553Sjkim goto ObjectRepaired; 261200553Sjkim } 262200553Sjkim } 263200553Sjkim if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 264200553Sjkim { 265200553Sjkim Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject); 266200553Sjkim if (ACPI_SUCCESS (Status)) 267200553Sjkim { 268200553Sjkim goto ObjectRepaired; 269200553Sjkim } 270200553Sjkim } 271200553Sjkim if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) 272200553Sjkim { 273233617Sjkim /* 274233617Sjkim * A package is expected. We will wrap the existing object with a 275233617Sjkim * new package object. It is often the case that if a variable-length 276233617Sjkim * package is required, but there is only a single object needed, the 277233617Sjkim * BIOS will return that object instead of wrapping it with a Package 278233617Sjkim * object. Note: after the wrapping, the package will be validated 279233617Sjkim * for correct contents (expected object type or types). 280233617Sjkim */ 281249663Sjkim Status = AcpiNsWrapWithPackage (Info, ReturnObject, &NewObject); 282200553Sjkim if (ACPI_SUCCESS (Status)) 283200553Sjkim { 284233617Sjkim /* 285233617Sjkim * The original object just had its reference count 286233617Sjkim * incremented for being inserted into the new package. 287233617Sjkim */ 288233617Sjkim *ReturnObjectPtr = NewObject; /* New Package object */ 289249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 290233617Sjkim return (AE_OK); 291200553Sjkim } 292200553Sjkim } 293200553Sjkim 294200553Sjkim /* We cannot repair this object */ 295200553Sjkim 296200553Sjkim return (AE_AML_OPERAND_TYPE); 297200553Sjkim 298200553Sjkim 299200553SjkimObjectRepaired: 300200553Sjkim 301200553Sjkim /* Object was successfully repaired */ 302200553Sjkim 303200553Sjkim if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) 304200553Sjkim { 305233617Sjkim /* 306233617Sjkim * The original object is a package element. We need to 307233617Sjkim * decrement the reference count of the original object, 308233617Sjkim * for removing it from the package. 309233617Sjkim * 310233617Sjkim * However, if the original object was just wrapped with a 311233617Sjkim * package object as part of the repair, we don't need to 312233617Sjkim * change the reference count. 313233617Sjkim */ 314249663Sjkim if (!(Info->ReturnFlags & ACPI_OBJECT_WRAPPED)) 315233617Sjkim { 316233617Sjkim NewObject->Common.ReferenceCount = 317233617Sjkim ReturnObject->Common.ReferenceCount; 318233555Sjkim 319233617Sjkim if (ReturnObject->Common.ReferenceCount > 1) 320233617Sjkim { 321233617Sjkim ReturnObject->Common.ReferenceCount--; 322233617Sjkim } 323200553Sjkim } 324200553Sjkim 325200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 326233617Sjkim "%s: Converted %s to expected %s at Package index %u\n", 327249663Sjkim Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), 328200553Sjkim AcpiUtGetObjectTypeName (NewObject), PackageIndex)); 329200553Sjkim } 330200553Sjkim else 331200553Sjkim { 332200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 333200553Sjkim "%s: Converted %s to expected %s\n", 334249663Sjkim Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), 335200553Sjkim AcpiUtGetObjectTypeName (NewObject))); 336200553Sjkim } 337200553Sjkim 338200553Sjkim /* Delete old object, install the new return object */ 339200553Sjkim 340200553Sjkim AcpiUtRemoveReference (ReturnObject); 341200553Sjkim *ReturnObjectPtr = NewObject; 342249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 343200553Sjkim return (AE_OK); 344200553Sjkim} 345200553Sjkim 346200553Sjkim 347246849Sjkim/****************************************************************************** 348200553Sjkim * 349246849Sjkim * FUNCTION: AcpiNsMatchSimpleRepair 350200553Sjkim * 351246849Sjkim * PARAMETERS: Node - Namespace node for the method/object 352246849Sjkim * ReturnBtype - Object type that was returned 353246849Sjkim * PackageIndex - Index of object within parent package (if 354246849Sjkim * applicable - ACPI_NOT_PACKAGE_ELEMENT 355246849Sjkim * otherwise) 356200553Sjkim * 357246849Sjkim * RETURN: Pointer to entry in repair table. NULL indicates not found. 358200553Sjkim * 359246849Sjkim * DESCRIPTION: Check an object name against the repairable object list. 360200553Sjkim * 361246849Sjkim *****************************************************************************/ 362200553Sjkim 363246849Sjkimstatic const ACPI_SIMPLE_REPAIR_INFO * 364246849SjkimAcpiNsMatchSimpleRepair ( 365246849Sjkim ACPI_NAMESPACE_NODE *Node, 366246849Sjkim UINT32 ReturnBtype, 367246849Sjkim UINT32 PackageIndex) 368200553Sjkim{ 369246849Sjkim const ACPI_SIMPLE_REPAIR_INFO *ThisName; 370200553Sjkim 371200553Sjkim 372246849Sjkim /* Search info table for a repairable predefined method/object name */ 373200553Sjkim 374246849Sjkim ThisName = AcpiObjectRepairInfo; 375246849Sjkim while (ThisName->ObjectConverter) 376200553Sjkim { 377246849Sjkim if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) 378200553Sjkim { 379246849Sjkim /* Check if we can actually repair this name/type combination */ 380200553Sjkim 381246849Sjkim if ((ReturnBtype & ThisName->UnexpectedBtypes) && 382306536Sjkim (ThisName->PackageIndex == ACPI_ALL_PACKAGE_ELEMENTS || 383306536Sjkim PackageIndex == ThisName->PackageIndex)) 384200553Sjkim { 385246849Sjkim return (ThisName); 386200553Sjkim } 387200553Sjkim 388246849Sjkim return (NULL); 389196000Sjkim } 390306536Sjkim 391246849Sjkim ThisName++; 392200553Sjkim } 393198237Sjkim 394246849Sjkim return (NULL); /* Name was not found in the repair table */ 395200553Sjkim} 396200553Sjkim 397200553Sjkim 398200553Sjkim/******************************************************************************* 399200553Sjkim * 400202771Sjkim * FUNCTION: AcpiNsRepairNullElement 401202771Sjkim * 402249663Sjkim * PARAMETERS: Info - Method execution information block 403202771Sjkim * ExpectedBtypes - Object types expected 404202771Sjkim * PackageIndex - Index of object within parent package (if 405202771Sjkim * applicable - ACPI_NOT_PACKAGE_ELEMENT 406202771Sjkim * otherwise) 407202771Sjkim * ReturnObjectPtr - Pointer to the object returned from the 408202771Sjkim * evaluation of a method or object 409202771Sjkim * 410202771Sjkim * RETURN: Status. AE_OK if repair was successful. 411202771Sjkim * 412202771Sjkim * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. 413202771Sjkim * 414202771Sjkim ******************************************************************************/ 415202771Sjkim 416202771SjkimACPI_STATUS 417202771SjkimAcpiNsRepairNullElement ( 418249663Sjkim ACPI_EVALUATE_INFO *Info, 419202771Sjkim UINT32 ExpectedBtypes, 420202771Sjkim UINT32 PackageIndex, 421202771Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 422202771Sjkim{ 423202771Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 424202771Sjkim ACPI_OPERAND_OBJECT *NewObject; 425202771Sjkim 426202771Sjkim 427202771Sjkim ACPI_FUNCTION_NAME (NsRepairNullElement); 428202771Sjkim 429202771Sjkim 430202771Sjkim /* No repair needed if return object is non-NULL */ 431202771Sjkim 432202771Sjkim if (ReturnObject) 433202771Sjkim { 434202771Sjkim return (AE_OK); 435202771Sjkim } 436202771Sjkim 437202771Sjkim /* 438202771Sjkim * Attempt to repair a NULL element of a Package object. This applies to 439202771Sjkim * predefined names that return a fixed-length package and each element 440202771Sjkim * is required. It does not apply to variable-length packages where NULL 441202771Sjkim * elements are allowed, especially at the end of the package. 442202771Sjkim */ 443202771Sjkim if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 444202771Sjkim { 445202771Sjkim /* Need an Integer - create a zero-value integer */ 446202771Sjkim 447209746Sjkim NewObject = AcpiUtCreateIntegerObject ((UINT64) 0); 448202771Sjkim } 449202771Sjkim else if (ExpectedBtypes & ACPI_RTYPE_STRING) 450202771Sjkim { 451202771Sjkim /* Need a String - create a NULL string */ 452202771Sjkim 453202771Sjkim NewObject = AcpiUtCreateStringObject (0); 454202771Sjkim } 455202771Sjkim else if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 456202771Sjkim { 457202771Sjkim /* Need a Buffer - create a zero-length buffer */ 458202771Sjkim 459202771Sjkim NewObject = AcpiUtCreateBufferObject (0); 460202771Sjkim } 461202771Sjkim else 462202771Sjkim { 463202771Sjkim /* Error for all other expected types */ 464202771Sjkim 465202771Sjkim return (AE_AML_OPERAND_TYPE); 466202771Sjkim } 467202771Sjkim 468202771Sjkim if (!NewObject) 469202771Sjkim { 470202771Sjkim return (AE_NO_MEMORY); 471202771Sjkim } 472202771Sjkim 473202771Sjkim /* Set the reference count according to the parent Package object */ 474202771Sjkim 475306536Sjkim NewObject->Common.ReferenceCount = 476306536Sjkim Info->ParentPackage->Common.ReferenceCount; 477202771Sjkim 478202771Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 479202771Sjkim "%s: Converted NULL package element to expected %s at index %u\n", 480306536Sjkim Info->FullPathname, AcpiUtGetObjectTypeName (NewObject), 481306536Sjkim PackageIndex)); 482202771Sjkim 483202771Sjkim *ReturnObjectPtr = NewObject; 484249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 485202771Sjkim return (AE_OK); 486202771Sjkim} 487202771Sjkim 488202771Sjkim 489202771Sjkim/****************************************************************************** 490202771Sjkim * 491202771Sjkim * FUNCTION: AcpiNsRemoveNullElements 492202771Sjkim * 493249663Sjkim * PARAMETERS: Info - Method execution information block 494202771Sjkim * PackageType - An AcpiReturnPackageTypes value 495202771Sjkim * ObjDesc - A Package object 496202771Sjkim * 497202771Sjkim * RETURN: None. 498202771Sjkim * 499202771Sjkim * DESCRIPTION: Remove all NULL package elements from packages that contain 500281075Sdim * a variable number of subpackages. For these types of 501202771Sjkim * packages, NULL elements can be safely removed. 502202771Sjkim * 503202771Sjkim *****************************************************************************/ 504202771Sjkim 505202771Sjkimvoid 506202771SjkimAcpiNsRemoveNullElements ( 507249663Sjkim ACPI_EVALUATE_INFO *Info, 508202771Sjkim UINT8 PackageType, 509202771Sjkim ACPI_OPERAND_OBJECT *ObjDesc) 510202771Sjkim{ 511202771Sjkim ACPI_OPERAND_OBJECT **Source; 512202771Sjkim ACPI_OPERAND_OBJECT **Dest; 513202771Sjkim UINT32 Count; 514202771Sjkim UINT32 NewCount; 515202771Sjkim UINT32 i; 516202771Sjkim 517202771Sjkim 518202771Sjkim ACPI_FUNCTION_NAME (NsRemoveNullElements); 519202771Sjkim 520202771Sjkim 521202771Sjkim /* 522220663Sjkim * We can safely remove all NULL elements from these package types: 523220663Sjkim * PTYPE1_VAR packages contain a variable number of simple data types. 524281075Sdim * PTYPE2 packages contain a variable number of subpackages. 525202771Sjkim */ 526202771Sjkim switch (PackageType) 527202771Sjkim { 528202771Sjkim case ACPI_PTYPE1_VAR: 529202771Sjkim case ACPI_PTYPE2: 530202771Sjkim case ACPI_PTYPE2_COUNT: 531202771Sjkim case ACPI_PTYPE2_PKG_COUNT: 532202771Sjkim case ACPI_PTYPE2_FIXED: 533202771Sjkim case ACPI_PTYPE2_MIN: 534202771Sjkim case ACPI_PTYPE2_REV_FIXED: 535228110Sjkim case ACPI_PTYPE2_FIX_VAR: 536202771Sjkim break; 537202771Sjkim 538202771Sjkim default: 539284460Sjkim case ACPI_PTYPE2_VAR_VAR: 540220663Sjkim case ACPI_PTYPE1_FIXED: 541220663Sjkim case ACPI_PTYPE1_OPTION: 542202771Sjkim return; 543202771Sjkim } 544202771Sjkim 545202771Sjkim Count = ObjDesc->Package.Count; 546202771Sjkim NewCount = Count; 547202771Sjkim 548202771Sjkim Source = ObjDesc->Package.Elements; 549202771Sjkim Dest = Source; 550202771Sjkim 551202771Sjkim /* Examine all elements of the package object, remove nulls */ 552202771Sjkim 553202771Sjkim for (i = 0; i < Count; i++) 554202771Sjkim { 555202771Sjkim if (!*Source) 556202771Sjkim { 557202771Sjkim NewCount--; 558202771Sjkim } 559202771Sjkim else 560202771Sjkim { 561202771Sjkim *Dest = *Source; 562202771Sjkim Dest++; 563202771Sjkim } 564306536Sjkim 565202771Sjkim Source++; 566202771Sjkim } 567202771Sjkim 568202771Sjkim /* Update parent package if any null elements were removed */ 569202771Sjkim 570202771Sjkim if (NewCount < Count) 571202771Sjkim { 572202771Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 573202771Sjkim "%s: Found and removed %u NULL elements\n", 574249663Sjkim Info->FullPathname, (Count - NewCount))); 575202771Sjkim 576202771Sjkim /* NULL terminate list and update the package count */ 577202771Sjkim 578202771Sjkim *Dest = NULL; 579202771Sjkim ObjDesc->Package.Count = NewCount; 580202771Sjkim } 581202771Sjkim} 582202771Sjkim 583202771Sjkim 584202771Sjkim/******************************************************************************* 585202771Sjkim * 586233617Sjkim * FUNCTION: AcpiNsWrapWithPackage 587196000Sjkim * 588249663Sjkim * PARAMETERS: Info - Method execution information block 589233617Sjkim * OriginalObject - Pointer to the object to repair. 590233617Sjkim * ObjDescPtr - The new package object is returned here 591196000Sjkim * 592196000Sjkim * RETURN: Status, new object in *ObjDescPtr 593196000Sjkim * 594233617Sjkim * DESCRIPTION: Repair a common problem with objects that are defined to 595233617Sjkim * return a variable-length Package of sub-objects. If there is 596233617Sjkim * only one sub-object, some BIOS code mistakenly simply declares 597233617Sjkim * the single object instead of a Package with one sub-object. 598233617Sjkim * This function attempts to repair this error by wrapping a 599233617Sjkim * Package object around the original object, creating the 600233617Sjkim * correct and expected Package with one sub-object. 601196000Sjkim * 602196000Sjkim * Names that can be repaired in this manner include: 603233617Sjkim * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, 604233617Sjkim * _BCL, _DOD, _FIX, _Sx 605196000Sjkim * 606196000Sjkim ******************************************************************************/ 607196000Sjkim 608196000SjkimACPI_STATUS 609233617SjkimAcpiNsWrapWithPackage ( 610249663Sjkim ACPI_EVALUATE_INFO *Info, 611233617Sjkim ACPI_OPERAND_OBJECT *OriginalObject, 612196000Sjkim ACPI_OPERAND_OBJECT **ObjDescPtr) 613196000Sjkim{ 614196000Sjkim ACPI_OPERAND_OBJECT *PkgObjDesc; 615196000Sjkim 616196000Sjkim 617233617Sjkim ACPI_FUNCTION_NAME (NsWrapWithPackage); 618200553Sjkim 619200553Sjkim 620196000Sjkim /* 621306536Sjkim * Create the new outer package and populate it. The new 622306536Sjkim * package will have a single element, the lone sub-object. 623196000Sjkim */ 624196000Sjkim PkgObjDesc = AcpiUtCreatePackageObject (1); 625196000Sjkim if (!PkgObjDesc) 626196000Sjkim { 627196000Sjkim return (AE_NO_MEMORY); 628196000Sjkim } 629196000Sjkim 630233617Sjkim PkgObjDesc->Package.Elements[0] = OriginalObject; 631196000Sjkim 632233617Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 633233617Sjkim "%s: Wrapped %s with expected Package object\n", 634249663Sjkim Info->FullPathname, AcpiUtGetObjectTypeName (OriginalObject))); 635233617Sjkim 636196000Sjkim /* Return the new object in the object pointer */ 637196000Sjkim 638196000Sjkim *ObjDescPtr = PkgObjDesc; 639249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; 640196000Sjkim return (AE_OK); 641196000Sjkim} 642