1196000Sjkim/****************************************************************************** 2196000Sjkim * 3196000Sjkim * Module Name: nsrepair - Repair for objects returned by predefined methods 4196000Sjkim * 5196000Sjkim *****************************************************************************/ 6196000Sjkim 7217365Sjkim/* 8281075Sdim * Copyright (C) 2000 - 2015, 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 117246849Sjkim /* Unicode conversions */ 118246849Sjkim 119246849Sjkim { "_MLS", ACPI_RTYPE_STRING, 1, 120246849Sjkim AcpiNsConvertToUnicode }, 121246849Sjkim { "_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 122246849Sjkim ACPI_NOT_PACKAGE_ELEMENT, 123246849Sjkim AcpiNsConvertToUnicode }, 124246849Sjkim { {0,0,0,0}, 0, 0, NULL } /* Table terminator */ 125246849Sjkim}; 126246849Sjkim 127246849Sjkim 128200553Sjkim/******************************************************************************* 129200553Sjkim * 130246849Sjkim * FUNCTION: AcpiNsSimpleRepair 131196000Sjkim * 132249663Sjkim * PARAMETERS: Info - Method execution information block 133196000Sjkim * ExpectedBtypes - Object types expected 134196000Sjkim * PackageIndex - Index of object within parent package (if 135196000Sjkim * applicable - ACPI_NOT_PACKAGE_ELEMENT 136196000Sjkim * otherwise) 137196000Sjkim * ReturnObjectPtr - Pointer to the object returned from the 138196000Sjkim * evaluation of a method or object 139196000Sjkim * 140196000Sjkim * RETURN: Status. AE_OK if repair was successful. 141196000Sjkim * 142196000Sjkim * DESCRIPTION: Attempt to repair/convert a return object of a type that was 143196000Sjkim * not expected. 144196000Sjkim * 145196000Sjkim ******************************************************************************/ 146196000Sjkim 147196000SjkimACPI_STATUS 148246849SjkimAcpiNsSimpleRepair ( 149249663Sjkim ACPI_EVALUATE_INFO *Info, 150196000Sjkim UINT32 ExpectedBtypes, 151196000Sjkim UINT32 PackageIndex, 152196000Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 153196000Sjkim{ 154196000Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 155246849Sjkim ACPI_OPERAND_OBJECT *NewObject = NULL; 156198237Sjkim ACPI_STATUS Status; 157246849Sjkim const ACPI_SIMPLE_REPAIR_INFO *Predefined; 158196000Sjkim 159196000Sjkim 160246849Sjkim ACPI_FUNCTION_NAME (NsSimpleRepair); 161200553Sjkim 162200553Sjkim 163198237Sjkim /* 164246849Sjkim * Special repairs for certain names that are in the repair table. 165246849Sjkim * Check if this name is in the list of repairable names. 166246849Sjkim */ 167249663Sjkim Predefined = AcpiNsMatchSimpleRepair (Info->Node, 168249663Sjkim Info->ReturnBtype, PackageIndex); 169246849Sjkim if (Predefined) 170246849Sjkim { 171246849Sjkim if (!ReturnObject) 172246849Sjkim { 173249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 174246849Sjkim ACPI_WARN_ALWAYS, "Missing expected return value")); 175246849Sjkim } 176246849Sjkim 177246849Sjkim Status = Predefined->ObjectConverter (ReturnObject, &NewObject); 178246849Sjkim if (ACPI_FAILURE (Status)) 179246849Sjkim { 180246849Sjkim /* A fatal error occurred during a conversion */ 181246849Sjkim 182246849Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 183246849Sjkim "During return object analysis")); 184246849Sjkim return (Status); 185246849Sjkim } 186246849Sjkim if (NewObject) 187246849Sjkim { 188246849Sjkim goto ObjectRepaired; 189246849Sjkim } 190246849Sjkim } 191246849Sjkim 192246849Sjkim /* 193246849Sjkim * Do not perform simple object repair unless the return type is not 194246849Sjkim * expected. 195246849Sjkim */ 196249663Sjkim if (Info->ReturnBtype & ExpectedBtypes) 197246849Sjkim { 198246849Sjkim return (AE_OK); 199246849Sjkim } 200246849Sjkim 201246849Sjkim /* 202198237Sjkim * At this point, we know that the type of the returned object was not 203198237Sjkim * one of the expected types for this predefined name. Attempt to 204200553Sjkim * repair the object by converting it to one of the expected object 205200553Sjkim * types for this predefined name. 206198237Sjkim */ 207246849Sjkim 208246849Sjkim /* 209246849Sjkim * If there is no return value, check if we require a return value for 210246849Sjkim * this predefined name. Either one return value is expected, or none, 211246849Sjkim * for both methods and other objects. 212246849Sjkim * 213281075Sdim * Try to fix if there was no return object. Warning if failed to fix. 214246849Sjkim */ 215246849Sjkim if (!ReturnObject) 216246849Sjkim { 217246849Sjkim if (ExpectedBtypes && (!(ExpectedBtypes & ACPI_RTYPE_NONE))) 218246849Sjkim { 219281075Sdim if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) 220281075Sdim { 221281075Sdim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 222281075Sdim ACPI_WARN_ALWAYS, "Found unexpected NULL package element")); 223246849Sjkim 224281075Sdim Status = AcpiNsRepairNullElement (Info, ExpectedBtypes, 225281075Sdim PackageIndex, ReturnObjectPtr); 226281075Sdim if (ACPI_SUCCESS (Status)) 227281075Sdim { 228281075Sdim return (AE_OK); /* Repair was successful */ 229281075Sdim } 230281075Sdim } 231281075Sdim else 232281075Sdim { 233281075Sdim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 234281075Sdim ACPI_WARN_ALWAYS, "Missing expected return value")); 235281075Sdim } 236281075Sdim 237246849Sjkim return (AE_AML_NO_RETURN_VALUE); 238246849Sjkim } 239246849Sjkim } 240246849Sjkim 241200553Sjkim if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 242196000Sjkim { 243200553Sjkim Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); 244200553Sjkim if (ACPI_SUCCESS (Status)) 245200553Sjkim { 246200553Sjkim goto ObjectRepaired; 247200553Sjkim } 248200553Sjkim } 249200553Sjkim if (ExpectedBtypes & ACPI_RTYPE_STRING) 250200553Sjkim { 251200553Sjkim Status = AcpiNsConvertToString (ReturnObject, &NewObject); 252200553Sjkim if (ACPI_SUCCESS (Status)) 253200553Sjkim { 254200553Sjkim goto ObjectRepaired; 255200553Sjkim } 256200553Sjkim } 257200553Sjkim if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 258200553Sjkim { 259200553Sjkim Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject); 260200553Sjkim if (ACPI_SUCCESS (Status)) 261200553Sjkim { 262200553Sjkim goto ObjectRepaired; 263200553Sjkim } 264200553Sjkim } 265200553Sjkim if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) 266200553Sjkim { 267233617Sjkim /* 268233617Sjkim * A package is expected. We will wrap the existing object with a 269233617Sjkim * new package object. It is often the case that if a variable-length 270233617Sjkim * package is required, but there is only a single object needed, the 271233617Sjkim * BIOS will return that object instead of wrapping it with a Package 272233617Sjkim * object. Note: after the wrapping, the package will be validated 273233617Sjkim * for correct contents (expected object type or types). 274233617Sjkim */ 275249663Sjkim Status = AcpiNsWrapWithPackage (Info, ReturnObject, &NewObject); 276200553Sjkim if (ACPI_SUCCESS (Status)) 277200553Sjkim { 278233617Sjkim /* 279233617Sjkim * The original object just had its reference count 280233617Sjkim * incremented for being inserted into the new package. 281233617Sjkim */ 282233617Sjkim *ReturnObjectPtr = NewObject; /* New Package object */ 283249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 284233617Sjkim return (AE_OK); 285200553Sjkim } 286200553Sjkim } 287200553Sjkim 288200553Sjkim /* We cannot repair this object */ 289200553Sjkim 290200553Sjkim return (AE_AML_OPERAND_TYPE); 291200553Sjkim 292200553Sjkim 293200553SjkimObjectRepaired: 294200553Sjkim 295200553Sjkim /* Object was successfully repaired */ 296200553Sjkim 297200553Sjkim if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) 298200553Sjkim { 299233617Sjkim /* 300233617Sjkim * The original object is a package element. We need to 301233617Sjkim * decrement the reference count of the original object, 302233617Sjkim * for removing it from the package. 303233617Sjkim * 304233617Sjkim * However, if the original object was just wrapped with a 305233617Sjkim * package object as part of the repair, we don't need to 306233617Sjkim * change the reference count. 307233617Sjkim */ 308249663Sjkim if (!(Info->ReturnFlags & ACPI_OBJECT_WRAPPED)) 309233617Sjkim { 310233617Sjkim NewObject->Common.ReferenceCount = 311233617Sjkim ReturnObject->Common.ReferenceCount; 312233555Sjkim 313233617Sjkim if (ReturnObject->Common.ReferenceCount > 1) 314233617Sjkim { 315233617Sjkim ReturnObject->Common.ReferenceCount--; 316233617Sjkim } 317200553Sjkim } 318200553Sjkim 319200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 320233617Sjkim "%s: Converted %s to expected %s at Package index %u\n", 321249663Sjkim Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), 322200553Sjkim AcpiUtGetObjectTypeName (NewObject), PackageIndex)); 323200553Sjkim } 324200553Sjkim else 325200553Sjkim { 326200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 327200553Sjkim "%s: Converted %s to expected %s\n", 328249663Sjkim Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), 329200553Sjkim AcpiUtGetObjectTypeName (NewObject))); 330200553Sjkim } 331200553Sjkim 332200553Sjkim /* Delete old object, install the new return object */ 333200553Sjkim 334200553Sjkim AcpiUtRemoveReference (ReturnObject); 335200553Sjkim *ReturnObjectPtr = NewObject; 336249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 337200553Sjkim return (AE_OK); 338200553Sjkim} 339200553Sjkim 340200553Sjkim 341246849Sjkim/****************************************************************************** 342200553Sjkim * 343246849Sjkim * FUNCTION: AcpiNsMatchSimpleRepair 344200553Sjkim * 345246849Sjkim * PARAMETERS: Node - Namespace node for the method/object 346246849Sjkim * ReturnBtype - Object type that was returned 347246849Sjkim * PackageIndex - Index of object within parent package (if 348246849Sjkim * applicable - ACPI_NOT_PACKAGE_ELEMENT 349246849Sjkim * otherwise) 350200553Sjkim * 351246849Sjkim * RETURN: Pointer to entry in repair table. NULL indicates not found. 352200553Sjkim * 353246849Sjkim * DESCRIPTION: Check an object name against the repairable object list. 354200553Sjkim * 355246849Sjkim *****************************************************************************/ 356200553Sjkim 357246849Sjkimstatic const ACPI_SIMPLE_REPAIR_INFO * 358246849SjkimAcpiNsMatchSimpleRepair ( 359246849Sjkim ACPI_NAMESPACE_NODE *Node, 360246849Sjkim UINT32 ReturnBtype, 361246849Sjkim UINT32 PackageIndex) 362200553Sjkim{ 363246849Sjkim const ACPI_SIMPLE_REPAIR_INFO *ThisName; 364200553Sjkim 365200553Sjkim 366246849Sjkim /* Search info table for a repairable predefined method/object name */ 367200553Sjkim 368246849Sjkim ThisName = AcpiObjectRepairInfo; 369246849Sjkim while (ThisName->ObjectConverter) 370200553Sjkim { 371246849Sjkim if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) 372200553Sjkim { 373246849Sjkim /* Check if we can actually repair this name/type combination */ 374200553Sjkim 375246849Sjkim if ((ReturnBtype & ThisName->UnexpectedBtypes) && 376246849Sjkim (PackageIndex == ThisName->PackageIndex)) 377200553Sjkim { 378246849Sjkim return (ThisName); 379200553Sjkim } 380200553Sjkim 381246849Sjkim return (NULL); 382196000Sjkim } 383246849Sjkim ThisName++; 384200553Sjkim } 385198237Sjkim 386246849Sjkim return (NULL); /* Name was not found in the repair table */ 387200553Sjkim} 388200553Sjkim 389200553Sjkim 390200553Sjkim/******************************************************************************* 391200553Sjkim * 392202771Sjkim * FUNCTION: AcpiNsRepairNullElement 393202771Sjkim * 394249663Sjkim * PARAMETERS: Info - Method execution information block 395202771Sjkim * ExpectedBtypes - Object types expected 396202771Sjkim * PackageIndex - Index of object within parent package (if 397202771Sjkim * applicable - ACPI_NOT_PACKAGE_ELEMENT 398202771Sjkim * otherwise) 399202771Sjkim * ReturnObjectPtr - Pointer to the object returned from the 400202771Sjkim * evaluation of a method or object 401202771Sjkim * 402202771Sjkim * RETURN: Status. AE_OK if repair was successful. 403202771Sjkim * 404202771Sjkim * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. 405202771Sjkim * 406202771Sjkim ******************************************************************************/ 407202771Sjkim 408202771SjkimACPI_STATUS 409202771SjkimAcpiNsRepairNullElement ( 410249663Sjkim ACPI_EVALUATE_INFO *Info, 411202771Sjkim UINT32 ExpectedBtypes, 412202771Sjkim UINT32 PackageIndex, 413202771Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 414202771Sjkim{ 415202771Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 416202771Sjkim ACPI_OPERAND_OBJECT *NewObject; 417202771Sjkim 418202771Sjkim 419202771Sjkim ACPI_FUNCTION_NAME (NsRepairNullElement); 420202771Sjkim 421202771Sjkim 422202771Sjkim /* No repair needed if return object is non-NULL */ 423202771Sjkim 424202771Sjkim if (ReturnObject) 425202771Sjkim { 426202771Sjkim return (AE_OK); 427202771Sjkim } 428202771Sjkim 429202771Sjkim /* 430202771Sjkim * Attempt to repair a NULL element of a Package object. This applies to 431202771Sjkim * predefined names that return a fixed-length package and each element 432202771Sjkim * is required. It does not apply to variable-length packages where NULL 433202771Sjkim * elements are allowed, especially at the end of the package. 434202771Sjkim */ 435202771Sjkim if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 436202771Sjkim { 437202771Sjkim /* Need an Integer - create a zero-value integer */ 438202771Sjkim 439209746Sjkim NewObject = AcpiUtCreateIntegerObject ((UINT64) 0); 440202771Sjkim } 441202771Sjkim else if (ExpectedBtypes & ACPI_RTYPE_STRING) 442202771Sjkim { 443202771Sjkim /* Need a String - create a NULL string */ 444202771Sjkim 445202771Sjkim NewObject = AcpiUtCreateStringObject (0); 446202771Sjkim } 447202771Sjkim else if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 448202771Sjkim { 449202771Sjkim /* Need a Buffer - create a zero-length buffer */ 450202771Sjkim 451202771Sjkim NewObject = AcpiUtCreateBufferObject (0); 452202771Sjkim } 453202771Sjkim else 454202771Sjkim { 455202771Sjkim /* Error for all other expected types */ 456202771Sjkim 457202771Sjkim return (AE_AML_OPERAND_TYPE); 458202771Sjkim } 459202771Sjkim 460202771Sjkim if (!NewObject) 461202771Sjkim { 462202771Sjkim return (AE_NO_MEMORY); 463202771Sjkim } 464202771Sjkim 465202771Sjkim /* Set the reference count according to the parent Package object */ 466202771Sjkim 467249663Sjkim NewObject->Common.ReferenceCount = Info->ParentPackage->Common.ReferenceCount; 468202771Sjkim 469202771Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 470202771Sjkim "%s: Converted NULL package element to expected %s at index %u\n", 471249663Sjkim Info->FullPathname, AcpiUtGetObjectTypeName (NewObject), PackageIndex)); 472202771Sjkim 473202771Sjkim *ReturnObjectPtr = NewObject; 474249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 475202771Sjkim return (AE_OK); 476202771Sjkim} 477202771Sjkim 478202771Sjkim 479202771Sjkim/****************************************************************************** 480202771Sjkim * 481202771Sjkim * FUNCTION: AcpiNsRemoveNullElements 482202771Sjkim * 483249663Sjkim * PARAMETERS: Info - Method execution information block 484202771Sjkim * PackageType - An AcpiReturnPackageTypes value 485202771Sjkim * ObjDesc - A Package object 486202771Sjkim * 487202771Sjkim * RETURN: None. 488202771Sjkim * 489202771Sjkim * DESCRIPTION: Remove all NULL package elements from packages that contain 490281075Sdim * a variable number of subpackages. For these types of 491202771Sjkim * packages, NULL elements can be safely removed. 492202771Sjkim * 493202771Sjkim *****************************************************************************/ 494202771Sjkim 495202771Sjkimvoid 496202771SjkimAcpiNsRemoveNullElements ( 497249663Sjkim ACPI_EVALUATE_INFO *Info, 498202771Sjkim UINT8 PackageType, 499202771Sjkim ACPI_OPERAND_OBJECT *ObjDesc) 500202771Sjkim{ 501202771Sjkim ACPI_OPERAND_OBJECT **Source; 502202771Sjkim ACPI_OPERAND_OBJECT **Dest; 503202771Sjkim UINT32 Count; 504202771Sjkim UINT32 NewCount; 505202771Sjkim UINT32 i; 506202771Sjkim 507202771Sjkim 508202771Sjkim ACPI_FUNCTION_NAME (NsRemoveNullElements); 509202771Sjkim 510202771Sjkim 511202771Sjkim /* 512220663Sjkim * We can safely remove all NULL elements from these package types: 513220663Sjkim * PTYPE1_VAR packages contain a variable number of simple data types. 514281075Sdim * PTYPE2 packages contain a variable number of subpackages. 515202771Sjkim */ 516202771Sjkim switch (PackageType) 517202771Sjkim { 518202771Sjkim case ACPI_PTYPE1_VAR: 519202771Sjkim case ACPI_PTYPE2: 520202771Sjkim case ACPI_PTYPE2_COUNT: 521202771Sjkim case ACPI_PTYPE2_PKG_COUNT: 522202771Sjkim case ACPI_PTYPE2_FIXED: 523202771Sjkim case ACPI_PTYPE2_MIN: 524202771Sjkim case ACPI_PTYPE2_REV_FIXED: 525228110Sjkim case ACPI_PTYPE2_FIX_VAR: 526202771Sjkim break; 527202771Sjkim 528202771Sjkim default: 529284460Sjkim case ACPI_PTYPE2_VAR_VAR: 530220663Sjkim case ACPI_PTYPE1_FIXED: 531220663Sjkim case ACPI_PTYPE1_OPTION: 532202771Sjkim return; 533202771Sjkim } 534202771Sjkim 535202771Sjkim Count = ObjDesc->Package.Count; 536202771Sjkim NewCount = Count; 537202771Sjkim 538202771Sjkim Source = ObjDesc->Package.Elements; 539202771Sjkim Dest = Source; 540202771Sjkim 541202771Sjkim /* Examine all elements of the package object, remove nulls */ 542202771Sjkim 543202771Sjkim for (i = 0; i < Count; i++) 544202771Sjkim { 545202771Sjkim if (!*Source) 546202771Sjkim { 547202771Sjkim NewCount--; 548202771Sjkim } 549202771Sjkim else 550202771Sjkim { 551202771Sjkim *Dest = *Source; 552202771Sjkim Dest++; 553202771Sjkim } 554202771Sjkim Source++; 555202771Sjkim } 556202771Sjkim 557202771Sjkim /* Update parent package if any null elements were removed */ 558202771Sjkim 559202771Sjkim if (NewCount < Count) 560202771Sjkim { 561202771Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 562202771Sjkim "%s: Found and removed %u NULL elements\n", 563249663Sjkim Info->FullPathname, (Count - NewCount))); 564202771Sjkim 565202771Sjkim /* NULL terminate list and update the package count */ 566202771Sjkim 567202771Sjkim *Dest = NULL; 568202771Sjkim ObjDesc->Package.Count = NewCount; 569202771Sjkim } 570202771Sjkim} 571202771Sjkim 572202771Sjkim 573202771Sjkim/******************************************************************************* 574202771Sjkim * 575233617Sjkim * FUNCTION: AcpiNsWrapWithPackage 576196000Sjkim * 577249663Sjkim * PARAMETERS: Info - Method execution information block 578233617Sjkim * OriginalObject - Pointer to the object to repair. 579233617Sjkim * ObjDescPtr - The new package object is returned here 580196000Sjkim * 581196000Sjkim * RETURN: Status, new object in *ObjDescPtr 582196000Sjkim * 583233617Sjkim * DESCRIPTION: Repair a common problem with objects that are defined to 584233617Sjkim * return a variable-length Package of sub-objects. If there is 585233617Sjkim * only one sub-object, some BIOS code mistakenly simply declares 586233617Sjkim * the single object instead of a Package with one sub-object. 587233617Sjkim * This function attempts to repair this error by wrapping a 588233617Sjkim * Package object around the original object, creating the 589233617Sjkim * correct and expected Package with one sub-object. 590196000Sjkim * 591196000Sjkim * Names that can be repaired in this manner include: 592233617Sjkim * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, 593233617Sjkim * _BCL, _DOD, _FIX, _Sx 594196000Sjkim * 595196000Sjkim ******************************************************************************/ 596196000Sjkim 597196000SjkimACPI_STATUS 598233617SjkimAcpiNsWrapWithPackage ( 599249663Sjkim ACPI_EVALUATE_INFO *Info, 600233617Sjkim ACPI_OPERAND_OBJECT *OriginalObject, 601196000Sjkim ACPI_OPERAND_OBJECT **ObjDescPtr) 602196000Sjkim{ 603196000Sjkim ACPI_OPERAND_OBJECT *PkgObjDesc; 604196000Sjkim 605196000Sjkim 606233617Sjkim ACPI_FUNCTION_NAME (NsWrapWithPackage); 607200553Sjkim 608200553Sjkim 609196000Sjkim /* 610196000Sjkim * Create the new outer package and populate it. The new package will 611233617Sjkim * have a single element, the lone sub-object. 612196000Sjkim */ 613196000Sjkim PkgObjDesc = AcpiUtCreatePackageObject (1); 614196000Sjkim if (!PkgObjDesc) 615196000Sjkim { 616196000Sjkim return (AE_NO_MEMORY); 617196000Sjkim } 618196000Sjkim 619233617Sjkim PkgObjDesc->Package.Elements[0] = OriginalObject; 620196000Sjkim 621233617Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 622233617Sjkim "%s: Wrapped %s with expected Package object\n", 623249663Sjkim Info->FullPathname, AcpiUtGetObjectTypeName (OriginalObject))); 624233617Sjkim 625196000Sjkim /* Return the new object in the object pointer */ 626196000Sjkim 627196000Sjkim *ObjDescPtr = PkgObjDesc; 628249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; 629196000Sjkim return (AE_OK); 630196000Sjkim} 631