nsrepair.c revision 259065
11541Srgrimes/****************************************************************************** 21541Srgrimes * 31541Srgrimes * Module Name: nsrepair - Repair for objects returned by predefined methods 41541Srgrimes * 551138Salfred *****************************************************************************/ 6250155Sjilles 71541Srgrimes/* 81541Srgrimes * Copyright (C) 2000 - 2013, Intel Corp. 9106149Sdwmalone * All rights reserved. 101541Srgrimes * 1164002Speter * Redistribution and use in source and binary forms, with or without 121541Srgrimes * modification, are permitted provided that the following conditions 131541Srgrimes * are met: 141541Srgrimes * 1. Redistributions of source code must retain the above copyright 151541Srgrimes * notice, this list of conditions, and the following disclaimer, 161541Srgrimes * without modification. 171541Srgrimes * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18171210Speter * substantially similar to the "NO WARRANTY" disclaimer below 191541Srgrimes * ("Disclaimer") and any redistribution must be conditioned upon 201541Srgrimes * including a substantially similar Disclaimer requirement for further 211541Srgrimes * binary redistribution. 221541Srgrimes * 3. Neither the names of the above-listed copyright holders nor the names 231541Srgrimes * of any contributors may be used to endorse or promote products derived 241541Srgrimes * from this software without specific prior written permission. 251541Srgrimes * 261541Srgrimes * Alternatively, this software may be distributed under the terms of the 271541Srgrimes * GNU General Public License ("GPL") version 2 as published by the Free 28194392Sjhb * Software Foundation. 29171210Speter * 301541Srgrimes * NO WARRANTY 311541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 321541Srgrimes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 331541Srgrimes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 341541Srgrimes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 351541Srgrimes * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 361541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 371541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 381541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 391541Srgrimes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 401541Srgrimes * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 411541Srgrimes * POSSIBILITY OF SUCH DAMAGES. 421541Srgrimes */ 431541Srgrimes 441541Srgrimes#define __NSREPAIR_C__ 451541Srgrimes 461541Srgrimes#include <contrib/dev/acpica/include/acpi.h> 471541Srgrimes#include <contrib/dev/acpica/include/accommon.h> 48171210Speter#include <contrib/dev/acpica/include/acnamesp.h> 491541Srgrimes#include <contrib/dev/acpica/include/acinterp.h> 50171210Speter#include <contrib/dev/acpica/include/acpredef.h> 511541Srgrimes#include <contrib/dev/acpica/include/amlresrc.h> 521541Srgrimes 531541Srgrimes#define _COMPONENT ACPI_NAMESPACE 541541Srgrimes ACPI_MODULE_NAME ("nsrepair") 551541Srgrimes 56171210Speter 571541Srgrimes/******************************************************************************* 58171210Speter * 591541Srgrimes * This module attempts to repair or convert objects returned by the 601541Srgrimes * predefined methods to an object type that is expected, as per the ACPI 611541Srgrimes * specification. The need for this code is dictated by the many machines that 62171210Speter * return incorrect types for the standard predefined methods. Performing these 631541Srgrimes * conversions here, in one place, eliminates the need for individual ACPI 641541Srgrimes * device drivers to do the same. Note: Most of these conversions are different 651541Srgrimes * than the internal object conversion routines used for implicit object 661541Srgrimes * conversion. 671541Srgrimes * 681541Srgrimes * The following conversions can be performed as necessary: 691541Srgrimes * 701541Srgrimes * Integer -> String 711541Srgrimes * Integer -> Buffer 72171210Speter * String -> Integer 73171210Speter * String -> Buffer 74171210Speter * Buffer -> Integer 751541Srgrimes * Buffer -> String 761541Srgrimes * Buffer -> Package of Integers 771541Srgrimes * Package -> Package of one Package 781541Srgrimes * 791541Srgrimes * Additional conversions that are available: 801541Srgrimes * Convert a null return or zero return value to an EndTag descriptor 81171210Speter * Convert an ASCII string to a Unicode buffer 821541Srgrimes * 831541Srgrimes * An incorrect standalone object is wrapped with required outer package 841541Srgrimes * 851541Srgrimes * Additional possible repairs: 861541Srgrimes * Required package elements that are NULL replaced by Integer/String/Buffer 871541Srgrimes * 881541Srgrimes ******************************************************************************/ 891541Srgrimes 901541Srgrimes 911541Srgrimes/* Local prototypes */ 921541Srgrimes 931541Srgrimesstatic const ACPI_SIMPLE_REPAIR_INFO * 94171210SpeterAcpiNsMatchSimpleRepair ( 951541Srgrimes ACPI_NAMESPACE_NODE *Node, 961541Srgrimes UINT32 ReturnBtype, 97171210Speter UINT32 PackageIndex); 98171210Speter 991541Srgrimes 1001541Srgrimes/* 1011541Srgrimes * Special but simple repairs for some names. 1021541Srgrimes * 1031541Srgrimes * 2nd argument: Unexpected types that can be repaired 1041541Srgrimes */ 1051541Srgrimesstatic const ACPI_SIMPLE_REPAIR_INFO AcpiObjectRepairInfo[] = 1061541Srgrimes{ 1071541Srgrimes /* Resource descriptor conversions */ 1081541Srgrimes 109171210Speter { "_CRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, 1101541Srgrimes ACPI_NOT_PACKAGE_ELEMENT, 111171210Speter AcpiNsConvertToResource }, 112171210Speter { "_DMA", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, 113171210Speter ACPI_NOT_PACKAGE_ELEMENT, 1141541Srgrimes AcpiNsConvertToResource }, 1151541Srgrimes { "_PRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, 1161541Srgrimes ACPI_NOT_PACKAGE_ELEMENT, 1171541Srgrimes AcpiNsConvertToResource }, 118171210Speter 119171210Speter /* Unicode conversions */ 120171210Speter 121171210Speter { "_MLS", ACPI_RTYPE_STRING, 1, 122171210Speter AcpiNsConvertToUnicode }, 123171210Speter { "_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 124171210Speter ACPI_NOT_PACKAGE_ELEMENT, 1251541Srgrimes AcpiNsConvertToUnicode }, 1261541Srgrimes { {0,0,0,0}, 0, 0, NULL } /* Table terminator */ 1271541Srgrimes}; 1281541Srgrimes 12914220Speter 1301541Srgrimes/******************************************************************************* 1311541Srgrimes * 1321541Srgrimes * FUNCTION: AcpiNsSimpleRepair 1331541Srgrimes * 1341541Srgrimes * PARAMETERS: Info - Method execution information block 135171210Speter * ExpectedBtypes - Object types expected 1368019Sache * PackageIndex - Index of object within parent package (if 1378019Sache * applicable - ACPI_NOT_PACKAGE_ELEMENT 1381541Srgrimes * otherwise) 139171210Speter * ReturnObjectPtr - Pointer to the object returned from the 140171210Speter * evaluation of a method or object 1411541Srgrimes * 1421541Srgrimes * RETURN: Status. AE_OK if repair was successful. 1431541Srgrimes * 1441541Srgrimes * DESCRIPTION: Attempt to repair/convert a return object of a type that was 1451541Srgrimes * not expected. 1461541Srgrimes * 1471541Srgrimes ******************************************************************************/ 1481541Srgrimes 1491541SrgrimesACPI_STATUS 1501541SrgrimesAcpiNsSimpleRepair ( 151171210Speter ACPI_EVALUATE_INFO *Info, 152171210Speter UINT32 ExpectedBtypes, 153171210Speter UINT32 PackageIndex, 154171210Speter ACPI_OPERAND_OBJECT **ReturnObjectPtr) 155171210Speter{ 156171210Speter ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 1571541Srgrimes ACPI_OPERAND_OBJECT *NewObject = NULL; 1581541Srgrimes ACPI_STATUS Status; 159171210Speter const ACPI_SIMPLE_REPAIR_INFO *Predefined; 160171210Speter 16114220Speter 16214220Speter ACPI_FUNCTION_NAME (NsSimpleRepair); 16314220Speter 164177634Sdfr 1651541Srgrimes /* 166171210Speter * Special repairs for certain names that are in the repair table. 167194392Sjhb * Check if this name is in the list of repairable names. 168194392Sjhb */ 1691541Srgrimes Predefined = AcpiNsMatchSimpleRepair (Info->Node, 170127891Sdfr Info->ReturnBtype, PackageIndex); 1711541Srgrimes if (Predefined) 172194392Sjhb { 173194392Sjhb if (!ReturnObject) 174194392Sjhb { 1751549Srgrimes ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 1762442Sdg ACPI_WARN_ALWAYS, "Missing expected return value")); 1771541Srgrimes } 1781541Srgrimes 1792729Sdfr Status = Predefined->ObjectConverter (ReturnObject, &NewObject); 1802729Sdfr if (ACPI_FAILURE (Status)) 1811541Srgrimes { 1821541Srgrimes /* A fatal error occurred during a conversion */ 183171210Speter 184171210Speter ACPI_EXCEPTION ((AE_INFO, Status, 185178888Sjulian "During return object analysis")); 1862297Swollman return (Status); 18714220Speter } 18814220Speter if (NewObject) 18914220Speter { 1901541Srgrimes goto ObjectRepaired; 1911541Srgrimes } 1921541Srgrimes } 1931541Srgrimes 19432889Sphk /* 19532889Sphk * Do not perform simple object repair unless the return type is not 19632889Sphk * expected. 19732889Sphk */ 1981541Srgrimes if (Info->ReturnBtype & ExpectedBtypes) 1991541Srgrimes { 2001541Srgrimes return (AE_OK); 2011541Srgrimes } 2021541Srgrimes 2031541Srgrimes /* 2041541Srgrimes * At this point, we know that the type of the returned object was not 2051541Srgrimes * one of the expected types for this predefined name. Attempt to 2061541Srgrimes * repair the object by converting it to one of the expected object 207171210Speter * types for this predefined name. 2081541Srgrimes */ 209171210Speter 210171210Speter /* 211171210Speter * If there is no return value, check if we require a return value for 2121541Srgrimes * this predefined name. Either one return value is expected, or none, 2131541Srgrimes * for both methods and other objects. 2141541Srgrimes * 21535938Sdyson * Exit now if there is no return object. Warning if one was expected. 21635938Sdyson */ 21728400Speter if (!ReturnObject) 21825582Speter { 21929349Speter if (ExpectedBtypes && (!(ExpectedBtypes & ACPI_RTYPE_NONE))) 2202124Sdg { 2212124Sdg ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 2222124Sdg ACPI_WARN_ALWAYS, "Missing expected return value")); 2232124Sdg 2242124Sdg return (AE_AML_NO_RETURN_VALUE); 2252124Sdg } 2262124Sdg } 2272124Sdg 2282124Sdg if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 2292124Sdg { 230194919Sjhb Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); 23112865Speter if (ACPI_SUCCESS (Status)) 23212865Speter { 23359829Speter goto ObjectRepaired; 234194919Sjhb } 23512865Speter } 23612865Speter if (ExpectedBtypes & ACPI_RTYPE_STRING) 23712865Speter { 23812865Speter Status = AcpiNsConvertToString (ReturnObject, &NewObject); 239194919Sjhb if (ACPI_SUCCESS (Status)) 24012865Speter { 24112865Speter goto ObjectRepaired; 24225582Speter } 24325582Speter } 24425582Speter if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 245156138Sdavidxu { 246156138Sdavidxu Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject); 247156138Sdavidxu if (ACPI_SUCCESS (Status)) 248156138Sdavidxu { 249156138Sdavidxu goto ObjectRepaired; 25025582Speter } 251227776Slstewart } 252227776Slstewart if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) 253227776Slstewart { 25414220Speter /* 25514220Speter * A package is expected. We will wrap the existing object with a 25614220Speter * new package object. It is often the case that if a variable-length 257239347Sdavidxu * package is required, but there is only a single object needed, the 258137875Smarks * BIOS will return that object instead of wrapping it with a Package 25914220Speter * object. Note: after the wrapping, the package will be validated 26014220Speter * for correct contents (expected object type or types). 26114220Speter */ 26229349Speter Status = AcpiNsWrapWithPackage (Info, ReturnObject, &NewObject); 26324452Speter if (ACPI_SUCCESS (Status)) 26424440Speter { 265151868Sdavidxu /* 266151868Sdavidxu * The original object just had its reference count 267151868Sdavidxu * incremented for being inserted into the new package. 268152846Sdavidxu */ 269152846Sdavidxu *ReturnObjectPtr = NewObject; /* New Package object */ 270152846Sdavidxu Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 271152846Sdavidxu return (AE_OK); 272152846Sdavidxu } 273152846Sdavidxu } 27425537Sdfr 27525537Sdfr /* We cannot repair this object */ 27625537Sdfr 27725537Sdfr return (AE_AML_OPERAND_TYPE); 27825537Sdfr 27925537Sdfr 28025537SdfrObjectRepaired: 28125537Sdfr 28235938Sdyson /* Object was successfully repaired */ 28325537Sdfr 28435938Sdyson if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) 28535938Sdyson { 28635938Sdyson /* 28735938Sdyson * The original object is a package element. We need to 28835938Sdyson * decrement the reference count of the original object, 28935938Sdyson * for removing it from the package. 29035938Sdyson * 29125537Sdfr * However, if the original object was just wrapped with a 29225537Sdfr * package object as part of the repair, we don't need to 29325537Sdfr * change the reference count. 29425537Sdfr */ 29525537Sdfr if (!(Info->ReturnFlags & ACPI_OBJECT_WRAPPED)) 29625537Sdfr { 29725537Sdfr NewObject->Common.ReferenceCount = 29825537Sdfr ReturnObject->Common.ReferenceCount; 299147814Sjhb 300147814Sjhb if (ReturnObject->Common.ReferenceCount > 1) 30125537Sdfr { 30225537Sdfr ReturnObject->Common.ReferenceCount--; 30325537Sdfr } 30425537Sdfr } 30525537Sdfr 30625537Sdfr ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 307194392Sjhb "%s: Converted %s to expected %s at Package index %u\n", 30851138Salfred Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), 30951138Salfred AcpiUtGetObjectTypeName (NewObject), PackageIndex)); 31025537Sdfr } 31125537Sdfr else 31225537Sdfr { 31325537Sdfr ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 31425537Sdfr "%s: Converted %s to expected %s\n", 31525537Sdfr Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), 31625537Sdfr AcpiUtGetObjectTypeName (NewObject))); 31725537Sdfr } 31825537Sdfr 31925537Sdfr /* Delete old object, install the new return object */ 32028400Speter 32156115Speter AcpiUtRemoveReference (ReturnObject); 32256115Speter *ReturnObjectPtr = NewObject; 32336034Speter Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 32426671Sdyson return (AE_OK); 32526671Sdyson} 32626671Sdyson 32726671Sdyson 328151868Sdavidxu/****************************************************************************** 329151868Sdavidxu * 330151868Sdavidxu * FUNCTION: AcpiNsMatchSimpleRepair 33126671Sdyson * 33269514Sjake * PARAMETERS: Node - Namespace node for the method/object 33369514Sjake * ReturnBtype - Object type that was returned 33426671Sdyson * PackageIndex - Index of object within parent package (if 33526671Sdyson * applicable - ACPI_NOT_PACKAGE_ELEMENT 33629391Sphk * otherwise) 33734925Sdufault * 33834925Sdufault * RETURN: Pointer to entry in repair table. NULL indicates not found. 33934925Sdufault * 34034925Sdufault * DESCRIPTION: Check an object name against the repairable object list. 34134925Sdufault * 34234925Sdufault *****************************************************************************/ 34334925Sdufault 34434925Sdufaultstatic const ACPI_SIMPLE_REPAIR_INFO * 34535938SdysonAcpiNsMatchSimpleRepair ( 346194392Sjhb ACPI_NAMESPACE_NODE *Node, 34741089Speter UINT32 ReturnBtype, 34846155Sphk UINT32 PackageIndex) 349211999Skib{ 35051791Smarcel const ACPI_SIMPLE_REPAIR_INFO *ThisName; 35151791Smarcel 352194392Sjhb 35351791Smarcel /* Search info table for a repairable predefined method/object name */ 354194392Sjhb 355112895Sjeff ThisName = AcpiObjectRepairInfo; 356112895Sjeff while (ThisName->ObjectConverter) 35756271Srwatson { 35856271Srwatson if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) 35956271Srwatson { 36056271Srwatson /* Check if we can actually repair this name/type combination */ 36156271Srwatson 36256271Srwatson if ((ReturnBtype & ThisName->UnexpectedBtypes) && 36356271Srwatson (PackageIndex == ThisName->PackageIndex)) 36456271Srwatson { 36554803Srwatson return (ThisName); 36654803Srwatson } 36754803Srwatson 36854803Srwatson return (NULL); 36955943Sjasone } 37056115Speter ThisName++; 37156115Speter } 37259288Sjlemon 37359288Sjlemon return (NULL); /* Name was not found in the repair table */ 37498198Srwatson} 37598198Srwatson 37698198Srwatson 37798198Srwatson/******************************************************************************* 37898198Srwatson * 37998198Srwatson * FUNCTION: AcpiNsRepairNullElement 380183362Sjhb * 38175039Srwatson * PARAMETERS: Info - Method execution information block 38275039Srwatson * ExpectedBtypes - Object types expected 38375039Srwatson * PackageIndex - Index of object within parent package (if 38475427Srwatson * applicable - ACPI_NOT_PACKAGE_ELEMENT 385194392Sjhb * otherwise) 38683796Srwatson * ReturnObjectPtr - Pointer to the object returned from the 387211999Skib * evaluation of a method or object 38885891Sphk * 389177091Sjeff * RETURN: Status. AE_OK if repair was successful. 390177091Sjeff * 391177091Sjeff * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. 392177091Sjeff * 393177091Sjeff ******************************************************************************/ 394100897Srwatson 395100897SrwatsonACPI_STATUS 396100897SrwatsonAcpiNsRepairNullElement ( 397100897Srwatson ACPI_EVALUATE_INFO *Info, 398100897Srwatson UINT32 ExpectedBtypes, 399100897Srwatson UINT32 PackageIndex, 40094936Smux ACPI_OPERAND_OBJECT **ReturnObjectPtr) 40196084Smux{ 40297372Smarcel ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 40399856Salfred ACPI_OPERAND_OBJECT *NewObject; 404101426Srwatson 405122540Smckusick 406122540Smckusick ACPI_FUNCTION_NAME (NsRepairNullElement); 407122540Smckusick 408122540Smckusick 409103575Salfred /* No repair needed if return object is non-NULL */ 410103575Salfred 411103575Salfred if (ReturnObject) 412103575Salfred { 413103575Salfred return (AE_OK); 414103575Salfred } 415103575Salfred 416103575Salfred /* 417103575Salfred * Attempt to repair a NULL element of a Package object. This applies to 418103575Salfred * predefined names that return a fixed-length package and each element 419105692Srwatson * is required. It does not apply to variable-length packages where NULL 420105692Srwatson * elements are allowed, especially at the end of the package. 421105692Srwatson */ 422104731Srwatson if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 423104731Srwatson { 424104731Srwatson /* Need an Integer - create a zero-value integer */ 425106467Srwatson 426105950Speter NewObject = AcpiUtCreateIntegerObject ((UINT64) 0); 427105950Speter } 428105692Srwatson else if (ExpectedBtypes & ACPI_RTYPE_STRING) 429105692Srwatson { 430105692Srwatson /* Need a String - create a NULL string */ 431106978Sdeischen 432106978Sdeischen NewObject = AcpiUtCreateStringObject (0); 433106978Sdeischen } 434107914Sdillon else if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 435108406Srwatson { 436108406Srwatson /* Need a Buffer - create a zero-length buffer */ 437108406Srwatson 438108406Srwatson NewObject = AcpiUtCreateBufferObject (0); 439112895Sjeff } 440112902Sjeff else 441112902Sjeff { 442112902Sjeff /* Error for all other expected types */ 443112902Sjeff 444112909Sjeff return (AE_AML_OPERAND_TYPE); 445112909Sjeff } 446113276Smike 447115800Srwatson if (!NewObject) 448115800Srwatson { 449115800Srwatson return (AE_NO_MEMORY); 450177091Sjeff } 451125369Sdeischen 452127484Smtm /* Set the reference count according to the parent Package object */ 453127484Smtm 454132117Sphk NewObject->Common.ReferenceCount = Info->ParentPackage->Common.ReferenceCount; 455136831Srwatson 456136831Srwatson ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 457136831Srwatson "%s: Converted NULL package element to expected %s at index %u\n", 458136831Srwatson Info->FullPathname, AcpiUtGetObjectTypeName (NewObject), PackageIndex)); 459136831Srwatson 460136831Srwatson *ReturnObjectPtr = NewObject; 461136831Srwatson Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 462136831Srwatson return (AE_OK); 463136831Srwatson} 464139013Sdavidxu 465145435Sdavidxu 466151317Sdavidxu/****************************************************************************** 467156138Sdavidxu * 468156138Sdavidxu * FUNCTION: AcpiNsRemoveNullElements 469156138Sdavidxu * 470156138Sdavidxu * PARAMETERS: Info - Method execution information block 471156138Sdavidxu * PackageType - An AcpiReturnPackageTypes value 472156138Sdavidxu * ObjDesc - A Package object 473153681Sphk * 474155328Sdavidxu * RETURN: None. 475157039Sdavidxu * 476162498Sdavidxu * DESCRIPTION: Remove all NULL package elements from packages that contain 477162498Sdavidxu * a variable number of sub-packages. For these types of 478162498Sdavidxu * packages, NULL elements can be safely removed. 479161679Sdavidxu * 480161679Sdavidxu *****************************************************************************/ 481163953Srrs 482163953Srrsvoid 483163953SrrsAcpiNsRemoveNullElements ( 484163953Srrs ACPI_EVALUATE_INFO *Info, 485171210Speter UINT8 PackageType, 486171210Speter ACPI_OPERAND_OBJECT *ObjDesc) 487171210Speter{ 488171210Speter ACPI_OPERAND_OBJECT **Source; 489171210Speter ACPI_OPERAND_OBJECT **Dest; 490171210Speter UINT32 Count; 491171861Sdavidxu UINT32 NewCount; 492175165Sjhb UINT32 i; 493175165Sjhb 494176731Sjeff 495176731Sjeff ACPI_FUNCTION_NAME (NsRemoveNullElements); 496176731Sjeff 497176731Sjeff 498176731Sjeff /* 499177790Skib * We can safely remove all NULL elements from these package types: 500177790Skib * PTYPE1_VAR packages contain a variable number of simple data types. 501177790Skib * PTYPE2 packages contain a variable number of sub-packages. 502177790Skib */ 503177790Skib switch (PackageType) 504177790Skib { 505177790Skib case ACPI_PTYPE1_VAR: 506177790Skib case ACPI_PTYPE2: 507177790Skib case ACPI_PTYPE2_COUNT: 508177790Skib case ACPI_PTYPE2_PKG_COUNT: 509177790Skib case ACPI_PTYPE2_FIXED: 510177790Skib case ACPI_PTYPE2_MIN: 511177790Skib case ACPI_PTYPE2_REV_FIXED: 512177790Skib case ACPI_PTYPE2_FIX_VAR: 513177790Skib 514181905Sed break; 515184589Sdfr 516191675Sjamie default: 517191675Sjamie case ACPI_PTYPE1_FIXED: 518191675Sjamie case ACPI_PTYPE1_OPTION: 519194263Sjhb return; 520194919Sjhb } 521194919Sjhb 522194919Sjhb Count = ObjDesc->Package.Count; 523195459Strasz NewCount = Count; 524224067Sjonathan 525247604Spjd Source = ObjDesc->Package.Elements; 526219132Srwatson Dest = Source; 527219132Srwatson 528224988Sjonathan /* Examine all elements of the package object, remove nulls */ 529224988Sjonathan 530224988Sjonathan for (i = 0; i < Count; i++) 531224988Sjonathan { 532198510Skib if (!*Source) 533219305Strasz { 534219305Strasz NewCount--; 535220164Strasz } 536220164Strasz else 537220164Strasz { 538220164Strasz *Dest = *Source; 539220164Strasz Dest++; 540220792Smdf } 541227071Sjhb Source++; 542242959Skib } 543247604Spjd 544247604Spjd /* Update parent package if any null elements were removed */ 545247604Spjd 546247604Spjd if (NewCount < Count) 547247604Spjd { 548247668Spjd ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 549247668Spjd "%s: Found and removed %u NULL elements\n", 550248600Spjd Info->FullPathname, (Count - NewCount))); 551250155Sjilles 5521541Srgrimes /* NULL terminate list and update the package count */ 553 554 *Dest = NULL; 555 ObjDesc->Package.Count = NewCount; 556 } 557} 558 559 560/******************************************************************************* 561 * 562 * FUNCTION: AcpiNsWrapWithPackage 563 * 564 * PARAMETERS: Info - Method execution information block 565 * OriginalObject - Pointer to the object to repair. 566 * ObjDescPtr - The new package object is returned here 567 * 568 * RETURN: Status, new object in *ObjDescPtr 569 * 570 * DESCRIPTION: Repair a common problem with objects that are defined to 571 * return a variable-length Package of sub-objects. If there is 572 * only one sub-object, some BIOS code mistakenly simply declares 573 * the single object instead of a Package with one sub-object. 574 * This function attempts to repair this error by wrapping a 575 * Package object around the original object, creating the 576 * correct and expected Package with one sub-object. 577 * 578 * Names that can be repaired in this manner include: 579 * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, 580 * _BCL, _DOD, _FIX, _Sx 581 * 582 ******************************************************************************/ 583 584ACPI_STATUS 585AcpiNsWrapWithPackage ( 586 ACPI_EVALUATE_INFO *Info, 587 ACPI_OPERAND_OBJECT *OriginalObject, 588 ACPI_OPERAND_OBJECT **ObjDescPtr) 589{ 590 ACPI_OPERAND_OBJECT *PkgObjDesc; 591 592 593 ACPI_FUNCTION_NAME (NsWrapWithPackage); 594 595 596 /* 597 * Create the new outer package and populate it. The new package will 598 * have a single element, the lone sub-object. 599 */ 600 PkgObjDesc = AcpiUtCreatePackageObject (1); 601 if (!PkgObjDesc) 602 { 603 return (AE_NO_MEMORY); 604 } 605 606 PkgObjDesc->Package.Elements[0] = OriginalObject; 607 608 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 609 "%s: Wrapped %s with expected Package object\n", 610 Info->FullPathname, AcpiUtGetObjectTypeName (OriginalObject))); 611 612 /* Return the new object in the object pointer */ 613 614 *ObjDescPtr = PkgObjDesc; 615 Info->ReturnFlags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; 616 return (AE_OK); 617} 618