1199323Sjkim/****************************************************************************** 2199323Sjkim * 3199323Sjkim * Module Name: nsrepair2 - Repair for objects returned by specific 4199323Sjkim * predefined methods 5199323Sjkim * 6199323Sjkim *****************************************************************************/ 7199323Sjkim 8217365Sjkim/* 9306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 10199323Sjkim * All rights reserved. 11199323Sjkim * 12217365Sjkim * Redistribution and use in source and binary forms, with or without 13217365Sjkim * modification, are permitted provided that the following conditions 14217365Sjkim * are met: 15217365Sjkim * 1. Redistributions of source code must retain the above copyright 16217365Sjkim * notice, this list of conditions, and the following disclaimer, 17217365Sjkim * without modification. 18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21217365Sjkim * including a substantially similar Disclaimer requirement for further 22217365Sjkim * binary redistribution. 23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24217365Sjkim * of any contributors may be used to endorse or promote products derived 25217365Sjkim * from this software without specific prior written permission. 26199323Sjkim * 27217365Sjkim * Alternatively, this software may be distributed under the terms of the 28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29217365Sjkim * Software Foundation. 30199323Sjkim * 31217365Sjkim * NO WARRANTY 32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 43217365Sjkim */ 44199323Sjkim 45199337Sjkim#include <contrib/dev/acpica/include/acpi.h> 46199337Sjkim#include <contrib/dev/acpica/include/accommon.h> 47199337Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 48199323Sjkim 49199323Sjkim#define _COMPONENT ACPI_NAMESPACE 50199323Sjkim ACPI_MODULE_NAME ("nsrepair2") 51199323Sjkim 52199323Sjkim 53199323Sjkim/* 54199323Sjkim * Information structure and handler for ACPI predefined names that can 55199323Sjkim * be repaired on a per-name basis. 56199323Sjkim */ 57199323Sjkimtypedef 58199323SjkimACPI_STATUS (*ACPI_REPAIR_FUNCTION) ( 59249663Sjkim ACPI_EVALUATE_INFO *Info, 60199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 61199323Sjkim 62199323Sjkimtypedef struct acpi_repair_info 63199323Sjkim{ 64199323Sjkim char Name[ACPI_NAME_SIZE]; 65199323Sjkim ACPI_REPAIR_FUNCTION RepairFunction; 66199323Sjkim 67199323Sjkim} ACPI_REPAIR_INFO; 68199323Sjkim 69199323Sjkim 70199323Sjkim/* Local prototypes */ 71199323Sjkim 72199323Sjkimstatic const ACPI_REPAIR_INFO * 73246849SjkimAcpiNsMatchComplexRepair ( 74199323Sjkim ACPI_NAMESPACE_NODE *Node); 75199323Sjkim 76199323Sjkimstatic ACPI_STATUS 77199323SjkimAcpiNsRepair_ALR ( 78249663Sjkim ACPI_EVALUATE_INFO *Info, 79199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 80199323Sjkim 81199323Sjkimstatic ACPI_STATUS 82212761SjkimAcpiNsRepair_CID ( 83249663Sjkim ACPI_EVALUATE_INFO *Info, 84212761Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 85212761Sjkim 86212761Sjkimstatic ACPI_STATUS 87250838SjkimAcpiNsRepair_CST ( 88250838Sjkim ACPI_EVALUATE_INFO *Info, 89250838Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 90250838Sjkim 91250838Sjkimstatic ACPI_STATUS 92200553SjkimAcpiNsRepair_FDE ( 93249663Sjkim ACPI_EVALUATE_INFO *Info, 94200553Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 95200553Sjkim 96200553Sjkimstatic ACPI_STATUS 97212761SjkimAcpiNsRepair_HID ( 98249663Sjkim ACPI_EVALUATE_INFO *Info, 99212761Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 100212761Sjkim 101212761Sjkimstatic ACPI_STATUS 102250838SjkimAcpiNsRepair_PRT ( 103250838Sjkim ACPI_EVALUATE_INFO *Info, 104250838Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 105250838Sjkim 106250838Sjkimstatic ACPI_STATUS 107199323SjkimAcpiNsRepair_PSS ( 108249663Sjkim ACPI_EVALUATE_INFO *Info, 109199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 110199323Sjkim 111199323Sjkimstatic ACPI_STATUS 112199323SjkimAcpiNsRepair_TSS ( 113249663Sjkim ACPI_EVALUATE_INFO *Info, 114199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 115199323Sjkim 116199323Sjkimstatic ACPI_STATUS 117199323SjkimAcpiNsCheckSortedList ( 118249663Sjkim ACPI_EVALUATE_INFO *Info, 119199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject, 120250838Sjkim UINT32 StartIndex, 121199323Sjkim UINT32 ExpectedCount, 122199323Sjkim UINT32 SortIndex, 123199323Sjkim UINT8 SortDirection, 124199323Sjkim char *SortKeyName); 125199323Sjkim 126250838Sjkim/* Values for SortDirection above */ 127250838Sjkim 128250838Sjkim#define ACPI_SORT_ASCENDING 0 129250838Sjkim#define ACPI_SORT_DESCENDING 1 130250838Sjkim 131202771Sjkimstatic void 132250838SjkimAcpiNsRemoveElement ( 133250838Sjkim ACPI_OPERAND_OBJECT *ObjDesc, 134250838Sjkim UINT32 Index); 135250838Sjkim 136250838Sjkimstatic void 137199323SjkimAcpiNsSortList ( 138199323Sjkim ACPI_OPERAND_OBJECT **Elements, 139199323Sjkim UINT32 Count, 140199323Sjkim UINT32 Index, 141199323Sjkim UINT8 SortDirection); 142199323Sjkim 143199323Sjkim 144199323Sjkim/* 145199323Sjkim * This table contains the names of the predefined methods for which we can 146199323Sjkim * perform more complex repairs. 147199323Sjkim * 148200553Sjkim * As necessary: 149200553Sjkim * 150200553Sjkim * _ALR: Sort the list ascending by AmbientIlluminance 151212761Sjkim * _CID: Strings: uppercase all, remove any leading asterisk 152250838Sjkim * _CST: Sort the list ascending by C state type 153200553Sjkim * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs 154200553Sjkim * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs 155212761Sjkim * _HID: Strings: uppercase all, remove any leading asterisk 156250838Sjkim * _PRT: Fix reversed SourceName and SourceIndex 157200553Sjkim * _PSS: Sort the list descending by Power 158200553Sjkim * _TSS: Sort the list descending by Power 159209746Sjkim * 160209746Sjkim * Names that must be packages, but cannot be sorted: 161209746Sjkim * 162209746Sjkim * _BCL: Values are tied to the Package index where they appear, and cannot 163209746Sjkim * be moved or sorted. These index values are used for _BQC and _BCM. 164209746Sjkim * However, we can fix the case where a buffer is returned, by converting 165209746Sjkim * it to a Package of integers. 166199323Sjkim */ 167199323Sjkimstatic const ACPI_REPAIR_INFO AcpiNsRepairableNames[] = 168199323Sjkim{ 169199323Sjkim {"_ALR", AcpiNsRepair_ALR}, 170212761Sjkim {"_CID", AcpiNsRepair_CID}, 171250838Sjkim {"_CST", AcpiNsRepair_CST}, 172200553Sjkim {"_FDE", AcpiNsRepair_FDE}, 173200553Sjkim {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */ 174212761Sjkim {"_HID", AcpiNsRepair_HID}, 175250838Sjkim {"_PRT", AcpiNsRepair_PRT}, 176199323Sjkim {"_PSS", AcpiNsRepair_PSS}, 177199323Sjkim {"_TSS", AcpiNsRepair_TSS}, 178200553Sjkim {{0,0,0,0}, NULL} /* Table terminator */ 179199323Sjkim}; 180199323Sjkim 181199323Sjkim 182200553Sjkim#define ACPI_FDE_FIELD_COUNT 5 183200553Sjkim#define ACPI_FDE_BYTE_BUFFER_SIZE 5 184200553Sjkim#define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * sizeof (UINT32)) 185200553Sjkim 186200553Sjkim 187199323Sjkim/****************************************************************************** 188199323Sjkim * 189199323Sjkim * FUNCTION: AcpiNsComplexRepairs 190199323Sjkim * 191249663Sjkim * PARAMETERS: Info - Method execution information block 192199323Sjkim * Node - Namespace node for the method/object 193199323Sjkim * ValidateStatus - Original status of earlier validation 194199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 195199323Sjkim * evaluation of a method or object 196199323Sjkim * 197200553Sjkim * RETURN: Status. AE_OK if repair was successful. If name is not 198199323Sjkim * matched, ValidateStatus is returned. 199199323Sjkim * 200199323Sjkim * DESCRIPTION: Attempt to repair/convert a return object of a type that was 201199323Sjkim * not expected. 202199323Sjkim * 203199323Sjkim *****************************************************************************/ 204199323Sjkim 205199323SjkimACPI_STATUS 206199323SjkimAcpiNsComplexRepairs ( 207249663Sjkim ACPI_EVALUATE_INFO *Info, 208199323Sjkim ACPI_NAMESPACE_NODE *Node, 209199323Sjkim ACPI_STATUS ValidateStatus, 210199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 211199323Sjkim{ 212199323Sjkim const ACPI_REPAIR_INFO *Predefined; 213199323Sjkim ACPI_STATUS Status; 214199323Sjkim 215199323Sjkim 216199323Sjkim /* Check if this name is in the list of repairable names */ 217199323Sjkim 218246849Sjkim Predefined = AcpiNsMatchComplexRepair (Node); 219199323Sjkim if (!Predefined) 220199323Sjkim { 221199323Sjkim return (ValidateStatus); 222199323Sjkim } 223199323Sjkim 224249663Sjkim Status = Predefined->RepairFunction (Info, ReturnObjectPtr); 225199323Sjkim return (Status); 226199323Sjkim} 227199323Sjkim 228199323Sjkim 229199323Sjkim/****************************************************************************** 230199323Sjkim * 231246849Sjkim * FUNCTION: AcpiNsMatchComplexRepair 232199323Sjkim * 233199323Sjkim * PARAMETERS: Node - Namespace node for the method/object 234199323Sjkim * 235199323Sjkim * RETURN: Pointer to entry in repair table. NULL indicates not found. 236199323Sjkim * 237199323Sjkim * DESCRIPTION: Check an object name against the repairable object list. 238199323Sjkim * 239199323Sjkim *****************************************************************************/ 240199323Sjkim 241199323Sjkimstatic const ACPI_REPAIR_INFO * 242246849SjkimAcpiNsMatchComplexRepair ( 243199323Sjkim ACPI_NAMESPACE_NODE *Node) 244199323Sjkim{ 245199323Sjkim const ACPI_REPAIR_INFO *ThisName; 246199323Sjkim 247199323Sjkim 248199323Sjkim /* Search info table for a repairable predefined method/object name */ 249199323Sjkim 250199323Sjkim ThisName = AcpiNsRepairableNames; 251199323Sjkim while (ThisName->RepairFunction) 252199323Sjkim { 253199323Sjkim if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) 254199323Sjkim { 255199323Sjkim return (ThisName); 256199323Sjkim } 257306536Sjkim 258199323Sjkim ThisName++; 259199323Sjkim } 260199323Sjkim 261199323Sjkim return (NULL); /* Not found */ 262199323Sjkim} 263199323Sjkim 264199323Sjkim 265199323Sjkim/****************************************************************************** 266199323Sjkim * 267199323Sjkim * FUNCTION: AcpiNsRepair_ALR 268199323Sjkim * 269249663Sjkim * PARAMETERS: Info - Method execution information block 270199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 271199323Sjkim * evaluation of a method or object 272199323Sjkim * 273199323Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 274199323Sjkim * 275199323Sjkim * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list 276199323Sjkim * ascending by the ambient illuminance values. 277199323Sjkim * 278199323Sjkim *****************************************************************************/ 279199323Sjkim 280199323Sjkimstatic ACPI_STATUS 281199323SjkimAcpiNsRepair_ALR ( 282249663Sjkim ACPI_EVALUATE_INFO *Info, 283199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 284199323Sjkim{ 285199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 286199323Sjkim ACPI_STATUS Status; 287199323Sjkim 288199323Sjkim 289250838Sjkim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1, 290306536Sjkim ACPI_SORT_ASCENDING, "AmbientIlluminance"); 291199323Sjkim 292199323Sjkim return (Status); 293199323Sjkim} 294199323Sjkim 295199323Sjkim 296199323Sjkim/****************************************************************************** 297199323Sjkim * 298200553Sjkim * FUNCTION: AcpiNsRepair_FDE 299200553Sjkim * 300249663Sjkim * PARAMETERS: Info - Method execution information block 301200553Sjkim * ReturnObjectPtr - Pointer to the object returned from the 302200553Sjkim * evaluation of a method or object 303200553Sjkim * 304200553Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 305200553Sjkim * 306200553Sjkim * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return 307200553Sjkim * value is a Buffer of 5 DWORDs. This function repairs a common 308200553Sjkim * problem where the return value is a Buffer of BYTEs, not 309200553Sjkim * DWORDs. 310200553Sjkim * 311200553Sjkim *****************************************************************************/ 312200553Sjkim 313200553Sjkimstatic ACPI_STATUS 314200553SjkimAcpiNsRepair_FDE ( 315249663Sjkim ACPI_EVALUATE_INFO *Info, 316200553Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 317200553Sjkim{ 318200553Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 319200553Sjkim ACPI_OPERAND_OBJECT *BufferObject; 320200553Sjkim UINT8 *ByteBuffer; 321200553Sjkim UINT32 *DwordBuffer; 322200553Sjkim UINT32 i; 323200553Sjkim 324200553Sjkim 325200553Sjkim ACPI_FUNCTION_NAME (NsRepair_FDE); 326200553Sjkim 327200553Sjkim 328200553Sjkim switch (ReturnObject->Common.Type) 329200553Sjkim { 330200553Sjkim case ACPI_TYPE_BUFFER: 331200553Sjkim 332200553Sjkim /* This is the expected type. Length should be (at least) 5 DWORDs */ 333200553Sjkim 334200553Sjkim if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE) 335200553Sjkim { 336200553Sjkim return (AE_OK); 337200553Sjkim } 338200553Sjkim 339200553Sjkim /* We can only repair if we have exactly 5 BYTEs */ 340200553Sjkim 341200553Sjkim if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE) 342200553Sjkim { 343306536Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, 344306536Sjkim Info->FullPathname, Info->NodeFlags, 345200553Sjkim "Incorrect return buffer length %u, expected %u", 346200553Sjkim ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE)); 347200553Sjkim 348200553Sjkim return (AE_AML_OPERAND_TYPE); 349200553Sjkim } 350200553Sjkim 351200553Sjkim /* Create the new (larger) buffer object */ 352200553Sjkim 353306536Sjkim BufferObject = AcpiUtCreateBufferObject ( 354306536Sjkim ACPI_FDE_DWORD_BUFFER_SIZE); 355200553Sjkim if (!BufferObject) 356200553Sjkim { 357200553Sjkim return (AE_NO_MEMORY); 358200553Sjkim } 359200553Sjkim 360200553Sjkim /* Expand each byte to a DWORD */ 361200553Sjkim 362200553Sjkim ByteBuffer = ReturnObject->Buffer.Pointer; 363306536Sjkim DwordBuffer = ACPI_CAST_PTR (UINT32, 364306536Sjkim BufferObject->Buffer.Pointer); 365200553Sjkim 366200553Sjkim for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++) 367200553Sjkim { 368200553Sjkim *DwordBuffer = (UINT32) *ByteBuffer; 369200553Sjkim DwordBuffer++; 370200553Sjkim ByteBuffer++; 371200553Sjkim } 372200553Sjkim 373200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 374200553Sjkim "%s Expanded Byte Buffer to expected DWord Buffer\n", 375249663Sjkim Info->FullPathname)); 376200553Sjkim break; 377200553Sjkim 378200553Sjkim default: 379250838Sjkim 380200553Sjkim return (AE_AML_OPERAND_TYPE); 381200553Sjkim } 382200553Sjkim 383200553Sjkim /* Delete the original return object, return the new buffer object */ 384200553Sjkim 385200553Sjkim AcpiUtRemoveReference (ReturnObject); 386200553Sjkim *ReturnObjectPtr = BufferObject; 387200553Sjkim 388249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 389200553Sjkim return (AE_OK); 390200553Sjkim} 391200553Sjkim 392200553Sjkim 393200553Sjkim/****************************************************************************** 394200553Sjkim * 395212761Sjkim * FUNCTION: AcpiNsRepair_CID 396212761Sjkim * 397249663Sjkim * PARAMETERS: Info - Method execution information block 398212761Sjkim * ReturnObjectPtr - Pointer to the object returned from the 399212761Sjkim * evaluation of a method or object 400212761Sjkim * 401212761Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 402212761Sjkim * 403212761Sjkim * DESCRIPTION: Repair for the _CID object. If a string, ensure that all 404212761Sjkim * letters are uppercase and that there is no leading asterisk. 405212761Sjkim * If a Package, ensure same for all string elements. 406212761Sjkim * 407212761Sjkim *****************************************************************************/ 408212761Sjkim 409212761Sjkimstatic ACPI_STATUS 410212761SjkimAcpiNsRepair_CID ( 411249663Sjkim ACPI_EVALUATE_INFO *Info, 412212761Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 413212761Sjkim{ 414212761Sjkim ACPI_STATUS Status; 415212761Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 416212761Sjkim ACPI_OPERAND_OBJECT **ElementPtr; 417212761Sjkim ACPI_OPERAND_OBJECT *OriginalElement; 418212761Sjkim UINT16 OriginalRefCount; 419212761Sjkim UINT32 i; 420212761Sjkim 421212761Sjkim 422212761Sjkim /* Check for _CID as a simple string */ 423212761Sjkim 424212761Sjkim if (ReturnObject->Common.Type == ACPI_TYPE_STRING) 425212761Sjkim { 426249663Sjkim Status = AcpiNsRepair_HID (Info, ReturnObjectPtr); 427212761Sjkim return (Status); 428212761Sjkim } 429212761Sjkim 430212761Sjkim /* Exit if not a Package */ 431212761Sjkim 432212761Sjkim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 433212761Sjkim { 434212761Sjkim return (AE_OK); 435212761Sjkim } 436212761Sjkim 437212761Sjkim /* Examine each element of the _CID package */ 438212761Sjkim 439212761Sjkim ElementPtr = ReturnObject->Package.Elements; 440212761Sjkim for (i = 0; i < ReturnObject->Package.Count; i++) 441212761Sjkim { 442212761Sjkim OriginalElement = *ElementPtr; 443212761Sjkim OriginalRefCount = OriginalElement->Common.ReferenceCount; 444212761Sjkim 445249663Sjkim Status = AcpiNsRepair_HID (Info, ElementPtr); 446212761Sjkim if (ACPI_FAILURE (Status)) 447212761Sjkim { 448212761Sjkim return (Status); 449212761Sjkim } 450212761Sjkim 451212761Sjkim /* Take care with reference counts */ 452212761Sjkim 453212761Sjkim if (OriginalElement != *ElementPtr) 454212761Sjkim { 455212761Sjkim /* Element was replaced */ 456212761Sjkim 457212761Sjkim (*ElementPtr)->Common.ReferenceCount = 458212761Sjkim OriginalRefCount; 459212761Sjkim 460212761Sjkim AcpiUtRemoveReference (OriginalElement); 461212761Sjkim } 462212761Sjkim 463212761Sjkim ElementPtr++; 464212761Sjkim } 465212761Sjkim 466212761Sjkim return (AE_OK); 467212761Sjkim} 468212761Sjkim 469212761Sjkim 470212761Sjkim/****************************************************************************** 471212761Sjkim * 472250838Sjkim * FUNCTION: AcpiNsRepair_CST 473250838Sjkim * 474250838Sjkim * PARAMETERS: Info - Method execution information block 475250838Sjkim * ReturnObjectPtr - Pointer to the object returned from the 476250838Sjkim * evaluation of a method or object 477250838Sjkim * 478250838Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 479250838Sjkim * 480250838Sjkim * DESCRIPTION: Repair for the _CST object: 481250838Sjkim * 1. Sort the list ascending by C state type 482250838Sjkim * 2. Ensure type cannot be zero 483281075Sdim * 3. A subpackage count of zero means _CST is meaningless 484281075Sdim * 4. Count must match the number of C state subpackages 485250838Sjkim * 486250838Sjkim *****************************************************************************/ 487250838Sjkim 488250838Sjkimstatic ACPI_STATUS 489250838SjkimAcpiNsRepair_CST ( 490250838Sjkim ACPI_EVALUATE_INFO *Info, 491250838Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 492250838Sjkim{ 493250838Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 494250838Sjkim ACPI_OPERAND_OBJECT **OuterElements; 495250838Sjkim UINT32 OuterElementCount; 496250838Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 497250838Sjkim ACPI_STATUS Status; 498250838Sjkim BOOLEAN Removing; 499250838Sjkim UINT32 i; 500250838Sjkim 501250838Sjkim 502250838Sjkim ACPI_FUNCTION_NAME (NsRepair_CST); 503250838Sjkim 504250838Sjkim 505250838Sjkim /* 506252279Sjkim * Check if the C-state type values are proportional. 507250838Sjkim */ 508250838Sjkim OuterElementCount = ReturnObject->Package.Count - 1; 509250838Sjkim i = 0; 510250838Sjkim while (i < OuterElementCount) 511250838Sjkim { 512250838Sjkim OuterElements = &ReturnObject->Package.Elements[i + 1]; 513250838Sjkim Removing = FALSE; 514250838Sjkim 515250838Sjkim if ((*OuterElements)->Package.Count == 0) 516250838Sjkim { 517306536Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, 518306536Sjkim Info->FullPathname, Info->NodeFlags, 519250838Sjkim "SubPackage[%u] - removing entry due to zero count", i)); 520250838Sjkim Removing = TRUE; 521252279Sjkim goto RemoveElement; 522250838Sjkim } 523250838Sjkim 524250838Sjkim ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */ 525250838Sjkim if ((UINT32) ObjDesc->Integer.Value == 0) 526250838Sjkim { 527306536Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, 528306536Sjkim Info->FullPathname, Info->NodeFlags, 529250838Sjkim "SubPackage[%u] - removing entry due to invalid Type(0)", i)); 530250838Sjkim Removing = TRUE; 531250838Sjkim } 532250838Sjkim 533252279SjkimRemoveElement: 534250838Sjkim if (Removing) 535250838Sjkim { 536250838Sjkim AcpiNsRemoveElement (ReturnObject, i + 1); 537250838Sjkim OuterElementCount--; 538250838Sjkim } 539250838Sjkim else 540250838Sjkim { 541250838Sjkim i++; 542250838Sjkim } 543250838Sjkim } 544250838Sjkim 545250838Sjkim /* Update top-level package count, Type "Integer" checked elsewhere */ 546250838Sjkim 547250838Sjkim ObjDesc = ReturnObject->Package.Elements[0]; 548250838Sjkim ObjDesc->Integer.Value = OuterElementCount; 549252279Sjkim 550252279Sjkim /* 551252279Sjkim * Entries (subpackages) in the _CST Package must be sorted by the 552252279Sjkim * C-state type, in ascending order. 553252279Sjkim */ 554252279Sjkim Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1, 555306536Sjkim ACPI_SORT_ASCENDING, "C-State Type"); 556252279Sjkim if (ACPI_FAILURE (Status)) 557252279Sjkim { 558252279Sjkim return (Status); 559252279Sjkim } 560252279Sjkim 561250838Sjkim return (AE_OK); 562250838Sjkim} 563250838Sjkim 564250838Sjkim 565250838Sjkim/****************************************************************************** 566250838Sjkim * 567212761Sjkim * FUNCTION: AcpiNsRepair_HID 568212761Sjkim * 569249663Sjkim * PARAMETERS: Info - Method execution information block 570212761Sjkim * ReturnObjectPtr - Pointer to the object returned from the 571212761Sjkim * evaluation of a method or object 572212761Sjkim * 573212761Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 574212761Sjkim * 575212761Sjkim * DESCRIPTION: Repair for the _HID object. If a string, ensure that all 576212761Sjkim * letters are uppercase and that there is no leading asterisk. 577212761Sjkim * 578212761Sjkim *****************************************************************************/ 579212761Sjkim 580212761Sjkimstatic ACPI_STATUS 581212761SjkimAcpiNsRepair_HID ( 582249663Sjkim ACPI_EVALUATE_INFO *Info, 583212761Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 584212761Sjkim{ 585212761Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 586212761Sjkim ACPI_OPERAND_OBJECT *NewString; 587212761Sjkim char *Source; 588212761Sjkim char *Dest; 589212761Sjkim 590212761Sjkim 591212761Sjkim ACPI_FUNCTION_NAME (NsRepair_HID); 592212761Sjkim 593212761Sjkim 594212761Sjkim /* We only care about string _HID objects (not integers) */ 595212761Sjkim 596212761Sjkim if (ReturnObject->Common.Type != ACPI_TYPE_STRING) 597212761Sjkim { 598212761Sjkim return (AE_OK); 599212761Sjkim } 600212761Sjkim 601212761Sjkim if (ReturnObject->String.Length == 0) 602212761Sjkim { 603306536Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, 604306536Sjkim Info->FullPathname, Info->NodeFlags, 605212761Sjkim "Invalid zero-length _HID or _CID string")); 606212761Sjkim 607212761Sjkim /* Return AE_OK anyway, let driver handle it */ 608212761Sjkim 609249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 610212761Sjkim return (AE_OK); 611212761Sjkim } 612212761Sjkim 613212761Sjkim /* It is simplest to always create a new string object */ 614212761Sjkim 615212761Sjkim NewString = AcpiUtCreateStringObject (ReturnObject->String.Length); 616212761Sjkim if (!NewString) 617212761Sjkim { 618212761Sjkim return (AE_NO_MEMORY); 619212761Sjkim } 620212761Sjkim 621212761Sjkim /* 622212761Sjkim * Remove a leading asterisk if present. For some unknown reason, there 623212761Sjkim * are many machines in the field that contains IDs like this. 624212761Sjkim * 625212761Sjkim * Examples: "*PNP0C03", "*ACPI0003" 626212761Sjkim */ 627212761Sjkim Source = ReturnObject->String.Pointer; 628212761Sjkim if (*Source == '*') 629212761Sjkim { 630212761Sjkim Source++; 631212761Sjkim NewString->String.Length--; 632212761Sjkim 633212761Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 634249663Sjkim "%s: Removed invalid leading asterisk\n", Info->FullPathname)); 635212761Sjkim } 636212761Sjkim 637212761Sjkim /* 638228110Sjkim * Copy and uppercase the string. From the ACPI 5.0 specification: 639212761Sjkim * 640212761Sjkim * A valid PNP ID must be of the form "AAA####" where A is an uppercase 641212761Sjkim * letter and # is a hex digit. A valid ACPI ID must be of the form 642228110Sjkim * "NNNN####" where N is an uppercase letter or decimal digit, and 643228110Sjkim * # is a hex digit. 644212761Sjkim */ 645212761Sjkim for (Dest = NewString->String.Pointer; *Source; Dest++, Source++) 646212761Sjkim { 647306536Sjkim *Dest = (char) toupper ((int) *Source); 648212761Sjkim } 649212761Sjkim 650212761Sjkim AcpiUtRemoveReference (ReturnObject); 651212761Sjkim *ReturnObjectPtr = NewString; 652212761Sjkim return (AE_OK); 653212761Sjkim} 654212761Sjkim 655212761Sjkim 656212761Sjkim/****************************************************************************** 657212761Sjkim * 658250838Sjkim * FUNCTION: AcpiNsRepair_PRT 659199323Sjkim * 660249663Sjkim * PARAMETERS: Info - Method execution information block 661199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 662199323Sjkim * evaluation of a method or object 663199323Sjkim * 664199323Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 665199323Sjkim * 666250838Sjkim * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed 667250838Sjkim * SourceName and SourceIndex field, a common BIOS bug. 668199323Sjkim * 669199323Sjkim *****************************************************************************/ 670199323Sjkim 671199323Sjkimstatic ACPI_STATUS 672250838SjkimAcpiNsRepair_PRT ( 673249663Sjkim ACPI_EVALUATE_INFO *Info, 674199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 675199323Sjkim{ 676250838Sjkim ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr; 677250838Sjkim ACPI_OPERAND_OBJECT **TopObjectList; 678250838Sjkim ACPI_OPERAND_OBJECT **SubObjectList; 679250838Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 680281075Sdim ACPI_OPERAND_OBJECT *SubPackage; 681250838Sjkim UINT32 ElementCount; 682250838Sjkim UINT32 Index; 683199323Sjkim 684199323Sjkim 685250838Sjkim /* Each element in the _PRT package is a subpackage */ 686250838Sjkim 687250838Sjkim TopObjectList = PackageObject->Package.Elements; 688250838Sjkim ElementCount = PackageObject->Package.Count; 689250838Sjkim 690281075Sdim /* Examine each subpackage */ 691281075Sdim 692281075Sdim for (Index = 0; Index < ElementCount; Index++, TopObjectList++) 693228110Sjkim { 694281075Sdim SubPackage = *TopObjectList; 695281075Sdim SubObjectList = SubPackage->Package.Elements; 696250838Sjkim 697281075Sdim /* Check for minimum required element count */ 698281075Sdim 699281075Sdim if (SubPackage->Package.Count < 4) 700281075Sdim { 701281075Sdim continue; 702281075Sdim } 703281075Sdim 704250838Sjkim /* 705250838Sjkim * If the BIOS has erroneously reversed the _PRT SourceName (index 2) 706250838Sjkim * and the SourceIndex (index 3), fix it. _PRT is important enough to 707250838Sjkim * workaround this BIOS error. This also provides compatibility with 708250838Sjkim * other ACPI implementations. 709250838Sjkim */ 710250838Sjkim ObjDesc = SubObjectList[3]; 711250838Sjkim if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)) 712250838Sjkim { 713250838Sjkim SubObjectList[3] = SubObjectList[2]; 714250838Sjkim SubObjectList[2] = ObjDesc; 715250838Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 716250838Sjkim 717281075Sdim ACPI_WARN_PREDEFINED ((AE_INFO, 718281075Sdim Info->FullPathname, Info->NodeFlags, 719250838Sjkim "PRT[%X]: Fixed reversed SourceName and SourceIndex", 720250838Sjkim Index)); 721250838Sjkim } 722228110Sjkim } 723228110Sjkim 724250838Sjkim return (AE_OK); 725199323Sjkim} 726199323Sjkim 727199323Sjkim 728199323Sjkim/****************************************************************************** 729199323Sjkim * 730199323Sjkim * FUNCTION: AcpiNsRepair_PSS 731199323Sjkim * 732249663Sjkim * PARAMETERS: Info - Method execution information block 733199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 734199323Sjkim * evaluation of a method or object 735199323Sjkim * 736199323Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 737199323Sjkim * 738199323Sjkim * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list 739199323Sjkim * by the CPU frequencies. Check that the power dissipation values 740199323Sjkim * are all proportional to CPU frequency (i.e., sorting by 741199323Sjkim * frequency should be the same as sorting by power.) 742199323Sjkim * 743199323Sjkim *****************************************************************************/ 744199323Sjkim 745199323Sjkimstatic ACPI_STATUS 746199323SjkimAcpiNsRepair_PSS ( 747249663Sjkim ACPI_EVALUATE_INFO *Info, 748199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 749199323Sjkim{ 750199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 751199323Sjkim ACPI_OPERAND_OBJECT **OuterElements; 752199323Sjkim UINT32 OuterElementCount; 753199323Sjkim ACPI_OPERAND_OBJECT **Elements; 754199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 755199323Sjkim UINT32 PreviousValue; 756199323Sjkim ACPI_STATUS Status; 757199323Sjkim UINT32 i; 758199323Sjkim 759199323Sjkim 760199323Sjkim /* 761281075Sdim * Entries (subpackages) in the _PSS Package must be sorted by power 762199323Sjkim * dissipation, in descending order. If it appears that the list is 763199323Sjkim * incorrectly sorted, sort it. We sort by CpuFrequency, since this 764199323Sjkim * should be proportional to the power. 765199323Sjkim */ 766306536Sjkim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0, 767306536Sjkim ACPI_SORT_DESCENDING, "CpuFrequency"); 768199323Sjkim if (ACPI_FAILURE (Status)) 769199323Sjkim { 770199323Sjkim return (Status); 771199323Sjkim } 772199323Sjkim 773199323Sjkim /* 774199323Sjkim * We now know the list is correctly sorted by CPU frequency. Check if 775199323Sjkim * the power dissipation values are proportional. 776199323Sjkim */ 777199323Sjkim PreviousValue = ACPI_UINT32_MAX; 778199323Sjkim OuterElements = ReturnObject->Package.Elements; 779199323Sjkim OuterElementCount = ReturnObject->Package.Count; 780199323Sjkim 781199323Sjkim for (i = 0; i < OuterElementCount; i++) 782199323Sjkim { 783199323Sjkim Elements = (*OuterElements)->Package.Elements; 784199323Sjkim ObjDesc = Elements[1]; /* Index1 = PowerDissipation */ 785199323Sjkim 786199323Sjkim if ((UINT32) ObjDesc->Integer.Value > PreviousValue) 787199323Sjkim { 788306536Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, 789306536Sjkim Info->FullPathname, Info->NodeFlags, 790199323Sjkim "SubPackage[%u,%u] - suspicious power dissipation values", 791199323Sjkim i-1, i)); 792199323Sjkim } 793199323Sjkim 794199323Sjkim PreviousValue = (UINT32) ObjDesc->Integer.Value; 795199323Sjkim OuterElements++; 796199323Sjkim } 797199323Sjkim 798199323Sjkim return (AE_OK); 799199323Sjkim} 800199323Sjkim 801199323Sjkim 802199323Sjkim/****************************************************************************** 803199323Sjkim * 804250838Sjkim * FUNCTION: AcpiNsRepair_TSS 805250838Sjkim * 806250838Sjkim * PARAMETERS: Info - Method execution information block 807250838Sjkim * ReturnObjectPtr - Pointer to the object returned from the 808250838Sjkim * evaluation of a method or object 809250838Sjkim * 810250838Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 811250838Sjkim * 812250838Sjkim * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list 813250838Sjkim * descending by the power dissipation values. 814250838Sjkim * 815250838Sjkim *****************************************************************************/ 816250838Sjkim 817250838Sjkimstatic ACPI_STATUS 818250838SjkimAcpiNsRepair_TSS ( 819250838Sjkim ACPI_EVALUATE_INFO *Info, 820250838Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 821250838Sjkim{ 822250838Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 823250838Sjkim ACPI_STATUS Status; 824250838Sjkim ACPI_NAMESPACE_NODE *Node; 825250838Sjkim 826250838Sjkim 827250838Sjkim /* 828250838Sjkim * We can only sort the _TSS return package if there is no _PSS in the 829250838Sjkim * same scope. This is because if _PSS is present, the ACPI specification 830250838Sjkim * dictates that the _TSS Power Dissipation field is to be ignored, and 831250838Sjkim * therefore some BIOSs leave garbage values in the _TSS Power field(s). 832250838Sjkim * In this case, it is best to just return the _TSS package as-is. 833250838Sjkim * (May, 2011) 834250838Sjkim */ 835250838Sjkim Status = AcpiNsGetNode (Info->Node, "^_PSS", 836250838Sjkim ACPI_NS_NO_UPSEARCH, &Node); 837250838Sjkim if (ACPI_SUCCESS (Status)) 838250838Sjkim { 839250838Sjkim return (AE_OK); 840250838Sjkim } 841250838Sjkim 842250838Sjkim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1, 843306536Sjkim ACPI_SORT_DESCENDING, "PowerDissipation"); 844250838Sjkim 845250838Sjkim return (Status); 846250838Sjkim} 847250838Sjkim 848250838Sjkim 849250838Sjkim/****************************************************************************** 850250838Sjkim * 851199323Sjkim * FUNCTION: AcpiNsCheckSortedList 852199323Sjkim * 853249663Sjkim * PARAMETERS: Info - Method execution information block 854199323Sjkim * ReturnObject - Pointer to the top-level returned object 855281075Sdim * StartIndex - Index of the first subpackage 856281075Sdim * ExpectedCount - Minimum length of each subpackage 857281075Sdim * SortIndex - Subpackage entry to sort on 858199323Sjkim * SortDirection - Ascending or descending 859199323Sjkim * SortKeyName - Name of the SortIndex field 860199323Sjkim * 861199323Sjkim * RETURN: Status. AE_OK if the list is valid and is sorted correctly or 862199323Sjkim * has been repaired by sorting the list. 863199323Sjkim * 864199323Sjkim * DESCRIPTION: Check if the package list is valid and sorted correctly by the 865199323Sjkim * SortIndex. If not, then sort the list. 866199323Sjkim * 867199323Sjkim *****************************************************************************/ 868199323Sjkim 869199323Sjkimstatic ACPI_STATUS 870199323SjkimAcpiNsCheckSortedList ( 871249663Sjkim ACPI_EVALUATE_INFO *Info, 872199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject, 873250838Sjkim UINT32 StartIndex, 874199323Sjkim UINT32 ExpectedCount, 875199323Sjkim UINT32 SortIndex, 876199323Sjkim UINT8 SortDirection, 877199323Sjkim char *SortKeyName) 878199323Sjkim{ 879199323Sjkim UINT32 OuterElementCount; 880199323Sjkim ACPI_OPERAND_OBJECT **OuterElements; 881199323Sjkim ACPI_OPERAND_OBJECT **Elements; 882199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 883199323Sjkim UINT32 i; 884199323Sjkim UINT32 PreviousValue; 885199323Sjkim 886199323Sjkim 887200553Sjkim ACPI_FUNCTION_NAME (NsCheckSortedList); 888200553Sjkim 889200553Sjkim 890199323Sjkim /* The top-level object must be a package */ 891199323Sjkim 892199323Sjkim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 893199323Sjkim { 894199323Sjkim return (AE_AML_OPERAND_TYPE); 895199323Sjkim } 896199323Sjkim 897199323Sjkim /* 898281075Sdim * NOTE: assumes list of subpackages contains no NULL elements. 899200553Sjkim * Any NULL elements should have been removed by earlier call 900200553Sjkim * to AcpiNsRemoveNullElements. 901199323Sjkim */ 902199323Sjkim OuterElementCount = ReturnObject->Package.Count; 903250838Sjkim if (!OuterElementCount || StartIndex >= OuterElementCount) 904199323Sjkim { 905199323Sjkim return (AE_AML_PACKAGE_LIMIT); 906199323Sjkim } 907199323Sjkim 908250838Sjkim OuterElements = &ReturnObject->Package.Elements[StartIndex]; 909250838Sjkim OuterElementCount -= StartIndex; 910250838Sjkim 911199323Sjkim PreviousValue = 0; 912199323Sjkim if (SortDirection == ACPI_SORT_DESCENDING) 913199323Sjkim { 914199323Sjkim PreviousValue = ACPI_UINT32_MAX; 915199323Sjkim } 916199323Sjkim 917199323Sjkim /* Examine each subpackage */ 918199323Sjkim 919199323Sjkim for (i = 0; i < OuterElementCount; i++) 920199323Sjkim { 921199323Sjkim /* Each element of the top-level package must also be a package */ 922199323Sjkim 923199323Sjkim if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE) 924199323Sjkim { 925199323Sjkim return (AE_AML_OPERAND_TYPE); 926199323Sjkim } 927199323Sjkim 928281075Sdim /* Each subpackage must have the minimum length */ 929199323Sjkim 930199323Sjkim if ((*OuterElements)->Package.Count < ExpectedCount) 931199323Sjkim { 932199323Sjkim return (AE_AML_PACKAGE_LIMIT); 933199323Sjkim } 934199323Sjkim 935199323Sjkim Elements = (*OuterElements)->Package.Elements; 936199323Sjkim ObjDesc = Elements[SortIndex]; 937199323Sjkim 938199323Sjkim if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) 939199323Sjkim { 940199323Sjkim return (AE_AML_OPERAND_TYPE); 941199323Sjkim } 942199323Sjkim 943199323Sjkim /* 944199323Sjkim * The list must be sorted in the specified order. If we detect a 945202771Sjkim * discrepancy, sort the entire list. 946199323Sjkim */ 947199323Sjkim if (((SortDirection == ACPI_SORT_ASCENDING) && 948199323Sjkim (ObjDesc->Integer.Value < PreviousValue)) || 949199323Sjkim ((SortDirection == ACPI_SORT_DESCENDING) && 950199323Sjkim (ObjDesc->Integer.Value > PreviousValue))) 951199323Sjkim { 952250838Sjkim AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex], 953202771Sjkim OuterElementCount, SortIndex, SortDirection); 954199323Sjkim 955249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 956199323Sjkim 957200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 958200553Sjkim "%s: Repaired unsorted list - now sorted by %s\n", 959249663Sjkim Info->FullPathname, SortKeyName)); 960199323Sjkim return (AE_OK); 961199323Sjkim } 962199323Sjkim 963199323Sjkim PreviousValue = (UINT32) ObjDesc->Integer.Value; 964199323Sjkim OuterElements++; 965199323Sjkim } 966199323Sjkim 967199323Sjkim return (AE_OK); 968199323Sjkim} 969199323Sjkim 970199323Sjkim 971199323Sjkim/****************************************************************************** 972199323Sjkim * 973199323Sjkim * FUNCTION: AcpiNsSortList 974199323Sjkim * 975199323Sjkim * PARAMETERS: Elements - Package object element list 976199323Sjkim * Count - Element count for above 977199323Sjkim * Index - Sort by which package element 978199323Sjkim * SortDirection - Ascending or Descending sort 979199323Sjkim * 980202771Sjkim * RETURN: None 981199323Sjkim * 982199323Sjkim * DESCRIPTION: Sort the objects that are in a package element list. 983199323Sjkim * 984202771Sjkim * NOTE: Assumes that all NULL elements have been removed from the package, 985202771Sjkim * and that all elements have been verified to be of type Integer. 986199323Sjkim * 987199323Sjkim *****************************************************************************/ 988199323Sjkim 989202771Sjkimstatic void 990199323SjkimAcpiNsSortList ( 991199323Sjkim ACPI_OPERAND_OBJECT **Elements, 992199323Sjkim UINT32 Count, 993199323Sjkim UINT32 Index, 994199323Sjkim UINT8 SortDirection) 995199323Sjkim{ 996199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc1; 997199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc2; 998199323Sjkim ACPI_OPERAND_OBJECT *TempObj; 999199323Sjkim UINT32 i; 1000199323Sjkim UINT32 j; 1001199323Sjkim 1002199323Sjkim 1003199323Sjkim /* Simple bubble sort */ 1004199323Sjkim 1005199323Sjkim for (i = 1; i < Count; i++) 1006199323Sjkim { 1007199323Sjkim for (j = (Count - 1); j >= i; j--) 1008199323Sjkim { 1009199323Sjkim ObjDesc1 = Elements[j-1]->Package.Elements[Index]; 1010199323Sjkim ObjDesc2 = Elements[j]->Package.Elements[Index]; 1011199323Sjkim 1012199323Sjkim if (((SortDirection == ACPI_SORT_ASCENDING) && 1013199323Sjkim (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) || 1014199323Sjkim 1015199323Sjkim ((SortDirection == ACPI_SORT_DESCENDING) && 1016199323Sjkim (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value))) 1017199323Sjkim { 1018199323Sjkim TempObj = Elements[j-1]; 1019199323Sjkim Elements[j-1] = Elements[j]; 1020199323Sjkim Elements[j] = TempObj; 1021199323Sjkim } 1022199323Sjkim } 1023199323Sjkim } 1024199323Sjkim} 1025250838Sjkim 1026250838Sjkim 1027250838Sjkim/****************************************************************************** 1028250838Sjkim * 1029250838Sjkim * FUNCTION: AcpiNsRemoveElement 1030250838Sjkim * 1031250838Sjkim * PARAMETERS: ObjDesc - Package object element list 1032250838Sjkim * Index - Index of element to remove 1033250838Sjkim * 1034250838Sjkim * RETURN: None 1035250838Sjkim * 1036250838Sjkim * DESCRIPTION: Remove the requested element of a package and delete it. 1037250838Sjkim * 1038250838Sjkim *****************************************************************************/ 1039250838Sjkim 1040250838Sjkimstatic void 1041250838SjkimAcpiNsRemoveElement ( 1042250838Sjkim ACPI_OPERAND_OBJECT *ObjDesc, 1043250838Sjkim UINT32 Index) 1044250838Sjkim{ 1045250838Sjkim ACPI_OPERAND_OBJECT **Source; 1046250838Sjkim ACPI_OPERAND_OBJECT **Dest; 1047250838Sjkim UINT32 Count; 1048250838Sjkim UINT32 NewCount; 1049250838Sjkim UINT32 i; 1050250838Sjkim 1051250838Sjkim 1052250838Sjkim ACPI_FUNCTION_NAME (NsRemoveElement); 1053250838Sjkim 1054250838Sjkim 1055250838Sjkim Count = ObjDesc->Package.Count; 1056250838Sjkim NewCount = Count - 1; 1057250838Sjkim 1058250838Sjkim Source = ObjDesc->Package.Elements; 1059250838Sjkim Dest = Source; 1060250838Sjkim 1061250838Sjkim /* Examine all elements of the package object, remove matched index */ 1062250838Sjkim 1063250838Sjkim for (i = 0; i < Count; i++) 1064250838Sjkim { 1065250838Sjkim if (i == Index) 1066250838Sjkim { 1067250838Sjkim AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */ 1068250838Sjkim AcpiUtRemoveReference (*Source); 1069250838Sjkim } 1070250838Sjkim else 1071250838Sjkim { 1072250838Sjkim *Dest = *Source; 1073250838Sjkim Dest++; 1074250838Sjkim } 1075306536Sjkim 1076250838Sjkim Source++; 1077250838Sjkim } 1078250838Sjkim 1079250838Sjkim /* NULL terminate list and update the package count */ 1080250838Sjkim 1081250838Sjkim *Dest = NULL; 1082250838Sjkim ObjDesc->Package.Count = NewCount; 1083250838Sjkim} 1084