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