nsxfobj.c revision 82367
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: nsxfobj - Public interfaces to the ACPI subsystem 467754Smsmith * ACPI Object oriented interfaces 582367Smsmith * $Revision: 88 $ 667754Smsmith * 767754Smsmith ******************************************************************************/ 867754Smsmith 967754Smsmith/****************************************************************************** 1067754Smsmith * 1167754Smsmith * 1. Copyright Notice 1267754Smsmith * 1371867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1470243Smsmith * All rights reserved. 1567754Smsmith * 1667754Smsmith * 2. License 1767754Smsmith * 1867754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1967754Smsmith * rights. You may have additional license terms from the party that provided 2067754Smsmith * you this software, covering your right to use that party's intellectual 2167754Smsmith * property rights. 2267754Smsmith * 2367754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2467754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2567754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2667754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2767754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2867754Smsmith * Code in any form, with the right to sublicense such rights; and 2967754Smsmith * 3067754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3167754Smsmith * license (with the right to sublicense), under only those claims of Intel 3267754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3367754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3467754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3567754Smsmith * license, and in no event shall the patent license extend to any additions 3667754Smsmith * to or modifications of the Original Intel Code. No other license or right 3767754Smsmith * is granted directly or by implication, estoppel or otherwise; 3867754Smsmith * 3967754Smsmith * The above copyright and patent license is granted only if the following 4067754Smsmith * conditions are met: 4167754Smsmith * 4267754Smsmith * 3. Conditions 4367754Smsmith * 4467754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4567754Smsmith * Redistribution of source code of any substantial portion of the Covered 4667754Smsmith * Code or modification with rights to further distribute source must include 4767754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4867754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4967754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 5067754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5167754Smsmith * Code and the date of any change. Licensee must include in that file the 5267754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5367754Smsmith * must include a prominent statement that the modification is derived, 5467754Smsmith * directly or indirectly, from Original Intel Code. 5567754Smsmith * 5667754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5767754Smsmith * Redistribution of source code of any substantial portion of the Covered 5867754Smsmith * Code or modification without rights to further distribute source must 5967754Smsmith * include the following Disclaimer and Export Compliance provision in the 6067754Smsmith * documentation and/or other materials provided with distribution. In 6167754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6267754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6367754Smsmith * license from Licensee to its licensee is limited to the intellectual 6467754Smsmith * property embodied in the software Licensee provides to its licensee, and 6567754Smsmith * not to intellectual property embodied in modifications its licensee may 6667754Smsmith * make. 6767754Smsmith * 6867754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6967754Smsmith * substantial portion of the Covered Code or modification must reproduce the 7067754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7167754Smsmith * provision in the documentation and/or other materials provided with the 7267754Smsmith * distribution. 7367754Smsmith * 7467754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7567754Smsmith * Intel Code. 7667754Smsmith * 7767754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7867754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7967754Smsmith * other dealings in products derived from or relating to the Covered Code 8067754Smsmith * without prior written authorization from Intel. 8167754Smsmith * 8267754Smsmith * 4. Disclaimer and Export Compliance 8367754Smsmith * 8467754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8567754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8667754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8767754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8867754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8967754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9067754Smsmith * PARTICULAR PURPOSE. 9167754Smsmith * 9267754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9367754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9467754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9567754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9667754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9767754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9867754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9967754Smsmith * LIMITED REMEDY. 10067754Smsmith * 10167754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10267754Smsmith * software or system incorporating such software without first obtaining any 10367754Smsmith * required license or other approval from the U. S. Department of Commerce or 10467754Smsmith * any other agency or department of the United States Government. In the 10567754Smsmith * event Licensee exports any such software from the United States or 10667754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10767754Smsmith * ensure that the distribution and export/re-export of the software is in 10867754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10967754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 11067754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11167754Smsmith * software, or service, directly or indirectly, to any country for which the 11267754Smsmith * United States government or any agency thereof requires an export license, 11367754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11467754Smsmith * such license, approval or letter. 11567754Smsmith * 11667754Smsmith *****************************************************************************/ 11767754Smsmith 11867754Smsmith 11967754Smsmith#define __NSXFOBJ_C__ 12067754Smsmith 12167754Smsmith#include "acpi.h" 12267754Smsmith#include "acinterp.h" 12367754Smsmith#include "acnamesp.h" 12467754Smsmith#include "acdispat.h" 12567754Smsmith 12667754Smsmith 12777424Smsmith#define _COMPONENT ACPI_NAMESPACE 12867754Smsmith MODULE_NAME ("nsxfobj") 12967754Smsmith 13067754Smsmith 13167754Smsmith/******************************************************************************* 13267754Smsmith * 13367754Smsmith * FUNCTION: AcpiEvaluateObject 13467754Smsmith * 13567754Smsmith * PARAMETERS: Handle - Object handle (optional) 13667754Smsmith * *Pathname - Object pathname (optional) 13767754Smsmith * **Params - List of parameters to pass to 13867754Smsmith * method, terminated by NULL. 13967754Smsmith * Params itself may be NULL 14067754Smsmith * if no parameters are being 14167754Smsmith * passed. 14267754Smsmith * *ReturnObject - Where to put method's return value (if 14367754Smsmith * any). If NULL, no value is returned. 14467754Smsmith * 14567754Smsmith * RETURN: Status 14667754Smsmith * 14767754Smsmith * DESCRIPTION: Find and evaluate the given object, passing the given 14867754Smsmith * parameters if necessary. One of "Handle" or "Pathname" must 14967754Smsmith * be valid (non-null) 15067754Smsmith * 15167754Smsmith ******************************************************************************/ 15267754Smsmith 15367754SmsmithACPI_STATUS 15467754SmsmithAcpiEvaluateObject ( 15567754Smsmith ACPI_HANDLE Handle, 15667754Smsmith ACPI_STRING Pathname, 15767754Smsmith ACPI_OBJECT_LIST *ParamObjects, 15867754Smsmith ACPI_BUFFER *ReturnBuffer) 15967754Smsmith{ 16067754Smsmith ACPI_STATUS Status; 16167754Smsmith ACPI_OPERAND_OBJECT **ParamPtr = NULL; 16267754Smsmith ACPI_OPERAND_OBJECT *ReturnObj = NULL; 16367754Smsmith ACPI_OPERAND_OBJECT *ObjectPtr = NULL; 16467754Smsmith UINT32 BufferSpaceNeeded; 16567754Smsmith UINT32 UserBufferLength; 16667754Smsmith UINT32 Count; 16767754Smsmith UINT32 i; 16867754Smsmith UINT32 ParamLength; 16967754Smsmith UINT32 ObjectLength; 17067754Smsmith 17167754Smsmith 17267754Smsmith FUNCTION_TRACE ("AcpiEvaluateObject"); 17367754Smsmith 17467754Smsmith 17577424Smsmith /* Ensure that ACPI has been initialized */ 17677424Smsmith 17777424Smsmith ACPI_IS_INITIALIZATION_COMPLETE (Status); 17877424Smsmith if (ACPI_FAILURE (Status)) 17977424Smsmith { 18077424Smsmith return_ACPI_STATUS (Status); 18177424Smsmith } 18277424Smsmith 18367754Smsmith /* 18467754Smsmith * If there are parameters to be passed to the object 18567754Smsmith * (which must be a control method), the external objects 18667754Smsmith * must be converted to internal objects 18767754Smsmith */ 18867754Smsmith 18967754Smsmith if (ParamObjects && ParamObjects->Count) 19067754Smsmith { 19167754Smsmith /* 19267754Smsmith * Allocate a new parameter block for the internal objects 19367754Smsmith * Add 1 to count to allow for null terminated internal list 19467754Smsmith */ 19567754Smsmith 19667754Smsmith Count = ParamObjects->Count; 19767754Smsmith ParamLength = (Count + 1) * sizeof (void *); 19867754Smsmith ObjectLength = Count * sizeof (ACPI_OPERAND_OBJECT); 19967754Smsmith 20080062Smsmith ParamPtr = ACPI_MEM_CALLOCATE (ParamLength + /* Parameter List part */ 20180062Smsmith ObjectLength); /* Actual objects */ 20267754Smsmith if (!ParamPtr) 20367754Smsmith { 20467754Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 20567754Smsmith } 20667754Smsmith 20767754Smsmith ObjectPtr = (ACPI_OPERAND_OBJECT *) ((UINT8 *) ParamPtr + 20867754Smsmith ParamLength); 20967754Smsmith 21067754Smsmith /* 21167754Smsmith * Init the param array of pointers and NULL terminate 21267754Smsmith * the list 21367754Smsmith */ 21467754Smsmith 21567754Smsmith for (i = 0; i < Count; i++) 21667754Smsmith { 21767754Smsmith ParamPtr[i] = &ObjectPtr[i]; 21877424Smsmith AcpiUtInitStaticObject (&ObjectPtr[i]); 21967754Smsmith } 22067754Smsmith ParamPtr[Count] = NULL; 22167754Smsmith 22267754Smsmith /* 22367754Smsmith * Convert each external object in the list to an 22467754Smsmith * internal object 22567754Smsmith */ 22667754Smsmith for (i = 0; i < Count; i++) 22767754Smsmith { 22877424Smsmith Status = AcpiUtCopyEobjectToIobject (&ParamObjects->Pointer[i], 22973561Smsmith ParamPtr[i]); 23067754Smsmith 23167754Smsmith if (ACPI_FAILURE (Status)) 23267754Smsmith { 23377424Smsmith AcpiUtDeleteInternalObjectList (ParamPtr); 23467754Smsmith return_ACPI_STATUS (Status); 23567754Smsmith } 23667754Smsmith } 23767754Smsmith } 23867754Smsmith 23967754Smsmith 24067754Smsmith /* 24167754Smsmith * Three major cases: 24267754Smsmith * 1) Fully qualified pathname 24367754Smsmith * 2) No handle, not fully qualified pathname (error) 24467754Smsmith * 3) Valid handle 24567754Smsmith */ 24667754Smsmith 24767754Smsmith if ((Pathname) && 24867754Smsmith (AcpiNsValidRootPrefix (Pathname[0]))) 24967754Smsmith { 25067754Smsmith /* 25167754Smsmith * The path is fully qualified, just evaluate by name 25267754Smsmith */ 25367754Smsmith Status = AcpiNsEvaluateByName (Pathname, ParamPtr, &ReturnObj); 25467754Smsmith } 25567754Smsmith 25667754Smsmith else if (!Handle) 25767754Smsmith { 25867754Smsmith /* 25967754Smsmith * A handle is optional iff a fully qualified pathname 26067754Smsmith * is specified. Since we've already handled fully 26167754Smsmith * qualified names above, this is an error 26267754Smsmith */ 26367754Smsmith 26467754Smsmith if (!Pathname) 26567754Smsmith { 26682367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Both Handle and Pathname are NULL\n")); 26767754Smsmith } 26867754Smsmith 26967754Smsmith else 27067754Smsmith { 27182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Handle is NULL and Pathname is relative\n")); 27267754Smsmith } 27367754Smsmith 27467754Smsmith Status = AE_BAD_PARAMETER; 27567754Smsmith } 27667754Smsmith 27767754Smsmith else 27867754Smsmith { 27967754Smsmith /* 28067754Smsmith * We get here if we have a handle -- and if we have a 28167754Smsmith * pathname it is relative. The handle will be validated 28267754Smsmith * in the lower procedures 28367754Smsmith */ 28467754Smsmith 28567754Smsmith if (!Pathname) 28667754Smsmith { 28767754Smsmith /* 28867754Smsmith * The null pathname case means the handle is for 28967754Smsmith * the actual object to be evaluated 29067754Smsmith */ 29167754Smsmith Status = AcpiNsEvaluateByHandle (Handle, ParamPtr, &ReturnObj); 29267754Smsmith } 29367754Smsmith 29467754Smsmith else 29567754Smsmith { 29667754Smsmith /* 29767754Smsmith * Both a Handle and a relative Pathname 29867754Smsmith */ 29967754Smsmith Status = AcpiNsEvaluateRelative (Handle, Pathname, ParamPtr, 30067754Smsmith &ReturnObj); 30167754Smsmith } 30267754Smsmith } 30367754Smsmith 30467754Smsmith 30567754Smsmith /* 30667754Smsmith * If we are expecting a return value, and all went well above, 30767754Smsmith * copy the return value to an external object. 30867754Smsmith */ 30967754Smsmith 31067754Smsmith if (ReturnBuffer) 31167754Smsmith { 31267754Smsmith UserBufferLength = ReturnBuffer->Length; 31367754Smsmith ReturnBuffer->Length = 0; 31467754Smsmith 31567754Smsmith if (ReturnObj) 31667754Smsmith { 31767754Smsmith if (VALID_DESCRIPTOR_TYPE (ReturnObj, ACPI_DESC_TYPE_NAMED)) 31867754Smsmith { 31967754Smsmith /* 32067754Smsmith * If we got an Node as a return object, 32167754Smsmith * this means the object we are evaluating 32267754Smsmith * has nothing interesting to return (such 32367754Smsmith * as a mutex, etc.) We return an error 32467754Smsmith * because these types are essentially 32567754Smsmith * unsupported by this interface. We 32667754Smsmith * don't check up front because this makes 32767754Smsmith * it easier to add support for various 32867754Smsmith * types at a later date if necessary. 32967754Smsmith */ 33067754Smsmith Status = AE_TYPE; 33167754Smsmith ReturnObj = NULL; /* No need to delete an Node */ 33267754Smsmith } 33367754Smsmith 33467754Smsmith if (ACPI_SUCCESS (Status)) 33567754Smsmith { 33667754Smsmith /* 33767754Smsmith * Find out how large a buffer is needed 33867754Smsmith * to contain the returned object 33967754Smsmith */ 34077424Smsmith Status = AcpiUtGetObjectSize (ReturnObj, 34167754Smsmith &BufferSpaceNeeded); 34267754Smsmith if (ACPI_SUCCESS (Status)) 34367754Smsmith { 34467754Smsmith /* 34567754Smsmith * Check if there is enough room in the 34667754Smsmith * caller's buffer 34767754Smsmith */ 34867754Smsmith 34967754Smsmith if (UserBufferLength < BufferSpaceNeeded) 35067754Smsmith { 35167754Smsmith /* 35267754Smsmith * Caller's buffer is too small, can't 35367754Smsmith * give him partial results fail the call 35467754Smsmith * but return the buffer size needed 35567754Smsmith */ 35667754Smsmith 35782367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 35882367Smsmith "Needed buffer size %X, received %X\n", 35967754Smsmith BufferSpaceNeeded, UserBufferLength)); 36067754Smsmith 36167754Smsmith ReturnBuffer->Length = BufferSpaceNeeded; 36267754Smsmith Status = AE_BUFFER_OVERFLOW; 36367754Smsmith } 36467754Smsmith 36567754Smsmith else 36667754Smsmith { 36767754Smsmith /* 36867754Smsmith * We have enough space for the object, build it 36967754Smsmith */ 37077424Smsmith Status = AcpiUtCopyIobjectToEobject (ReturnObj, 37167754Smsmith ReturnBuffer); 37267754Smsmith ReturnBuffer->Length = BufferSpaceNeeded; 37367754Smsmith } 37467754Smsmith } 37567754Smsmith } 37667754Smsmith } 37767754Smsmith } 37867754Smsmith 37967754Smsmith 38067754Smsmith /* Delete the return and parameter objects */ 38167754Smsmith 38267754Smsmith if (ReturnObj) 38367754Smsmith { 38467754Smsmith /* 38567754Smsmith * Delete the internal return object. (Or at least 38667754Smsmith * decrement the reference count by one) 38767754Smsmith */ 38877424Smsmith AcpiUtRemoveReference (ReturnObj); 38967754Smsmith } 39067754Smsmith 39167754Smsmith /* 39267754Smsmith * Free the input parameter list (if we created one), 39367754Smsmith */ 39467754Smsmith 39567754Smsmith if (ParamPtr) 39667754Smsmith { 39767754Smsmith /* Free the allocated parameter block */ 39867754Smsmith 39977424Smsmith AcpiUtDeleteInternalObjectList (ParamPtr); 40067754Smsmith } 40167754Smsmith 40267754Smsmith return_ACPI_STATUS (Status); 40367754Smsmith} 40467754Smsmith 40567754Smsmith 40667754Smsmith/******************************************************************************* 40767754Smsmith * 40867754Smsmith * FUNCTION: AcpiGetNextObject 40967754Smsmith * 41067754Smsmith * PARAMETERS: Type - Type of object to be searched for 41167754Smsmith * Parent - Parent object whose children we are getting 41267754Smsmith * LastChild - Previous child that was found. 41367754Smsmith * The NEXT child will be returned 41467754Smsmith * RetHandle - Where handle to the next object is placed 41567754Smsmith * 41667754Smsmith * RETURN: Status 41767754Smsmith * 41867754Smsmith * DESCRIPTION: Return the next peer object within the namespace. If Handle is 41967754Smsmith * valid, Scope is ignored. Otherwise, the first object within 42067754Smsmith * Scope is returned. 42167754Smsmith * 42267754Smsmith ******************************************************************************/ 42367754Smsmith 42467754SmsmithACPI_STATUS 42567754SmsmithAcpiGetNextObject ( 42667754Smsmith ACPI_OBJECT_TYPE Type, 42767754Smsmith ACPI_HANDLE Parent, 42867754Smsmith ACPI_HANDLE Child, 42967754Smsmith ACPI_HANDLE *RetHandle) 43067754Smsmith{ 43167754Smsmith ACPI_STATUS Status = AE_OK; 43267754Smsmith ACPI_NAMESPACE_NODE *Node; 43367754Smsmith ACPI_NAMESPACE_NODE *ParentNode = NULL; 43467754Smsmith ACPI_NAMESPACE_NODE *ChildNode = NULL; 43567754Smsmith 43667754Smsmith 43777424Smsmith /* Ensure that ACPI has been initialized */ 43877424Smsmith 43977424Smsmith ACPI_IS_INITIALIZATION_COMPLETE (Status); 44077424Smsmith if (ACPI_FAILURE (Status)) 44177424Smsmith { 44277424Smsmith return (Status); 44377424Smsmith } 44477424Smsmith 44567754Smsmith /* Parameter validation */ 44667754Smsmith 44767754Smsmith if (Type > ACPI_TYPE_MAX) 44867754Smsmith { 44967754Smsmith return (AE_BAD_PARAMETER); 45067754Smsmith } 45167754Smsmith 45277424Smsmith AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 45367754Smsmith 45467754Smsmith /* If null handle, use the parent */ 45567754Smsmith 45667754Smsmith if (!Child) 45767754Smsmith { 45867754Smsmith /* Start search at the beginning of the specified scope */ 45967754Smsmith 46067754Smsmith ParentNode = AcpiNsConvertHandleToEntry (Parent); 46167754Smsmith if (!ParentNode) 46267754Smsmith { 46367754Smsmith Status = AE_BAD_PARAMETER; 46467754Smsmith goto UnlockAndExit; 46567754Smsmith } 46667754Smsmith } 46767754Smsmith 46867754Smsmith /* Non-null handle, ignore the parent */ 46967754Smsmith 47067754Smsmith else 47167754Smsmith { 47267754Smsmith /* Convert and validate the handle */ 47367754Smsmith 47467754Smsmith ChildNode = AcpiNsConvertHandleToEntry (Child); 47567754Smsmith if (!ChildNode) 47667754Smsmith { 47767754Smsmith Status = AE_BAD_PARAMETER; 47867754Smsmith goto UnlockAndExit; 47967754Smsmith } 48067754Smsmith } 48167754Smsmith 48267754Smsmith 48367754Smsmith /* Internal function does the real work */ 48467754Smsmith 48577424Smsmith Node = AcpiNsGetNextObject ((ACPI_OBJECT_TYPE8) Type, 48667754Smsmith ParentNode, ChildNode); 48767754Smsmith if (!Node) 48867754Smsmith { 48967754Smsmith Status = AE_NOT_FOUND; 49067754Smsmith goto UnlockAndExit; 49167754Smsmith } 49267754Smsmith 49367754Smsmith if (RetHandle) 49467754Smsmith { 49567754Smsmith *RetHandle = AcpiNsConvertEntryToHandle (Node); 49667754Smsmith } 49767754Smsmith 49867754Smsmith 49967754SmsmithUnlockAndExit: 50067754Smsmith 50177424Smsmith AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 50267754Smsmith return (Status); 50367754Smsmith} 50467754Smsmith 50567754Smsmith 50667754Smsmith/******************************************************************************* 50767754Smsmith * 50867754Smsmith * FUNCTION: AcpiGetType 50967754Smsmith * 51067754Smsmith * PARAMETERS: Handle - Handle of object whose type is desired 51167754Smsmith * *RetType - Where the type will be placed 51267754Smsmith * 51367754Smsmith * RETURN: Status 51467754Smsmith * 51567754Smsmith * DESCRIPTION: This routine returns the type associatd with a particular handle 51667754Smsmith * 51767754Smsmith ******************************************************************************/ 51867754Smsmith 51967754SmsmithACPI_STATUS 52067754SmsmithAcpiGetType ( 52167754Smsmith ACPI_HANDLE Handle, 52267754Smsmith ACPI_OBJECT_TYPE *RetType) 52367754Smsmith{ 52467754Smsmith ACPI_NAMESPACE_NODE *Node; 52577424Smsmith ACPI_STATUS Status; 52667754Smsmith 52767754Smsmith 52877424Smsmith /* Ensure that ACPI has been initialized */ 52977424Smsmith 53077424Smsmith ACPI_IS_INITIALIZATION_COMPLETE (Status); 53177424Smsmith if (ACPI_FAILURE (Status)) 53277424Smsmith { 53377424Smsmith return (Status); 53477424Smsmith } 53577424Smsmith 53667754Smsmith /* Parameter Validation */ 53767754Smsmith 53867754Smsmith if (!RetType) 53967754Smsmith { 54067754Smsmith return (AE_BAD_PARAMETER); 54167754Smsmith } 54267754Smsmith 54367754Smsmith /* 54467754Smsmith * Special case for the predefined Root Node 54567754Smsmith * (return type ANY) 54667754Smsmith */ 54767754Smsmith if (Handle == ACPI_ROOT_OBJECT) 54867754Smsmith { 54967754Smsmith *RetType = ACPI_TYPE_ANY; 55067754Smsmith return (AE_OK); 55167754Smsmith } 55267754Smsmith 55377424Smsmith AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 55467754Smsmith 55567754Smsmith /* Convert and validate the handle */ 55667754Smsmith 55767754Smsmith Node = AcpiNsConvertHandleToEntry (Handle); 55867754Smsmith if (!Node) 55967754Smsmith { 56077424Smsmith AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 56167754Smsmith return (AE_BAD_PARAMETER); 56267754Smsmith } 56367754Smsmith 56467754Smsmith *RetType = Node->Type; 56567754Smsmith 56667754Smsmith 56777424Smsmith AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 56867754Smsmith return (AE_OK); 56967754Smsmith} 57067754Smsmith 57167754Smsmith 57267754Smsmith/******************************************************************************* 57367754Smsmith * 57467754Smsmith * FUNCTION: AcpiGetParent 57567754Smsmith * 57667754Smsmith * PARAMETERS: Handle - Handle of object whose parent is desired 57767754Smsmith * RetHandle - Where the parent handle will be placed 57867754Smsmith * 57967754Smsmith * RETURN: Status 58067754Smsmith * 58167754Smsmith * DESCRIPTION: Returns a handle to the parent of the object represented by 58267754Smsmith * Handle. 58367754Smsmith * 58467754Smsmith ******************************************************************************/ 58567754Smsmith 58667754SmsmithACPI_STATUS 58767754SmsmithAcpiGetParent ( 58867754Smsmith ACPI_HANDLE Handle, 58967754Smsmith ACPI_HANDLE *RetHandle) 59067754Smsmith{ 59167754Smsmith ACPI_NAMESPACE_NODE *Node; 59267754Smsmith ACPI_STATUS Status = AE_OK; 59367754Smsmith 59467754Smsmith 59577424Smsmith /* Ensure that ACPI has been initialized */ 59667754Smsmith 59777424Smsmith ACPI_IS_INITIALIZATION_COMPLETE (Status); 59877424Smsmith if (ACPI_FAILURE (Status)) 59977424Smsmith { 60077424Smsmith return (Status); 60177424Smsmith } 60267754Smsmith 60367754Smsmith if (!RetHandle) 60467754Smsmith { 60567754Smsmith return (AE_BAD_PARAMETER); 60667754Smsmith } 60767754Smsmith 60867754Smsmith /* Special case for the predefined Root Node (no parent) */ 60967754Smsmith 61067754Smsmith if (Handle == ACPI_ROOT_OBJECT) 61167754Smsmith { 61267754Smsmith return (AE_NULL_ENTRY); 61367754Smsmith } 61467754Smsmith 61567754Smsmith 61677424Smsmith AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 61767754Smsmith 61867754Smsmith /* Convert and validate the handle */ 61967754Smsmith 62067754Smsmith Node = AcpiNsConvertHandleToEntry (Handle); 62167754Smsmith if (!Node) 62267754Smsmith { 62367754Smsmith Status = AE_BAD_PARAMETER; 62467754Smsmith goto UnlockAndExit; 62567754Smsmith } 62667754Smsmith 62767754Smsmith 62867754Smsmith /* Get the parent entry */ 62967754Smsmith 63067754Smsmith *RetHandle = 63167754Smsmith AcpiNsConvertEntryToHandle (AcpiNsGetParentObject (Node)); 63267754Smsmith 63367754Smsmith /* Return exeption if parent is null */ 63467754Smsmith 63567754Smsmith if (!AcpiNsGetParentObject (Node)) 63667754Smsmith { 63767754Smsmith Status = AE_NULL_ENTRY; 63867754Smsmith } 63967754Smsmith 64067754Smsmith 64167754SmsmithUnlockAndExit: 64267754Smsmith 64377424Smsmith AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 64467754Smsmith return (Status); 64567754Smsmith} 64667754Smsmith 64767754Smsmith 64867754Smsmith/******************************************************************************* 64967754Smsmith * 65067754Smsmith * FUNCTION: AcpiWalkNamespace 65167754Smsmith * 65267754Smsmith * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 65367754Smsmith * StartObject - Handle in namespace where search begins 65467754Smsmith * MaxDepth - Depth to which search is to reach 65567754Smsmith * UserFunction - Called when an object of "Type" is found 65667754Smsmith * Context - Passed to user function 65767754Smsmith * ReturnValue - Location where return value of 65867754Smsmith * UserFunction is put if terminated early 65967754Smsmith * 66067754Smsmith * RETURNS Return value from the UserFunction if terminated early. 66167754Smsmith * Otherwise, returns NULL. 66267754Smsmith * 66367754Smsmith * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 66467754Smsmith * starting (and ending) at the object specified by StartHandle. 66567754Smsmith * The UserFunction is called whenever an object that matches 66667754Smsmith * the type parameter is found. If the user function returns 66767754Smsmith * a non-zero value, the search is terminated immediately and this 66867754Smsmith * value is returned to the caller. 66967754Smsmith * 67067754Smsmith * The point of this procedure is to provide a generic namespace 67167754Smsmith * walk routine that can be called from multiple places to 67267754Smsmith * provide multiple services; the User Function can be tailored 67367754Smsmith * to each task, whether it is a print function, a compare 67467754Smsmith * function, etc. 67567754Smsmith * 67667754Smsmith ******************************************************************************/ 67767754Smsmith 67867754SmsmithACPI_STATUS 67967754SmsmithAcpiWalkNamespace ( 68067754Smsmith ACPI_OBJECT_TYPE Type, 68167754Smsmith ACPI_HANDLE StartObject, 68267754Smsmith UINT32 MaxDepth, 68377424Smsmith ACPI_WALK_CALLBACK UserFunction, 68467754Smsmith void *Context, 68567754Smsmith void **ReturnValue) 68667754Smsmith{ 68767754Smsmith ACPI_STATUS Status; 68867754Smsmith 68967754Smsmith 69067754Smsmith FUNCTION_TRACE ("AcpiWalkNamespace"); 69167754Smsmith 69267754Smsmith 69377424Smsmith /* Ensure that ACPI has been initialized */ 69477424Smsmith 69577424Smsmith ACPI_IS_INITIALIZATION_COMPLETE (Status); 69677424Smsmith if (ACPI_FAILURE (Status)) 69777424Smsmith { 69877424Smsmith return_ACPI_STATUS (Status); 69977424Smsmith } 70077424Smsmith 70167754Smsmith /* Parameter validation */ 70267754Smsmith 70367754Smsmith if ((Type > ACPI_TYPE_MAX) || 70467754Smsmith (!MaxDepth) || 70567754Smsmith (!UserFunction)) 70667754Smsmith { 70767754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 70867754Smsmith } 70967754Smsmith 71067754Smsmith /* 71167754Smsmith * Lock the namespace around the walk. 71267754Smsmith * The namespace will be unlocked/locked around each call 71367754Smsmith * to the user function - since this function 71467754Smsmith * must be allowed to make Acpi calls itself. 71567754Smsmith */ 71667754Smsmith 71777424Smsmith AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 71877424Smsmith Status = AcpiNsWalkNamespace ((ACPI_OBJECT_TYPE8) Type, 71967754Smsmith StartObject, MaxDepth, 72067754Smsmith NS_WALK_UNLOCK, 72167754Smsmith UserFunction, Context, 72267754Smsmith ReturnValue); 72367754Smsmith 72477424Smsmith AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 72567754Smsmith 72667754Smsmith return_ACPI_STATUS (Status); 72767754Smsmith} 72867754Smsmith 72967754Smsmith 73067754Smsmith/******************************************************************************* 73167754Smsmith * 73267754Smsmith * FUNCTION: AcpiNsGetDeviceCallback 73367754Smsmith * 73467754Smsmith * PARAMETERS: Callback from AcpiGetDevice 73567754Smsmith * 73667754Smsmith * RETURN: Status 73767754Smsmith * 73867754Smsmith * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 73967754Smsmith * present devices, or if they specified a HID, it filters based 74067754Smsmith * on that. 74167754Smsmith * 74267754Smsmith ******************************************************************************/ 74367754Smsmith 74467754Smsmithstatic ACPI_STATUS 74567754SmsmithAcpiNsGetDeviceCallback ( 74667754Smsmith ACPI_HANDLE ObjHandle, 74767754Smsmith UINT32 NestingLevel, 74867754Smsmith void *Context, 74967754Smsmith void **ReturnValue) 75067754Smsmith{ 75167754Smsmith ACPI_STATUS Status; 75267754Smsmith ACPI_NAMESPACE_NODE *Node; 75367754Smsmith UINT32 Flags; 75477424Smsmith ACPI_DEVICE_ID DeviceId; 75567754Smsmith ACPI_GET_DEVICES_INFO *Info; 75667754Smsmith 75767754Smsmith 75867754Smsmith Info = Context; 75967754Smsmith 76077424Smsmith AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 76167754Smsmith Node = AcpiNsConvertHandleToEntry (ObjHandle); 76277424Smsmith AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 76373561Smsmith 76467754Smsmith if (!Node) 76567754Smsmith { 76667754Smsmith return (AE_BAD_PARAMETER); 76767754Smsmith } 76867754Smsmith 76967754Smsmith /* 77067754Smsmith * Run _STA to determine if device is present 77167754Smsmith */ 77277424Smsmith Status = AcpiUtExecute_STA (Node, &Flags); 77367754Smsmith if (ACPI_FAILURE (Status)) 77467754Smsmith { 77577424Smsmith return (AE_CTRL_DEPTH); 77667754Smsmith } 77767754Smsmith 77867754Smsmith if (!(Flags & 0x01)) 77967754Smsmith { 78067754Smsmith /* don't return at the device or children of the device if not there */ 78167754Smsmith return (AE_CTRL_DEPTH); 78267754Smsmith } 78367754Smsmith 78467754Smsmith /* 78567754Smsmith * Filter based on device HID 78667754Smsmith */ 78767754Smsmith if (Info->Hid != NULL) 78867754Smsmith { 78977424Smsmith Status = AcpiUtExecute_HID (Node, &DeviceId); 79067754Smsmith if (Status == AE_NOT_FOUND) 79167754Smsmith { 79267754Smsmith return (AE_OK); 79367754Smsmith } 79467754Smsmith 79567754Smsmith else if (ACPI_FAILURE (Status)) 79667754Smsmith { 79777424Smsmith return (AE_CTRL_DEPTH); 79867754Smsmith } 79967754Smsmith 80067754Smsmith if (STRNCMP (DeviceId.Buffer, Info->Hid, sizeof (DeviceId.Buffer)) != 0) 80167754Smsmith { 80267754Smsmith return (AE_OK); 80367754Smsmith } 80467754Smsmith } 80567754Smsmith 80667754Smsmith Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue); 80767754Smsmith return (AE_OK); 80867754Smsmith} 80967754Smsmith 81067754Smsmith 81167754Smsmith/******************************************************************************* 81267754Smsmith * 81367754Smsmith * FUNCTION: AcpiGetDevices 81467754Smsmith * 81567754Smsmith * PARAMETERS: HID - HID to search for. Can be NULL. 81667754Smsmith * UserFunction - Called when a matching object is found 81767754Smsmith * Context - Passed to user function 81867754Smsmith * ReturnValue - Location where return value of 81967754Smsmith * UserFunction is put if terminated early 82067754Smsmith * 82167754Smsmith * RETURNS Return value from the UserFunction if terminated early. 82267754Smsmith * Otherwise, returns NULL. 82367754Smsmith * 82467754Smsmith * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 82567754Smsmith * starting (and ending) at the object specified by StartHandle. 82667754Smsmith * The UserFunction is called whenever an object that matches 82767754Smsmith * the type parameter is found. If the user function returns 82867754Smsmith * a non-zero value, the search is terminated immediately and this 82967754Smsmith * value is returned to the caller. 83067754Smsmith * 83167754Smsmith * This is a wrapper for WalkNamespace, but the callback performs 83267754Smsmith * additional filtering. Please see AcpiGetDeviceCallback. 83367754Smsmith * 83467754Smsmith ******************************************************************************/ 83567754Smsmith 83667754SmsmithACPI_STATUS 83767754SmsmithAcpiGetDevices ( 83867754Smsmith NATIVE_CHAR *HID, 83977424Smsmith ACPI_WALK_CALLBACK UserFunction, 84067754Smsmith void *Context, 84167754Smsmith void **ReturnValue) 84267754Smsmith{ 84367754Smsmith ACPI_STATUS Status; 84467754Smsmith ACPI_GET_DEVICES_INFO Info; 84567754Smsmith 84667754Smsmith 84767754Smsmith FUNCTION_TRACE ("AcpiGetDevices"); 84867754Smsmith 84967754Smsmith 85077424Smsmith /* Ensure that ACPI has been initialized */ 85177424Smsmith 85277424Smsmith ACPI_IS_INITIALIZATION_COMPLETE (Status); 85377424Smsmith if (ACPI_FAILURE (Status)) 85477424Smsmith { 85577424Smsmith return_ACPI_STATUS (Status); 85677424Smsmith } 85777424Smsmith 85867754Smsmith /* Parameter validation */ 85967754Smsmith 86067754Smsmith if (!UserFunction) 86167754Smsmith { 86267754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 86367754Smsmith } 86467754Smsmith 86567754Smsmith /* 86667754Smsmith * We're going to call their callback from OUR callback, so we need 86767754Smsmith * to know what it is, and their context parameter. 86867754Smsmith */ 86967754Smsmith Info.Context = Context; 87067754Smsmith Info.UserFunction = UserFunction; 87167754Smsmith Info.Hid = HID; 87267754Smsmith 87367754Smsmith /* 87467754Smsmith * Lock the namespace around the walk. 87567754Smsmith * The namespace will be unlocked/locked around each call 87667754Smsmith * to the user function - since this function 87767754Smsmith * must be allowed to make Acpi calls itself. 87867754Smsmith */ 87967754Smsmith 88077424Smsmith AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 88167754Smsmith Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, 88267754Smsmith ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 88367754Smsmith NS_WALK_UNLOCK, 88467754Smsmith AcpiNsGetDeviceCallback, &Info, 88567754Smsmith ReturnValue); 88667754Smsmith 88777424Smsmith AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 88867754Smsmith 88967754Smsmith return_ACPI_STATUS (Status); 89069450Smsmith} 891