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