167754Smsmith/******************************************************************************* 267754Smsmith * 377424Smsmith * Module Name: utmisc - common utility procedures 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 4467754Smsmith 4577424Smsmith#define __UTMISC_C__ 4667754Smsmith 47193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 48193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 5067754Smsmith 5167754Smsmith 5277424Smsmith#define _COMPONENT ACPI_UTILITIES 5391116Smsmith ACPI_MODULE_NAME ("utmisc") 5467754Smsmith 5567754Smsmith 5699679Siwasaki/******************************************************************************* 5799679Siwasaki * 58167802Sjkim * FUNCTION: AcpiUtValidateException 59167802Sjkim * 60167802Sjkim * PARAMETERS: Status - The ACPI_STATUS code to be formatted 61167802Sjkim * 62167802Sjkim * RETURN: A string containing the exception text. NULL if exception is 63167802Sjkim * not valid. 64167802Sjkim * 65167802Sjkim * DESCRIPTION: This function validates and translates an ACPI exception into 66167802Sjkim * an ASCII string. 67167802Sjkim * 68167802Sjkim ******************************************************************************/ 69167802Sjkim 70167802Sjkimconst char * 71167802SjkimAcpiUtValidateException ( 72167802Sjkim ACPI_STATUS Status) 73167802Sjkim{ 74193267Sjkim UINT32 SubStatus; 75167802Sjkim const char *Exception = NULL; 76167802Sjkim 77167802Sjkim 78167802Sjkim ACPI_FUNCTION_ENTRY (); 79167802Sjkim 80167802Sjkim 81167802Sjkim /* 82167802Sjkim * Status is composed of two parts, a "type" and an actual code 83167802Sjkim */ 84167802Sjkim SubStatus = (Status & ~AE_CODE_MASK); 85167802Sjkim 86167802Sjkim switch (Status & AE_CODE_MASK) 87167802Sjkim { 88167802Sjkim case AE_CODE_ENVIRONMENTAL: 89167802Sjkim 90167802Sjkim if (SubStatus <= AE_CODE_ENV_MAX) 91167802Sjkim { 92167802Sjkim Exception = AcpiGbl_ExceptionNames_Env [SubStatus]; 93167802Sjkim } 94167802Sjkim break; 95167802Sjkim 96167802Sjkim case AE_CODE_PROGRAMMER: 97167802Sjkim 98167802Sjkim if (SubStatus <= AE_CODE_PGM_MAX) 99167802Sjkim { 100193267Sjkim Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus]; 101167802Sjkim } 102167802Sjkim break; 103167802Sjkim 104167802Sjkim case AE_CODE_ACPI_TABLES: 105167802Sjkim 106167802Sjkim if (SubStatus <= AE_CODE_TBL_MAX) 107167802Sjkim { 108193267Sjkim Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus]; 109167802Sjkim } 110167802Sjkim break; 111167802Sjkim 112167802Sjkim case AE_CODE_AML: 113167802Sjkim 114167802Sjkim if (SubStatus <= AE_CODE_AML_MAX) 115167802Sjkim { 116193267Sjkim Exception = AcpiGbl_ExceptionNames_Aml [SubStatus]; 117167802Sjkim } 118167802Sjkim break; 119167802Sjkim 120167802Sjkim case AE_CODE_CONTROL: 121167802Sjkim 122167802Sjkim if (SubStatus <= AE_CODE_CTRL_MAX) 123167802Sjkim { 124193267Sjkim Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus]; 125167802Sjkim } 126167802Sjkim break; 127167802Sjkim 128167802Sjkim default: 129167802Sjkim break; 130167802Sjkim } 131167802Sjkim 132167802Sjkim return (ACPI_CAST_PTR (const char, Exception)); 133167802Sjkim} 134167802Sjkim 135167802Sjkim 136167802Sjkim/******************************************************************************* 137167802Sjkim * 138197104Sjkim * FUNCTION: AcpiUtIsPciRootBridge 139197104Sjkim * 140197104Sjkim * PARAMETERS: Id - The HID/CID in string format 141197104Sjkim * 142197104Sjkim * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge 143197104Sjkim * 144197104Sjkim * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. 145197104Sjkim * 146197104Sjkim ******************************************************************************/ 147197104Sjkim 148197104SjkimBOOLEAN 149197104SjkimAcpiUtIsPciRootBridge ( 150197104Sjkim char *Id) 151197104Sjkim{ 152197104Sjkim 153197104Sjkim /* 154197104Sjkim * Check if this is a PCI root bridge. 155197104Sjkim * ACPI 3.0+: check for a PCI Express root also. 156197104Sjkim */ 157197104Sjkim if (!(ACPI_STRCMP (Id, 158197104Sjkim PCI_ROOT_HID_STRING)) || 159197104Sjkim 160197104Sjkim !(ACPI_STRCMP (Id, 161197104Sjkim PCI_EXPRESS_ROOT_HID_STRING))) 162197104Sjkim { 163197104Sjkim return (TRUE); 164197104Sjkim } 165197104Sjkim 166197104Sjkim return (FALSE); 167197104Sjkim} 168197104Sjkim 169197104Sjkim 170197104Sjkim/******************************************************************************* 171197104Sjkim * 172167802Sjkim * FUNCTION: AcpiUtIsAmlTable 173167802Sjkim * 174167802Sjkim * PARAMETERS: Table - An ACPI table 175167802Sjkim * 176167802Sjkim * RETURN: TRUE if table contains executable AML; FALSE otherwise 177167802Sjkim * 178167802Sjkim * DESCRIPTION: Check ACPI Signature for a table that contains AML code. 179167802Sjkim * Currently, these are DSDT,SSDT,PSDT. All other table types are 180167802Sjkim * data tables that do not contain AML code. 181167802Sjkim * 182167802Sjkim ******************************************************************************/ 183167802Sjkim 184167802SjkimBOOLEAN 185167802SjkimAcpiUtIsAmlTable ( 186167802Sjkim ACPI_TABLE_HEADER *Table) 187167802Sjkim{ 188167802Sjkim 189167802Sjkim /* These are the only tables that contain executable AML */ 190167802Sjkim 191167802Sjkim if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) || 192167802Sjkim ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) || 193167802Sjkim ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT)) 194167802Sjkim { 195167802Sjkim return (TRUE); 196167802Sjkim } 197167802Sjkim 198167802Sjkim return (FALSE); 199167802Sjkim} 200167802Sjkim 201167802Sjkim 202167802Sjkim/******************************************************************************* 203167802Sjkim * 204151937Sjkim * FUNCTION: AcpiUtAllocateOwnerId 205151937Sjkim * 206151937Sjkim * PARAMETERS: OwnerId - Where the new owner ID is returned 207151937Sjkim * 208151937Sjkim * RETURN: Status 209151937Sjkim * 210151937Sjkim * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to 211151937Sjkim * track objects created by the table or method, to be deleted 212151937Sjkim * when the method exits or the table is unloaded. 213151937Sjkim * 214151937Sjkim ******************************************************************************/ 215151937Sjkim 216151937SjkimACPI_STATUS 217151937SjkimAcpiUtAllocateOwnerId ( 218151937Sjkim ACPI_OWNER_ID *OwnerId) 219151937Sjkim{ 220193267Sjkim UINT32 i; 221193267Sjkim UINT32 j; 222193267Sjkim UINT32 k; 223151937Sjkim ACPI_STATUS Status; 224151937Sjkim 225151937Sjkim 226167802Sjkim ACPI_FUNCTION_TRACE (UtAllocateOwnerId); 227151937Sjkim 228151937Sjkim 229151937Sjkim /* Guard against multiple allocations of ID to the same location */ 230151937Sjkim 231151937Sjkim if (*OwnerId) 232151937Sjkim { 233204773Sjkim ACPI_ERROR ((AE_INFO, "Owner ID [0x%2.2X] already exists", *OwnerId)); 234151937Sjkim return_ACPI_STATUS (AE_ALREADY_EXISTS); 235151937Sjkim } 236151937Sjkim 237151937Sjkim /* Mutex for the global ID mask */ 238151937Sjkim 239151937Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 240151937Sjkim if (ACPI_FAILURE (Status)) 241151937Sjkim { 242151937Sjkim return_ACPI_STATUS (Status); 243151937Sjkim } 244151937Sjkim 245167802Sjkim /* 246167802Sjkim * Find a free owner ID, cycle through all possible IDs on repeated 247167802Sjkim * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have 248167802Sjkim * to be scanned twice. 249167802Sjkim */ 250167802Sjkim for (i = 0, j = AcpiGbl_LastOwnerIdIndex; 251167802Sjkim i < (ACPI_NUM_OWNERID_MASKS + 1); 252167802Sjkim i++, j++) 253151937Sjkim { 254167802Sjkim if (j >= ACPI_NUM_OWNERID_MASKS) 255151937Sjkim { 256167802Sjkim j = 0; /* Wraparound to start of mask array */ 257167802Sjkim } 258151937Sjkim 259167802Sjkim for (k = AcpiGbl_NextOwnerIdOffset; k < 32; k++) 260167802Sjkim { 261167802Sjkim if (AcpiGbl_OwnerIdMask[j] == ACPI_UINT32_MAX) 262167802Sjkim { 263167802Sjkim /* There are no free IDs in this mask */ 264167802Sjkim 265167802Sjkim break; 266167802Sjkim } 267167802Sjkim 268167802Sjkim if (!(AcpiGbl_OwnerIdMask[j] & (1 << k))) 269167802Sjkim { 270167802Sjkim /* 271167802Sjkim * Found a free ID. The actual ID is the bit index plus one, 272167802Sjkim * making zero an invalid Owner ID. Save this as the last ID 273167802Sjkim * allocated and update the global ID mask. 274167802Sjkim */ 275167802Sjkim AcpiGbl_OwnerIdMask[j] |= (1 << k); 276167802Sjkim 277167802Sjkim AcpiGbl_LastOwnerIdIndex = (UINT8) j; 278167802Sjkim AcpiGbl_NextOwnerIdOffset = (UINT8) (k + 1); 279167802Sjkim 280167802Sjkim /* 281167802Sjkim * Construct encoded ID from the index and bit position 282167802Sjkim * 283167802Sjkim * Note: Last [j].k (bit 255) is never used and is marked 284167802Sjkim * permanently allocated (prevents +1 overflow) 285167802Sjkim */ 286167802Sjkim *OwnerId = (ACPI_OWNER_ID) ((k + 1) + ACPI_MUL_32 (j)); 287167802Sjkim 288167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_VALUES, 289167802Sjkim "Allocated OwnerId: %2.2X\n", (unsigned int) *OwnerId)); 290167802Sjkim goto Exit; 291167802Sjkim } 292151937Sjkim } 293167802Sjkim 294167802Sjkim AcpiGbl_NextOwnerIdOffset = 0; 295151937Sjkim } 296151937Sjkim 297151937Sjkim /* 298167802Sjkim * All OwnerIds have been allocated. This typically should 299151937Sjkim * not happen since the IDs are reused after deallocation. The IDs are 300151937Sjkim * allocated upon table load (one per table) and method execution, and 301151937Sjkim * they are released when a table is unloaded or a method completes 302151937Sjkim * execution. 303167802Sjkim * 304167802Sjkim * If this error happens, there may be very deep nesting of invoked control 305167802Sjkim * methods, or there may be a bug where the IDs are not released. 306151937Sjkim */ 307151937Sjkim Status = AE_OWNER_ID_LIMIT; 308167802Sjkim ACPI_ERROR ((AE_INFO, 309167802Sjkim "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT")); 310151937Sjkim 311151937SjkimExit: 312151937Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 313151937Sjkim return_ACPI_STATUS (Status); 314151937Sjkim} 315151937Sjkim 316151937Sjkim 317151937Sjkim/******************************************************************************* 318151937Sjkim * 319151937Sjkim * FUNCTION: AcpiUtReleaseOwnerId 320151937Sjkim * 321151937Sjkim * PARAMETERS: OwnerIdPtr - Pointer to a previously allocated OwnerID 322151937Sjkim * 323151937Sjkim * RETURN: None. No error is returned because we are either exiting a 324151937Sjkim * control method or unloading a table. Either way, we would 325151937Sjkim * ignore any error anyway. 326151937Sjkim * 327167802Sjkim * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255 328151937Sjkim * 329151937Sjkim ******************************************************************************/ 330151937Sjkim 331151937Sjkimvoid 332151937SjkimAcpiUtReleaseOwnerId ( 333151937Sjkim ACPI_OWNER_ID *OwnerIdPtr) 334151937Sjkim{ 335151937Sjkim ACPI_OWNER_ID OwnerId = *OwnerIdPtr; 336151937Sjkim ACPI_STATUS Status; 337193267Sjkim UINT32 Index; 338167802Sjkim UINT32 Bit; 339151937Sjkim 340151937Sjkim 341167802Sjkim ACPI_FUNCTION_TRACE_U32 (UtReleaseOwnerId, OwnerId); 342151937Sjkim 343151937Sjkim 344151937Sjkim /* Always clear the input OwnerId (zero is an invalid ID) */ 345151937Sjkim 346151937Sjkim *OwnerIdPtr = 0; 347151937Sjkim 348151937Sjkim /* Zero is not a valid OwnerID */ 349151937Sjkim 350167802Sjkim if (OwnerId == 0) 351151937Sjkim { 352204773Sjkim ACPI_ERROR ((AE_INFO, "Invalid OwnerId: 0x%2.2X", OwnerId)); 353151937Sjkim return_VOID; 354151937Sjkim } 355151937Sjkim 356151937Sjkim /* Mutex for the global ID mask */ 357151937Sjkim 358151937Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 359151937Sjkim if (ACPI_FAILURE (Status)) 360151937Sjkim { 361151937Sjkim return_VOID; 362151937Sjkim } 363151937Sjkim 364151937Sjkim /* Normalize the ID to zero */ 365151937Sjkim 366151937Sjkim OwnerId--; 367151937Sjkim 368167802Sjkim /* Decode ID to index/offset pair */ 369167802Sjkim 370167802Sjkim Index = ACPI_DIV_32 (OwnerId); 371167802Sjkim Bit = 1 << ACPI_MOD_32 (OwnerId); 372167802Sjkim 373151937Sjkim /* Free the owner ID only if it is valid */ 374151937Sjkim 375167802Sjkim if (AcpiGbl_OwnerIdMask[Index] & Bit) 376151937Sjkim { 377167802Sjkim AcpiGbl_OwnerIdMask[Index] ^= Bit; 378151937Sjkim } 379167802Sjkim else 380167802Sjkim { 381167802Sjkim ACPI_ERROR ((AE_INFO, 382204773Sjkim "Release of non-allocated OwnerId: 0x%2.2X", OwnerId + 1)); 383167802Sjkim } 384151937Sjkim 385151937Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 386151937Sjkim return_VOID; 387151937Sjkim} 388151937Sjkim 389151937Sjkim 390151937Sjkim/******************************************************************************* 391151937Sjkim * 392151937Sjkim * FUNCTION: AcpiUtStrupr (strupr) 393151937Sjkim * 394151937Sjkim * PARAMETERS: SrcString - The source string to convert 395151937Sjkim * 396151937Sjkim * RETURN: None 397151937Sjkim * 398151937Sjkim * DESCRIPTION: Convert string to uppercase 399151937Sjkim * 400151937Sjkim * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 401151937Sjkim * 402151937Sjkim ******************************************************************************/ 403151937Sjkim 404151937Sjkimvoid 405151937SjkimAcpiUtStrupr ( 406151937Sjkim char *SrcString) 407151937Sjkim{ 408151937Sjkim char *String; 409151937Sjkim 410151937Sjkim 411151937Sjkim ACPI_FUNCTION_ENTRY (); 412151937Sjkim 413151937Sjkim 414151937Sjkim if (!SrcString) 415151937Sjkim { 416151937Sjkim return; 417151937Sjkim } 418151937Sjkim 419151937Sjkim /* Walk entire string, uppercasing the letters */ 420151937Sjkim 421151937Sjkim for (String = SrcString; *String; String++) 422151937Sjkim { 423151937Sjkim *String = (char) ACPI_TOUPPER (*String); 424151937Sjkim } 425151937Sjkim 426151937Sjkim return; 427151937Sjkim} 428151937Sjkim 429151937Sjkim 430209746Sjkim#ifdef ACPI_ASL_COMPILER 431151937Sjkim/******************************************************************************* 432151937Sjkim * 433209746Sjkim * FUNCTION: AcpiUtStrlwr (strlwr) 434209746Sjkim * 435209746Sjkim * PARAMETERS: SrcString - The source string to convert 436209746Sjkim * 437209746Sjkim * RETURN: None 438209746Sjkim * 439209746Sjkim * DESCRIPTION: Convert string to lowercase 440209746Sjkim * 441209746Sjkim * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 442209746Sjkim * 443209746Sjkim ******************************************************************************/ 444209746Sjkim 445209746Sjkimvoid 446209746SjkimAcpiUtStrlwr ( 447209746Sjkim char *SrcString) 448209746Sjkim{ 449209746Sjkim char *String; 450209746Sjkim 451209746Sjkim 452209746Sjkim ACPI_FUNCTION_ENTRY (); 453209746Sjkim 454209746Sjkim 455209746Sjkim if (!SrcString) 456209746Sjkim { 457209746Sjkim return; 458209746Sjkim } 459209746Sjkim 460209746Sjkim /* Walk entire string, lowercasing the letters */ 461209746Sjkim 462209746Sjkim for (String = SrcString; *String; String++) 463209746Sjkim { 464209746Sjkim *String = (char) ACPI_TOLOWER (*String); 465209746Sjkim } 466209746Sjkim 467209746Sjkim return; 468209746Sjkim} 469209746Sjkim#endif 470209746Sjkim 471209746Sjkim 472209746Sjkim/******************************************************************************* 473209746Sjkim * 474107325Siwasaki * FUNCTION: AcpiUtPrintString 475107325Siwasaki * 476107325Siwasaki * PARAMETERS: String - Null terminated ASCII string 477151937Sjkim * MaxLength - Maximum output length 478107325Siwasaki * 479107325Siwasaki * RETURN: None 480107325Siwasaki * 481107325Siwasaki * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 482107325Siwasaki * sequences. 483107325Siwasaki * 484107325Siwasaki ******************************************************************************/ 485107325Siwasaki 486107325Siwasakivoid 487107325SiwasakiAcpiUtPrintString ( 488107325Siwasaki char *String, 489107325Siwasaki UINT8 MaxLength) 490107325Siwasaki{ 491107325Siwasaki UINT32 i; 492107325Siwasaki 493107325Siwasaki 494107325Siwasaki if (!String) 495107325Siwasaki { 496107325Siwasaki AcpiOsPrintf ("<\"NULL STRING PTR\">"); 497107325Siwasaki return; 498107325Siwasaki } 499107325Siwasaki 500107325Siwasaki AcpiOsPrintf ("\""); 501107325Siwasaki for (i = 0; String[i] && (i < MaxLength); i++) 502107325Siwasaki { 503107325Siwasaki /* Escape sequences */ 504107325Siwasaki 505107325Siwasaki switch (String[i]) 506107325Siwasaki { 507107325Siwasaki case 0x07: 508167802Sjkim AcpiOsPrintf ("\\a"); /* BELL */ 509107325Siwasaki break; 510107325Siwasaki 511107325Siwasaki case 0x08: 512107325Siwasaki AcpiOsPrintf ("\\b"); /* BACKSPACE */ 513107325Siwasaki break; 514107325Siwasaki 515107325Siwasaki case 0x0C: 516107325Siwasaki AcpiOsPrintf ("\\f"); /* FORMFEED */ 517107325Siwasaki break; 518107325Siwasaki 519107325Siwasaki case 0x0A: 520107325Siwasaki AcpiOsPrintf ("\\n"); /* LINEFEED */ 521107325Siwasaki break; 522107325Siwasaki 523107325Siwasaki case 0x0D: 524107325Siwasaki AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/ 525107325Siwasaki break; 526107325Siwasaki 527107325Siwasaki case 0x09: 528107325Siwasaki AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */ 529107325Siwasaki break; 530107325Siwasaki 531107325Siwasaki case 0x0B: 532107325Siwasaki AcpiOsPrintf ("\\v"); /* VERTICAL TAB */ 533107325Siwasaki break; 534107325Siwasaki 535107325Siwasaki case '\'': /* Single Quote */ 536107325Siwasaki case '\"': /* Double Quote */ 537107325Siwasaki case '\\': /* Backslash */ 538107325Siwasaki AcpiOsPrintf ("\\%c", (int) String[i]); 539107325Siwasaki break; 540107325Siwasaki 541107325Siwasaki default: 542107325Siwasaki 543107325Siwasaki /* Check for printable character or hex escape */ 544107325Siwasaki 545107325Siwasaki if (ACPI_IS_PRINT (String[i])) 546107325Siwasaki { 547107325Siwasaki /* This is a normal character */ 548107325Siwasaki 549107325Siwasaki AcpiOsPrintf ("%c", (int) String[i]); 550107325Siwasaki } 551107325Siwasaki else 552107325Siwasaki { 553107325Siwasaki /* All others will be Hex escapes */ 554107325Siwasaki 555107325Siwasaki AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]); 556107325Siwasaki } 557107325Siwasaki break; 558107325Siwasaki } 559107325Siwasaki } 560107325Siwasaki AcpiOsPrintf ("\""); 561107325Siwasaki 562107325Siwasaki if (i == MaxLength && String[i]) 563107325Siwasaki { 564107325Siwasaki AcpiOsPrintf ("..."); 565107325Siwasaki } 566107325Siwasaki} 567107325Siwasaki 568107325Siwasaki 569107325Siwasaki/******************************************************************************* 570107325Siwasaki * 57199679Siwasaki * FUNCTION: AcpiUtDwordByteSwap 57299679Siwasaki * 57399679Siwasaki * PARAMETERS: Value - Value to be converted 57499679Siwasaki * 575151937Sjkim * RETURN: UINT32 integer with bytes swapped 576151937Sjkim * 57799679Siwasaki * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) 57899679Siwasaki * 57999679Siwasaki ******************************************************************************/ 58099679Siwasaki 58199679SiwasakiUINT32 58299679SiwasakiAcpiUtDwordByteSwap ( 58399679Siwasaki UINT32 Value) 58499679Siwasaki{ 58599679Siwasaki union 58699679Siwasaki { 58799679Siwasaki UINT32 Value; 58899679Siwasaki UINT8 Bytes[4]; 58999679Siwasaki } Out; 59099679Siwasaki union 59199679Siwasaki { 59299679Siwasaki UINT32 Value; 59399679Siwasaki UINT8 Bytes[4]; 59499679Siwasaki } In; 59599679Siwasaki 59699679Siwasaki 59799679Siwasaki ACPI_FUNCTION_ENTRY (); 59899679Siwasaki 59999679Siwasaki 60099679Siwasaki In.Value = Value; 60199679Siwasaki 60299679Siwasaki Out.Bytes[0] = In.Bytes[3]; 60399679Siwasaki Out.Bytes[1] = In.Bytes[2]; 60499679Siwasaki Out.Bytes[2] = In.Bytes[1]; 60599679Siwasaki Out.Bytes[3] = In.Bytes[0]; 60699679Siwasaki 60799679Siwasaki return (Out.Value); 60899679Siwasaki} 60999679Siwasaki 61099679Siwasaki 61199679Siwasaki/******************************************************************************* 61299679Siwasaki * 61399679Siwasaki * FUNCTION: AcpiUtSetIntegerWidth 61499679Siwasaki * 61599679Siwasaki * PARAMETERS: Revision From DSDT header 61699679Siwasaki * 61799679Siwasaki * RETURN: None 61899679Siwasaki * 61999679Siwasaki * DESCRIPTION: Set the global integer bit width based upon the revision 62099679Siwasaki * of the DSDT. For Revision 1 and 0, Integers are 32 bits. 62199679Siwasaki * For Revision 2 and above, Integers are 64 bits. Yes, this 62299679Siwasaki * makes a difference. 62399679Siwasaki * 62499679Siwasaki ******************************************************************************/ 62599679Siwasaki 62699679Siwasakivoid 62799679SiwasakiAcpiUtSetIntegerWidth ( 62899679Siwasaki UINT8 Revision) 62999679Siwasaki{ 63099679Siwasaki 631167802Sjkim if (Revision < 2) 63299679Siwasaki { 633167802Sjkim /* 32-bit case */ 634167802Sjkim 635117521Snjl AcpiGbl_IntegerBitWidth = 32; 636117521Snjl AcpiGbl_IntegerNybbleWidth = 8; 637117521Snjl AcpiGbl_IntegerByteWidth = 4; 63899679Siwasaki } 63999679Siwasaki else 64099679Siwasaki { 641167802Sjkim /* 64-bit case (ACPI 2.0+) */ 642167802Sjkim 643117521Snjl AcpiGbl_IntegerBitWidth = 64; 644117521Snjl AcpiGbl_IntegerNybbleWidth = 16; 645117521Snjl AcpiGbl_IntegerByteWidth = 8; 64699679Siwasaki } 64799679Siwasaki} 64899679Siwasaki 64999679Siwasaki 650102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT 65167754Smsmith/******************************************************************************* 65267754Smsmith * 65391116Smsmith * FUNCTION: AcpiUtDisplayInitPathname 65491116Smsmith * 655151937Sjkim * PARAMETERS: Type - Object type of the node 656151937Sjkim * ObjHandle - Handle whose pathname will be displayed 657114237Snjl * Path - Additional path string to be appended. 658114237Snjl * (NULL if no extra path) 65991116Smsmith * 66091116Smsmith * RETURN: ACPI_STATUS 66191116Smsmith * 662114237Snjl * DESCRIPTION: Display full pathname of an object, DEBUG ONLY 66391116Smsmith * 66491116Smsmith ******************************************************************************/ 66591116Smsmith 66691116Smsmithvoid 66791116SmsmithAcpiUtDisplayInitPathname ( 668114237Snjl UINT8 Type, 669114237Snjl ACPI_NAMESPACE_NODE *ObjHandle, 67091116Smsmith char *Path) 67191116Smsmith{ 67291116Smsmith ACPI_STATUS Status; 67391116Smsmith ACPI_BUFFER Buffer; 67491116Smsmith 67591116Smsmith 676114237Snjl ACPI_FUNCTION_ENTRY (); 67791116Smsmith 67891116Smsmith 679114237Snjl /* Only print the path if the appropriate debug level is enabled */ 680114237Snjl 681114237Snjl if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES)) 682114237Snjl { 683114237Snjl return; 684114237Snjl } 685114237Snjl 686114237Snjl /* Get the full pathname to the node */ 687114237Snjl 68891116Smsmith Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 68991116Smsmith Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 690114237Snjl if (ACPI_FAILURE (Status)) 69191116Smsmith { 692114237Snjl return; 693114237Snjl } 69491116Smsmith 695114237Snjl /* Print what we're doing */ 696114237Snjl 697114237Snjl switch (Type) 698114237Snjl { 699114237Snjl case ACPI_TYPE_METHOD: 700114237Snjl AcpiOsPrintf ("Executing "); 701114237Snjl break; 702114237Snjl 703114237Snjl default: 704114237Snjl AcpiOsPrintf ("Initializing "); 705114237Snjl break; 70691116Smsmith } 707114237Snjl 708114237Snjl /* Print the object type and pathname */ 709114237Snjl 710151937Sjkim AcpiOsPrintf ("%-12s %s", 711151937Sjkim AcpiUtGetTypeName (Type), (char *) Buffer.Pointer); 712114237Snjl 713114237Snjl /* Extra path is used to append names like _STA, _INI, etc. */ 714114237Snjl 715114237Snjl if (Path) 716114237Snjl { 717114237Snjl AcpiOsPrintf (".%s", Path); 718114237Snjl } 719114237Snjl AcpiOsPrintf ("\n"); 720114237Snjl 721167802Sjkim ACPI_FREE (Buffer.Pointer); 72291116Smsmith} 72391116Smsmith#endif 72491116Smsmith 72591116Smsmith 72691116Smsmith/******************************************************************************* 72791116Smsmith * 728167802Sjkim * FUNCTION: AcpiUtValidAcpiChar 729167802Sjkim * 730167802Sjkim * PARAMETERS: Char - The character to be examined 731167802Sjkim * Position - Byte position (0-3) 732167802Sjkim * 733167802Sjkim * RETURN: TRUE if the character is valid, FALSE otherwise 734167802Sjkim * 735167802Sjkim * DESCRIPTION: Check for a valid ACPI character. Must be one of: 736167802Sjkim * 1) Upper case alpha 737167802Sjkim * 2) numeric 738167802Sjkim * 3) underscore 739167802Sjkim * 740167802Sjkim * We allow a '!' as the last character because of the ASF! table 741167802Sjkim * 742167802Sjkim ******************************************************************************/ 743167802Sjkim 744167802SjkimBOOLEAN 745167802SjkimAcpiUtValidAcpiChar ( 746167802Sjkim char Character, 747193267Sjkim UINT32 Position) 748167802Sjkim{ 749167802Sjkim 750167802Sjkim if (!((Character >= 'A' && Character <= 'Z') || 751167802Sjkim (Character >= '0' && Character <= '9') || 752167802Sjkim (Character == '_'))) 753167802Sjkim { 754167802Sjkim /* Allow a '!' in the last position */ 755167802Sjkim 756167802Sjkim if (Character == '!' && Position == 3) 757167802Sjkim { 758167802Sjkim return (TRUE); 759167802Sjkim } 760167802Sjkim 761167802Sjkim return (FALSE); 762167802Sjkim } 763167802Sjkim 764167802Sjkim return (TRUE); 765167802Sjkim} 766167802Sjkim 767167802Sjkim 768167802Sjkim/******************************************************************************* 769167802Sjkim * 77077424Smsmith * FUNCTION: AcpiUtValidAcpiName 77167754Smsmith * 772151937Sjkim * PARAMETERS: Name - The name to be examined 77367754Smsmith * 774151937Sjkim * RETURN: TRUE if the name is valid, FALSE otherwise 77567754Smsmith * 77667754Smsmith * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 77767754Smsmith * 1) Upper case alpha 77867754Smsmith * 2) numeric 77967754Smsmith * 3) underscore 78067754Smsmith * 78167754Smsmith ******************************************************************************/ 78267754Smsmith 78367754SmsmithBOOLEAN 78477424SmsmithAcpiUtValidAcpiName ( 78567754Smsmith UINT32 Name) 78667754Smsmith{ 787193267Sjkim UINT32 i; 78867754Smsmith 78967754Smsmith 79091116Smsmith ACPI_FUNCTION_ENTRY (); 79183174Smsmith 79283174Smsmith 79367754Smsmith for (i = 0; i < ACPI_NAME_SIZE; i++) 79467754Smsmith { 795167802Sjkim if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i)) 79667754Smsmith { 79767754Smsmith return (FALSE); 79867754Smsmith } 79967754Smsmith } 80067754Smsmith 80167754Smsmith return (TRUE); 80267754Smsmith} 80367754Smsmith 80467754Smsmith 80567754Smsmith/******************************************************************************* 80667754Smsmith * 807167802Sjkim * FUNCTION: AcpiUtRepairName 80867754Smsmith * 809167802Sjkim * PARAMETERS: Name - The ACPI name to be repaired 81067754Smsmith * 811167802Sjkim * RETURN: Repaired version of the name 81267754Smsmith * 813167802Sjkim * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 814193267Sjkim * return the new name. NOTE: the Name parameter must reside in 815193267Sjkim * read/write memory, cannot be a const. 81667754Smsmith * 817193267Sjkim * An ACPI Name must consist of valid ACPI characters. We will repair the name 818193267Sjkim * if necessary because we don't want to abort because of this, but we want 819193267Sjkim * all namespace names to be printable. A warning message is appropriate. 820193267Sjkim * 821193267Sjkim * This issue came up because there are in fact machines that exhibit 822193267Sjkim * this problem, and we want to be able to enable ACPI support for them, 823193267Sjkim * even though there are a few bad names. 824193267Sjkim * 82567754Smsmith ******************************************************************************/ 82667754Smsmith 827193267Sjkimvoid 828167802SjkimAcpiUtRepairName ( 829167802Sjkim char *Name) 83067754Smsmith{ 831193267Sjkim UINT32 i; 832193267Sjkim BOOLEAN FoundBadChar = FALSE; 83367754Smsmith 83483174Smsmith 835193267Sjkim ACPI_FUNCTION_NAME (UtRepairName); 836193267Sjkim 837193267Sjkim 838193267Sjkim /* Check each character in the name */ 839193267Sjkim 840167802Sjkim for (i = 0; i < ACPI_NAME_SIZE; i++) 841167802Sjkim { 842193267Sjkim if (AcpiUtValidAcpiChar (Name[i], i)) 843193267Sjkim { 844193267Sjkim continue; 845193267Sjkim } 846167802Sjkim 847167802Sjkim /* 848167802Sjkim * Replace a bad character with something printable, yet technically 849167802Sjkim * still invalid. This prevents any collisions with existing "good" 850167802Sjkim * names in the namespace. 851167802Sjkim */ 852193267Sjkim Name[i] = '*'; 853193267Sjkim FoundBadChar = TRUE; 854193267Sjkim } 855193267Sjkim 856193267Sjkim if (FoundBadChar) 857193267Sjkim { 858193267Sjkim /* Report warning only if in strict mode or debug mode */ 859193267Sjkim 860193267Sjkim if (!AcpiGbl_EnableInterpreterSlack) 861167802Sjkim { 862193267Sjkim ACPI_WARNING ((AE_INFO, 863193267Sjkim "Found bad character(s) in name, repaired: [%4.4s]\n", Name)); 864167802Sjkim } 865193267Sjkim else 866193267Sjkim { 867193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 868193267Sjkim "Found bad character(s) in name, repaired: [%4.4s]\n", Name)); 869193267Sjkim } 870167802Sjkim } 87167754Smsmith} 87267754Smsmith 87383174Smsmith 87477424Smsmith/******************************************************************************* 87577424Smsmith * 87699679Siwasaki * FUNCTION: AcpiUtStrtoul64 87799679Siwasaki * 87899679Siwasaki * PARAMETERS: String - Null terminated string 879167802Sjkim * Base - Radix of the string: 16 or ACPI_ANY_BASE; 880167802Sjkim * ACPI_ANY_BASE means 'in behalf of ToInteger' 881138287Smarks * RetInteger - Where the converted integer is returned 88299679Siwasaki * 883138287Smarks * RETURN: Status and Converted value 88499679Siwasaki * 885167802Sjkim * DESCRIPTION: Convert a string into an unsigned value. Performs either a 886167802Sjkim * 32-bit or 64-bit conversion, depending on the current mode 887167802Sjkim * of the interpreter. 888138287Smarks * NOTE: Does not support Octal strings, not needed. 88999679Siwasaki * 89099679Siwasaki ******************************************************************************/ 89199679Siwasaki 89299679SiwasakiACPI_STATUS 89399679SiwasakiAcpiUtStrtoul64 ( 894114237Snjl char *String, 89599679Siwasaki UINT32 Base, 896202771Sjkim UINT64 *RetInteger) 89799679Siwasaki{ 898151937Sjkim UINT32 ThisDigit = 0; 899202771Sjkim UINT64 ReturnValue = 0; 900202771Sjkim UINT64 Quotient; 901202771Sjkim UINT64 Dividend; 902167802Sjkim UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE); 903167802Sjkim UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4); 904167802Sjkim UINT8 ValidDigits = 0; 905167802Sjkim UINT8 SignOf0x = 0; 906167802Sjkim UINT8 Term = 0; 90799679Siwasaki 90899679Siwasaki 909167802Sjkim ACPI_FUNCTION_TRACE_STR (UtStroul64, String); 91099679Siwasaki 911138287Smarks 91299679Siwasaki switch (Base) 91399679Siwasaki { 914138287Smarks case ACPI_ANY_BASE: 91599679Siwasaki case 16: 91699679Siwasaki break; 91799679Siwasaki 91899679Siwasaki default: 919138287Smarks /* Invalid Base */ 920138287Smarks return_ACPI_STATUS (AE_BAD_PARAMETER); 92199679Siwasaki } 92299679Siwasaki 923167802Sjkim if (!String) 924167802Sjkim { 925167802Sjkim goto ErrorExit; 926167802Sjkim } 927167802Sjkim 928138287Smarks /* Skip over any white space in the buffer */ 929138287Smarks 930167802Sjkim while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t')) 93199679Siwasaki { 932151937Sjkim String++; 93399679Siwasaki } 93499679Siwasaki 935167802Sjkim if (ToIntegerOp) 93699679Siwasaki { 937167802Sjkim /* 938167802Sjkim * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. 939167802Sjkim * We need to determine if it is decimal or hexadecimal. 940167802Sjkim */ 941167802Sjkim if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x')) 94299679Siwasaki { 943167802Sjkim SignOf0x = 1; 944138287Smarks Base = 16; 945167802Sjkim 946167802Sjkim /* Skip over the leading '0x' */ 947151937Sjkim String += 2; 94899679Siwasaki } 94999679Siwasaki else 95099679Siwasaki { 95199679Siwasaki Base = 10; 95299679Siwasaki } 95399679Siwasaki } 95499679Siwasaki 955167802Sjkim /* Any string left? Check that '0x' is not followed by white space. */ 956167802Sjkim 957167802Sjkim if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t') 95899679Siwasaki { 959167802Sjkim if (ToIntegerOp) 960167802Sjkim { 961167802Sjkim goto ErrorExit; 962167802Sjkim } 963167802Sjkim else 964167802Sjkim { 965167802Sjkim goto AllDone; 966167802Sjkim } 96799679Siwasaki } 96899679Siwasaki 969167802Sjkim /* 970167802Sjkim * Perform a 32-bit or 64-bit conversion, depending upon the current 971167802Sjkim * execution mode of the interpreter 972167802Sjkim */ 973167802Sjkim Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; 974151937Sjkim 975167802Sjkim /* Main loop: convert the string to a 32- or 64-bit integer */ 976151937Sjkim 97799679Siwasaki while (*String) 97899679Siwasaki { 97999679Siwasaki if (ACPI_IS_DIGIT (*String)) 98099679Siwasaki { 981138287Smarks /* Convert ASCII 0-9 to Decimal value */ 982138287Smarks 983138287Smarks ThisDigit = ((UINT8) *String) - '0'; 98499679Siwasaki } 985167802Sjkim else if (Base == 10) 986167802Sjkim { 987167802Sjkim /* Digit is out of range; possible in ToInteger case only */ 988167802Sjkim 989167802Sjkim Term = 1; 990167802Sjkim } 99199679Siwasaki else 99299679Siwasaki { 993138287Smarks ThisDigit = (UINT8) ACPI_TOUPPER (*String); 994151937Sjkim if (ACPI_IS_XDIGIT ((char) ThisDigit)) 99599679Siwasaki { 996138287Smarks /* Convert ASCII Hex char to value */ 997138287Smarks 998138287Smarks ThisDigit = ThisDigit - 'A' + 10; 99999679Siwasaki } 100099679Siwasaki else 100199679Siwasaki { 1002167802Sjkim Term = 1; 1003167802Sjkim } 1004167802Sjkim } 1005167802Sjkim 1006167802Sjkim if (Term) 1007167802Sjkim { 1008167802Sjkim if (ToIntegerOp) 1009167802Sjkim { 1010167802Sjkim goto ErrorExit; 1011167802Sjkim } 1012167802Sjkim else 1013167802Sjkim { 1014151937Sjkim break; 101599679Siwasaki } 101699679Siwasaki } 1017167802Sjkim else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 1018167802Sjkim { 1019167802Sjkim /* Skip zeros */ 1020167802Sjkim String++; 1021167802Sjkim continue; 1022167802Sjkim } 102399679Siwasaki 1024167802Sjkim ValidDigits++; 1025167802Sjkim 1026167802Sjkim if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32))) 1027167802Sjkim { 1028167802Sjkim /* 1029167802Sjkim * This is ToInteger operation case. 1030167802Sjkim * No any restrictions for string-to-integer conversion, 1031167802Sjkim * see ACPI spec. 1032167802Sjkim */ 1033167802Sjkim goto ErrorExit; 1034167802Sjkim } 1035167802Sjkim 1036138287Smarks /* Divide the digit into the correct position */ 103799679Siwasaki 1038202771Sjkim (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit), 1039138287Smarks Base, &Quotient, NULL); 1040167802Sjkim 104199679Siwasaki if (ReturnValue > Quotient) 104299679Siwasaki { 1043167802Sjkim if (ToIntegerOp) 1044167802Sjkim { 1045167802Sjkim goto ErrorExit; 1046167802Sjkim } 1047167802Sjkim else 1048167802Sjkim { 1049167802Sjkim break; 1050167802Sjkim } 105199679Siwasaki } 105299679Siwasaki 105399679Siwasaki ReturnValue *= Base; 1054138287Smarks ReturnValue += ThisDigit; 1055151937Sjkim String++; 105699679Siwasaki } 105799679Siwasaki 1058151937Sjkim /* All done, normal exit */ 1059151937Sjkim 1060167802SjkimAllDone: 1061167802Sjkim 1062167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 1063167802Sjkim ACPI_FORMAT_UINT64 (ReturnValue))); 1064167802Sjkim 106599679Siwasaki *RetInteger = ReturnValue; 1066138287Smarks return_ACPI_STATUS (AE_OK); 106799679Siwasaki 106899679Siwasaki 106999679SiwasakiErrorExit: 1070138287Smarks /* Base was set/validated above */ 1071138287Smarks 1072138287Smarks if (Base == 10) 107399679Siwasaki { 1074138287Smarks return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 107599679Siwasaki } 1076138287Smarks else 1077138287Smarks { 1078138287Smarks return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 1079138287Smarks } 108099679Siwasaki} 108199679Siwasaki 108299679Siwasaki 108399679Siwasaki/******************************************************************************* 108499679Siwasaki * 108577424Smsmith * FUNCTION: AcpiUtCreateUpdateStateAndPush 108667754Smsmith * 1087151937Sjkim * PARAMETERS: Object - Object to be added to the new state 108867754Smsmith * Action - Increment/Decrement 108967754Smsmith * StateList - List the state will be added to 109067754Smsmith * 1091151937Sjkim * RETURN: Status 109267754Smsmith * 109367754Smsmith * DESCRIPTION: Create a new state and push it 109467754Smsmith * 109567754Smsmith ******************************************************************************/ 109667754Smsmith 109767754SmsmithACPI_STATUS 109877424SmsmithAcpiUtCreateUpdateStateAndPush ( 109967754Smsmith ACPI_OPERAND_OBJECT *Object, 110067754Smsmith UINT16 Action, 110167754Smsmith ACPI_GENERIC_STATE **StateList) 110267754Smsmith{ 110367754Smsmith ACPI_GENERIC_STATE *State; 110467754Smsmith 110567754Smsmith 110691116Smsmith ACPI_FUNCTION_ENTRY (); 110783174Smsmith 110883174Smsmith 110967754Smsmith /* Ignore null objects; these are expected */ 111067754Smsmith 111167754Smsmith if (!Object) 111267754Smsmith { 111367754Smsmith return (AE_OK); 111467754Smsmith } 111567754Smsmith 111677424Smsmith State = AcpiUtCreateUpdateState (Object, Action); 111767754Smsmith if (!State) 111867754Smsmith { 111967754Smsmith return (AE_NO_MEMORY); 112067754Smsmith } 112167754Smsmith 112277424Smsmith AcpiUtPushGenericState (StateList, State); 112367754Smsmith return (AE_OK); 112467754Smsmith} 112567754Smsmith 112667754Smsmith 112767754Smsmith/******************************************************************************* 112867754Smsmith * 112977424Smsmith * FUNCTION: AcpiUtWalkPackageTree 113073561Smsmith * 1131151937Sjkim * PARAMETERS: SourceObject - The package to walk 1132151937Sjkim * TargetObject - Target object (if package is being copied) 1133151937Sjkim * WalkCallback - Called once for each package element 1134151937Sjkim * Context - Passed to the callback function 113573561Smsmith * 113673561Smsmith * RETURN: Status 113773561Smsmith * 113873561Smsmith * DESCRIPTION: Walk through a package 113973561Smsmith * 114073561Smsmith ******************************************************************************/ 114173561Smsmith 114273561SmsmithACPI_STATUS 114377424SmsmithAcpiUtWalkPackageTree ( 114473561Smsmith ACPI_OPERAND_OBJECT *SourceObject, 114573561Smsmith void *TargetObject, 114673561Smsmith ACPI_PKG_CALLBACK WalkCallback, 114773561Smsmith void *Context) 114873561Smsmith{ 114973561Smsmith ACPI_STATUS Status = AE_OK; 115073561Smsmith ACPI_GENERIC_STATE *StateList = NULL; 115173561Smsmith ACPI_GENERIC_STATE *State; 115273561Smsmith UINT32 ThisIndex; 115373561Smsmith ACPI_OPERAND_OBJECT *ThisSourceObj; 115473561Smsmith 115573561Smsmith 1156167802Sjkim ACPI_FUNCTION_TRACE (UtWalkPackageTree); 115773561Smsmith 115873561Smsmith 115977424Smsmith State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0); 116073561Smsmith if (!State) 116173561Smsmith { 116273561Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 116373561Smsmith } 116473561Smsmith 116573561Smsmith while (State) 116673561Smsmith { 1167114237Snjl /* Get one element of the package */ 1168114237Snjl 116977424Smsmith ThisIndex = State->Pkg.Index; 117077424Smsmith ThisSourceObj = (ACPI_OPERAND_OBJECT *) 117177424Smsmith State->Pkg.SourceObject->Package.Elements[ThisIndex]; 117273561Smsmith 117373561Smsmith /* 117487031Smsmith * Check for: 117573561Smsmith * 1) An uninitialized package element. It is completely 117691116Smsmith * legal to declare a package and leave it uninitialized 117773561Smsmith * 2) Not an internal object - can be a namespace node instead 117877424Smsmith * 3) Any type other than a package. Packages are handled in else 117991116Smsmith * case below. 118073561Smsmith */ 118173561Smsmith if ((!ThisSourceObj) || 118299679Siwasaki (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) || 1183193267Sjkim (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE)) 118473561Smsmith { 118577424Smsmith Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj, 118677424Smsmith State, Context); 118773561Smsmith if (ACPI_FAILURE (Status)) 118873561Smsmith { 118973561Smsmith return_ACPI_STATUS (Status); 119073561Smsmith } 119173561Smsmith 119273561Smsmith State->Pkg.Index++; 119373561Smsmith while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count) 119473561Smsmith { 119573561Smsmith /* 119673561Smsmith * We've handled all of the objects at this level, This means 119773561Smsmith * that we have just completed a package. That package may 119873561Smsmith * have contained one or more packages itself. 119973561Smsmith * 120073561Smsmith * Delete this state and pop the previous state (package). 120173561Smsmith */ 120277424Smsmith AcpiUtDeleteGenericState (State); 120377424Smsmith State = AcpiUtPopGenericState (&StateList); 120473561Smsmith 120573561Smsmith /* Finished when there are no more states */ 120673561Smsmith 120773561Smsmith if (!State) 120873561Smsmith { 120973561Smsmith /* 121073561Smsmith * We have handled all of the objects in the top level 121173561Smsmith * package just add the length of the package objects 121273561Smsmith * and exit 121373561Smsmith */ 121473561Smsmith return_ACPI_STATUS (AE_OK); 121573561Smsmith } 121673561Smsmith 121773561Smsmith /* 121873561Smsmith * Go back up a level and move the index past the just 121973561Smsmith * completed package object. 122073561Smsmith */ 122173561Smsmith State->Pkg.Index++; 122273561Smsmith } 122373561Smsmith } 122473561Smsmith else 122573561Smsmith { 122687031Smsmith /* This is a subobject of type package */ 122773561Smsmith 122877424Smsmith Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj, 122977424Smsmith State, Context); 123073561Smsmith if (ACPI_FAILURE (Status)) 123173561Smsmith { 123273561Smsmith return_ACPI_STATUS (Status); 123373561Smsmith } 123473561Smsmith 123577424Smsmith /* 123687031Smsmith * Push the current state and create a new one 123773561Smsmith * The callback above returned a new target package object. 123873561Smsmith */ 123977424Smsmith AcpiUtPushGenericState (&StateList, State); 124077424Smsmith State = AcpiUtCreatePkgState (ThisSourceObj, 124177424Smsmith State->Pkg.ThisTargetObj, 0); 124273561Smsmith if (!State) 124373561Smsmith { 1244193267Sjkim /* Free any stacked Update State objects */ 1245193267Sjkim 1246193267Sjkim while (StateList) 1247193267Sjkim { 1248193267Sjkim State = AcpiUtPopGenericState (&StateList); 1249193267Sjkim AcpiUtDeleteGenericState (State); 1250193267Sjkim } 125173561Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 125273561Smsmith } 125373561Smsmith } 125473561Smsmith } 125573561Smsmith 125673561Smsmith /* We should never get here */ 125773561Smsmith 125887031Smsmith return_ACPI_STATUS (AE_AML_INTERNAL); 125973561Smsmith} 126073561Smsmith 126173561Smsmith 1262