xref: /onnv-gate/usr/src/uts/intel/io/acpica/namespace/nsxfname.c (revision 11225:eb6056029d84)
13446Smrj /******************************************************************************
23446Smrj  *
33446Smrj  * Module Name: nsxfname - Public interfaces to the ACPI subsystem
43446Smrj  *                         ACPI Namespace oriented interfaces
53446Smrj  *
63446Smrj  *****************************************************************************/
73446Smrj 
83446Smrj /******************************************************************************
93446Smrj  *
103446Smrj  * 1. Copyright Notice
113446Smrj  *
129980SDana.Myers@Sun.COM  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
133446Smrj  * All rights reserved.
143446Smrj  *
153446Smrj  * 2. License
163446Smrj  *
173446Smrj  * 2.1. This is your license from Intel Corp. under its intellectual property
183446Smrj  * rights.  You may have additional license terms from the party that provided
193446Smrj  * you this software, covering your right to use that party's intellectual
203446Smrj  * property rights.
213446Smrj  *
223446Smrj  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
233446Smrj  * copy of the source code appearing in this file ("Covered Code") an
243446Smrj  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
253446Smrj  * base code distributed originally by Intel ("Original Intel Code") to copy,
263446Smrj  * make derivatives, distribute, use and display any portion of the Covered
273446Smrj  * Code in any form, with the right to sublicense such rights; and
283446Smrj  *
293446Smrj  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
303446Smrj  * license (with the right to sublicense), under only those claims of Intel
313446Smrj  * patents that are infringed by the Original Intel Code, to make, use, sell,
323446Smrj  * offer to sell, and import the Covered Code and derivative works thereof
333446Smrj  * solely to the minimum extent necessary to exercise the above copyright
343446Smrj  * license, and in no event shall the patent license extend to any additions
353446Smrj  * to or modifications of the Original Intel Code.  No other license or right
363446Smrj  * is granted directly or by implication, estoppel or otherwise;
373446Smrj  *
383446Smrj  * The above copyright and patent license is granted only if the following
393446Smrj  * conditions are met:
403446Smrj  *
413446Smrj  * 3. Conditions
423446Smrj  *
433446Smrj  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
443446Smrj  * Redistribution of source code of any substantial portion of the Covered
453446Smrj  * Code or modification with rights to further distribute source must include
463446Smrj  * the above Copyright Notice, the above License, this list of Conditions,
473446Smrj  * and the following Disclaimer and Export Compliance provision.  In addition,
483446Smrj  * Licensee must cause all Covered Code to which Licensee contributes to
493446Smrj  * contain a file documenting the changes Licensee made to create that Covered
503446Smrj  * Code and the date of any change.  Licensee must include in that file the
513446Smrj  * documentation of any changes made by any predecessor Licensee.  Licensee
523446Smrj  * must include a prominent statement that the modification is derived,
533446Smrj  * directly or indirectly, from Original Intel Code.
543446Smrj  *
553446Smrj  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
563446Smrj  * Redistribution of source code of any substantial portion of the Covered
573446Smrj  * Code or modification without rights to further distribute source must
583446Smrj  * include the following Disclaimer and Export Compliance provision in the
593446Smrj  * documentation and/or other materials provided with distribution.  In
603446Smrj  * addition, Licensee may not authorize further sublicense of source of any
613446Smrj  * portion of the Covered Code, and must include terms to the effect that the
623446Smrj  * license from Licensee to its licensee is limited to the intellectual
633446Smrj  * property embodied in the software Licensee provides to its licensee, and
643446Smrj  * not to intellectual property embodied in modifications its licensee may
653446Smrj  * make.
663446Smrj  *
673446Smrj  * 3.3. Redistribution of Executable. Redistribution in executable form of any
683446Smrj  * substantial portion of the Covered Code or modification must reproduce the
693446Smrj  * above Copyright Notice, and the following Disclaimer and Export Compliance
703446Smrj  * provision in the documentation and/or other materials provided with the
713446Smrj  * distribution.
723446Smrj  *
733446Smrj  * 3.4. Intel retains all right, title, and interest in and to the Original
743446Smrj  * Intel Code.
753446Smrj  *
763446Smrj  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
773446Smrj  * Intel shall be used in advertising or otherwise to promote the sale, use or
783446Smrj  * other dealings in products derived from or relating to the Covered Code
793446Smrj  * without prior written authorization from Intel.
803446Smrj  *
813446Smrj  * 4. Disclaimer and Export Compliance
823446Smrj  *
833446Smrj  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
843446Smrj  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
853446Smrj  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
863446Smrj  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
873446Smrj  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
883446Smrj  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
893446Smrj  * PARTICULAR PURPOSE.
903446Smrj  *
913446Smrj  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
923446Smrj  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
933446Smrj  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
943446Smrj  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
953446Smrj  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
963446Smrj  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
973446Smrj  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
983446Smrj  * LIMITED REMEDY.
993446Smrj  *
1003446Smrj  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1013446Smrj  * software or system incorporating such software without first obtaining any
1023446Smrj  * required license or other approval from the U. S. Department of Commerce or
1033446Smrj  * any other agency or department of the United States Government.  In the
1043446Smrj  * event Licensee exports any such software from the United States or
1053446Smrj  * re-exports any such software from a foreign destination, Licensee shall
1063446Smrj  * ensure that the distribution and export/re-export of the software is in
1073446Smrj  * compliance with all laws, regulations, orders, or other restrictions of the
1083446Smrj  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1093446Smrj  * any of its subsidiaries will export/re-export any technical data, process,
1103446Smrj  * software, or service, directly or indirectly, to any country for which the
1113446Smrj  * United States government or any agency thereof requires an export license,
1123446Smrj  * other governmental approval, or letter of assurance, without first obtaining
1133446Smrj  * such license, approval or letter.
1143446Smrj  *
1153446Smrj  *****************************************************************************/
1163446Smrj 
1173446Smrj #define __NSXFNAME_C__
1183446Smrj 
1193446Smrj #include "acpi.h"
1209980SDana.Myers@Sun.COM #include "accommon.h"
1213446Smrj #include "acnamesp.h"
1229980SDana.Myers@Sun.COM #include "acparser.h"
1239980SDana.Myers@Sun.COM #include "amlcode.h"
1243446Smrj 
1253446Smrj 
1263446Smrj #define _COMPONENT          ACPI_NAMESPACE
1273446Smrj         ACPI_MODULE_NAME    ("nsxfname")
1283446Smrj 
129*11225SDana.Myers@Sun.COM /* Local prototypes */
130*11225SDana.Myers@Sun.COM 
131*11225SDana.Myers@Sun.COM static char *
132*11225SDana.Myers@Sun.COM AcpiNsCopyDeviceId (
133*11225SDana.Myers@Sun.COM     ACPI_DEVICE_ID          *Dest,
134*11225SDana.Myers@Sun.COM     ACPI_DEVICE_ID          *Source,
135*11225SDana.Myers@Sun.COM     char                    *StringArea);
136*11225SDana.Myers@Sun.COM 
1373446Smrj 
1383446Smrj /******************************************************************************
1393446Smrj  *
1403446Smrj  * FUNCTION:    AcpiGetHandle
1413446Smrj  *
1423446Smrj  * PARAMETERS:  Parent          - Object to search under (search scope).
1433446Smrj  *              Pathname        - Pointer to an asciiz string containing the
1443446Smrj  *                                name
1453446Smrj  *              RetHandle       - Where the return handle is returned
1463446Smrj  *
1473446Smrj  * RETURN:      Status
1483446Smrj  *
1493446Smrj  * DESCRIPTION: This routine will search for a caller specified name in the
1503446Smrj  *              name space.  The caller can restrict the search region by
1513446Smrj  *              specifying a non NULL parent.  The parent value is itself a
1523446Smrj  *              namespace handle.
1533446Smrj  *
1543446Smrj  ******************************************************************************/
1553446Smrj 
1563446Smrj ACPI_STATUS
AcpiGetHandle(ACPI_HANDLE Parent,ACPI_STRING Pathname,ACPI_HANDLE * RetHandle)1573446Smrj AcpiGetHandle (
1583446Smrj     ACPI_HANDLE             Parent,
1593446Smrj     ACPI_STRING             Pathname,
1603446Smrj     ACPI_HANDLE             *RetHandle)
1613446Smrj {
1623446Smrj     ACPI_STATUS             Status;
1633446Smrj     ACPI_NAMESPACE_NODE     *Node = NULL;
1643446Smrj     ACPI_NAMESPACE_NODE     *PrefixNode = NULL;
1653446Smrj 
1663446Smrj 
1673446Smrj     ACPI_FUNCTION_ENTRY ();
1683446Smrj 
1693446Smrj 
1703446Smrj     /* Parameter Validation */
1713446Smrj 
1723446Smrj     if (!RetHandle || !Pathname)
1733446Smrj     {
1743446Smrj         return (AE_BAD_PARAMETER);
1753446Smrj     }
1763446Smrj 
1773446Smrj     /* Convert a parent handle to a prefix node */
1783446Smrj 
1793446Smrj     if (Parent)
1803446Smrj     {
1813446Smrj         PrefixNode = AcpiNsMapHandleToNode (Parent);
1823446Smrj         if (!PrefixNode)
1833446Smrj         {
1843446Smrj             return (AE_BAD_PARAMETER);
1853446Smrj         }
1863446Smrj     }
1873446Smrj 
1887851SDana.Myers@Sun.COM     /*
1897851SDana.Myers@Sun.COM      * Valid cases are:
1907851SDana.Myers@Sun.COM      * 1) Fully qualified pathname
1917851SDana.Myers@Sun.COM      * 2) Parent + Relative pathname
1927851SDana.Myers@Sun.COM      *
1937851SDana.Myers@Sun.COM      * Error for <null Parent + relative path>
1947851SDana.Myers@Sun.COM      */
1957851SDana.Myers@Sun.COM     if (AcpiNsValidRootPrefix (Pathname[0]))
1967851SDana.Myers@Sun.COM     {
1977851SDana.Myers@Sun.COM         /* Pathname is fully qualified (starts with '\') */
1983446Smrj 
1997851SDana.Myers@Sun.COM         /* Special case for root-only, since we can't search for it */
2007851SDana.Myers@Sun.COM 
2017851SDana.Myers@Sun.COM         if (!ACPI_STRCMP (Pathname, ACPI_NS_ROOT_PATH))
2027851SDana.Myers@Sun.COM         {
2037851SDana.Myers@Sun.COM             *RetHandle = AcpiNsConvertEntryToHandle (AcpiGbl_RootNode);
2047851SDana.Myers@Sun.COM             return (AE_OK);
2057851SDana.Myers@Sun.COM         }
2067851SDana.Myers@Sun.COM     }
2077851SDana.Myers@Sun.COM     else if (!PrefixNode)
2083446Smrj     {
2097851SDana.Myers@Sun.COM         /* Relative path with null prefix is disallowed */
2107851SDana.Myers@Sun.COM 
2117851SDana.Myers@Sun.COM         return (AE_BAD_PARAMETER);
2123446Smrj     }
2133446Smrj 
2147851SDana.Myers@Sun.COM     /* Find the Node and convert to a handle */
2153446Smrj 
2167851SDana.Myers@Sun.COM     Status = AcpiNsGetNode (PrefixNode, Pathname, ACPI_NS_NO_UPSEARCH, &Node);
2173446Smrj     if (ACPI_SUCCESS (Status))
2183446Smrj     {
2193446Smrj         *RetHandle = AcpiNsConvertEntryToHandle (Node);
2203446Smrj     }
2213446Smrj 
2223446Smrj     return (Status);
2233446Smrj }
2243446Smrj 
ACPI_EXPORT_SYMBOL(AcpiGetHandle)2253446Smrj ACPI_EXPORT_SYMBOL (AcpiGetHandle)
2263446Smrj 
2273446Smrj 
2283446Smrj /******************************************************************************
2293446Smrj  *
2303446Smrj  * FUNCTION:    AcpiGetName
2313446Smrj  *
2323446Smrj  * PARAMETERS:  Handle          - Handle to be converted to a pathname
2333446Smrj  *              NameType        - Full pathname or single segment
2343446Smrj  *              Buffer          - Buffer for returned path
2353446Smrj  *
2363446Smrj  * RETURN:      Pointer to a string containing the fully qualified Name.
2373446Smrj  *
2383446Smrj  * DESCRIPTION: This routine returns the fully qualified name associated with
2393446Smrj  *              the Handle parameter.  This and the AcpiPathnameToHandle are
2403446Smrj  *              complementary functions.
2413446Smrj  *
2423446Smrj  ******************************************************************************/
2433446Smrj 
2443446Smrj ACPI_STATUS
2453446Smrj AcpiGetName (
2463446Smrj     ACPI_HANDLE             Handle,
2473446Smrj     UINT32                  NameType,
2483446Smrj     ACPI_BUFFER             *Buffer)
2493446Smrj {
2503446Smrj     ACPI_STATUS             Status;
2513446Smrj     ACPI_NAMESPACE_NODE     *Node;
2523446Smrj 
2533446Smrj 
2543446Smrj     /* Parameter validation */
2553446Smrj 
2563446Smrj     if (NameType > ACPI_NAME_TYPE_MAX)
2573446Smrj     {
2583446Smrj         return (AE_BAD_PARAMETER);
2593446Smrj     }
2603446Smrj 
2613446Smrj     Status = AcpiUtValidateBuffer (Buffer);
2623446Smrj     if (ACPI_FAILURE (Status))
2633446Smrj     {
2643446Smrj         return (Status);
2653446Smrj     }
2663446Smrj 
2673446Smrj     if (NameType == ACPI_FULL_PATHNAME)
2683446Smrj     {
2693446Smrj         /* Get the full pathname (From the namespace root) */
2703446Smrj 
2713446Smrj         Status = AcpiNsHandleToPathname (Handle, Buffer);
2723446Smrj         return (Status);
2733446Smrj     }
2743446Smrj 
2753446Smrj     /*
2763446Smrj      * Wants the single segment ACPI name.
2773446Smrj      * Validate handle and convert to a namespace Node
2783446Smrj      */
2793446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
2803446Smrj     if (ACPI_FAILURE (Status))
2813446Smrj     {
2823446Smrj         return (Status);
2833446Smrj     }
2843446Smrj 
2853446Smrj     Node = AcpiNsMapHandleToNode (Handle);
2863446Smrj     if (!Node)
2873446Smrj     {
2883446Smrj         Status = AE_BAD_PARAMETER;
2893446Smrj         goto UnlockAndExit;
2903446Smrj     }
2913446Smrj 
2923446Smrj     /* Validate/Allocate/Clear caller buffer */
2933446Smrj 
2943446Smrj     Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH);
2953446Smrj     if (ACPI_FAILURE (Status))
2963446Smrj     {
2973446Smrj         goto UnlockAndExit;
2983446Smrj     }
2993446Smrj 
3003446Smrj     /* Just copy the ACPI name from the Node and zero terminate it */
3013446Smrj 
3023446Smrj     ACPI_STRNCPY (Buffer->Pointer, AcpiUtGetNodeName (Node),
3033446Smrj                 ACPI_NAME_SIZE);
3043446Smrj     ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0;
3053446Smrj     Status = AE_OK;
3063446Smrj 
3073446Smrj 
3083446Smrj UnlockAndExit:
3093446Smrj 
3103446Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
3113446Smrj     return (Status);
3123446Smrj }
3133446Smrj 
ACPI_EXPORT_SYMBOL(AcpiGetName)3143446Smrj ACPI_EXPORT_SYMBOL (AcpiGetName)
3153446Smrj 
3163446Smrj 
3173446Smrj /******************************************************************************
3183446Smrj  *
319*11225SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsCopyDeviceId
320*11225SDana.Myers@Sun.COM  *
321*11225SDana.Myers@Sun.COM  * PARAMETERS:  Dest                - Pointer to the destination DEVICE_ID
322*11225SDana.Myers@Sun.COM  *              Source              - Pointer to the source DEVICE_ID
323*11225SDana.Myers@Sun.COM  *              StringArea          - Pointer to where to copy the dest string
324*11225SDana.Myers@Sun.COM  *
325*11225SDana.Myers@Sun.COM  * RETURN:      Pointer to the next string area
326*11225SDana.Myers@Sun.COM  *
327*11225SDana.Myers@Sun.COM  * DESCRIPTION: Copy a single DEVICE_ID, including the string data.
328*11225SDana.Myers@Sun.COM  *
329*11225SDana.Myers@Sun.COM  ******************************************************************************/
330*11225SDana.Myers@Sun.COM 
331*11225SDana.Myers@Sun.COM static char *
332*11225SDana.Myers@Sun.COM AcpiNsCopyDeviceId (
333*11225SDana.Myers@Sun.COM     ACPI_DEVICE_ID          *Dest,
334*11225SDana.Myers@Sun.COM     ACPI_DEVICE_ID          *Source,
335*11225SDana.Myers@Sun.COM     char                    *StringArea)
336*11225SDana.Myers@Sun.COM {
337*11225SDana.Myers@Sun.COM     /* Create the destination DEVICE_ID */
338*11225SDana.Myers@Sun.COM 
339*11225SDana.Myers@Sun.COM     Dest->String = StringArea;
340*11225SDana.Myers@Sun.COM     Dest->Length = Source->Length;
341*11225SDana.Myers@Sun.COM 
342*11225SDana.Myers@Sun.COM     /* Copy actual string and return a pointer to the next string area */
343*11225SDana.Myers@Sun.COM 
344*11225SDana.Myers@Sun.COM     ACPI_MEMCPY (StringArea, Source->String, Source->Length);
345*11225SDana.Myers@Sun.COM     return (StringArea + Source->Length);
346*11225SDana.Myers@Sun.COM }
347*11225SDana.Myers@Sun.COM 
348*11225SDana.Myers@Sun.COM 
349*11225SDana.Myers@Sun.COM /******************************************************************************
350*11225SDana.Myers@Sun.COM  *
3513446Smrj  * FUNCTION:    AcpiGetObjectInfo
3523446Smrj  *
353*11225SDana.Myers@Sun.COM  * PARAMETERS:  Handle              - Object Handle
354*11225SDana.Myers@Sun.COM  *              ReturnBuffer        - Where the info is returned
3553446Smrj  *
3563446Smrj  * RETURN:      Status
3573446Smrj  *
3583446Smrj  * DESCRIPTION: Returns information about an object as gleaned from the
3593446Smrj  *              namespace node and possibly by running several standard
3603446Smrj  *              control methods (Such as in the case of a device.)
3613446Smrj  *
362*11225SDana.Myers@Sun.COM  * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA,
363*11225SDana.Myers@Sun.COM  * _ADR, _SxW, and _SxD methods.
364*11225SDana.Myers@Sun.COM  *
365*11225SDana.Myers@Sun.COM  * Note: Allocates the return buffer, must be freed by the caller.
366*11225SDana.Myers@Sun.COM  *
3673446Smrj  ******************************************************************************/
3683446Smrj 
3693446Smrj ACPI_STATUS
AcpiGetObjectInfo(ACPI_HANDLE Handle,ACPI_DEVICE_INFO ** ReturnBuffer)3703446Smrj AcpiGetObjectInfo (
3713446Smrj     ACPI_HANDLE             Handle,
372*11225SDana.Myers@Sun.COM     ACPI_DEVICE_INFO        **ReturnBuffer)
3733446Smrj {
3743446Smrj     ACPI_NAMESPACE_NODE     *Node;
3753446Smrj     ACPI_DEVICE_INFO        *Info;
376*11225SDana.Myers@Sun.COM     ACPI_DEVICE_ID_LIST     *CidList = NULL;
377*11225SDana.Myers@Sun.COM     ACPI_DEVICE_ID          *Hid = NULL;
378*11225SDana.Myers@Sun.COM     ACPI_DEVICE_ID          *Uid = NULL;
379*11225SDana.Myers@Sun.COM     char                    *NextIdString;
380*11225SDana.Myers@Sun.COM     ACPI_OBJECT_TYPE        Type;
381*11225SDana.Myers@Sun.COM     ACPI_NAME               Name;
382*11225SDana.Myers@Sun.COM     UINT8                   ParamCount= 0;
383*11225SDana.Myers@Sun.COM     UINT8                   Valid = 0;
384*11225SDana.Myers@Sun.COM     UINT32                  InfoSize;
385*11225SDana.Myers@Sun.COM     UINT32                  i;
386*11225SDana.Myers@Sun.COM     ACPI_STATUS             Status;
3873446Smrj 
3883446Smrj 
3893446Smrj     /* Parameter validation */
3903446Smrj 
391*11225SDana.Myers@Sun.COM     if (!Handle || !ReturnBuffer)
3923446Smrj     {
3933446Smrj         return (AE_BAD_PARAMETER);
3943446Smrj     }
3953446Smrj 
3963446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
3973446Smrj     if (ACPI_FAILURE (Status))
3983446Smrj     {
3993446Smrj         goto Cleanup;
4003446Smrj     }
4013446Smrj 
4023446Smrj     Node = AcpiNsMapHandleToNode (Handle);
4033446Smrj     if (!Node)
4043446Smrj     {
4053446Smrj         (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
406*11225SDana.Myers@Sun.COM         return (AE_BAD_PARAMETER);
4073446Smrj     }
4083446Smrj 
409*11225SDana.Myers@Sun.COM     /* Get the namespace node data while the namespace is locked */
4103446Smrj 
411*11225SDana.Myers@Sun.COM     InfoSize = sizeof (ACPI_DEVICE_INFO);
412*11225SDana.Myers@Sun.COM     Type = Node->Type;
413*11225SDana.Myers@Sun.COM     Name = Node->Name.Integer;
4143446Smrj 
4157851SDana.Myers@Sun.COM     if (Node->Type == ACPI_TYPE_METHOD)
4167851SDana.Myers@Sun.COM     {
417*11225SDana.Myers@Sun.COM         ParamCount = Node->Object->Method.ParamCount;
4187851SDana.Myers@Sun.COM     }
4197851SDana.Myers@Sun.COM 
4203446Smrj     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
4213446Smrj     if (ACPI_FAILURE (Status))
4223446Smrj     {
423*11225SDana.Myers@Sun.COM         return (Status);
4243446Smrj     }
4253446Smrj 
426*11225SDana.Myers@Sun.COM     if ((Type == ACPI_TYPE_DEVICE) ||
427*11225SDana.Myers@Sun.COM         (Type == ACPI_TYPE_PROCESSOR))
4283446Smrj     {
4293446Smrj         /*
430*11225SDana.Myers@Sun.COM          * Get extra info for ACPI Device/Processor objects only:
431*11225SDana.Myers@Sun.COM          * Run the Device _HID, _UID, and _CID methods.
4323446Smrj          *
4333446Smrj          * Note: none of these methods are required, so they may or may
434*11225SDana.Myers@Sun.COM          * not be present for this device. The Info->Valid bitfield is used
435*11225SDana.Myers@Sun.COM          * to indicate which methods were found and run successfully.
4363446Smrj          */
4373446Smrj 
4383446Smrj         /* Execute the Device._HID method */
4393446Smrj 
440*11225SDana.Myers@Sun.COM         Status = AcpiUtExecute_HID (Node, &Hid);
4413446Smrj         if (ACPI_SUCCESS (Status))
4423446Smrj         {
443*11225SDana.Myers@Sun.COM             InfoSize += Hid->Length;
444*11225SDana.Myers@Sun.COM             Valid |= ACPI_VALID_HID;
4453446Smrj         }
4463446Smrj 
4473446Smrj         /* Execute the Device._UID method */
4483446Smrj 
449*11225SDana.Myers@Sun.COM         Status = AcpiUtExecute_UID (Node, &Uid);
4503446Smrj         if (ACPI_SUCCESS (Status))
4513446Smrj         {
452*11225SDana.Myers@Sun.COM             InfoSize += Uid->Length;
453*11225SDana.Myers@Sun.COM             Valid |= ACPI_VALID_UID;
4543446Smrj         }
4553446Smrj 
4563446Smrj         /* Execute the Device._CID method */
4573446Smrj 
4583446Smrj         Status = AcpiUtExecute_CID (Node, &CidList);
4593446Smrj         if (ACPI_SUCCESS (Status))
4603446Smrj         {
461*11225SDana.Myers@Sun.COM             /* Add size of CID strings and CID pointer array */
462*11225SDana.Myers@Sun.COM 
463*11225SDana.Myers@Sun.COM             InfoSize += (CidList->ListSize - sizeof (ACPI_DEVICE_ID_LIST));
464*11225SDana.Myers@Sun.COM             Valid |= ACPI_VALID_CID;
4653446Smrj         }
466*11225SDana.Myers@Sun.COM     }
467*11225SDana.Myers@Sun.COM 
468*11225SDana.Myers@Sun.COM     /*
469*11225SDana.Myers@Sun.COM      * Now that we have the variable-length data, we can allocate the
470*11225SDana.Myers@Sun.COM      * return buffer
471*11225SDana.Myers@Sun.COM      */
472*11225SDana.Myers@Sun.COM     Info = ACPI_ALLOCATE_ZEROED (InfoSize);
473*11225SDana.Myers@Sun.COM     if (!Info)
474*11225SDana.Myers@Sun.COM     {
475*11225SDana.Myers@Sun.COM         Status = AE_NO_MEMORY;
476*11225SDana.Myers@Sun.COM         goto Cleanup;
477*11225SDana.Myers@Sun.COM     }
478*11225SDana.Myers@Sun.COM 
479*11225SDana.Myers@Sun.COM     /* Get the fixed-length data */
480*11225SDana.Myers@Sun.COM 
481*11225SDana.Myers@Sun.COM     if ((Type == ACPI_TYPE_DEVICE) ||
482*11225SDana.Myers@Sun.COM         (Type == ACPI_TYPE_PROCESSOR))
483*11225SDana.Myers@Sun.COM     {
484*11225SDana.Myers@Sun.COM         /*
485*11225SDana.Myers@Sun.COM          * Get extra info for ACPI Device/Processor objects only:
486*11225SDana.Myers@Sun.COM          * Run the _STA, _ADR and, SxW, and _SxD methods.
487*11225SDana.Myers@Sun.COM          *
488*11225SDana.Myers@Sun.COM          * Note: none of these methods are required, so they may or may
489*11225SDana.Myers@Sun.COM          * not be present for this device. The Info->Valid bitfield is used
490*11225SDana.Myers@Sun.COM          * to indicate which methods were found and run successfully.
491*11225SDana.Myers@Sun.COM          */
4923446Smrj 
4933446Smrj         /* Execute the Device._STA method */
4943446Smrj 
4953446Smrj         Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus);
4963446Smrj         if (ACPI_SUCCESS (Status))
4973446Smrj         {
498*11225SDana.Myers@Sun.COM             Valid |= ACPI_VALID_STA;
4993446Smrj         }
5003446Smrj 
5013446Smrj         /* Execute the Device._ADR method */
5023446Smrj 
5033446Smrj         Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node,
504*11225SDana.Myers@Sun.COM                     &Info->Address);
5053446Smrj         if (ACPI_SUCCESS (Status))
5063446Smrj         {
507*11225SDana.Myers@Sun.COM             Valid |= ACPI_VALID_ADR;
508*11225SDana.Myers@Sun.COM         }
509*11225SDana.Myers@Sun.COM 
510*11225SDana.Myers@Sun.COM         /* Execute the Device._SxW methods */
511*11225SDana.Myers@Sun.COM 
512*11225SDana.Myers@Sun.COM         Status = AcpiUtExecutePowerMethods (Node,
513*11225SDana.Myers@Sun.COM                     AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS,
514*11225SDana.Myers@Sun.COM                     Info->LowestDstates);
515*11225SDana.Myers@Sun.COM         if (ACPI_SUCCESS (Status))
516*11225SDana.Myers@Sun.COM         {
517*11225SDana.Myers@Sun.COM             Valid |= ACPI_VALID_SXWS;
5183446Smrj         }
5193446Smrj 
5203446Smrj         /* Execute the Device._SxD methods */
5213446Smrj 
522*11225SDana.Myers@Sun.COM         Status = AcpiUtExecutePowerMethods (Node,
523*11225SDana.Myers@Sun.COM                     AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS,
524*11225SDana.Myers@Sun.COM                     Info->HighestDstates);
5253446Smrj         if (ACPI_SUCCESS (Status))
5263446Smrj         {
527*11225SDana.Myers@Sun.COM             Valid |= ACPI_VALID_SXDS;
528*11225SDana.Myers@Sun.COM         }
529*11225SDana.Myers@Sun.COM     }
530*11225SDana.Myers@Sun.COM 
531*11225SDana.Myers@Sun.COM     /*
532*11225SDana.Myers@Sun.COM      * Create a pointer to the string area of the return buffer.
533*11225SDana.Myers@Sun.COM      * Point to the end of the base ACPI_DEVICE_INFO structure.
534*11225SDana.Myers@Sun.COM      */
535*11225SDana.Myers@Sun.COM     NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids);
536*11225SDana.Myers@Sun.COM     if (CidList)
537*11225SDana.Myers@Sun.COM     {
538*11225SDana.Myers@Sun.COM         /* Point past the CID DEVICE_ID array */
539*11225SDana.Myers@Sun.COM 
540*11225SDana.Myers@Sun.COM         NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_DEVICE_ID));
541*11225SDana.Myers@Sun.COM     }
542*11225SDana.Myers@Sun.COM 
543*11225SDana.Myers@Sun.COM     /*
544*11225SDana.Myers@Sun.COM      * Copy the HID, UID, and CIDs to the return buffer. The variable-length
545*11225SDana.Myers@Sun.COM      * strings are copied to the reserved area at the end of the buffer.
546*11225SDana.Myers@Sun.COM      *
547*11225SDana.Myers@Sun.COM      * For HID and CID, check if the ID is a PCI Root Bridge.
548*11225SDana.Myers@Sun.COM      */
549*11225SDana.Myers@Sun.COM     if (Hid)
550*11225SDana.Myers@Sun.COM     {
551*11225SDana.Myers@Sun.COM         NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId,
552*11225SDana.Myers@Sun.COM             Hid, NextIdString);
553*11225SDana.Myers@Sun.COM 
554*11225SDana.Myers@Sun.COM         if (AcpiUtIsPciRootBridge (Hid->String))
555*11225SDana.Myers@Sun.COM         {
556*11225SDana.Myers@Sun.COM             Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
5573446Smrj         }
5583446Smrj     }
5593446Smrj 
560*11225SDana.Myers@Sun.COM     if (Uid)
5613446Smrj     {
562*11225SDana.Myers@Sun.COM         NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId,
563*11225SDana.Myers@Sun.COM             Uid, NextIdString);
5643446Smrj     }
5653446Smrj 
5663446Smrj     if (CidList)
5673446Smrj     {
568*11225SDana.Myers@Sun.COM         Info->CompatibleIdList.Count = CidList->Count;
569*11225SDana.Myers@Sun.COM         Info->CompatibleIdList.ListSize = CidList->ListSize;
570*11225SDana.Myers@Sun.COM 
571*11225SDana.Myers@Sun.COM         /* Copy each CID */
572*11225SDana.Myers@Sun.COM 
573*11225SDana.Myers@Sun.COM         for (i = 0; i < CidList->Count; i++)
574*11225SDana.Myers@Sun.COM         {
575*11225SDana.Myers@Sun.COM             NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i],
576*11225SDana.Myers@Sun.COM                 &CidList->Ids[i], NextIdString);
577*11225SDana.Myers@Sun.COM 
578*11225SDana.Myers@Sun.COM             if (AcpiUtIsPciRootBridge (CidList->Ids[i].String))
579*11225SDana.Myers@Sun.COM             {
580*11225SDana.Myers@Sun.COM                 Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
581*11225SDana.Myers@Sun.COM             }
582*11225SDana.Myers@Sun.COM         }
5833446Smrj     }
5843446Smrj 
585*11225SDana.Myers@Sun.COM     /* Copy the fixed-length data */
586*11225SDana.Myers@Sun.COM 
587*11225SDana.Myers@Sun.COM     Info->InfoSize = InfoSize;
588*11225SDana.Myers@Sun.COM     Info->Type = Type;
589*11225SDana.Myers@Sun.COM     Info->Name = Name;
590*11225SDana.Myers@Sun.COM     Info->ParamCount = ParamCount;
591*11225SDana.Myers@Sun.COM     Info->Valid = Valid;
592*11225SDana.Myers@Sun.COM 
593*11225SDana.Myers@Sun.COM     *ReturnBuffer = Info;
594*11225SDana.Myers@Sun.COM     Status = AE_OK;
595*11225SDana.Myers@Sun.COM 
5963446Smrj 
5973446Smrj Cleanup:
598*11225SDana.Myers@Sun.COM     if (Hid)
599*11225SDana.Myers@Sun.COM     {
600*11225SDana.Myers@Sun.COM         ACPI_FREE (Hid);
601*11225SDana.Myers@Sun.COM     }
602*11225SDana.Myers@Sun.COM     if (Uid)
603*11225SDana.Myers@Sun.COM     {
604*11225SDana.Myers@Sun.COM         ACPI_FREE (Uid);
605*11225SDana.Myers@Sun.COM     }
6063446Smrj     if (CidList)
6073446Smrj     {
6083446Smrj         ACPI_FREE (CidList);
6093446Smrj     }
6103446Smrj     return (Status);
6113446Smrj }
6123446Smrj 
ACPI_EXPORT_SYMBOL(AcpiGetObjectInfo)6133446Smrj ACPI_EXPORT_SYMBOL (AcpiGetObjectInfo)
6143446Smrj 
6159980SDana.Myers@Sun.COM 
6169980SDana.Myers@Sun.COM /******************************************************************************
6179980SDana.Myers@Sun.COM  *
6189980SDana.Myers@Sun.COM  * FUNCTION:    AcpiInstallMethod
6199980SDana.Myers@Sun.COM  *
6209980SDana.Myers@Sun.COM  * PARAMETERS:  Buffer         - An ACPI table containing one control method
6219980SDana.Myers@Sun.COM  *
6229980SDana.Myers@Sun.COM  * RETURN:      Status
6239980SDana.Myers@Sun.COM  *
6249980SDana.Myers@Sun.COM  * DESCRIPTION: Install a control method into the namespace. If the method
6259980SDana.Myers@Sun.COM  *              name already exists in the namespace, it is overwritten. The
6269980SDana.Myers@Sun.COM  *              input buffer must contain a valid DSDT or SSDT containing a
6279980SDana.Myers@Sun.COM  *              single control method.
6289980SDana.Myers@Sun.COM  *
6299980SDana.Myers@Sun.COM  ******************************************************************************/
6309980SDana.Myers@Sun.COM 
6319980SDana.Myers@Sun.COM ACPI_STATUS
6329980SDana.Myers@Sun.COM AcpiInstallMethod (
6339980SDana.Myers@Sun.COM     UINT8                   *Buffer)
6349980SDana.Myers@Sun.COM {
6359980SDana.Myers@Sun.COM     ACPI_TABLE_HEADER       *Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Buffer);
6369980SDana.Myers@Sun.COM     UINT8                   *AmlBuffer;
6379980SDana.Myers@Sun.COM     UINT8                   *AmlStart;
6389980SDana.Myers@Sun.COM     char                    *Path;
6399980SDana.Myers@Sun.COM     ACPI_NAMESPACE_NODE     *Node;
6409980SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *MethodObj;
6419980SDana.Myers@Sun.COM     ACPI_PARSE_STATE        ParserState;
6429980SDana.Myers@Sun.COM     UINT32                  AmlLength;
6439980SDana.Myers@Sun.COM     UINT16                  Opcode;
6449980SDana.Myers@Sun.COM     UINT8                   MethodFlags;
6459980SDana.Myers@Sun.COM     ACPI_STATUS             Status;
6469980SDana.Myers@Sun.COM 
6479980SDana.Myers@Sun.COM 
6489980SDana.Myers@Sun.COM     /* Parameter validation */
6499980SDana.Myers@Sun.COM 
6509980SDana.Myers@Sun.COM     if (!Buffer)
6519980SDana.Myers@Sun.COM     {
6529980SDana.Myers@Sun.COM         return (AE_BAD_PARAMETER);
6539980SDana.Myers@Sun.COM     }
6549980SDana.Myers@Sun.COM 
6559980SDana.Myers@Sun.COM     /* Table must be a DSDT or SSDT */
6569980SDana.Myers@Sun.COM 
6579980SDana.Myers@Sun.COM     if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) &&
6589980SDana.Myers@Sun.COM         !ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
6599980SDana.Myers@Sun.COM     {
6609980SDana.Myers@Sun.COM         return (AE_BAD_HEADER);
6619980SDana.Myers@Sun.COM     }
6629980SDana.Myers@Sun.COM 
6639980SDana.Myers@Sun.COM     /* First AML opcode in the table must be a control method */
6649980SDana.Myers@Sun.COM 
6659980SDana.Myers@Sun.COM     ParserState.Aml = Buffer + sizeof (ACPI_TABLE_HEADER);
6669980SDana.Myers@Sun.COM     Opcode = AcpiPsPeekOpcode (&ParserState);
6679980SDana.Myers@Sun.COM     if (Opcode != AML_METHOD_OP)
6689980SDana.Myers@Sun.COM     {
6699980SDana.Myers@Sun.COM         return (AE_BAD_PARAMETER);
6709980SDana.Myers@Sun.COM     }
6719980SDana.Myers@Sun.COM 
6729980SDana.Myers@Sun.COM     /* Extract method information from the raw AML */
6739980SDana.Myers@Sun.COM 
6749980SDana.Myers@Sun.COM     ParserState.Aml += AcpiPsGetOpcodeSize (Opcode);
6759980SDana.Myers@Sun.COM     ParserState.PkgEnd = AcpiPsGetNextPackageEnd (&ParserState);
6769980SDana.Myers@Sun.COM     Path = AcpiPsGetNextNamestring (&ParserState);
6779980SDana.Myers@Sun.COM     MethodFlags = *ParserState.Aml++;
6789980SDana.Myers@Sun.COM     AmlStart = ParserState.Aml;
6799980SDana.Myers@Sun.COM     AmlLength = ACPI_PTR_DIFF (ParserState.PkgEnd, AmlStart);
6809980SDana.Myers@Sun.COM 
6819980SDana.Myers@Sun.COM     /*
6829980SDana.Myers@Sun.COM      * Allocate resources up-front. We don't want to have to delete a new
6839980SDana.Myers@Sun.COM      * node from the namespace if we cannot allocate memory.
6849980SDana.Myers@Sun.COM      */
6859980SDana.Myers@Sun.COM     AmlBuffer = ACPI_ALLOCATE (AmlLength);
6869980SDana.Myers@Sun.COM     if (!AmlBuffer)
6879980SDana.Myers@Sun.COM     {
6889980SDana.Myers@Sun.COM         return (AE_NO_MEMORY);
6899980SDana.Myers@Sun.COM     }
6909980SDana.Myers@Sun.COM 
6919980SDana.Myers@Sun.COM     MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
6929980SDana.Myers@Sun.COM     if (!MethodObj)
6939980SDana.Myers@Sun.COM     {
6949980SDana.Myers@Sun.COM         ACPI_FREE (AmlBuffer);
6959980SDana.Myers@Sun.COM         return (AE_NO_MEMORY);
6969980SDana.Myers@Sun.COM     }
6979980SDana.Myers@Sun.COM 
6989980SDana.Myers@Sun.COM     /* Lock namespace for AcpiNsLookup, we may be creating a new node */
6999980SDana.Myers@Sun.COM 
7009980SDana.Myers@Sun.COM     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
7019980SDana.Myers@Sun.COM     if (ACPI_FAILURE (Status))
7029980SDana.Myers@Sun.COM     {
7039980SDana.Myers@Sun.COM         goto ErrorExit;
7049980SDana.Myers@Sun.COM     }
7059980SDana.Myers@Sun.COM 
7069980SDana.Myers@Sun.COM     /* The lookup either returns an existing node or creates a new one */
7079980SDana.Myers@Sun.COM 
7089980SDana.Myers@Sun.COM     Status = AcpiNsLookup (NULL, Path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1,
7099980SDana.Myers@Sun.COM                 ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
7109980SDana.Myers@Sun.COM 
7119980SDana.Myers@Sun.COM     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
7129980SDana.Myers@Sun.COM 
7139980SDana.Myers@Sun.COM     if (ACPI_FAILURE (Status)) /* NsLookup */
7149980SDana.Myers@Sun.COM     {
7159980SDana.Myers@Sun.COM         if (Status != AE_ALREADY_EXISTS)
7169980SDana.Myers@Sun.COM         {
7179980SDana.Myers@Sun.COM             goto ErrorExit;
7189980SDana.Myers@Sun.COM         }
7199980SDana.Myers@Sun.COM 
7209980SDana.Myers@Sun.COM         /* Node existed previously, make sure it is a method node */
7219980SDana.Myers@Sun.COM 
7229980SDana.Myers@Sun.COM         if (Node->Type != ACPI_TYPE_METHOD)
7239980SDana.Myers@Sun.COM         {
7249980SDana.Myers@Sun.COM             Status = AE_TYPE;
7259980SDana.Myers@Sun.COM             goto ErrorExit;
7269980SDana.Myers@Sun.COM         }
7279980SDana.Myers@Sun.COM     }
7289980SDana.Myers@Sun.COM 
7299980SDana.Myers@Sun.COM     /* Copy the method AML to the local buffer */
7309980SDana.Myers@Sun.COM 
7319980SDana.Myers@Sun.COM     ACPI_MEMCPY (AmlBuffer, AmlStart, AmlLength);
7329980SDana.Myers@Sun.COM 
7339980SDana.Myers@Sun.COM     /* Initialize the method object with the new method's information */
7349980SDana.Myers@Sun.COM 
7359980SDana.Myers@Sun.COM     MethodObj->Method.AmlStart = AmlBuffer;
7369980SDana.Myers@Sun.COM     MethodObj->Method.AmlLength = AmlLength;
7379980SDana.Myers@Sun.COM 
7389980SDana.Myers@Sun.COM     MethodObj->Method.ParamCount = (UINT8)
7399980SDana.Myers@Sun.COM         (MethodFlags & AML_METHOD_ARG_COUNT);
7409980SDana.Myers@Sun.COM 
7419980SDana.Myers@Sun.COM     MethodObj->Method.MethodFlags = (UINT8)
7429980SDana.Myers@Sun.COM         (MethodFlags & ~AML_METHOD_ARG_COUNT);
7439980SDana.Myers@Sun.COM 
7449980SDana.Myers@Sun.COM     if (MethodFlags & AML_METHOD_SERIALIZED)
7459980SDana.Myers@Sun.COM     {
7469980SDana.Myers@Sun.COM         MethodObj->Method.SyncLevel = (UINT8)
7479980SDana.Myers@Sun.COM             ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4);
7489980SDana.Myers@Sun.COM     }
7499980SDana.Myers@Sun.COM 
7509980SDana.Myers@Sun.COM     /*
7519980SDana.Myers@Sun.COM      * Now that it is complete, we can attach the new method object to
7529980SDana.Myers@Sun.COM      * the method Node (detaches/deletes any existing object)
7539980SDana.Myers@Sun.COM      */
7549980SDana.Myers@Sun.COM     Status = AcpiNsAttachObject (Node, MethodObj,
7559980SDana.Myers@Sun.COM                 ACPI_TYPE_METHOD);
7569980SDana.Myers@Sun.COM 
7579980SDana.Myers@Sun.COM     /*
7589980SDana.Myers@Sun.COM      * Flag indicates AML buffer is dynamic, must be deleted later.
7599980SDana.Myers@Sun.COM      * Must be set only after attach above.
7609980SDana.Myers@Sun.COM      */
7619980SDana.Myers@Sun.COM     Node->Flags |= ANOBJ_ALLOCATED_BUFFER;
7629980SDana.Myers@Sun.COM 
7639980SDana.Myers@Sun.COM     /* Remove local reference to the method object */
7649980SDana.Myers@Sun.COM 
7659980SDana.Myers@Sun.COM     AcpiUtRemoveReference (MethodObj);
7669980SDana.Myers@Sun.COM     return (Status);
7679980SDana.Myers@Sun.COM 
7689980SDana.Myers@Sun.COM 
7699980SDana.Myers@Sun.COM ErrorExit:
7709980SDana.Myers@Sun.COM 
7719980SDana.Myers@Sun.COM     ACPI_FREE (AmlBuffer);
7729980SDana.Myers@Sun.COM     ACPI_FREE (MethodObj);
7739980SDana.Myers@Sun.COM     return (Status);
7749980SDana.Myers@Sun.COM }
7759980SDana.Myers@Sun.COM 
7769980SDana.Myers@Sun.COM ACPI_EXPORT_SYMBOL (AcpiInstallMethod)
777