1199323Sjkim/****************************************************************************** 2199323Sjkim * 3199323Sjkim * Module Name: nsrepair2 - Repair for objects returned by specific 4199323Sjkim * predefined methods 5199323Sjkim * 6199323Sjkim *****************************************************************************/ 7199323Sjkim 8217365Sjkim/* 9245582Sjkim * Copyright (C) 2000 - 2013, 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 45199323Sjkim#define __NSREPAIR2_C__ 46199323Sjkim 47199337Sjkim#include <contrib/dev/acpica/include/acpi.h> 48199337Sjkim#include <contrib/dev/acpica/include/accommon.h> 49199337Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50199323Sjkim 51199323Sjkim#define _COMPONENT ACPI_NAMESPACE 52199323Sjkim ACPI_MODULE_NAME ("nsrepair2") 53199323Sjkim 54199323Sjkim 55199323Sjkim/* 56199323Sjkim * Information structure and handler for ACPI predefined names that can 57199323Sjkim * be repaired on a per-name basis. 58199323Sjkim */ 59199323Sjkimtypedef 60199323SjkimACPI_STATUS (*ACPI_REPAIR_FUNCTION) ( 61249663Sjkim ACPI_EVALUATE_INFO *Info, 62199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 63199323Sjkim 64199323Sjkimtypedef struct acpi_repair_info 65199323Sjkim{ 66199323Sjkim char Name[ACPI_NAME_SIZE]; 67199323Sjkim ACPI_REPAIR_FUNCTION RepairFunction; 68199323Sjkim 69199323Sjkim} ACPI_REPAIR_INFO; 70199323Sjkim 71199323Sjkim 72199323Sjkim/* Local prototypes */ 73199323Sjkim 74199323Sjkimstatic const ACPI_REPAIR_INFO * 75246849SjkimAcpiNsMatchComplexRepair ( 76199323Sjkim ACPI_NAMESPACE_NODE *Node); 77199323Sjkim 78199323Sjkimstatic ACPI_STATUS 79199323SjkimAcpiNsRepair_ALR ( 80249663Sjkim ACPI_EVALUATE_INFO *Info, 81199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 82199323Sjkim 83199323Sjkimstatic ACPI_STATUS 84212761SjkimAcpiNsRepair_CID ( 85249663Sjkim ACPI_EVALUATE_INFO *Info, 86212761Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 87212761Sjkim 88212761Sjkimstatic ACPI_STATUS 89250838SjkimAcpiNsRepair_CST ( 90250838Sjkim ACPI_EVALUATE_INFO *Info, 91250838Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 92250838Sjkim 93250838Sjkimstatic ACPI_STATUS 94200553SjkimAcpiNsRepair_FDE ( 95249663Sjkim ACPI_EVALUATE_INFO *Info, 96200553Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 97200553Sjkim 98200553Sjkimstatic ACPI_STATUS 99212761SjkimAcpiNsRepair_HID ( 100249663Sjkim ACPI_EVALUATE_INFO *Info, 101212761Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 102212761Sjkim 103212761Sjkimstatic ACPI_STATUS 104250838SjkimAcpiNsRepair_PRT ( 105250838Sjkim ACPI_EVALUATE_INFO *Info, 106250838Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 107250838Sjkim 108250838Sjkimstatic ACPI_STATUS 109199323SjkimAcpiNsRepair_PSS ( 110249663Sjkim ACPI_EVALUATE_INFO *Info, 111199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 112199323Sjkim 113199323Sjkimstatic ACPI_STATUS 114199323SjkimAcpiNsRepair_TSS ( 115249663Sjkim ACPI_EVALUATE_INFO *Info, 116199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 117199323Sjkim 118199323Sjkimstatic ACPI_STATUS 119199323SjkimAcpiNsCheckSortedList ( 120249663Sjkim ACPI_EVALUATE_INFO *Info, 121199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject, 122250838Sjkim UINT32 StartIndex, 123199323Sjkim UINT32 ExpectedCount, 124199323Sjkim UINT32 SortIndex, 125199323Sjkim UINT8 SortDirection, 126199323Sjkim char *SortKeyName); 127199323Sjkim 128250838Sjkim/* Values for SortDirection above */ 129250838Sjkim 130250838Sjkim#define ACPI_SORT_ASCENDING 0 131250838Sjkim#define ACPI_SORT_DESCENDING 1 132250838Sjkim 133202771Sjkimstatic void 134250838SjkimAcpiNsRemoveElement ( 135250838Sjkim ACPI_OPERAND_OBJECT *ObjDesc, 136250838Sjkim UINT32 Index); 137250838Sjkim 138250838Sjkimstatic void 139199323SjkimAcpiNsSortList ( 140199323Sjkim ACPI_OPERAND_OBJECT **Elements, 141199323Sjkim UINT32 Count, 142199323Sjkim UINT32 Index, 143199323Sjkim UINT8 SortDirection); 144199323Sjkim 145199323Sjkim 146199323Sjkim/* 147199323Sjkim * This table contains the names of the predefined methods for which we can 148199323Sjkim * perform more complex repairs. 149199323Sjkim * 150200553Sjkim * As necessary: 151200553Sjkim * 152200553Sjkim * _ALR: Sort the list ascending by AmbientIlluminance 153212761Sjkim * _CID: Strings: uppercase all, remove any leading asterisk 154250838Sjkim * _CST: Sort the list ascending by C state type 155200553Sjkim * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs 156200553Sjkim * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs 157212761Sjkim * _HID: Strings: uppercase all, remove any leading asterisk 158250838Sjkim * _PRT: Fix reversed SourceName and SourceIndex 159200553Sjkim * _PSS: Sort the list descending by Power 160200553Sjkim * _TSS: Sort the list descending by Power 161209746Sjkim * 162209746Sjkim * Names that must be packages, but cannot be sorted: 163209746Sjkim * 164209746Sjkim * _BCL: Values are tied to the Package index where they appear, and cannot 165209746Sjkim * be moved or sorted. These index values are used for _BQC and _BCM. 166209746Sjkim * However, we can fix the case where a buffer is returned, by converting 167209746Sjkim * it to a Package of integers. 168199323Sjkim */ 169199323Sjkimstatic const ACPI_REPAIR_INFO AcpiNsRepairableNames[] = 170199323Sjkim{ 171199323Sjkim {"_ALR", AcpiNsRepair_ALR}, 172212761Sjkim {"_CID", AcpiNsRepair_CID}, 173250838Sjkim {"_CST", AcpiNsRepair_CST}, 174200553Sjkim {"_FDE", AcpiNsRepair_FDE}, 175200553Sjkim {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */ 176212761Sjkim {"_HID", AcpiNsRepair_HID}, 177250838Sjkim {"_PRT", AcpiNsRepair_PRT}, 178199323Sjkim {"_PSS", AcpiNsRepair_PSS}, 179199323Sjkim {"_TSS", AcpiNsRepair_TSS}, 180200553Sjkim {{0,0,0,0}, NULL} /* Table terminator */ 181199323Sjkim}; 182199323Sjkim 183199323Sjkim 184200553Sjkim#define ACPI_FDE_FIELD_COUNT 5 185200553Sjkim#define ACPI_FDE_BYTE_BUFFER_SIZE 5 186200553Sjkim#define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * sizeof (UINT32)) 187200553Sjkim 188200553Sjkim 189199323Sjkim/****************************************************************************** 190199323Sjkim * 191199323Sjkim * FUNCTION: AcpiNsComplexRepairs 192199323Sjkim * 193249663Sjkim * PARAMETERS: Info - Method execution information block 194199323Sjkim * Node - Namespace node for the method/object 195199323Sjkim * ValidateStatus - Original status of earlier validation 196199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 197199323Sjkim * evaluation of a method or object 198199323Sjkim * 199200553Sjkim * RETURN: Status. AE_OK if repair was successful. If name is not 200199323Sjkim * matched, ValidateStatus is returned. 201199323Sjkim * 202199323Sjkim * DESCRIPTION: Attempt to repair/convert a return object of a type that was 203199323Sjkim * not expected. 204199323Sjkim * 205199323Sjkim *****************************************************************************/ 206199323Sjkim 207199323SjkimACPI_STATUS 208199323SjkimAcpiNsComplexRepairs ( 209249663Sjkim ACPI_EVALUATE_INFO *Info, 210199323Sjkim ACPI_NAMESPACE_NODE *Node, 211199323Sjkim ACPI_STATUS ValidateStatus, 212199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 213199323Sjkim{ 214199323Sjkim const ACPI_REPAIR_INFO *Predefined; 215199323Sjkim ACPI_STATUS Status; 216199323Sjkim 217199323Sjkim 218199323Sjkim /* Check if this name is in the list of repairable names */ 219199323Sjkim 220246849Sjkim Predefined = AcpiNsMatchComplexRepair (Node); 221199323Sjkim if (!Predefined) 222199323Sjkim { 223199323Sjkim return (ValidateStatus); 224199323Sjkim } 225199323Sjkim 226249663Sjkim Status = Predefined->RepairFunction (Info, ReturnObjectPtr); 227199323Sjkim return (Status); 228199323Sjkim} 229199323Sjkim 230199323Sjkim 231199323Sjkim/****************************************************************************** 232199323Sjkim * 233246849Sjkim * FUNCTION: AcpiNsMatchComplexRepair 234199323Sjkim * 235199323Sjkim * PARAMETERS: Node - Namespace node for the method/object 236199323Sjkim * 237199323Sjkim * RETURN: Pointer to entry in repair table. NULL indicates not found. 238199323Sjkim * 239199323Sjkim * DESCRIPTION: Check an object name against the repairable object list. 240199323Sjkim * 241199323Sjkim *****************************************************************************/ 242199323Sjkim 243199323Sjkimstatic const ACPI_REPAIR_INFO * 244246849SjkimAcpiNsMatchComplexRepair ( 245199323Sjkim ACPI_NAMESPACE_NODE *Node) 246199323Sjkim{ 247199323Sjkim const ACPI_REPAIR_INFO *ThisName; 248199323Sjkim 249199323Sjkim 250199323Sjkim /* Search info table for a repairable predefined method/object name */ 251199323Sjkim 252199323Sjkim ThisName = AcpiNsRepairableNames; 253199323Sjkim while (ThisName->RepairFunction) 254199323Sjkim { 255199323Sjkim if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) 256199323Sjkim { 257199323Sjkim return (ThisName); 258199323Sjkim } 259199323Sjkim ThisName++; 260199323Sjkim } 261199323Sjkim 262199323Sjkim return (NULL); /* Not found */ 263199323Sjkim} 264199323Sjkim 265199323Sjkim 266199323Sjkim/****************************************************************************** 267199323Sjkim * 268199323Sjkim * FUNCTION: AcpiNsRepair_ALR 269199323Sjkim * 270249663Sjkim * PARAMETERS: Info - Method execution information block 271199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 272199323Sjkim * evaluation of a method or object 273199323Sjkim * 274199323Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 275199323Sjkim * 276199323Sjkim * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list 277199323Sjkim * ascending by the ambient illuminance values. 278199323Sjkim * 279199323Sjkim *****************************************************************************/ 280199323Sjkim 281199323Sjkimstatic ACPI_STATUS 282199323SjkimAcpiNsRepair_ALR ( 283249663Sjkim ACPI_EVALUATE_INFO *Info, 284199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 285199323Sjkim{ 286199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 287199323Sjkim ACPI_STATUS Status; 288199323Sjkim 289199323Sjkim 290250838Sjkim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1, 291199323Sjkim ACPI_SORT_ASCENDING, "AmbientIlluminance"); 292199323Sjkim 293199323Sjkim return (Status); 294199323Sjkim} 295199323Sjkim 296199323Sjkim 297199323Sjkim/****************************************************************************** 298199323Sjkim * 299200553Sjkim * FUNCTION: AcpiNsRepair_FDE 300200553Sjkim * 301249663Sjkim * PARAMETERS: Info - Method execution information block 302200553Sjkim * ReturnObjectPtr - Pointer to the object returned from the 303200553Sjkim * evaluation of a method or object 304200553Sjkim * 305200553Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 306200553Sjkim * 307200553Sjkim * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return 308200553Sjkim * value is a Buffer of 5 DWORDs. This function repairs a common 309200553Sjkim * problem where the return value is a Buffer of BYTEs, not 310200553Sjkim * DWORDs. 311200553Sjkim * 312200553Sjkim *****************************************************************************/ 313200553Sjkim 314200553Sjkimstatic ACPI_STATUS 315200553SjkimAcpiNsRepair_FDE ( 316249663Sjkim ACPI_EVALUATE_INFO *Info, 317200553Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 318200553Sjkim{ 319200553Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 320200553Sjkim ACPI_OPERAND_OBJECT *BufferObject; 321200553Sjkim UINT8 *ByteBuffer; 322200553Sjkim UINT32 *DwordBuffer; 323200553Sjkim UINT32 i; 324200553Sjkim 325200553Sjkim 326200553Sjkim ACPI_FUNCTION_NAME (NsRepair_FDE); 327200553Sjkim 328200553Sjkim 329200553Sjkim switch (ReturnObject->Common.Type) 330200553Sjkim { 331200553Sjkim case ACPI_TYPE_BUFFER: 332200553Sjkim 333200553Sjkim /* This is the expected type. Length should be (at least) 5 DWORDs */ 334200553Sjkim 335200553Sjkim if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE) 336200553Sjkim { 337200553Sjkim return (AE_OK); 338200553Sjkim } 339200553Sjkim 340200553Sjkim /* We can only repair if we have exactly 5 BYTEs */ 341200553Sjkim 342200553Sjkim if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE) 343200553Sjkim { 344249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, 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 353200553Sjkim BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE); 354200553Sjkim if (!BufferObject) 355200553Sjkim { 356200553Sjkim return (AE_NO_MEMORY); 357200553Sjkim } 358200553Sjkim 359200553Sjkim /* Expand each byte to a DWORD */ 360200553Sjkim 361200553Sjkim ByteBuffer = ReturnObject->Buffer.Pointer; 362200553Sjkim DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer); 363200553Sjkim 364200553Sjkim for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++) 365200553Sjkim { 366200553Sjkim *DwordBuffer = (UINT32) *ByteBuffer; 367200553Sjkim DwordBuffer++; 368200553Sjkim ByteBuffer++; 369200553Sjkim } 370200553Sjkim 371200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 372200553Sjkim "%s Expanded Byte Buffer to expected DWord Buffer\n", 373249663Sjkim Info->FullPathname)); 374200553Sjkim break; 375200553Sjkim 376200553Sjkim default: 377250838Sjkim 378200553Sjkim return (AE_AML_OPERAND_TYPE); 379200553Sjkim } 380200553Sjkim 381200553Sjkim /* Delete the original return object, return the new buffer object */ 382200553Sjkim 383200553Sjkim AcpiUtRemoveReference (ReturnObject); 384200553Sjkim *ReturnObjectPtr = BufferObject; 385200553Sjkim 386249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 387200553Sjkim return (AE_OK); 388200553Sjkim} 389200553Sjkim 390200553Sjkim 391200553Sjkim/****************************************************************************** 392200553Sjkim * 393212761Sjkim * FUNCTION: AcpiNsRepair_CID 394212761Sjkim * 395249663Sjkim * PARAMETERS: Info - Method execution information block 396212761Sjkim * ReturnObjectPtr - Pointer to the object returned from the 397212761Sjkim * evaluation of a method or object 398212761Sjkim * 399212761Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 400212761Sjkim * 401212761Sjkim * DESCRIPTION: Repair for the _CID object. If a string, ensure that all 402212761Sjkim * letters are uppercase and that there is no leading asterisk. 403212761Sjkim * If a Package, ensure same for all string elements. 404212761Sjkim * 405212761Sjkim *****************************************************************************/ 406212761Sjkim 407212761Sjkimstatic ACPI_STATUS 408212761SjkimAcpiNsRepair_CID ( 409249663Sjkim ACPI_EVALUATE_INFO *Info, 410212761Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 411212761Sjkim{ 412212761Sjkim ACPI_STATUS Status; 413212761Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 414212761Sjkim ACPI_OPERAND_OBJECT **ElementPtr; 415212761Sjkim ACPI_OPERAND_OBJECT *OriginalElement; 416212761Sjkim UINT16 OriginalRefCount; 417212761Sjkim UINT32 i; 418212761Sjkim 419212761Sjkim 420212761Sjkim /* Check for _CID as a simple string */ 421212761Sjkim 422212761Sjkim if (ReturnObject->Common.Type == ACPI_TYPE_STRING) 423212761Sjkim { 424249663Sjkim Status = AcpiNsRepair_HID (Info, ReturnObjectPtr); 425212761Sjkim return (Status); 426212761Sjkim } 427212761Sjkim 428212761Sjkim /* Exit if not a Package */ 429212761Sjkim 430212761Sjkim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 431212761Sjkim { 432212761Sjkim return (AE_OK); 433212761Sjkim } 434212761Sjkim 435212761Sjkim /* Examine each element of the _CID package */ 436212761Sjkim 437212761Sjkim ElementPtr = ReturnObject->Package.Elements; 438212761Sjkim for (i = 0; i < ReturnObject->Package.Count; i++) 439212761Sjkim { 440212761Sjkim OriginalElement = *ElementPtr; 441212761Sjkim OriginalRefCount = OriginalElement->Common.ReferenceCount; 442212761Sjkim 443249663Sjkim Status = AcpiNsRepair_HID (Info, ElementPtr); 444212761Sjkim if (ACPI_FAILURE (Status)) 445212761Sjkim { 446212761Sjkim return (Status); 447212761Sjkim } 448212761Sjkim 449212761Sjkim /* Take care with reference counts */ 450212761Sjkim 451212761Sjkim if (OriginalElement != *ElementPtr) 452212761Sjkim { 453212761Sjkim /* Element was replaced */ 454212761Sjkim 455212761Sjkim (*ElementPtr)->Common.ReferenceCount = 456212761Sjkim OriginalRefCount; 457212761Sjkim 458212761Sjkim AcpiUtRemoveReference (OriginalElement); 459212761Sjkim } 460212761Sjkim 461212761Sjkim ElementPtr++; 462212761Sjkim } 463212761Sjkim 464212761Sjkim return (AE_OK); 465212761Sjkim} 466212761Sjkim 467212761Sjkim 468212761Sjkim/****************************************************************************** 469212761Sjkim * 470250838Sjkim * FUNCTION: AcpiNsRepair_CST 471250838Sjkim * 472250838Sjkim * PARAMETERS: Info - Method execution information block 473250838Sjkim * ReturnObjectPtr - Pointer to the object returned from the 474250838Sjkim * evaluation of a method or object 475250838Sjkim * 476250838Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 477250838Sjkim * 478250838Sjkim * DESCRIPTION: Repair for the _CST object: 479250838Sjkim * 1. Sort the list ascending by C state type 480250838Sjkim * 2. Ensure type cannot be zero 481250838Sjkim * 3. A sub-package count of zero means _CST is meaningless 482250838Sjkim * 4. Count must match the number of C state sub-packages 483250838Sjkim * 484250838Sjkim *****************************************************************************/ 485250838Sjkim 486250838Sjkimstatic ACPI_STATUS 487250838SjkimAcpiNsRepair_CST ( 488250838Sjkim ACPI_EVALUATE_INFO *Info, 489250838Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 490250838Sjkim{ 491250838Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 492250838Sjkim ACPI_OPERAND_OBJECT **OuterElements; 493250838Sjkim UINT32 OuterElementCount; 494250838Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 495250838Sjkim ACPI_STATUS Status; 496250838Sjkim BOOLEAN Removing; 497250838Sjkim UINT32 i; 498250838Sjkim 499250838Sjkim 500250838Sjkim ACPI_FUNCTION_NAME (NsRepair_CST); 501250838Sjkim 502250838Sjkim 503250838Sjkim /* 504252279Sjkim * Check if the C-state type values are proportional. 505250838Sjkim */ 506250838Sjkim OuterElementCount = ReturnObject->Package.Count - 1; 507250838Sjkim i = 0; 508250838Sjkim while (i < OuterElementCount) 509250838Sjkim { 510250838Sjkim OuterElements = &ReturnObject->Package.Elements[i + 1]; 511250838Sjkim Removing = FALSE; 512250838Sjkim 513250838Sjkim if ((*OuterElements)->Package.Count == 0) 514250838Sjkim { 515250838Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 516250838Sjkim "SubPackage[%u] - removing entry due to zero count", i)); 517250838Sjkim Removing = TRUE; 518252279Sjkim goto RemoveElement; 519250838Sjkim } 520250838Sjkim 521250838Sjkim ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */ 522250838Sjkim if ((UINT32) ObjDesc->Integer.Value == 0) 523250838Sjkim { 524250838Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 525250838Sjkim "SubPackage[%u] - removing entry due to invalid Type(0)", i)); 526250838Sjkim Removing = TRUE; 527250838Sjkim } 528250838Sjkim 529252279SjkimRemoveElement: 530250838Sjkim if (Removing) 531250838Sjkim { 532250838Sjkim AcpiNsRemoveElement (ReturnObject, i + 1); 533250838Sjkim OuterElementCount--; 534250838Sjkim } 535250838Sjkim else 536250838Sjkim { 537250838Sjkim i++; 538250838Sjkim } 539250838Sjkim } 540250838Sjkim 541250838Sjkim /* Update top-level package count, Type "Integer" checked elsewhere */ 542250838Sjkim 543250838Sjkim ObjDesc = ReturnObject->Package.Elements[0]; 544250838Sjkim ObjDesc->Integer.Value = OuterElementCount; 545252279Sjkim 546252279Sjkim /* 547252279Sjkim * Entries (subpackages) in the _CST Package must be sorted by the 548252279Sjkim * C-state type, in ascending order. 549252279Sjkim */ 550252279Sjkim Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1, 551252279Sjkim ACPI_SORT_ASCENDING, "C-State Type"); 552252279Sjkim if (ACPI_FAILURE (Status)) 553252279Sjkim { 554252279Sjkim return (Status); 555252279Sjkim } 556252279Sjkim 557250838Sjkim return (AE_OK); 558250838Sjkim} 559250838Sjkim 560250838Sjkim 561250838Sjkim/****************************************************************************** 562250838Sjkim * 563212761Sjkim * FUNCTION: AcpiNsRepair_HID 564212761Sjkim * 565249663Sjkim * PARAMETERS: Info - Method execution information block 566212761Sjkim * ReturnObjectPtr - Pointer to the object returned from the 567212761Sjkim * evaluation of a method or object 568212761Sjkim * 569212761Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 570212761Sjkim * 571212761Sjkim * DESCRIPTION: Repair for the _HID object. If a string, ensure that all 572212761Sjkim * letters are uppercase and that there is no leading asterisk. 573212761Sjkim * 574212761Sjkim *****************************************************************************/ 575212761Sjkim 576212761Sjkimstatic ACPI_STATUS 577212761SjkimAcpiNsRepair_HID ( 578249663Sjkim ACPI_EVALUATE_INFO *Info, 579212761Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 580212761Sjkim{ 581212761Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 582212761Sjkim ACPI_OPERAND_OBJECT *NewString; 583212761Sjkim char *Source; 584212761Sjkim char *Dest; 585212761Sjkim 586212761Sjkim 587212761Sjkim ACPI_FUNCTION_NAME (NsRepair_HID); 588212761Sjkim 589212761Sjkim 590212761Sjkim /* We only care about string _HID objects (not integers) */ 591212761Sjkim 592212761Sjkim if (ReturnObject->Common.Type != ACPI_TYPE_STRING) 593212761Sjkim { 594212761Sjkim return (AE_OK); 595212761Sjkim } 596212761Sjkim 597212761Sjkim if (ReturnObject->String.Length == 0) 598212761Sjkim { 599249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 600212761Sjkim "Invalid zero-length _HID or _CID string")); 601212761Sjkim 602212761Sjkim /* Return AE_OK anyway, let driver handle it */ 603212761Sjkim 604249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 605212761Sjkim return (AE_OK); 606212761Sjkim } 607212761Sjkim 608212761Sjkim /* It is simplest to always create a new string object */ 609212761Sjkim 610212761Sjkim NewString = AcpiUtCreateStringObject (ReturnObject->String.Length); 611212761Sjkim if (!NewString) 612212761Sjkim { 613212761Sjkim return (AE_NO_MEMORY); 614212761Sjkim } 615212761Sjkim 616212761Sjkim /* 617212761Sjkim * Remove a leading asterisk if present. For some unknown reason, there 618212761Sjkim * are many machines in the field that contains IDs like this. 619212761Sjkim * 620212761Sjkim * Examples: "*PNP0C03", "*ACPI0003" 621212761Sjkim */ 622212761Sjkim Source = ReturnObject->String.Pointer; 623212761Sjkim if (*Source == '*') 624212761Sjkim { 625212761Sjkim Source++; 626212761Sjkim NewString->String.Length--; 627212761Sjkim 628212761Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 629249663Sjkim "%s: Removed invalid leading asterisk\n", Info->FullPathname)); 630212761Sjkim } 631212761Sjkim 632212761Sjkim /* 633228110Sjkim * Copy and uppercase the string. From the ACPI 5.0 specification: 634212761Sjkim * 635212761Sjkim * A valid PNP ID must be of the form "AAA####" where A is an uppercase 636212761Sjkim * letter and # is a hex digit. A valid ACPI ID must be of the form 637228110Sjkim * "NNNN####" where N is an uppercase letter or decimal digit, and 638228110Sjkim * # is a hex digit. 639212761Sjkim */ 640212761Sjkim for (Dest = NewString->String.Pointer; *Source; Dest++, Source++) 641212761Sjkim { 642212761Sjkim *Dest = (char) ACPI_TOUPPER (*Source); 643212761Sjkim } 644212761Sjkim 645212761Sjkim AcpiUtRemoveReference (ReturnObject); 646212761Sjkim *ReturnObjectPtr = NewString; 647212761Sjkim return (AE_OK); 648212761Sjkim} 649212761Sjkim 650212761Sjkim 651212761Sjkim/****************************************************************************** 652212761Sjkim * 653250838Sjkim * FUNCTION: AcpiNsRepair_PRT 654199323Sjkim * 655249663Sjkim * PARAMETERS: Info - Method execution information block 656199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 657199323Sjkim * evaluation of a method or object 658199323Sjkim * 659199323Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 660199323Sjkim * 661250838Sjkim * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed 662250838Sjkim * SourceName and SourceIndex field, a common BIOS bug. 663199323Sjkim * 664199323Sjkim *****************************************************************************/ 665199323Sjkim 666199323Sjkimstatic ACPI_STATUS 667250838SjkimAcpiNsRepair_PRT ( 668249663Sjkim ACPI_EVALUATE_INFO *Info, 669199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 670199323Sjkim{ 671250838Sjkim ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr; 672250838Sjkim ACPI_OPERAND_OBJECT **TopObjectList; 673250838Sjkim ACPI_OPERAND_OBJECT **SubObjectList; 674250838Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 675250838Sjkim UINT32 ElementCount; 676250838Sjkim UINT32 Index; 677199323Sjkim 678199323Sjkim 679250838Sjkim /* Each element in the _PRT package is a subpackage */ 680250838Sjkim 681250838Sjkim TopObjectList = PackageObject->Package.Elements; 682250838Sjkim ElementCount = PackageObject->Package.Count; 683250838Sjkim 684250838Sjkim for (Index = 0; Index < ElementCount; Index++) 685228110Sjkim { 686250838Sjkim SubObjectList = (*TopObjectList)->Package.Elements; 687250838Sjkim 688250838Sjkim /* 689250838Sjkim * If the BIOS has erroneously reversed the _PRT SourceName (index 2) 690250838Sjkim * and the SourceIndex (index 3), fix it. _PRT is important enough to 691250838Sjkim * workaround this BIOS error. This also provides compatibility with 692250838Sjkim * other ACPI implementations. 693250838Sjkim */ 694250838Sjkim ObjDesc = SubObjectList[3]; 695250838Sjkim if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)) 696250838Sjkim { 697250838Sjkim SubObjectList[3] = SubObjectList[2]; 698250838Sjkim SubObjectList[2] = ObjDesc; 699250838Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 700250838Sjkim 701250838Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 702250838Sjkim "PRT[%X]: Fixed reversed SourceName and SourceIndex", 703250838Sjkim Index)); 704250838Sjkim } 705250838Sjkim 706250838Sjkim /* Point to the next ACPI_OPERAND_OBJECT in the top level package */ 707250838Sjkim 708250838Sjkim TopObjectList++; 709228110Sjkim } 710228110Sjkim 711250838Sjkim return (AE_OK); 712199323Sjkim} 713199323Sjkim 714199323Sjkim 715199323Sjkim/****************************************************************************** 716199323Sjkim * 717199323Sjkim * FUNCTION: AcpiNsRepair_PSS 718199323Sjkim * 719249663Sjkim * PARAMETERS: Info - Method execution information block 720199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 721199323Sjkim * evaluation of a method or object 722199323Sjkim * 723199323Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 724199323Sjkim * 725199323Sjkim * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list 726199323Sjkim * by the CPU frequencies. Check that the power dissipation values 727199323Sjkim * are all proportional to CPU frequency (i.e., sorting by 728199323Sjkim * frequency should be the same as sorting by power.) 729199323Sjkim * 730199323Sjkim *****************************************************************************/ 731199323Sjkim 732199323Sjkimstatic ACPI_STATUS 733199323SjkimAcpiNsRepair_PSS ( 734249663Sjkim ACPI_EVALUATE_INFO *Info, 735199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 736199323Sjkim{ 737199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 738199323Sjkim ACPI_OPERAND_OBJECT **OuterElements; 739199323Sjkim UINT32 OuterElementCount; 740199323Sjkim ACPI_OPERAND_OBJECT **Elements; 741199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 742199323Sjkim UINT32 PreviousValue; 743199323Sjkim ACPI_STATUS Status; 744199323Sjkim UINT32 i; 745199323Sjkim 746199323Sjkim 747199323Sjkim /* 748199323Sjkim * Entries (sub-packages) in the _PSS Package must be sorted by power 749199323Sjkim * dissipation, in descending order. If it appears that the list is 750199323Sjkim * incorrectly sorted, sort it. We sort by CpuFrequency, since this 751199323Sjkim * should be proportional to the power. 752199323Sjkim */ 753250838Sjkim Status =AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0, 754199323Sjkim ACPI_SORT_DESCENDING, "CpuFrequency"); 755199323Sjkim if (ACPI_FAILURE (Status)) 756199323Sjkim { 757199323Sjkim return (Status); 758199323Sjkim } 759199323Sjkim 760199323Sjkim /* 761199323Sjkim * We now know the list is correctly sorted by CPU frequency. Check if 762199323Sjkim * the power dissipation values are proportional. 763199323Sjkim */ 764199323Sjkim PreviousValue = ACPI_UINT32_MAX; 765199323Sjkim OuterElements = ReturnObject->Package.Elements; 766199323Sjkim OuterElementCount = ReturnObject->Package.Count; 767199323Sjkim 768199323Sjkim for (i = 0; i < OuterElementCount; i++) 769199323Sjkim { 770199323Sjkim Elements = (*OuterElements)->Package.Elements; 771199323Sjkim ObjDesc = Elements[1]; /* Index1 = PowerDissipation */ 772199323Sjkim 773199323Sjkim if ((UINT32) ObjDesc->Integer.Value > PreviousValue) 774199323Sjkim { 775249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 776199323Sjkim "SubPackage[%u,%u] - suspicious power dissipation values", 777199323Sjkim i-1, i)); 778199323Sjkim } 779199323Sjkim 780199323Sjkim PreviousValue = (UINT32) ObjDesc->Integer.Value; 781199323Sjkim OuterElements++; 782199323Sjkim } 783199323Sjkim 784199323Sjkim return (AE_OK); 785199323Sjkim} 786199323Sjkim 787199323Sjkim 788199323Sjkim/****************************************************************************** 789199323Sjkim * 790250838Sjkim * FUNCTION: AcpiNsRepair_TSS 791250838Sjkim * 792250838Sjkim * PARAMETERS: Info - Method execution information block 793250838Sjkim * ReturnObjectPtr - Pointer to the object returned from the 794250838Sjkim * evaluation of a method or object 795250838Sjkim * 796250838Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 797250838Sjkim * 798250838Sjkim * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list 799250838Sjkim * descending by the power dissipation values. 800250838Sjkim * 801250838Sjkim *****************************************************************************/ 802250838Sjkim 803250838Sjkimstatic ACPI_STATUS 804250838SjkimAcpiNsRepair_TSS ( 805250838Sjkim ACPI_EVALUATE_INFO *Info, 806250838Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 807250838Sjkim{ 808250838Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 809250838Sjkim ACPI_STATUS Status; 810250838Sjkim ACPI_NAMESPACE_NODE *Node; 811250838Sjkim 812250838Sjkim 813250838Sjkim /* 814250838Sjkim * We can only sort the _TSS return package if there is no _PSS in the 815250838Sjkim * same scope. This is because if _PSS is present, the ACPI specification 816250838Sjkim * dictates that the _TSS Power Dissipation field is to be ignored, and 817250838Sjkim * therefore some BIOSs leave garbage values in the _TSS Power field(s). 818250838Sjkim * In this case, it is best to just return the _TSS package as-is. 819250838Sjkim * (May, 2011) 820250838Sjkim */ 821250838Sjkim Status = AcpiNsGetNode (Info->Node, "^_PSS", 822250838Sjkim ACPI_NS_NO_UPSEARCH, &Node); 823250838Sjkim if (ACPI_SUCCESS (Status)) 824250838Sjkim { 825250838Sjkim return (AE_OK); 826250838Sjkim } 827250838Sjkim 828250838Sjkim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1, 829250838Sjkim ACPI_SORT_DESCENDING, "PowerDissipation"); 830250838Sjkim 831250838Sjkim return (Status); 832250838Sjkim} 833250838Sjkim 834250838Sjkim 835250838Sjkim/****************************************************************************** 836250838Sjkim * 837199323Sjkim * FUNCTION: AcpiNsCheckSortedList 838199323Sjkim * 839249663Sjkim * PARAMETERS: Info - Method execution information block 840199323Sjkim * ReturnObject - Pointer to the top-level returned object 841250838Sjkim * StartIndex - Index of the first sub-package 842199323Sjkim * ExpectedCount - Minimum length of each sub-package 843199323Sjkim * SortIndex - Sub-package entry to sort on 844199323Sjkim * SortDirection - Ascending or descending 845199323Sjkim * SortKeyName - Name of the SortIndex field 846199323Sjkim * 847199323Sjkim * RETURN: Status. AE_OK if the list is valid and is sorted correctly or 848199323Sjkim * has been repaired by sorting the list. 849199323Sjkim * 850199323Sjkim * DESCRIPTION: Check if the package list is valid and sorted correctly by the 851199323Sjkim * SortIndex. If not, then sort the list. 852199323Sjkim * 853199323Sjkim *****************************************************************************/ 854199323Sjkim 855199323Sjkimstatic ACPI_STATUS 856199323SjkimAcpiNsCheckSortedList ( 857249663Sjkim ACPI_EVALUATE_INFO *Info, 858199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject, 859250838Sjkim UINT32 StartIndex, 860199323Sjkim UINT32 ExpectedCount, 861199323Sjkim UINT32 SortIndex, 862199323Sjkim UINT8 SortDirection, 863199323Sjkim char *SortKeyName) 864199323Sjkim{ 865199323Sjkim UINT32 OuterElementCount; 866199323Sjkim ACPI_OPERAND_OBJECT **OuterElements; 867199323Sjkim ACPI_OPERAND_OBJECT **Elements; 868199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 869199323Sjkim UINT32 i; 870199323Sjkim UINT32 PreviousValue; 871199323Sjkim 872199323Sjkim 873200553Sjkim ACPI_FUNCTION_NAME (NsCheckSortedList); 874200553Sjkim 875200553Sjkim 876199323Sjkim /* The top-level object must be a package */ 877199323Sjkim 878199323Sjkim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 879199323Sjkim { 880199323Sjkim return (AE_AML_OPERAND_TYPE); 881199323Sjkim } 882199323Sjkim 883199323Sjkim /* 884200553Sjkim * NOTE: assumes list of sub-packages contains no NULL elements. 885200553Sjkim * Any NULL elements should have been removed by earlier call 886200553Sjkim * to AcpiNsRemoveNullElements. 887199323Sjkim */ 888199323Sjkim OuterElementCount = ReturnObject->Package.Count; 889250838Sjkim if (!OuterElementCount || StartIndex >= OuterElementCount) 890199323Sjkim { 891199323Sjkim return (AE_AML_PACKAGE_LIMIT); 892199323Sjkim } 893199323Sjkim 894250838Sjkim OuterElements = &ReturnObject->Package.Elements[StartIndex]; 895250838Sjkim OuterElementCount -= StartIndex; 896250838Sjkim 897199323Sjkim PreviousValue = 0; 898199323Sjkim if (SortDirection == ACPI_SORT_DESCENDING) 899199323Sjkim { 900199323Sjkim PreviousValue = ACPI_UINT32_MAX; 901199323Sjkim } 902199323Sjkim 903199323Sjkim /* Examine each subpackage */ 904199323Sjkim 905199323Sjkim for (i = 0; i < OuterElementCount; i++) 906199323Sjkim { 907199323Sjkim /* Each element of the top-level package must also be a package */ 908199323Sjkim 909199323Sjkim if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE) 910199323Sjkim { 911199323Sjkim return (AE_AML_OPERAND_TYPE); 912199323Sjkim } 913199323Sjkim 914199323Sjkim /* Each sub-package must have the minimum length */ 915199323Sjkim 916199323Sjkim if ((*OuterElements)->Package.Count < ExpectedCount) 917199323Sjkim { 918199323Sjkim return (AE_AML_PACKAGE_LIMIT); 919199323Sjkim } 920199323Sjkim 921199323Sjkim Elements = (*OuterElements)->Package.Elements; 922199323Sjkim ObjDesc = Elements[SortIndex]; 923199323Sjkim 924199323Sjkim if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) 925199323Sjkim { 926199323Sjkim return (AE_AML_OPERAND_TYPE); 927199323Sjkim } 928199323Sjkim 929199323Sjkim /* 930199323Sjkim * The list must be sorted in the specified order. If we detect a 931202771Sjkim * discrepancy, sort the entire list. 932199323Sjkim */ 933199323Sjkim if (((SortDirection == ACPI_SORT_ASCENDING) && 934199323Sjkim (ObjDesc->Integer.Value < PreviousValue)) || 935199323Sjkim ((SortDirection == ACPI_SORT_DESCENDING) && 936199323Sjkim (ObjDesc->Integer.Value > PreviousValue))) 937199323Sjkim { 938250838Sjkim AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex], 939202771Sjkim OuterElementCount, SortIndex, SortDirection); 940199323Sjkim 941249663Sjkim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 942199323Sjkim 943200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 944200553Sjkim "%s: Repaired unsorted list - now sorted by %s\n", 945249663Sjkim Info->FullPathname, SortKeyName)); 946199323Sjkim return (AE_OK); 947199323Sjkim } 948199323Sjkim 949199323Sjkim PreviousValue = (UINT32) ObjDesc->Integer.Value; 950199323Sjkim OuterElements++; 951199323Sjkim } 952199323Sjkim 953199323Sjkim return (AE_OK); 954199323Sjkim} 955199323Sjkim 956199323Sjkim 957199323Sjkim/****************************************************************************** 958199323Sjkim * 959199323Sjkim * FUNCTION: AcpiNsSortList 960199323Sjkim * 961199323Sjkim * PARAMETERS: Elements - Package object element list 962199323Sjkim * Count - Element count for above 963199323Sjkim * Index - Sort by which package element 964199323Sjkim * SortDirection - Ascending or Descending sort 965199323Sjkim * 966202771Sjkim * RETURN: None 967199323Sjkim * 968199323Sjkim * DESCRIPTION: Sort the objects that are in a package element list. 969199323Sjkim * 970202771Sjkim * NOTE: Assumes that all NULL elements have been removed from the package, 971202771Sjkim * and that all elements have been verified to be of type Integer. 972199323Sjkim * 973199323Sjkim *****************************************************************************/ 974199323Sjkim 975202771Sjkimstatic void 976199323SjkimAcpiNsSortList ( 977199323Sjkim ACPI_OPERAND_OBJECT **Elements, 978199323Sjkim UINT32 Count, 979199323Sjkim UINT32 Index, 980199323Sjkim UINT8 SortDirection) 981199323Sjkim{ 982199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc1; 983199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc2; 984199323Sjkim ACPI_OPERAND_OBJECT *TempObj; 985199323Sjkim UINT32 i; 986199323Sjkim UINT32 j; 987199323Sjkim 988199323Sjkim 989199323Sjkim /* Simple bubble sort */ 990199323Sjkim 991199323Sjkim for (i = 1; i < Count; i++) 992199323Sjkim { 993199323Sjkim for (j = (Count - 1); j >= i; j--) 994199323Sjkim { 995199323Sjkim ObjDesc1 = Elements[j-1]->Package.Elements[Index]; 996199323Sjkim ObjDesc2 = Elements[j]->Package.Elements[Index]; 997199323Sjkim 998199323Sjkim if (((SortDirection == ACPI_SORT_ASCENDING) && 999199323Sjkim (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) || 1000199323Sjkim 1001199323Sjkim ((SortDirection == ACPI_SORT_DESCENDING) && 1002199323Sjkim (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value))) 1003199323Sjkim { 1004199323Sjkim TempObj = Elements[j-1]; 1005199323Sjkim Elements[j-1] = Elements[j]; 1006199323Sjkim Elements[j] = TempObj; 1007199323Sjkim } 1008199323Sjkim } 1009199323Sjkim } 1010199323Sjkim} 1011250838Sjkim 1012250838Sjkim 1013250838Sjkim/****************************************************************************** 1014250838Sjkim * 1015250838Sjkim * FUNCTION: AcpiNsRemoveElement 1016250838Sjkim * 1017250838Sjkim * PARAMETERS: ObjDesc - Package object element list 1018250838Sjkim * Index - Index of element to remove 1019250838Sjkim * 1020250838Sjkim * RETURN: None 1021250838Sjkim * 1022250838Sjkim * DESCRIPTION: Remove the requested element of a package and delete it. 1023250838Sjkim * 1024250838Sjkim *****************************************************************************/ 1025250838Sjkim 1026250838Sjkimstatic void 1027250838SjkimAcpiNsRemoveElement ( 1028250838Sjkim ACPI_OPERAND_OBJECT *ObjDesc, 1029250838Sjkim UINT32 Index) 1030250838Sjkim{ 1031250838Sjkim ACPI_OPERAND_OBJECT **Source; 1032250838Sjkim ACPI_OPERAND_OBJECT **Dest; 1033250838Sjkim UINT32 Count; 1034250838Sjkim UINT32 NewCount; 1035250838Sjkim UINT32 i; 1036250838Sjkim 1037250838Sjkim 1038250838Sjkim ACPI_FUNCTION_NAME (NsRemoveElement); 1039250838Sjkim 1040250838Sjkim 1041250838Sjkim Count = ObjDesc->Package.Count; 1042250838Sjkim NewCount = Count - 1; 1043250838Sjkim 1044250838Sjkim Source = ObjDesc->Package.Elements; 1045250838Sjkim Dest = Source; 1046250838Sjkim 1047250838Sjkim /* Examine all elements of the package object, remove matched index */ 1048250838Sjkim 1049250838Sjkim for (i = 0; i < Count; i++) 1050250838Sjkim { 1051250838Sjkim if (i == Index) 1052250838Sjkim { 1053250838Sjkim AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */ 1054250838Sjkim AcpiUtRemoveReference (*Source); 1055250838Sjkim } 1056250838Sjkim else 1057250838Sjkim { 1058250838Sjkim *Dest = *Source; 1059250838Sjkim Dest++; 1060250838Sjkim } 1061250838Sjkim Source++; 1062250838Sjkim } 1063250838Sjkim 1064250838Sjkim /* NULL terminate list and update the package count */ 1065250838Sjkim 1066250838Sjkim *Dest = NULL; 1067250838Sjkim ObjDesc->Package.Count = NewCount; 1068250838Sjkim} 1069