157190917SDana Myers /****************************************************************************** 257190917SDana Myers * 357190917SDana Myers * Module Name: nsrepair - Repair for objects returned by predefined methods 457190917SDana Myers * 557190917SDana Myers *****************************************************************************/ 657190917SDana Myers 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 957190917SDana Myers * All rights reserved. 1057190917SDana Myers * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 2557190917SDana Myers * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 2957190917SDana Myers * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 4357190917SDana Myers 4457190917SDana Myers #include "acpi.h" 4557190917SDana Myers #include "accommon.h" 4657190917SDana Myers #include "acnamesp.h" 4757190917SDana Myers #include "acinterp.h" 4857190917SDana Myers #include "acpredef.h" 49*385cc6b4SJerry Jelinek #include "amlresrc.h" 5057190917SDana Myers 5157190917SDana Myers #define _COMPONENT ACPI_NAMESPACE 5257190917SDana Myers ACPI_MODULE_NAME ("nsrepair") 5357190917SDana Myers 5457190917SDana Myers 5557190917SDana Myers /******************************************************************************* 5657190917SDana Myers * 5726f3cdf0SGordon Ross * This module attempts to repair or convert objects returned by the 5826f3cdf0SGordon Ross * predefined methods to an object type that is expected, as per the ACPI 5926f3cdf0SGordon Ross * specification. The need for this code is dictated by the many machines that 6026f3cdf0SGordon Ross * return incorrect types for the standard predefined methods. Performing these 6126f3cdf0SGordon Ross * conversions here, in one place, eliminates the need for individual ACPI 6226f3cdf0SGordon Ross * device drivers to do the same. Note: Most of these conversions are different 6326f3cdf0SGordon Ross * than the internal object conversion routines used for implicit object 6426f3cdf0SGordon Ross * conversion. 6526f3cdf0SGordon Ross * 6626f3cdf0SGordon Ross * The following conversions can be performed as necessary: 6726f3cdf0SGordon Ross * 6826f3cdf0SGordon Ross * Integer -> String 6926f3cdf0SGordon Ross * Integer -> Buffer 7026f3cdf0SGordon Ross * String -> Integer 7126f3cdf0SGordon Ross * String -> Buffer 7226f3cdf0SGordon Ross * Buffer -> Integer 7326f3cdf0SGordon Ross * Buffer -> String 7426f3cdf0SGordon Ross * Buffer -> Package of Integers 7526f3cdf0SGordon Ross * Package -> Package of one Package 7626f3cdf0SGordon Ross * 77*385cc6b4SJerry Jelinek * Additional conversions that are available: 78*385cc6b4SJerry Jelinek * Convert a null return or zero return value to an EndTag descriptor 79*385cc6b4SJerry Jelinek * Convert an ASCII string to a Unicode buffer 8026f3cdf0SGordon Ross * 81*385cc6b4SJerry Jelinek * An incorrect standalone object is wrapped with required outer package 82*385cc6b4SJerry Jelinek * 83*385cc6b4SJerry Jelinek * Additional possible repairs: 8426f3cdf0SGordon Ross * Required package elements that are NULL replaced by Integer/String/Buffer 8526f3cdf0SGordon Ross * 8626f3cdf0SGordon Ross ******************************************************************************/ 8726f3cdf0SGordon Ross 8826f3cdf0SGordon Ross 8926f3cdf0SGordon Ross /* Local prototypes */ 9026f3cdf0SGordon Ross 91*385cc6b4SJerry Jelinek static const ACPI_SIMPLE_REPAIR_INFO * 92*385cc6b4SJerry Jelinek AcpiNsMatchSimpleRepair ( 93*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *Node, 94*385cc6b4SJerry Jelinek UINT32 ReturnBtype, 95*385cc6b4SJerry Jelinek UINT32 PackageIndex); 9626f3cdf0SGordon Ross 9726f3cdf0SGordon Ross 98*385cc6b4SJerry Jelinek /* 99*385cc6b4SJerry Jelinek * Special but simple repairs for some names. 100*385cc6b4SJerry Jelinek * 101*385cc6b4SJerry Jelinek * 2nd argument: Unexpected types that can be repaired 102*385cc6b4SJerry Jelinek */ 103*385cc6b4SJerry Jelinek static const ACPI_SIMPLE_REPAIR_INFO AcpiObjectRepairInfo[] = 104*385cc6b4SJerry Jelinek { 105*385cc6b4SJerry Jelinek /* Resource descriptor conversions */ 10626f3cdf0SGordon Ross 107*385cc6b4SJerry Jelinek { "_CRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, 108*385cc6b4SJerry Jelinek ACPI_NOT_PACKAGE_ELEMENT, 109*385cc6b4SJerry Jelinek AcpiNsConvertToResource }, 110*385cc6b4SJerry Jelinek { "_DMA", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, 111*385cc6b4SJerry Jelinek ACPI_NOT_PACKAGE_ELEMENT, 112*385cc6b4SJerry Jelinek AcpiNsConvertToResource }, 113*385cc6b4SJerry Jelinek { "_PRS", ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | ACPI_RTYPE_NONE, 114*385cc6b4SJerry Jelinek ACPI_NOT_PACKAGE_ELEMENT, 115*385cc6b4SJerry Jelinek AcpiNsConvertToResource }, 116*385cc6b4SJerry Jelinek 117*385cc6b4SJerry Jelinek /* Object reference conversions */ 118*385cc6b4SJerry Jelinek 119*385cc6b4SJerry Jelinek { "_DEP", ACPI_RTYPE_STRING, ACPI_ALL_PACKAGE_ELEMENTS, 120*385cc6b4SJerry Jelinek AcpiNsConvertToReference }, 121*385cc6b4SJerry Jelinek 122*385cc6b4SJerry Jelinek /* Unicode conversions */ 123*385cc6b4SJerry Jelinek 124*385cc6b4SJerry Jelinek { "_MLS", ACPI_RTYPE_STRING, 1, 125*385cc6b4SJerry Jelinek AcpiNsConvertToUnicode }, 126*385cc6b4SJerry Jelinek { "_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 127*385cc6b4SJerry Jelinek ACPI_NOT_PACKAGE_ELEMENT, 128*385cc6b4SJerry Jelinek AcpiNsConvertToUnicode }, 129*385cc6b4SJerry Jelinek { {0,0,0,0}, 0, 0, NULL } /* Table terminator */ 130*385cc6b4SJerry Jelinek }; 13126f3cdf0SGordon Ross 13226f3cdf0SGordon Ross 13326f3cdf0SGordon Ross /******************************************************************************* 13426f3cdf0SGordon Ross * 135*385cc6b4SJerry Jelinek * FUNCTION: AcpiNsSimpleRepair 13657190917SDana Myers * 137*385cc6b4SJerry Jelinek * PARAMETERS: Info - Method execution information block 13857190917SDana Myers * ExpectedBtypes - Object types expected 13957190917SDana Myers * PackageIndex - Index of object within parent package (if 14057190917SDana Myers * applicable - ACPI_NOT_PACKAGE_ELEMENT 14157190917SDana Myers * otherwise) 14257190917SDana Myers * ReturnObjectPtr - Pointer to the object returned from the 14357190917SDana Myers * evaluation of a method or object 14457190917SDana Myers * 14557190917SDana Myers * RETURN: Status. AE_OK if repair was successful. 14657190917SDana Myers * 14757190917SDana Myers * DESCRIPTION: Attempt to repair/convert a return object of a type that was 14857190917SDana Myers * not expected. 14957190917SDana Myers * 15057190917SDana Myers ******************************************************************************/ 15157190917SDana Myers 15257190917SDana Myers ACPI_STATUS 153*385cc6b4SJerry Jelinek AcpiNsSimpleRepair ( 154*385cc6b4SJerry Jelinek ACPI_EVALUATE_INFO *Info, 15557190917SDana Myers UINT32 ExpectedBtypes, 15657190917SDana Myers UINT32 PackageIndex, 15757190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr) 15857190917SDana Myers { 15957190917SDana Myers ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 160*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *NewObject = NULL; 16157190917SDana Myers ACPI_STATUS Status; 162*385cc6b4SJerry Jelinek const ACPI_SIMPLE_REPAIR_INFO *Predefined; 16357190917SDana Myers 16457190917SDana Myers 165*385cc6b4SJerry Jelinek ACPI_FUNCTION_NAME (NsSimpleRepair); 16626f3cdf0SGordon Ross 16726f3cdf0SGordon Ross 16857190917SDana Myers /* 169*385cc6b4SJerry Jelinek * Special repairs for certain names that are in the repair table. 170*385cc6b4SJerry Jelinek * Check if this name is in the list of repairable names. 171*385cc6b4SJerry Jelinek */ 172*385cc6b4SJerry Jelinek Predefined = AcpiNsMatchSimpleRepair (Info->Node, 173*385cc6b4SJerry Jelinek Info->ReturnBtype, PackageIndex); 174*385cc6b4SJerry Jelinek if (Predefined) 175*385cc6b4SJerry Jelinek { 176*385cc6b4SJerry Jelinek if (!ReturnObject) 177*385cc6b4SJerry Jelinek { 178*385cc6b4SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 179*385cc6b4SJerry Jelinek ACPI_WARN_ALWAYS, "Missing expected return value")); 180*385cc6b4SJerry Jelinek } 181*385cc6b4SJerry Jelinek 182*385cc6b4SJerry Jelinek Status = Predefined->ObjectConverter (Info->Node, ReturnObject, 183*385cc6b4SJerry Jelinek &NewObject); 184*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 185*385cc6b4SJerry Jelinek { 186*385cc6b4SJerry Jelinek /* A fatal error occurred during a conversion */ 187*385cc6b4SJerry Jelinek 188*385cc6b4SJerry Jelinek ACPI_EXCEPTION ((AE_INFO, Status, 189*385cc6b4SJerry Jelinek "During return object analysis")); 190*385cc6b4SJerry Jelinek return (Status); 191*385cc6b4SJerry Jelinek } 192*385cc6b4SJerry Jelinek if (NewObject) 193*385cc6b4SJerry Jelinek { 194*385cc6b4SJerry Jelinek goto ObjectRepaired; 195*385cc6b4SJerry Jelinek } 196*385cc6b4SJerry Jelinek } 197*385cc6b4SJerry Jelinek 198*385cc6b4SJerry Jelinek /* 199*385cc6b4SJerry Jelinek * Do not perform simple object repair unless the return type is not 200*385cc6b4SJerry Jelinek * expected. 201*385cc6b4SJerry Jelinek */ 202*385cc6b4SJerry Jelinek if (Info->ReturnBtype & ExpectedBtypes) 203*385cc6b4SJerry Jelinek { 204*385cc6b4SJerry Jelinek return (AE_OK); 205*385cc6b4SJerry Jelinek } 206*385cc6b4SJerry Jelinek 207*385cc6b4SJerry Jelinek /* 20857190917SDana Myers * At this point, we know that the type of the returned object was not 20957190917SDana Myers * one of the expected types for this predefined name. Attempt to 21026f3cdf0SGordon Ross * repair the object by converting it to one of the expected object 21126f3cdf0SGordon Ross * types for this predefined name. 21257190917SDana Myers */ 213*385cc6b4SJerry Jelinek 214*385cc6b4SJerry Jelinek /* 215*385cc6b4SJerry Jelinek * If there is no return value, check if we require a return value for 216*385cc6b4SJerry Jelinek * this predefined name. Either one return value is expected, or none, 217*385cc6b4SJerry Jelinek * for both methods and other objects. 218*385cc6b4SJerry Jelinek * 219*385cc6b4SJerry Jelinek * Try to fix if there was no return object. Warning if failed to fix. 220*385cc6b4SJerry Jelinek */ 221*385cc6b4SJerry Jelinek if (!ReturnObject) 222*385cc6b4SJerry Jelinek { 223*385cc6b4SJerry Jelinek if (ExpectedBtypes && (!(ExpectedBtypes & ACPI_RTYPE_NONE))) 224*385cc6b4SJerry Jelinek { 225*385cc6b4SJerry Jelinek if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) 226*385cc6b4SJerry Jelinek { 227*385cc6b4SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 228*385cc6b4SJerry Jelinek ACPI_WARN_ALWAYS, "Found unexpected NULL package element")); 229*385cc6b4SJerry Jelinek 230*385cc6b4SJerry Jelinek Status = AcpiNsRepairNullElement (Info, ExpectedBtypes, 231*385cc6b4SJerry Jelinek PackageIndex, ReturnObjectPtr); 232*385cc6b4SJerry Jelinek if (ACPI_SUCCESS (Status)) 233*385cc6b4SJerry Jelinek { 234*385cc6b4SJerry Jelinek return (AE_OK); /* Repair was successful */ 235*385cc6b4SJerry Jelinek } 236*385cc6b4SJerry Jelinek } 237*385cc6b4SJerry Jelinek else 238*385cc6b4SJerry Jelinek { 239*385cc6b4SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 240*385cc6b4SJerry Jelinek ACPI_WARN_ALWAYS, "Missing expected return value")); 241*385cc6b4SJerry Jelinek } 242*385cc6b4SJerry Jelinek 243*385cc6b4SJerry Jelinek return (AE_AML_NO_RETURN_VALUE); 244*385cc6b4SJerry Jelinek } 245*385cc6b4SJerry Jelinek } 246*385cc6b4SJerry Jelinek 24726f3cdf0SGordon Ross if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 24857190917SDana Myers { 24926f3cdf0SGordon Ross Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); 25026f3cdf0SGordon Ross if (ACPI_SUCCESS (Status)) 25157190917SDana Myers { 25226f3cdf0SGordon Ross goto ObjectRepaired; 25357190917SDana Myers } 25457190917SDana Myers } 25526f3cdf0SGordon Ross if (ExpectedBtypes & ACPI_RTYPE_STRING) 25657190917SDana Myers { 25726f3cdf0SGordon Ross Status = AcpiNsConvertToString (ReturnObject, &NewObject); 25826f3cdf0SGordon Ross if (ACPI_SUCCESS (Status)) 25926f3cdf0SGordon Ross { 26026f3cdf0SGordon Ross goto ObjectRepaired; 26157190917SDana Myers } 26226f3cdf0SGordon Ross } 26357190917SDana Myers if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 26457190917SDana Myers { 26526f3cdf0SGordon Ross Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject); 26626f3cdf0SGordon Ross if (ACPI_SUCCESS (Status)) 26757190917SDana Myers { 26826f3cdf0SGordon Ross goto ObjectRepaired; 26957190917SDana Myers } 27057190917SDana Myers } 27126f3cdf0SGordon Ross if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) 27257190917SDana Myers { 273*385cc6b4SJerry Jelinek /* 274*385cc6b4SJerry Jelinek * A package is expected. We will wrap the existing object with a 275*385cc6b4SJerry Jelinek * new package object. It is often the case that if a variable-length 276*385cc6b4SJerry Jelinek * package is required, but there is only a single object needed, the 277*385cc6b4SJerry Jelinek * BIOS will return that object instead of wrapping it with a Package 278*385cc6b4SJerry Jelinek * object. Note: after the wrapping, the package will be validated 279*385cc6b4SJerry Jelinek * for correct contents (expected object type or types). 280*385cc6b4SJerry Jelinek */ 281*385cc6b4SJerry Jelinek Status = AcpiNsWrapWithPackage (Info, ReturnObject, &NewObject); 28226f3cdf0SGordon Ross if (ACPI_SUCCESS (Status)) 28357190917SDana Myers { 284*385cc6b4SJerry Jelinek /* 285*385cc6b4SJerry Jelinek * The original object just had its reference count 286*385cc6b4SJerry Jelinek * incremented for being inserted into the new package. 287*385cc6b4SJerry Jelinek */ 288*385cc6b4SJerry Jelinek *ReturnObjectPtr = NewObject; /* New Package object */ 289*385cc6b4SJerry Jelinek Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 290*385cc6b4SJerry Jelinek return (AE_OK); 29157190917SDana Myers } 29257190917SDana Myers } 29357190917SDana Myers 29457190917SDana Myers /* We cannot repair this object */ 29557190917SDana Myers 29657190917SDana Myers return (AE_AML_OPERAND_TYPE); 29726f3cdf0SGordon Ross 29826f3cdf0SGordon Ross 29926f3cdf0SGordon Ross ObjectRepaired: 30057190917SDana Myers 30157190917SDana Myers /* Object was successfully repaired */ 30257190917SDana Myers 30357190917SDana Myers if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) 30457190917SDana Myers { 305*385cc6b4SJerry Jelinek /* 306*385cc6b4SJerry Jelinek * The original object is a package element. We need to 307*385cc6b4SJerry Jelinek * decrement the reference count of the original object, 308*385cc6b4SJerry Jelinek * for removing it from the package. 309*385cc6b4SJerry Jelinek * 310*385cc6b4SJerry Jelinek * However, if the original object was just wrapped with a 311*385cc6b4SJerry Jelinek * package object as part of the repair, we don't need to 312*385cc6b4SJerry Jelinek * change the reference count. 313*385cc6b4SJerry Jelinek */ 314*385cc6b4SJerry Jelinek if (!(Info->ReturnFlags & ACPI_OBJECT_WRAPPED)) 315*385cc6b4SJerry Jelinek { 31657190917SDana Myers NewObject->Common.ReferenceCount = 31757190917SDana Myers ReturnObject->Common.ReferenceCount; 31857190917SDana Myers 31957190917SDana Myers if (ReturnObject->Common.ReferenceCount > 1) 32057190917SDana Myers { 32157190917SDana Myers ReturnObject->Common.ReferenceCount--; 32257190917SDana Myers } 323*385cc6b4SJerry Jelinek } 32457190917SDana Myers 32526f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 326*385cc6b4SJerry Jelinek "%s: Converted %s to expected %s at Package index %u\n", 327*385cc6b4SJerry Jelinek Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), 32857190917SDana Myers AcpiUtGetObjectTypeName (NewObject), PackageIndex)); 32957190917SDana Myers } 33057190917SDana Myers else 33157190917SDana Myers { 33226f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 33326f3cdf0SGordon Ross "%s: Converted %s to expected %s\n", 334*385cc6b4SJerry Jelinek Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), 33557190917SDana Myers AcpiUtGetObjectTypeName (NewObject))); 33657190917SDana Myers } 33757190917SDana Myers 33857190917SDana Myers /* Delete old object, install the new return object */ 33957190917SDana Myers 34057190917SDana Myers AcpiUtRemoveReference (ReturnObject); 34157190917SDana Myers *ReturnObjectPtr = NewObject; 342*385cc6b4SJerry Jelinek Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 34357190917SDana Myers return (AE_OK); 34457190917SDana Myers } 34557190917SDana Myers 34657190917SDana Myers 347*385cc6b4SJerry Jelinek /****************************************************************************** 34857190917SDana Myers * 349*385cc6b4SJerry Jelinek * FUNCTION: AcpiNsMatchSimpleRepair 35026f3cdf0SGordon Ross * 351*385cc6b4SJerry Jelinek * PARAMETERS: Node - Namespace node for the method/object 352*385cc6b4SJerry Jelinek * ReturnBtype - Object type that was returned 353*385cc6b4SJerry Jelinek * PackageIndex - Index of object within parent package (if 354*385cc6b4SJerry Jelinek * applicable - ACPI_NOT_PACKAGE_ELEMENT 355*385cc6b4SJerry Jelinek * otherwise) 35626f3cdf0SGordon Ross * 357*385cc6b4SJerry Jelinek * RETURN: Pointer to entry in repair table. NULL indicates not found. 35826f3cdf0SGordon Ross * 359*385cc6b4SJerry Jelinek * DESCRIPTION: Check an object name against the repairable object list. 36026f3cdf0SGordon Ross * 361*385cc6b4SJerry Jelinek *****************************************************************************/ 36226f3cdf0SGordon Ross 363*385cc6b4SJerry Jelinek static const ACPI_SIMPLE_REPAIR_INFO * 364*385cc6b4SJerry Jelinek AcpiNsMatchSimpleRepair ( 365*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *Node, 366*385cc6b4SJerry Jelinek UINT32 ReturnBtype, 367*385cc6b4SJerry Jelinek UINT32 PackageIndex) 36826f3cdf0SGordon Ross { 369*385cc6b4SJerry Jelinek const ACPI_SIMPLE_REPAIR_INFO *ThisName; 37026f3cdf0SGordon Ross 37126f3cdf0SGordon Ross 372*385cc6b4SJerry Jelinek /* Search info table for a repairable predefined method/object name */ 373*385cc6b4SJerry Jelinek 374*385cc6b4SJerry Jelinek ThisName = AcpiObjectRepairInfo; 375*385cc6b4SJerry Jelinek while (ThisName->ObjectConverter) 37626f3cdf0SGordon Ross { 377*385cc6b4SJerry Jelinek if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) 37826f3cdf0SGordon Ross { 379*385cc6b4SJerry Jelinek /* Check if we can actually repair this name/type combination */ 38026f3cdf0SGordon Ross 381*385cc6b4SJerry Jelinek if ((ReturnBtype & ThisName->UnexpectedBtypes) && 382*385cc6b4SJerry Jelinek (ThisName->PackageIndex == ACPI_ALL_PACKAGE_ELEMENTS || 383*385cc6b4SJerry Jelinek PackageIndex == ThisName->PackageIndex)) 38426f3cdf0SGordon Ross { 385*385cc6b4SJerry Jelinek return (ThisName); 38626f3cdf0SGordon Ross } 38726f3cdf0SGordon Ross 388*385cc6b4SJerry Jelinek return (NULL); 38926f3cdf0SGordon Ross } 39026f3cdf0SGordon Ross 391*385cc6b4SJerry Jelinek ThisName++; 39226f3cdf0SGordon Ross } 39326f3cdf0SGordon Ross 394*385cc6b4SJerry Jelinek return (NULL); /* Name was not found in the repair table */ 39526f3cdf0SGordon Ross } 39626f3cdf0SGordon Ross 39726f3cdf0SGordon Ross 39826f3cdf0SGordon Ross /******************************************************************************* 39926f3cdf0SGordon Ross * 40026f3cdf0SGordon Ross * FUNCTION: AcpiNsRepairNullElement 40126f3cdf0SGordon Ross * 402*385cc6b4SJerry Jelinek * PARAMETERS: Info - Method execution information block 40326f3cdf0SGordon Ross * ExpectedBtypes - Object types expected 40426f3cdf0SGordon Ross * PackageIndex - Index of object within parent package (if 40526f3cdf0SGordon Ross * applicable - ACPI_NOT_PACKAGE_ELEMENT 40626f3cdf0SGordon Ross * otherwise) 40726f3cdf0SGordon Ross * ReturnObjectPtr - Pointer to the object returned from the 40826f3cdf0SGordon Ross * evaluation of a method or object 40926f3cdf0SGordon Ross * 41026f3cdf0SGordon Ross * RETURN: Status. AE_OK if repair was successful. 41126f3cdf0SGordon Ross * 41226f3cdf0SGordon Ross * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. 41326f3cdf0SGordon Ross * 41426f3cdf0SGordon Ross ******************************************************************************/ 41526f3cdf0SGordon Ross 41626f3cdf0SGordon Ross ACPI_STATUS 41726f3cdf0SGordon Ross AcpiNsRepairNullElement ( 418*385cc6b4SJerry Jelinek ACPI_EVALUATE_INFO *Info, 41926f3cdf0SGordon Ross UINT32 ExpectedBtypes, 42026f3cdf0SGordon Ross UINT32 PackageIndex, 42126f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr) 42226f3cdf0SGordon Ross { 42326f3cdf0SGordon Ross ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 42426f3cdf0SGordon Ross ACPI_OPERAND_OBJECT *NewObject; 42526f3cdf0SGordon Ross 42626f3cdf0SGordon Ross 42726f3cdf0SGordon Ross ACPI_FUNCTION_NAME (NsRepairNullElement); 42826f3cdf0SGordon Ross 42926f3cdf0SGordon Ross 43026f3cdf0SGordon Ross /* No repair needed if return object is non-NULL */ 43126f3cdf0SGordon Ross 43226f3cdf0SGordon Ross if (ReturnObject) 43326f3cdf0SGordon Ross { 43426f3cdf0SGordon Ross return (AE_OK); 43526f3cdf0SGordon Ross } 43626f3cdf0SGordon Ross 43726f3cdf0SGordon Ross /* 43826f3cdf0SGordon Ross * Attempt to repair a NULL element of a Package object. This applies to 43926f3cdf0SGordon Ross * predefined names that return a fixed-length package and each element 44026f3cdf0SGordon Ross * is required. It does not apply to variable-length packages where NULL 44126f3cdf0SGordon Ross * elements are allowed, especially at the end of the package. 44226f3cdf0SGordon Ross */ 44326f3cdf0SGordon Ross if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 44426f3cdf0SGordon Ross { 44526f3cdf0SGordon Ross /* Need an Integer - create a zero-value integer */ 44626f3cdf0SGordon Ross 44726f3cdf0SGordon Ross NewObject = AcpiUtCreateIntegerObject ((UINT64) 0); 44826f3cdf0SGordon Ross } 44926f3cdf0SGordon Ross else if (ExpectedBtypes & ACPI_RTYPE_STRING) 45026f3cdf0SGordon Ross { 45126f3cdf0SGordon Ross /* Need a String - create a NULL string */ 45226f3cdf0SGordon Ross 45326f3cdf0SGordon Ross NewObject = AcpiUtCreateStringObject (0); 45426f3cdf0SGordon Ross } 45526f3cdf0SGordon Ross else if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 45626f3cdf0SGordon Ross { 45726f3cdf0SGordon Ross /* Need a Buffer - create a zero-length buffer */ 45826f3cdf0SGordon Ross 45926f3cdf0SGordon Ross NewObject = AcpiUtCreateBufferObject (0); 46026f3cdf0SGordon Ross } 46126f3cdf0SGordon Ross else 46226f3cdf0SGordon Ross { 46326f3cdf0SGordon Ross /* Error for all other expected types */ 46426f3cdf0SGordon Ross 46526f3cdf0SGordon Ross return (AE_AML_OPERAND_TYPE); 46626f3cdf0SGordon Ross } 46726f3cdf0SGordon Ross 46826f3cdf0SGordon Ross if (!NewObject) 46926f3cdf0SGordon Ross { 47026f3cdf0SGordon Ross return (AE_NO_MEMORY); 47126f3cdf0SGordon Ross } 47226f3cdf0SGordon Ross 47326f3cdf0SGordon Ross /* Set the reference count according to the parent Package object */ 47426f3cdf0SGordon Ross 475*385cc6b4SJerry Jelinek NewObject->Common.ReferenceCount = 476*385cc6b4SJerry Jelinek Info->ParentPackage->Common.ReferenceCount; 47726f3cdf0SGordon Ross 47826f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 47926f3cdf0SGordon Ross "%s: Converted NULL package element to expected %s at index %u\n", 480*385cc6b4SJerry Jelinek Info->FullPathname, AcpiUtGetObjectTypeName (NewObject), 481*385cc6b4SJerry Jelinek PackageIndex)); 48226f3cdf0SGordon Ross 48326f3cdf0SGordon Ross *ReturnObjectPtr = NewObject; 484*385cc6b4SJerry Jelinek Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 48526f3cdf0SGordon Ross return (AE_OK); 48626f3cdf0SGordon Ross } 48726f3cdf0SGordon Ross 48826f3cdf0SGordon Ross 48926f3cdf0SGordon Ross /****************************************************************************** 49026f3cdf0SGordon Ross * 49126f3cdf0SGordon Ross * FUNCTION: AcpiNsRemoveNullElements 49226f3cdf0SGordon Ross * 493*385cc6b4SJerry Jelinek * PARAMETERS: Info - Method execution information block 49426f3cdf0SGordon Ross * PackageType - An AcpiReturnPackageTypes value 49526f3cdf0SGordon Ross * ObjDesc - A Package object 49626f3cdf0SGordon Ross * 49726f3cdf0SGordon Ross * RETURN: None. 49826f3cdf0SGordon Ross * 49926f3cdf0SGordon Ross * DESCRIPTION: Remove all NULL package elements from packages that contain 500*385cc6b4SJerry Jelinek * a variable number of subpackages. For these types of 50126f3cdf0SGordon Ross * packages, NULL elements can be safely removed. 50226f3cdf0SGordon Ross * 50326f3cdf0SGordon Ross *****************************************************************************/ 50426f3cdf0SGordon Ross 50526f3cdf0SGordon Ross void 50626f3cdf0SGordon Ross AcpiNsRemoveNullElements ( 507*385cc6b4SJerry Jelinek ACPI_EVALUATE_INFO *Info, 50826f3cdf0SGordon Ross UINT8 PackageType, 50926f3cdf0SGordon Ross ACPI_OPERAND_OBJECT *ObjDesc) 51026f3cdf0SGordon Ross { 51126f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **Source; 51226f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **Dest; 51326f3cdf0SGordon Ross UINT32 Count; 51426f3cdf0SGordon Ross UINT32 NewCount; 51526f3cdf0SGordon Ross UINT32 i; 51626f3cdf0SGordon Ross 51726f3cdf0SGordon Ross 51826f3cdf0SGordon Ross ACPI_FUNCTION_NAME (NsRemoveNullElements); 51926f3cdf0SGordon Ross 52026f3cdf0SGordon Ross 52126f3cdf0SGordon Ross /* 52226f3cdf0SGordon Ross * We can safely remove all NULL elements from these package types: 52326f3cdf0SGordon Ross * PTYPE1_VAR packages contain a variable number of simple data types. 524*385cc6b4SJerry Jelinek * PTYPE2 packages contain a variable number of subpackages. 52526f3cdf0SGordon Ross */ 52626f3cdf0SGordon Ross switch (PackageType) 52726f3cdf0SGordon Ross { 52826f3cdf0SGordon Ross case ACPI_PTYPE1_VAR: 52926f3cdf0SGordon Ross case ACPI_PTYPE2: 53026f3cdf0SGordon Ross case ACPI_PTYPE2_COUNT: 53126f3cdf0SGordon Ross case ACPI_PTYPE2_PKG_COUNT: 53226f3cdf0SGordon Ross case ACPI_PTYPE2_FIXED: 53326f3cdf0SGordon Ross case ACPI_PTYPE2_MIN: 53426f3cdf0SGordon Ross case ACPI_PTYPE2_REV_FIXED: 535*385cc6b4SJerry Jelinek case ACPI_PTYPE2_FIX_VAR: 53626f3cdf0SGordon Ross break; 53726f3cdf0SGordon Ross 53826f3cdf0SGordon Ross default: 539*385cc6b4SJerry Jelinek case ACPI_PTYPE2_VAR_VAR: 54026f3cdf0SGordon Ross case ACPI_PTYPE1_FIXED: 54126f3cdf0SGordon Ross case ACPI_PTYPE1_OPTION: 54226f3cdf0SGordon Ross return; 54326f3cdf0SGordon Ross } 54426f3cdf0SGordon Ross 54526f3cdf0SGordon Ross Count = ObjDesc->Package.Count; 54626f3cdf0SGordon Ross NewCount = Count; 54726f3cdf0SGordon Ross 54826f3cdf0SGordon Ross Source = ObjDesc->Package.Elements; 54926f3cdf0SGordon Ross Dest = Source; 55026f3cdf0SGordon Ross 55126f3cdf0SGordon Ross /* Examine all elements of the package object, remove nulls */ 55226f3cdf0SGordon Ross 55326f3cdf0SGordon Ross for (i = 0; i < Count; i++) 55426f3cdf0SGordon Ross { 55526f3cdf0SGordon Ross if (!*Source) 55626f3cdf0SGordon Ross { 55726f3cdf0SGordon Ross NewCount--; 55826f3cdf0SGordon Ross } 55926f3cdf0SGordon Ross else 56026f3cdf0SGordon Ross { 56126f3cdf0SGordon Ross *Dest = *Source; 56226f3cdf0SGordon Ross Dest++; 56326f3cdf0SGordon Ross } 564*385cc6b4SJerry Jelinek 56526f3cdf0SGordon Ross Source++; 56626f3cdf0SGordon Ross } 56726f3cdf0SGordon Ross 56826f3cdf0SGordon Ross /* Update parent package if any null elements were removed */ 56926f3cdf0SGordon Ross 57026f3cdf0SGordon Ross if (NewCount < Count) 57126f3cdf0SGordon Ross { 57226f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 57326f3cdf0SGordon Ross "%s: Found and removed %u NULL elements\n", 574*385cc6b4SJerry Jelinek Info->FullPathname, (Count - NewCount))); 57526f3cdf0SGordon Ross 57626f3cdf0SGordon Ross /* NULL terminate list and update the package count */ 57726f3cdf0SGordon Ross 57826f3cdf0SGordon Ross *Dest = NULL; 57926f3cdf0SGordon Ross ObjDesc->Package.Count = NewCount; 58026f3cdf0SGordon Ross } 58126f3cdf0SGordon Ross } 58226f3cdf0SGordon Ross 58326f3cdf0SGordon Ross 58426f3cdf0SGordon Ross /******************************************************************************* 58526f3cdf0SGordon Ross * 586*385cc6b4SJerry Jelinek * FUNCTION: AcpiNsWrapWithPackage 58757190917SDana Myers * 588*385cc6b4SJerry Jelinek * PARAMETERS: Info - Method execution information block 589*385cc6b4SJerry Jelinek * OriginalObject - Pointer to the object to repair. 590*385cc6b4SJerry Jelinek * ObjDescPtr - The new package object is returned here 59157190917SDana Myers * 59257190917SDana Myers * RETURN: Status, new object in *ObjDescPtr 59357190917SDana Myers * 594*385cc6b4SJerry Jelinek * DESCRIPTION: Repair a common problem with objects that are defined to 595*385cc6b4SJerry Jelinek * return a variable-length Package of sub-objects. If there is 596*385cc6b4SJerry Jelinek * only one sub-object, some BIOS code mistakenly simply declares 597*385cc6b4SJerry Jelinek * the single object instead of a Package with one sub-object. 598*385cc6b4SJerry Jelinek * This function attempts to repair this error by wrapping a 599*385cc6b4SJerry Jelinek * Package object around the original object, creating the 600*385cc6b4SJerry Jelinek * correct and expected Package with one sub-object. 60157190917SDana Myers * 60257190917SDana Myers * Names that can be repaired in this manner include: 603*385cc6b4SJerry Jelinek * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, 604*385cc6b4SJerry Jelinek * _BCL, _DOD, _FIX, _Sx 60557190917SDana Myers * 60657190917SDana Myers ******************************************************************************/ 60757190917SDana Myers 60857190917SDana Myers ACPI_STATUS 609*385cc6b4SJerry Jelinek AcpiNsWrapWithPackage ( 610*385cc6b4SJerry Jelinek ACPI_EVALUATE_INFO *Info, 611*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *OriginalObject, 61257190917SDana Myers ACPI_OPERAND_OBJECT **ObjDescPtr) 61357190917SDana Myers { 61457190917SDana Myers ACPI_OPERAND_OBJECT *PkgObjDesc; 61557190917SDana Myers 61657190917SDana Myers 617*385cc6b4SJerry Jelinek ACPI_FUNCTION_NAME (NsWrapWithPackage); 61826f3cdf0SGordon Ross 61926f3cdf0SGordon Ross 62057190917SDana Myers /* 621*385cc6b4SJerry Jelinek * Create the new outer package and populate it. The new 622*385cc6b4SJerry Jelinek * package will have a single element, the lone sub-object. 62357190917SDana Myers */ 62457190917SDana Myers PkgObjDesc = AcpiUtCreatePackageObject (1); 62557190917SDana Myers if (!PkgObjDesc) 62657190917SDana Myers { 62757190917SDana Myers return (AE_NO_MEMORY); 62857190917SDana Myers } 62957190917SDana Myers 630*385cc6b4SJerry Jelinek PkgObjDesc->Package.Elements[0] = OriginalObject; 631*385cc6b4SJerry Jelinek 632*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 633*385cc6b4SJerry Jelinek "%s: Wrapped %s with expected Package object\n", 634*385cc6b4SJerry Jelinek Info->FullPathname, AcpiUtGetObjectTypeName (OriginalObject))); 63557190917SDana Myers 63657190917SDana Myers /* Return the new object in the object pointer */ 63757190917SDana Myers 63857190917SDana Myers *ObjDescPtr = PkgObjDesc; 639*385cc6b4SJerry Jelinek Info->ReturnFlags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; 64057190917SDana Myers return (AE_OK); 64157190917SDana Myers } 642