Path: blob/main/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
48524 views
/******************************************************************************1*2* Module Name: nsrepair2 - Repair for objects returned by specific3* predefined methods4*5*****************************************************************************/67/******************************************************************************8*9* 1. Copyright Notice10*11* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.12* All rights reserved.13*14* 2. License15*16* 2.1. This is your license from Intel Corp. under its intellectual property17* rights. You may have additional license terms from the party that provided18* you this software, covering your right to use that party's intellectual19* property rights.20*21* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a22* copy of the source code appearing in this file ("Covered Code") an23* irrevocable, perpetual, worldwide license under Intel's copyrights in the24* base code distributed originally by Intel ("Original Intel Code") to copy,25* make derivatives, distribute, use and display any portion of the Covered26* Code in any form, with the right to sublicense such rights; and27*28* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent29* license (with the right to sublicense), under only those claims of Intel30* patents that are infringed by the Original Intel Code, to make, use, sell,31* offer to sell, and import the Covered Code and derivative works thereof32* solely to the minimum extent necessary to exercise the above copyright33* license, and in no event shall the patent license extend to any additions34* to or modifications of the Original Intel Code. No other license or right35* is granted directly or by implication, estoppel or otherwise;36*37* The above copyright and patent license is granted only if the following38* conditions are met:39*40* 3. Conditions41*42* 3.1. Redistribution of Source with Rights to Further Distribute Source.43* Redistribution of source code of any substantial portion of the Covered44* Code or modification with rights to further distribute source must include45* the above Copyright Notice, the above License, this list of Conditions,46* and the following Disclaimer and Export Compliance provision. In addition,47* Licensee must cause all Covered Code to which Licensee contributes to48* contain a file documenting the changes Licensee made to create that Covered49* Code and the date of any change. Licensee must include in that file the50* documentation of any changes made by any predecessor Licensee. Licensee51* must include a prominent statement that the modification is derived,52* directly or indirectly, from Original Intel Code.53*54* 3.2. Redistribution of Source with no Rights to Further Distribute Source.55* Redistribution of source code of any substantial portion of the Covered56* Code or modification without rights to further distribute source must57* include the following Disclaimer and Export Compliance provision in the58* documentation and/or other materials provided with distribution. In59* addition, Licensee may not authorize further sublicense of source of any60* portion of the Covered Code, and must include terms to the effect that the61* license from Licensee to its licensee is limited to the intellectual62* property embodied in the software Licensee provides to its licensee, and63* not to intellectual property embodied in modifications its licensee may64* make.65*66* 3.3. Redistribution of Executable. Redistribution in executable form of any67* substantial portion of the Covered Code or modification must reproduce the68* above Copyright Notice, and the following Disclaimer and Export Compliance69* provision in the documentation and/or other materials provided with the70* distribution.71*72* 3.4. Intel retains all right, title, and interest in and to the Original73* Intel Code.74*75* 3.5. Neither the name Intel nor any other trademark owned or controlled by76* Intel shall be used in advertising or otherwise to promote the sale, use or77* other dealings in products derived from or relating to the Covered Code78* without prior written authorization from Intel.79*80* 4. Disclaimer and Export Compliance81*82* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED83* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE84* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,85* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY86* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY87* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A88* PARTICULAR PURPOSE.89*90* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES91* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR92* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,93* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY94* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL95* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS96* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY97* LIMITED REMEDY.98*99* 4.3. Licensee shall not export, either directly or indirectly, any of this100* software or system incorporating such software without first obtaining any101* required license or other approval from the U. S. Department of Commerce or102* any other agency or department of the United States Government. In the103* event Licensee exports any such software from the United States or104* re-exports any such software from a foreign destination, Licensee shall105* ensure that the distribution and export/re-export of the software is in106* compliance with all laws, regulations, orders, or other restrictions of the107* U.S. Export Administration Regulations. Licensee agrees that neither it nor108* any of its subsidiaries will export/re-export any technical data, process,109* software, or service, directly or indirectly, to any country for which the110* United States government or any agency thereof requires an export license,111* other governmental approval, or letter of assurance, without first obtaining112* such license, approval or letter.113*114*****************************************************************************115*116* Alternatively, you may choose to be licensed under the terms of the117* following license:118*119* Redistribution and use in source and binary forms, with or without120* modification, are permitted provided that the following conditions121* are met:122* 1. Redistributions of source code must retain the above copyright123* notice, this list of conditions, and the following disclaimer,124* without modification.125* 2. Redistributions in binary form must reproduce at minimum a disclaimer126* substantially similar to the "NO WARRANTY" disclaimer below127* ("Disclaimer") and any redistribution must be conditioned upon128* including a substantially similar Disclaimer requirement for further129* binary redistribution.130* 3. Neither the names of the above-listed copyright holders nor the names131* of any contributors may be used to endorse or promote products derived132* from this software without specific prior written permission.133*134* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS135* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT136* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR137* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT138* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,139* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT140* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,141* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY142* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT143* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE144* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.145*146* Alternatively, you may choose to be licensed under the terms of the147* GNU General Public License ("GPL") version 2 as published by the Free148* Software Foundation.149*150*****************************************************************************/151152#include <contrib/dev/acpica/include/acpi.h>153#include <contrib/dev/acpica/include/accommon.h>154#include <contrib/dev/acpica/include/acnamesp.h>155156#define _COMPONENT ACPI_NAMESPACE157ACPI_MODULE_NAME ("nsrepair2")158159160/*161* Information structure and handler for ACPI predefined names that can162* be repaired on a per-name basis.163*/164typedef165ACPI_STATUS (*ACPI_REPAIR_FUNCTION) (166ACPI_EVALUATE_INFO *Info,167ACPI_OPERAND_OBJECT **ReturnObjectPtr);168169typedef struct acpi_repair_info170{171char Name[ACPI_NAMESEG_SIZE] ACPI_NONSTRING;172ACPI_REPAIR_FUNCTION RepairFunction;173174} ACPI_REPAIR_INFO;175176177/* Local prototypes */178179static const ACPI_REPAIR_INFO *180AcpiNsMatchComplexRepair (181ACPI_NAMESPACE_NODE *Node);182183static ACPI_STATUS184AcpiNsRepair_ALR (185ACPI_EVALUATE_INFO *Info,186ACPI_OPERAND_OBJECT **ReturnObjectPtr);187188static ACPI_STATUS189AcpiNsRepair_CID (190ACPI_EVALUATE_INFO *Info,191ACPI_OPERAND_OBJECT **ReturnObjectPtr);192193static ACPI_STATUS194AcpiNsRepair_CST (195ACPI_EVALUATE_INFO *Info,196ACPI_OPERAND_OBJECT **ReturnObjectPtr);197198static ACPI_STATUS199AcpiNsRepair_FDE (200ACPI_EVALUATE_INFO *Info,201ACPI_OPERAND_OBJECT **ReturnObjectPtr);202203static ACPI_STATUS204AcpiNsRepair_HID (205ACPI_EVALUATE_INFO *Info,206ACPI_OPERAND_OBJECT **ReturnObjectPtr);207208static ACPI_STATUS209AcpiNsRepair_PRT (210ACPI_EVALUATE_INFO *Info,211ACPI_OPERAND_OBJECT **ReturnObjectPtr);212213static ACPI_STATUS214AcpiNsRepair_PSS (215ACPI_EVALUATE_INFO *Info,216ACPI_OPERAND_OBJECT **ReturnObjectPtr);217218static ACPI_STATUS219AcpiNsRepair_TSS (220ACPI_EVALUATE_INFO *Info,221ACPI_OPERAND_OBJECT **ReturnObjectPtr);222223static ACPI_STATUS224AcpiNsCheckSortedList (225ACPI_EVALUATE_INFO *Info,226ACPI_OPERAND_OBJECT *ReturnObject,227UINT32 StartIndex,228UINT32 ExpectedCount,229UINT32 SortIndex,230UINT8 SortDirection,231char *SortKeyName);232233/* Values for SortDirection above */234235#define ACPI_SORT_ASCENDING 0236#define ACPI_SORT_DESCENDING 1237238static void239AcpiNsRemoveElement (240ACPI_OPERAND_OBJECT *ObjDesc,241UINT32 Index);242243static void244AcpiNsSortList (245ACPI_OPERAND_OBJECT **Elements,246UINT32 Count,247UINT32 Index,248UINT8 SortDirection);249250251/*252* This table contains the names of the predefined methods for which we can253* perform more complex repairs.254*255* As necessary:256*257* _ALR: Sort the list ascending by AmbientIlluminance258* _CID: Strings: uppercase all, remove any leading asterisk259* _CST: Sort the list ascending by C state type260* _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs261* _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs262* _HID: Strings: uppercase all, remove any leading asterisk263* _PRT: Fix reversed SourceName and SourceIndex264* _PSS: Sort the list descending by Power265* _TSS: Sort the list descending by Power266*267* Names that must be packages, but cannot be sorted:268*269* _BCL: Values are tied to the Package index where they appear, and cannot270* be moved or sorted. These index values are used for _BQC and _BCM.271* However, we can fix the case where a buffer is returned, by converting272* it to a Package of integers.273*/274static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] =275{276{"_ALR", AcpiNsRepair_ALR},277{"_CID", AcpiNsRepair_CID},278{"_CST", AcpiNsRepair_CST},279{"_FDE", AcpiNsRepair_FDE},280{"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */281{"_HID", AcpiNsRepair_HID},282{"_PRT", AcpiNsRepair_PRT},283{"_PSS", AcpiNsRepair_PSS},284{"_TSS", AcpiNsRepair_TSS},285{{0,0,0,0}, NULL} /* Table terminator */286};287288289#define ACPI_FDE_FIELD_COUNT 5290#define ACPI_FDE_BYTE_BUFFER_SIZE 5291#define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * (UINT32) sizeof (UINT32))292293294/******************************************************************************295*296* FUNCTION: AcpiNsComplexRepairs297*298* PARAMETERS: Info - Method execution information block299* Node - Namespace node for the method/object300* ValidateStatus - Original status of earlier validation301* ReturnObjectPtr - Pointer to the object returned from the302* evaluation of a method or object303*304* RETURN: Status. AE_OK if repair was successful. If name is not305* matched, ValidateStatus is returned.306*307* DESCRIPTION: Attempt to repair/convert a return object of a type that was308* not expected.309*310*****************************************************************************/311312ACPI_STATUS313AcpiNsComplexRepairs (314ACPI_EVALUATE_INFO *Info,315ACPI_NAMESPACE_NODE *Node,316ACPI_STATUS ValidateStatus,317ACPI_OPERAND_OBJECT **ReturnObjectPtr)318{319const ACPI_REPAIR_INFO *Predefined;320ACPI_STATUS Status;321322323ACPI_FUNCTION_TRACE (NsComplexRepairs);324325/* Check if this name is in the list of repairable names */326327Predefined = AcpiNsMatchComplexRepair (Node);328if (!Predefined)329{330return_ACPI_STATUS (ValidateStatus);331}332333Status = Predefined->RepairFunction (Info, ReturnObjectPtr);334return_ACPI_STATUS (Status);335}336337338/******************************************************************************339*340* FUNCTION: AcpiNsMatchComplexRepair341*342* PARAMETERS: Node - Namespace node for the method/object343*344* RETURN: Pointer to entry in repair table. NULL indicates not found.345*346* DESCRIPTION: Check an object name against the repairable object list.347*348*****************************************************************************/349350static const ACPI_REPAIR_INFO *351AcpiNsMatchComplexRepair (352ACPI_NAMESPACE_NODE *Node)353{354const ACPI_REPAIR_INFO *ThisName;355356357/* Search info table for a repairable predefined method/object name */358359ThisName = AcpiNsRepairableNames;360while (ThisName->RepairFunction)361{362if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, ThisName->Name))363{364return (ThisName);365}366367ThisName++;368}369370return (NULL); /* Not found */371}372373374/******************************************************************************375*376* FUNCTION: AcpiNsRepair_ALR377*378* PARAMETERS: Info - Method execution information block379* ReturnObjectPtr - Pointer to the object returned from the380* evaluation of a method or object381*382* RETURN: Status. AE_OK if object is OK or was repaired successfully383*384* DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list385* ascending by the ambient illuminance values.386*387*****************************************************************************/388389static ACPI_STATUS390AcpiNsRepair_ALR (391ACPI_EVALUATE_INFO *Info,392ACPI_OPERAND_OBJECT **ReturnObjectPtr)393{394ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;395ACPI_STATUS Status;396397398Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1,399ACPI_SORT_ASCENDING, "AmbientIlluminance");400401return (Status);402}403404405/******************************************************************************406*407* FUNCTION: AcpiNsRepair_FDE408*409* PARAMETERS: Info - Method execution information block410* ReturnObjectPtr - Pointer to the object returned from the411* evaluation of a method or object412*413* RETURN: Status. AE_OK if object is OK or was repaired successfully414*415* DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return416* value is a Buffer of 5 DWORDs. This function repairs a common417* problem where the return value is a Buffer of BYTEs, not418* DWORDs.419*420*****************************************************************************/421422static ACPI_STATUS423AcpiNsRepair_FDE (424ACPI_EVALUATE_INFO *Info,425ACPI_OPERAND_OBJECT **ReturnObjectPtr)426{427ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;428ACPI_OPERAND_OBJECT *BufferObject;429UINT8 *ByteBuffer;430UINT32 *DwordBuffer;431UINT32 i;432433434ACPI_FUNCTION_NAME (NsRepair_FDE);435436437switch (ReturnObject->Common.Type)438{439case ACPI_TYPE_BUFFER:440441/* This is the expected type. Length should be (at least) 5 DWORDs */442443if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)444{445return (AE_OK);446}447448/* We can only repair if we have exactly 5 BYTEs */449450if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)451{452ACPI_WARN_PREDEFINED ((AE_INFO,453Info->FullPathname, Info->NodeFlags,454"Incorrect return buffer length %u, expected %u",455ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));456457return (AE_AML_OPERAND_TYPE);458}459460/* Create the new (larger) buffer object */461462BufferObject = AcpiUtCreateBufferObject (463ACPI_FDE_DWORD_BUFFER_SIZE);464if (!BufferObject)465{466return (AE_NO_MEMORY);467}468469/* Expand each byte to a DWORD */470471ByteBuffer = ReturnObject->Buffer.Pointer;472DwordBuffer = ACPI_CAST_PTR (UINT32,473BufferObject->Buffer.Pointer);474475for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)476{477*DwordBuffer = (UINT32) *ByteBuffer;478DwordBuffer++;479ByteBuffer++;480}481482ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,483"%s Expanded Byte Buffer to expected DWord Buffer\n",484Info->FullPathname));485break;486487default:488489return (AE_AML_OPERAND_TYPE);490}491492/* Delete the original return object, return the new buffer object */493494AcpiUtRemoveReference (ReturnObject);495*ReturnObjectPtr = BufferObject;496497Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;498return (AE_OK);499}500501502/******************************************************************************503*504* FUNCTION: AcpiNsRepair_CID505*506* PARAMETERS: Info - Method execution information block507* ReturnObjectPtr - Pointer to the object returned from the508* evaluation of a method or object509*510* RETURN: Status. AE_OK if object is OK or was repaired successfully511*512* DESCRIPTION: Repair for the _CID object. If a string, ensure that all513* letters are uppercase and that there is no leading asterisk.514* If a Package, ensure same for all string elements.515*516*****************************************************************************/517518static ACPI_STATUS519AcpiNsRepair_CID (520ACPI_EVALUATE_INFO *Info,521ACPI_OPERAND_OBJECT **ReturnObjectPtr)522{523ACPI_STATUS Status;524ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;525ACPI_OPERAND_OBJECT **ElementPtr;526ACPI_OPERAND_OBJECT *OriginalElement;527UINT16 OriginalRefCount;528UINT32 i;529530ACPI_FUNCTION_TRACE (NsRepair_CID);531532/* Check for _CID as a simple string */533534if (ReturnObject->Common.Type == ACPI_TYPE_STRING)535{536Status = AcpiNsRepair_HID (Info, ReturnObjectPtr);537return_ACPI_STATUS (Status);538}539540/* Exit if not a Package */541542if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)543{544return_ACPI_STATUS (AE_OK);545}546547/* Examine each element of the _CID package */548549ElementPtr = ReturnObject->Package.Elements;550for (i = 0; i < ReturnObject->Package.Count; i++)551{552OriginalElement = *ElementPtr;553OriginalRefCount = OriginalElement->Common.ReferenceCount;554555Status = AcpiNsRepair_HID (Info, ElementPtr);556if (ACPI_FAILURE (Status))557{558return_ACPI_STATUS (Status);559}560561if (OriginalElement != *ElementPtr)562{563/* Update reference count of new object */564565(*ElementPtr)->Common.ReferenceCount =566OriginalRefCount;567}568569ElementPtr++;570}571572return_ACPI_STATUS (AE_OK);573}574575576/******************************************************************************577*578* FUNCTION: AcpiNsRepair_CST579*580* PARAMETERS: Info - Method execution information block581* ReturnObjectPtr - Pointer to the object returned from the582* evaluation of a method or object583*584* RETURN: Status. AE_OK if object is OK or was repaired successfully585*586* DESCRIPTION: Repair for the _CST object:587* 1. Sort the list ascending by C state type588* 2. Ensure type cannot be zero589* 3. A subpackage count of zero means _CST is meaningless590* 4. Count must match the number of C state subpackages591*592*****************************************************************************/593594static ACPI_STATUS595AcpiNsRepair_CST (596ACPI_EVALUATE_INFO *Info,597ACPI_OPERAND_OBJECT **ReturnObjectPtr)598{599ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;600ACPI_OPERAND_OBJECT **OuterElements;601UINT32 OuterElementCount;602ACPI_OPERAND_OBJECT *ObjDesc;603ACPI_STATUS Status;604BOOLEAN Removing;605UINT32 i;606607608ACPI_FUNCTION_NAME (NsRepair_CST);609610611/*612* Check if the C-state type values are proportional.613*/614OuterElementCount = ReturnObject->Package.Count - 1;615i = 0;616while (i < OuterElementCount)617{618OuterElements = &ReturnObject->Package.Elements[i + 1];619Removing = FALSE;620621if ((*OuterElements)->Package.Count == 0)622{623ACPI_WARN_PREDEFINED ((AE_INFO,624Info->FullPathname, Info->NodeFlags,625"SubPackage[%u] - removing entry due to zero count", i));626Removing = TRUE;627goto RemoveElement;628}629630ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */631if ((UINT32) ObjDesc->Integer.Value == 0)632{633ACPI_WARN_PREDEFINED ((AE_INFO,634Info->FullPathname, Info->NodeFlags,635"SubPackage[%u] - removing entry due to invalid Type(0)", i));636Removing = TRUE;637}638639RemoveElement:640if (Removing)641{642AcpiNsRemoveElement (ReturnObject, i + 1);643OuterElementCount--;644}645else646{647i++;648}649}650651/* Update top-level package count, Type "Integer" checked elsewhere */652653ObjDesc = ReturnObject->Package.Elements[0];654ObjDesc->Integer.Value = OuterElementCount;655656/*657* Entries (subpackages) in the _CST Package must be sorted by the658* C-state type, in ascending order.659*/660Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1,661ACPI_SORT_ASCENDING, "C-State Type");662if (ACPI_FAILURE (Status))663{664return (Status);665}666667return (AE_OK);668}669670671/******************************************************************************672*673* FUNCTION: AcpiNsRepair_HID674*675* PARAMETERS: Info - Method execution information block676* ReturnObjectPtr - Pointer to the object returned from the677* evaluation of a method or object678*679* RETURN: Status. AE_OK if object is OK or was repaired successfully680*681* DESCRIPTION: Repair for the _HID object. If a string, ensure that all682* letters are uppercase and that there is no leading asterisk.683*684*****************************************************************************/685686static ACPI_STATUS687AcpiNsRepair_HID (688ACPI_EVALUATE_INFO *Info,689ACPI_OPERAND_OBJECT **ReturnObjectPtr)690{691ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;692ACPI_OPERAND_OBJECT *NewString;693char *Source;694char *Dest;695696697ACPI_FUNCTION_TRACE (NsRepair_HID);698699700/* We only care about string _HID objects (not integers) */701702if (ReturnObject->Common.Type != ACPI_TYPE_STRING)703{704return_ACPI_STATUS (AE_OK);705}706707if (ReturnObject->String.Length == 0)708{709ACPI_WARN_PREDEFINED ((AE_INFO,710Info->FullPathname, Info->NodeFlags,711"Invalid zero-length _HID or _CID string"));712713/* Return AE_OK anyway, let driver handle it */714715Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;716return_ACPI_STATUS (AE_OK);717}718719/* It is simplest to always create a new string object */720721NewString = AcpiUtCreateStringObject (ReturnObject->String.Length);722if (!NewString)723{724return_ACPI_STATUS (AE_NO_MEMORY);725}726727/*728* Remove a leading asterisk if present. For some unknown reason, there729* are many machines in the field that contains IDs like this.730*731* Examples: "*PNP0C03", "*ACPI0003"732*/733Source = ReturnObject->String.Pointer;734if (*Source == '*')735{736Source++;737NewString->String.Length--;738739ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,740"%s: Removed invalid leading asterisk\n", Info->FullPathname));741}742743/*744* Copy and uppercase the string. From the ACPI 5.0 specification:745*746* A valid PNP ID must be of the form "AAA####" where A is an uppercase747* letter and # is a hex digit. A valid ACPI ID must be of the form748* "NNNN####" where N is an uppercase letter or decimal digit, and749* # is a hex digit.750*/751for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)752{753*Dest = (char) toupper ((int) *Source);754}755756AcpiUtRemoveReference (ReturnObject);757*ReturnObjectPtr = NewString;758return_ACPI_STATUS (AE_OK);759}760761762/******************************************************************************763*764* FUNCTION: AcpiNsRepair_PRT765*766* PARAMETERS: Info - Method execution information block767* ReturnObjectPtr - Pointer to the object returned from the768* evaluation of a method or object769*770* RETURN: Status. AE_OK if object is OK or was repaired successfully771*772* DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed773* SourceName and SourceIndex field, a common BIOS bug.774*775*****************************************************************************/776777static ACPI_STATUS778AcpiNsRepair_PRT (779ACPI_EVALUATE_INFO *Info,780ACPI_OPERAND_OBJECT **ReturnObjectPtr)781{782ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr;783ACPI_OPERAND_OBJECT **TopObjectList;784ACPI_OPERAND_OBJECT **SubObjectList;785ACPI_OPERAND_OBJECT *ObjDesc;786ACPI_OPERAND_OBJECT *SubPackage;787UINT32 ElementCount;788UINT32 Index;789790791/* Each element in the _PRT package is a subpackage */792793TopObjectList = PackageObject->Package.Elements;794ElementCount = PackageObject->Package.Count;795796/* Examine each subpackage */797798for (Index = 0; Index < ElementCount; Index++, TopObjectList++)799{800SubPackage = *TopObjectList;801SubObjectList = SubPackage->Package.Elements;802803/* Check for minimum required element count */804805if (SubPackage->Package.Count < 4)806{807continue;808}809810/*811* If the BIOS has erroneously reversed the _PRT SourceName (index 2)812* and the SourceIndex (index 3), fix it. _PRT is important enough to813* workaround this BIOS error. This also provides compatibility with814* other ACPI implementations.815*/816ObjDesc = SubObjectList[3];817if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))818{819SubObjectList[3] = SubObjectList[2];820SubObjectList[2] = ObjDesc;821Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;822823ACPI_WARN_PREDEFINED ((AE_INFO,824Info->FullPathname, Info->NodeFlags,825"PRT[%X]: Fixed reversed SourceName and SourceIndex",826Index));827}828}829830return (AE_OK);831}832833834/******************************************************************************835*836* FUNCTION: AcpiNsRepair_PSS837*838* PARAMETERS: Info - Method execution information block839* ReturnObjectPtr - Pointer to the object returned from the840* evaluation of a method or object841*842* RETURN: Status. AE_OK if object is OK or was repaired successfully843*844* DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list845* by the CPU frequencies. Check that the power dissipation values846* are all proportional to CPU frequency (i.e., sorting by847* frequency should be the same as sorting by power.)848*849*****************************************************************************/850851static ACPI_STATUS852AcpiNsRepair_PSS (853ACPI_EVALUATE_INFO *Info,854ACPI_OPERAND_OBJECT **ReturnObjectPtr)855{856ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;857ACPI_OPERAND_OBJECT **OuterElements;858UINT32 OuterElementCount;859ACPI_OPERAND_OBJECT **Elements;860ACPI_OPERAND_OBJECT *ObjDesc;861UINT32 PreviousValue;862ACPI_STATUS Status;863UINT32 i;864865866/*867* Entries (subpackages) in the _PSS Package must be sorted by power868* dissipation, in descending order. If it appears that the list is869* incorrectly sorted, sort it. We sort by CpuFrequency, since this870* should be proportional to the power.871*/872Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0,873ACPI_SORT_DESCENDING, "CpuFrequency");874if (ACPI_FAILURE (Status))875{876return (Status);877}878879/*880* We now know the list is correctly sorted by CPU frequency. Check if881* the power dissipation values are proportional.882*/883PreviousValue = ACPI_UINT32_MAX;884OuterElements = ReturnObject->Package.Elements;885OuterElementCount = ReturnObject->Package.Count;886887for (i = 0; i < OuterElementCount; i++)888{889Elements = (*OuterElements)->Package.Elements;890ObjDesc = Elements[1]; /* Index1 = PowerDissipation */891892if ((UINT32) ObjDesc->Integer.Value > PreviousValue)893{894ACPI_WARN_PREDEFINED ((AE_INFO,895Info->FullPathname, Info->NodeFlags,896"SubPackage[%u,%u] - suspicious power dissipation values",897i-1, i));898}899900PreviousValue = (UINT32) ObjDesc->Integer.Value;901OuterElements++;902}903904return (AE_OK);905}906907908/******************************************************************************909*910* FUNCTION: AcpiNsRepair_TSS911*912* PARAMETERS: Info - Method execution information block913* ReturnObjectPtr - Pointer to the object returned from the914* evaluation of a method or object915*916* RETURN: Status. AE_OK if object is OK or was repaired successfully917*918* DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list919* descending by the power dissipation values.920*921*****************************************************************************/922923static ACPI_STATUS924AcpiNsRepair_TSS (925ACPI_EVALUATE_INFO *Info,926ACPI_OPERAND_OBJECT **ReturnObjectPtr)927{928ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;929ACPI_STATUS Status;930ACPI_NAMESPACE_NODE *Node;931932933/*934* We can only sort the _TSS return package if there is no _PSS in the935* same scope. This is because if _PSS is present, the ACPI specification936* dictates that the _TSS Power Dissipation field is to be ignored, and937* therefore some BIOSs leave garbage values in the _TSS Power field(s).938* In this case, it is best to just return the _TSS package as-is.939* (May, 2011)940*/941Status = AcpiNsGetNode (Info->Node, "^_PSS",942ACPI_NS_NO_UPSEARCH, &Node);943if (ACPI_SUCCESS (Status))944{945return (AE_OK);946}947948Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1,949ACPI_SORT_DESCENDING, "PowerDissipation");950951return (Status);952}953954955/******************************************************************************956*957* FUNCTION: AcpiNsCheckSortedList958*959* PARAMETERS: Info - Method execution information block960* ReturnObject - Pointer to the top-level returned object961* StartIndex - Index of the first subpackage962* ExpectedCount - Minimum length of each subpackage963* SortIndex - Subpackage entry to sort on964* SortDirection - Ascending or descending965* SortKeyName - Name of the SortIndex field966*967* RETURN: Status. AE_OK if the list is valid and is sorted correctly or968* has been repaired by sorting the list.969*970* DESCRIPTION: Check if the package list is valid and sorted correctly by the971* SortIndex. If not, then sort the list.972*973*****************************************************************************/974975static ACPI_STATUS976AcpiNsCheckSortedList (977ACPI_EVALUATE_INFO *Info,978ACPI_OPERAND_OBJECT *ReturnObject,979UINT32 StartIndex,980UINT32 ExpectedCount,981UINT32 SortIndex,982UINT8 SortDirection,983char *SortKeyName)984{985UINT32 OuterElementCount;986ACPI_OPERAND_OBJECT **OuterElements;987ACPI_OPERAND_OBJECT **Elements;988ACPI_OPERAND_OBJECT *ObjDesc;989UINT32 i;990UINT32 PreviousValue;991992993ACPI_FUNCTION_NAME (NsCheckSortedList);994995996/* The top-level object must be a package */997998if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)999{1000return (AE_AML_OPERAND_TYPE);1001}10021003/*1004* NOTE: assumes list of subpackages contains no NULL elements.1005* Any NULL elements should have been removed by earlier call1006* to AcpiNsRemoveNullElements.1007*/1008OuterElementCount = ReturnObject->Package.Count;1009if (!OuterElementCount || StartIndex >= OuterElementCount)1010{1011return (AE_AML_PACKAGE_LIMIT);1012}10131014OuterElements = &ReturnObject->Package.Elements[StartIndex];1015OuterElementCount -= StartIndex;10161017PreviousValue = 0;1018if (SortDirection == ACPI_SORT_DESCENDING)1019{1020PreviousValue = ACPI_UINT32_MAX;1021}10221023/* Examine each subpackage */10241025for (i = 0; i < OuterElementCount; i++)1026{1027/* Each element of the top-level package must also be a package */10281029if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)1030{1031return (AE_AML_OPERAND_TYPE);1032}10331034/* Each subpackage must have the minimum length */10351036if ((*OuterElements)->Package.Count < ExpectedCount)1037{1038return (AE_AML_PACKAGE_LIMIT);1039}10401041Elements = (*OuterElements)->Package.Elements;1042ObjDesc = Elements[SortIndex];10431044if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)1045{1046return (AE_AML_OPERAND_TYPE);1047}10481049/*1050* The list must be sorted in the specified order. If we detect a1051* discrepancy, sort the entire list.1052*/1053if (((SortDirection == ACPI_SORT_ASCENDING) &&1054(ObjDesc->Integer.Value < PreviousValue)) ||1055((SortDirection == ACPI_SORT_DESCENDING) &&1056(ObjDesc->Integer.Value > PreviousValue)))1057{1058AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex],1059OuterElementCount, SortIndex, SortDirection);10601061Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;10621063ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,1064"%s: Repaired unsorted list - now sorted by %s\n",1065Info->FullPathname, SortKeyName));1066return (AE_OK);1067}10681069PreviousValue = (UINT32) ObjDesc->Integer.Value;1070OuterElements++;1071}10721073return (AE_OK);1074}107510761077/******************************************************************************1078*1079* FUNCTION: AcpiNsSortList1080*1081* PARAMETERS: Elements - Package object element list1082* Count - Element count for above1083* Index - Sort by which package element1084* SortDirection - Ascending or Descending sort1085*1086* RETURN: None1087*1088* DESCRIPTION: Sort the objects that are in a package element list.1089*1090* NOTE: Assumes that all NULL elements have been removed from the package,1091* and that all elements have been verified to be of type Integer.1092*1093*****************************************************************************/10941095static void1096AcpiNsSortList (1097ACPI_OPERAND_OBJECT **Elements,1098UINT32 Count,1099UINT32 Index,1100UINT8 SortDirection)1101{1102ACPI_OPERAND_OBJECT *ObjDesc1;1103ACPI_OPERAND_OBJECT *ObjDesc2;1104ACPI_OPERAND_OBJECT *TempObj;1105UINT32 i;1106UINT32 j;110711081109/* Simple bubble sort */11101111for (i = 1; i < Count; i++)1112{1113for (j = (Count - 1); j >= i; j--)1114{1115ObjDesc1 = Elements[j-1]->Package.Elements[Index];1116ObjDesc2 = Elements[j]->Package.Elements[Index];11171118if (((SortDirection == ACPI_SORT_ASCENDING) &&1119(ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||11201121((SortDirection == ACPI_SORT_DESCENDING) &&1122(ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))1123{1124TempObj = Elements[j-1];1125Elements[j-1] = Elements[j];1126Elements[j] = TempObj;1127}1128}1129}1130}113111321133/******************************************************************************1134*1135* FUNCTION: AcpiNsRemoveElement1136*1137* PARAMETERS: ObjDesc - Package object element list1138* Index - Index of element to remove1139*1140* RETURN: None1141*1142* DESCRIPTION: Remove the requested element of a package and delete it.1143*1144*****************************************************************************/11451146static void1147AcpiNsRemoveElement (1148ACPI_OPERAND_OBJECT *ObjDesc,1149UINT32 Index)1150{1151ACPI_OPERAND_OBJECT **Source;1152ACPI_OPERAND_OBJECT **Dest;1153UINT32 Count;1154UINT32 NewCount;1155UINT32 i;115611571158ACPI_FUNCTION_NAME (NsRemoveElement);115911601161Count = ObjDesc->Package.Count;1162NewCount = Count - 1;11631164Source = ObjDesc->Package.Elements;1165Dest = Source;11661167/* Examine all elements of the package object, remove matched index */11681169for (i = 0; i < Count; i++)1170{1171if (i == Index)1172{1173AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */1174AcpiUtRemoveReference (*Source);1175}1176else1177{1178*Dest = *Source;1179Dest++;1180}11811182Source++;1183}11841185/* NULL terminate list and update the package count */11861187*Dest = NULL;1188ObjDesc->Package.Count = NewCount;1189}119011911192