nsxfobj.c revision 73561
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: nsxfobj - Public interfaces to the ACPI subsystem 467754Smsmith * ACPI Object oriented interfaces 573561Smsmith * $Revision: 80 $ 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 12767754Smsmith#define _COMPONENT 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 17567754Smsmith /* 17667754Smsmith * If there are parameters to be passed to the object 17767754Smsmith * (which must be a control method), the external objects 17867754Smsmith * must be converted to internal objects 17967754Smsmith */ 18067754Smsmith 18167754Smsmith if (ParamObjects && ParamObjects->Count) 18267754Smsmith { 18367754Smsmith /* 18467754Smsmith * Allocate a new parameter block for the internal objects 18567754Smsmith * Add 1 to count to allow for null terminated internal list 18667754Smsmith */ 18767754Smsmith 18867754Smsmith Count = ParamObjects->Count; 18967754Smsmith ParamLength = (Count + 1) * sizeof (void *); 19067754Smsmith ObjectLength = Count * sizeof (ACPI_OPERAND_OBJECT); 19167754Smsmith 19267754Smsmith ParamPtr = AcpiCmCallocate (ParamLength + /* Parameter List part */ 19367754Smsmith ObjectLength); /* Actual objects */ 19467754Smsmith if (!ParamPtr) 19567754Smsmith { 19667754Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 19767754Smsmith } 19867754Smsmith 19967754Smsmith ObjectPtr = (ACPI_OPERAND_OBJECT *) ((UINT8 *) ParamPtr + 20067754Smsmith ParamLength); 20167754Smsmith 20267754Smsmith /* 20367754Smsmith * Init the param array of pointers and NULL terminate 20467754Smsmith * the list 20567754Smsmith */ 20667754Smsmith 20767754Smsmith for (i = 0; i < Count; i++) 20867754Smsmith { 20967754Smsmith ParamPtr[i] = &ObjectPtr[i]; 21067754Smsmith AcpiCmInitStaticObject (&ObjectPtr[i]); 21167754Smsmith } 21267754Smsmith ParamPtr[Count] = NULL; 21367754Smsmith 21467754Smsmith /* 21567754Smsmith * Convert each external object in the list to an 21667754Smsmith * internal object 21767754Smsmith */ 21867754Smsmith for (i = 0; i < Count; i++) 21967754Smsmith { 22073561Smsmith Status = AcpiCmCopyEobjectToIobject (&ParamObjects->Pointer[i], 22173561Smsmith ParamPtr[i]); 22267754Smsmith 22367754Smsmith if (ACPI_FAILURE (Status)) 22467754Smsmith { 22567754Smsmith AcpiCmDeleteInternalObjectList (ParamPtr); 22667754Smsmith return_ACPI_STATUS (Status); 22767754Smsmith } 22867754Smsmith } 22967754Smsmith } 23067754Smsmith 23167754Smsmith 23267754Smsmith /* 23367754Smsmith * Three major cases: 23467754Smsmith * 1) Fully qualified pathname 23567754Smsmith * 2) No handle, not fully qualified pathname (error) 23667754Smsmith * 3) Valid handle 23767754Smsmith */ 23867754Smsmith 23967754Smsmith if ((Pathname) && 24067754Smsmith (AcpiNsValidRootPrefix (Pathname[0]))) 24167754Smsmith { 24267754Smsmith /* 24367754Smsmith * The path is fully qualified, just evaluate by name 24467754Smsmith */ 24567754Smsmith Status = AcpiNsEvaluateByName (Pathname, ParamPtr, &ReturnObj); 24667754Smsmith } 24767754Smsmith 24867754Smsmith else if (!Handle) 24967754Smsmith { 25067754Smsmith /* 25167754Smsmith * A handle is optional iff a fully qualified pathname 25267754Smsmith * is specified. Since we've already handled fully 25367754Smsmith * qualified names above, this is an error 25467754Smsmith */ 25567754Smsmith 25667754Smsmith if (!Pathname) 25767754Smsmith { 25867754Smsmith DEBUG_PRINT (ACPI_ERROR, 25967754Smsmith ("AcpiEvaluateObject: Both Handle and Pathname are NULL\n")); 26067754Smsmith } 26167754Smsmith 26267754Smsmith else 26367754Smsmith { 26467754Smsmith DEBUG_PRINT (ACPI_ERROR, 26567754Smsmith ("AcpiEvaluateObject: Handle is NULL and Pathname is relative\n")); 26667754Smsmith } 26767754Smsmith 26867754Smsmith Status = AE_BAD_PARAMETER; 26967754Smsmith } 27067754Smsmith 27167754Smsmith else 27267754Smsmith { 27367754Smsmith /* 27467754Smsmith * We get here if we have a handle -- and if we have a 27567754Smsmith * pathname it is relative. The handle will be validated 27667754Smsmith * in the lower procedures 27767754Smsmith */ 27867754Smsmith 27967754Smsmith if (!Pathname) 28067754Smsmith { 28167754Smsmith /* 28267754Smsmith * The null pathname case means the handle is for 28367754Smsmith * the actual object to be evaluated 28467754Smsmith */ 28567754Smsmith Status = AcpiNsEvaluateByHandle (Handle, ParamPtr, &ReturnObj); 28667754Smsmith } 28767754Smsmith 28867754Smsmith else 28967754Smsmith { 29067754Smsmith /* 29167754Smsmith * Both a Handle and a relative Pathname 29267754Smsmith */ 29367754Smsmith Status = AcpiNsEvaluateRelative (Handle, Pathname, ParamPtr, 29467754Smsmith &ReturnObj); 29567754Smsmith } 29667754Smsmith } 29767754Smsmith 29867754Smsmith 29967754Smsmith /* 30067754Smsmith * If we are expecting a return value, and all went well above, 30167754Smsmith * copy the return value to an external object. 30267754Smsmith */ 30367754Smsmith 30467754Smsmith if (ReturnBuffer) 30567754Smsmith { 30667754Smsmith UserBufferLength = ReturnBuffer->Length; 30767754Smsmith ReturnBuffer->Length = 0; 30867754Smsmith 30967754Smsmith if (ReturnObj) 31067754Smsmith { 31167754Smsmith if (VALID_DESCRIPTOR_TYPE (ReturnObj, ACPI_DESC_TYPE_NAMED)) 31267754Smsmith { 31367754Smsmith /* 31467754Smsmith * If we got an Node as a return object, 31567754Smsmith * this means the object we are evaluating 31667754Smsmith * has nothing interesting to return (such 31767754Smsmith * as a mutex, etc.) We return an error 31867754Smsmith * because these types are essentially 31967754Smsmith * unsupported by this interface. We 32067754Smsmith * don't check up front because this makes 32167754Smsmith * it easier to add support for various 32267754Smsmith * types at a later date if necessary. 32367754Smsmith */ 32467754Smsmith Status = AE_TYPE; 32567754Smsmith ReturnObj = NULL; /* No need to delete an Node */ 32667754Smsmith } 32767754Smsmith 32867754Smsmith if (ACPI_SUCCESS (Status)) 32967754Smsmith { 33067754Smsmith /* 33167754Smsmith * Find out how large a buffer is needed 33267754Smsmith * to contain the returned object 33367754Smsmith */ 33467754Smsmith Status = AcpiCmGetObjectSize (ReturnObj, 33567754Smsmith &BufferSpaceNeeded); 33667754Smsmith if (ACPI_SUCCESS (Status)) 33767754Smsmith { 33867754Smsmith /* 33967754Smsmith * Check if there is enough room in the 34067754Smsmith * caller's buffer 34167754Smsmith */ 34267754Smsmith 34367754Smsmith if (UserBufferLength < BufferSpaceNeeded) 34467754Smsmith { 34567754Smsmith /* 34667754Smsmith * Caller's buffer is too small, can't 34767754Smsmith * give him partial results fail the call 34867754Smsmith * but return the buffer size needed 34967754Smsmith */ 35067754Smsmith 35167754Smsmith DEBUG_PRINT (ACPI_INFO, 35269746Smsmith ("AcpiEvaluateObject: Needed buffer size %X, received %X\n", 35367754Smsmith BufferSpaceNeeded, UserBufferLength)); 35467754Smsmith 35567754Smsmith ReturnBuffer->Length = BufferSpaceNeeded; 35667754Smsmith Status = AE_BUFFER_OVERFLOW; 35767754Smsmith } 35867754Smsmith 35967754Smsmith else 36067754Smsmith { 36167754Smsmith /* 36267754Smsmith * We have enough space for the object, build it 36367754Smsmith */ 36473561Smsmith Status = AcpiCmCopyIobjectToEobject (ReturnObj, 36567754Smsmith ReturnBuffer); 36667754Smsmith ReturnBuffer->Length = BufferSpaceNeeded; 36767754Smsmith } 36867754Smsmith } 36967754Smsmith } 37067754Smsmith } 37167754Smsmith } 37267754Smsmith 37367754Smsmith 37467754Smsmith /* Delete the return and parameter objects */ 37567754Smsmith 37667754Smsmith if (ReturnObj) 37767754Smsmith { 37867754Smsmith /* 37967754Smsmith * Delete the internal return object. (Or at least 38067754Smsmith * decrement the reference count by one) 38167754Smsmith */ 38267754Smsmith AcpiCmRemoveReference (ReturnObj); 38367754Smsmith } 38467754Smsmith 38567754Smsmith /* 38667754Smsmith * Free the input parameter list (if we created one), 38767754Smsmith */ 38867754Smsmith 38967754Smsmith if (ParamPtr) 39067754Smsmith { 39167754Smsmith /* Free the allocated parameter block */ 39267754Smsmith 39367754Smsmith AcpiCmDeleteInternalObjectList (ParamPtr); 39467754Smsmith } 39567754Smsmith 39667754Smsmith return_ACPI_STATUS (Status); 39767754Smsmith} 39867754Smsmith 39967754Smsmith 40067754Smsmith/******************************************************************************* 40167754Smsmith * 40267754Smsmith * FUNCTION: AcpiGetNextObject 40367754Smsmith * 40467754Smsmith * PARAMETERS: Type - Type of object to be searched for 40567754Smsmith * Parent - Parent object whose children we are getting 40667754Smsmith * LastChild - Previous child that was found. 40767754Smsmith * The NEXT child will be returned 40867754Smsmith * RetHandle - Where handle to the next object is placed 40967754Smsmith * 41067754Smsmith * RETURN: Status 41167754Smsmith * 41267754Smsmith * DESCRIPTION: Return the next peer object within the namespace. If Handle is 41367754Smsmith * valid, Scope is ignored. Otherwise, the first object within 41467754Smsmith * Scope is returned. 41567754Smsmith * 41667754Smsmith ******************************************************************************/ 41767754Smsmith 41867754SmsmithACPI_STATUS 41967754SmsmithAcpiGetNextObject ( 42067754Smsmith ACPI_OBJECT_TYPE Type, 42167754Smsmith ACPI_HANDLE Parent, 42267754Smsmith ACPI_HANDLE Child, 42367754Smsmith ACPI_HANDLE *RetHandle) 42467754Smsmith{ 42567754Smsmith ACPI_STATUS Status = AE_OK; 42667754Smsmith ACPI_NAMESPACE_NODE *Node; 42767754Smsmith ACPI_NAMESPACE_NODE *ParentNode = NULL; 42867754Smsmith ACPI_NAMESPACE_NODE *ChildNode = NULL; 42967754Smsmith 43067754Smsmith 43167754Smsmith /* Parameter validation */ 43267754Smsmith 43367754Smsmith if (Type > ACPI_TYPE_MAX) 43467754Smsmith { 43567754Smsmith return (AE_BAD_PARAMETER); 43667754Smsmith } 43767754Smsmith 43867754Smsmith AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE); 43967754Smsmith 44067754Smsmith /* If null handle, use the parent */ 44167754Smsmith 44267754Smsmith if (!Child) 44367754Smsmith { 44467754Smsmith /* Start search at the beginning of the specified scope */ 44567754Smsmith 44667754Smsmith ParentNode = AcpiNsConvertHandleToEntry (Parent); 44767754Smsmith if (!ParentNode) 44867754Smsmith { 44967754Smsmith Status = AE_BAD_PARAMETER; 45067754Smsmith goto UnlockAndExit; 45167754Smsmith } 45267754Smsmith } 45367754Smsmith 45467754Smsmith /* Non-null handle, ignore the parent */ 45567754Smsmith 45667754Smsmith else 45767754Smsmith { 45867754Smsmith /* Convert and validate the handle */ 45967754Smsmith 46067754Smsmith ChildNode = AcpiNsConvertHandleToEntry (Child); 46167754Smsmith if (!ChildNode) 46267754Smsmith { 46367754Smsmith Status = AE_BAD_PARAMETER; 46467754Smsmith goto UnlockAndExit; 46567754Smsmith } 46667754Smsmith } 46767754Smsmith 46867754Smsmith 46967754Smsmith /* Internal function does the real work */ 47067754Smsmith 47167754Smsmith Node = AcpiNsGetNextObject ((OBJECT_TYPE_INTERNAL) Type, 47267754Smsmith ParentNode, ChildNode); 47367754Smsmith if (!Node) 47467754Smsmith { 47567754Smsmith Status = AE_NOT_FOUND; 47667754Smsmith goto UnlockAndExit; 47767754Smsmith } 47867754Smsmith 47967754Smsmith if (RetHandle) 48067754Smsmith { 48167754Smsmith *RetHandle = AcpiNsConvertEntryToHandle (Node); 48267754Smsmith } 48367754Smsmith 48467754Smsmith 48567754SmsmithUnlockAndExit: 48667754Smsmith 48767754Smsmith AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 48867754Smsmith return (Status); 48967754Smsmith} 49067754Smsmith 49167754Smsmith 49267754Smsmith/******************************************************************************* 49367754Smsmith * 49467754Smsmith * FUNCTION: AcpiGetType 49567754Smsmith * 49667754Smsmith * PARAMETERS: Handle - Handle of object whose type is desired 49767754Smsmith * *RetType - Where the type will be placed 49867754Smsmith * 49967754Smsmith * RETURN: Status 50067754Smsmith * 50167754Smsmith * DESCRIPTION: This routine returns the type associatd with a particular handle 50267754Smsmith * 50367754Smsmith ******************************************************************************/ 50467754Smsmith 50567754SmsmithACPI_STATUS 50667754SmsmithAcpiGetType ( 50767754Smsmith ACPI_HANDLE Handle, 50867754Smsmith ACPI_OBJECT_TYPE *RetType) 50967754Smsmith{ 51067754Smsmith ACPI_NAMESPACE_NODE *Node; 51167754Smsmith 51267754Smsmith 51367754Smsmith /* Parameter Validation */ 51467754Smsmith 51567754Smsmith if (!RetType) 51667754Smsmith { 51767754Smsmith return (AE_BAD_PARAMETER); 51867754Smsmith } 51967754Smsmith 52067754Smsmith /* 52167754Smsmith * Special case for the predefined Root Node 52267754Smsmith * (return type ANY) 52367754Smsmith */ 52467754Smsmith if (Handle == ACPI_ROOT_OBJECT) 52567754Smsmith { 52667754Smsmith *RetType = ACPI_TYPE_ANY; 52767754Smsmith return (AE_OK); 52867754Smsmith } 52967754Smsmith 53067754Smsmith AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE); 53167754Smsmith 53267754Smsmith /* Convert and validate the handle */ 53367754Smsmith 53467754Smsmith Node = AcpiNsConvertHandleToEntry (Handle); 53567754Smsmith if (!Node) 53667754Smsmith { 53767754Smsmith AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 53867754Smsmith return (AE_BAD_PARAMETER); 53967754Smsmith } 54067754Smsmith 54167754Smsmith *RetType = Node->Type; 54267754Smsmith 54367754Smsmith 54467754Smsmith AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 54567754Smsmith return (AE_OK); 54667754Smsmith} 54767754Smsmith 54867754Smsmith 54967754Smsmith/******************************************************************************* 55067754Smsmith * 55167754Smsmith * FUNCTION: AcpiGetParent 55267754Smsmith * 55367754Smsmith * PARAMETERS: Handle - Handle of object whose parent is desired 55467754Smsmith * RetHandle - Where the parent handle will be placed 55567754Smsmith * 55667754Smsmith * RETURN: Status 55767754Smsmith * 55867754Smsmith * DESCRIPTION: Returns a handle to the parent of the object represented by 55967754Smsmith * Handle. 56067754Smsmith * 56167754Smsmith ******************************************************************************/ 56267754Smsmith 56367754SmsmithACPI_STATUS 56467754SmsmithAcpiGetParent ( 56567754Smsmith ACPI_HANDLE Handle, 56667754Smsmith ACPI_HANDLE *RetHandle) 56767754Smsmith{ 56867754Smsmith ACPI_NAMESPACE_NODE *Node; 56967754Smsmith ACPI_STATUS Status = AE_OK; 57067754Smsmith 57167754Smsmith 57267754Smsmith /* No trace macro, too verbose */ 57367754Smsmith 57467754Smsmith 57567754Smsmith if (!RetHandle) 57667754Smsmith { 57767754Smsmith return (AE_BAD_PARAMETER); 57867754Smsmith } 57967754Smsmith 58067754Smsmith /* Special case for the predefined Root Node (no parent) */ 58167754Smsmith 58267754Smsmith if (Handle == ACPI_ROOT_OBJECT) 58367754Smsmith { 58467754Smsmith return (AE_NULL_ENTRY); 58567754Smsmith } 58667754Smsmith 58767754Smsmith 58867754Smsmith AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE); 58967754Smsmith 59067754Smsmith /* Convert and validate the handle */ 59167754Smsmith 59267754Smsmith Node = AcpiNsConvertHandleToEntry (Handle); 59367754Smsmith if (!Node) 59467754Smsmith { 59567754Smsmith Status = AE_BAD_PARAMETER; 59667754Smsmith goto UnlockAndExit; 59767754Smsmith } 59867754Smsmith 59967754Smsmith 60067754Smsmith /* Get the parent entry */ 60167754Smsmith 60267754Smsmith *RetHandle = 60367754Smsmith AcpiNsConvertEntryToHandle (AcpiNsGetParentObject (Node)); 60467754Smsmith 60567754Smsmith /* Return exeption if parent is null */ 60667754Smsmith 60767754Smsmith if (!AcpiNsGetParentObject (Node)) 60867754Smsmith { 60967754Smsmith Status = AE_NULL_ENTRY; 61067754Smsmith } 61167754Smsmith 61267754Smsmith 61367754SmsmithUnlockAndExit: 61467754Smsmith 61567754Smsmith AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 61667754Smsmith return (Status); 61767754Smsmith} 61867754Smsmith 61967754Smsmith 62067754Smsmith/******************************************************************************* 62167754Smsmith * 62267754Smsmith * FUNCTION: AcpiWalkNamespace 62367754Smsmith * 62467754Smsmith * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 62567754Smsmith * StartObject - Handle in namespace where search begins 62667754Smsmith * MaxDepth - Depth to which search is to reach 62767754Smsmith * UserFunction - Called when an object of "Type" is found 62867754Smsmith * Context - Passed to user function 62967754Smsmith * ReturnValue - Location where return value of 63067754Smsmith * UserFunction is put if terminated early 63167754Smsmith * 63267754Smsmith * RETURNS Return value from the UserFunction if terminated early. 63367754Smsmith * Otherwise, returns NULL. 63467754Smsmith * 63567754Smsmith * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 63667754Smsmith * starting (and ending) at the object specified by StartHandle. 63767754Smsmith * The UserFunction is called whenever an object that matches 63867754Smsmith * the type parameter is found. If the user function returns 63967754Smsmith * a non-zero value, the search is terminated immediately and this 64067754Smsmith * value is returned to the caller. 64167754Smsmith * 64267754Smsmith * The point of this procedure is to provide a generic namespace 64367754Smsmith * walk routine that can be called from multiple places to 64467754Smsmith * provide multiple services; the User Function can be tailored 64567754Smsmith * to each task, whether it is a print function, a compare 64667754Smsmith * function, etc. 64767754Smsmith * 64867754Smsmith ******************************************************************************/ 64967754Smsmith 65067754SmsmithACPI_STATUS 65167754SmsmithAcpiWalkNamespace ( 65267754Smsmith ACPI_OBJECT_TYPE Type, 65367754Smsmith ACPI_HANDLE StartObject, 65467754Smsmith UINT32 MaxDepth, 65567754Smsmith WALK_CALLBACK UserFunction, 65667754Smsmith void *Context, 65767754Smsmith void **ReturnValue) 65867754Smsmith{ 65967754Smsmith ACPI_STATUS Status; 66067754Smsmith 66167754Smsmith 66267754Smsmith FUNCTION_TRACE ("AcpiWalkNamespace"); 66367754Smsmith 66467754Smsmith 66567754Smsmith /* Parameter validation */ 66667754Smsmith 66767754Smsmith if ((Type > ACPI_TYPE_MAX) || 66867754Smsmith (!MaxDepth) || 66967754Smsmith (!UserFunction)) 67067754Smsmith { 67167754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 67267754Smsmith } 67367754Smsmith 67467754Smsmith /* 67567754Smsmith * Lock the namespace around the walk. 67667754Smsmith * The namespace will be unlocked/locked around each call 67767754Smsmith * to the user function - since this function 67867754Smsmith * must be allowed to make Acpi calls itself. 67967754Smsmith */ 68067754Smsmith 68167754Smsmith AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE); 68267754Smsmith Status = AcpiNsWalkNamespace ((OBJECT_TYPE_INTERNAL) Type, 68367754Smsmith StartObject, MaxDepth, 68467754Smsmith NS_WALK_UNLOCK, 68567754Smsmith UserFunction, Context, 68667754Smsmith ReturnValue); 68767754Smsmith 68867754Smsmith AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 68967754Smsmith 69067754Smsmith return_ACPI_STATUS (Status); 69167754Smsmith} 69267754Smsmith 69367754Smsmith 69467754Smsmith/******************************************************************************* 69567754Smsmith * 69667754Smsmith * FUNCTION: AcpiNsGetDeviceCallback 69767754Smsmith * 69867754Smsmith * PARAMETERS: Callback from AcpiGetDevice 69967754Smsmith * 70067754Smsmith * RETURN: Status 70167754Smsmith * 70267754Smsmith * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 70367754Smsmith * present devices, or if they specified a HID, it filters based 70467754Smsmith * on that. 70567754Smsmith * 70667754Smsmith ******************************************************************************/ 70767754Smsmith 70867754Smsmithstatic ACPI_STATUS 70967754SmsmithAcpiNsGetDeviceCallback ( 71067754Smsmith ACPI_HANDLE ObjHandle, 71167754Smsmith UINT32 NestingLevel, 71267754Smsmith void *Context, 71367754Smsmith void **ReturnValue) 71467754Smsmith{ 71567754Smsmith ACPI_STATUS Status; 71667754Smsmith ACPI_NAMESPACE_NODE *Node; 71767754Smsmith UINT32 Flags; 71867754Smsmith DEVICE_ID DeviceId; 71967754Smsmith ACPI_GET_DEVICES_INFO *Info; 72067754Smsmith 72167754Smsmith 72267754Smsmith Info = Context; 72367754Smsmith 72467754Smsmith AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE); 72567754Smsmith 72667754Smsmith Node = AcpiNsConvertHandleToEntry (ObjHandle); 72773561Smsmith 72873561Smsmith AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 72973561Smsmith 73067754Smsmith if (!Node) 73167754Smsmith { 73267754Smsmith return (AE_BAD_PARAMETER); 73367754Smsmith } 73467754Smsmith 73567754Smsmith /* 73667754Smsmith * Run _STA to determine if device is present 73767754Smsmith */ 73867754Smsmith 73967754Smsmith Status = AcpiCmExecute_STA (Node, &Flags); 74067754Smsmith if (ACPI_FAILURE (Status)) 74167754Smsmith { 74267754Smsmith return (Status); 74367754Smsmith } 74467754Smsmith 74567754Smsmith if (!(Flags & 0x01)) 74667754Smsmith { 74767754Smsmith /* don't return at the device or children of the device if not there */ 74867754Smsmith 74967754Smsmith return (AE_CTRL_DEPTH); 75067754Smsmith } 75167754Smsmith 75267754Smsmith /* 75367754Smsmith * Filter based on device HID 75467754Smsmith */ 75567754Smsmith if (Info->Hid != NULL) 75667754Smsmith { 75767754Smsmith Status = AcpiCmExecute_HID (Node, &DeviceId); 75867754Smsmith 75967754Smsmith if (Status == AE_NOT_FOUND) 76067754Smsmith { 76167754Smsmith return (AE_OK); 76267754Smsmith } 76367754Smsmith 76467754Smsmith else if (ACPI_FAILURE (Status)) 76567754Smsmith { 76667754Smsmith return (Status); 76767754Smsmith } 76867754Smsmith 76967754Smsmith if (STRNCMP (DeviceId.Buffer, Info->Hid, sizeof (DeviceId.Buffer)) != 0) 77067754Smsmith { 77167754Smsmith return (AE_OK); 77267754Smsmith } 77367754Smsmith } 77467754Smsmith 77567754Smsmith Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue); 77667754Smsmith 77767754Smsmith return (AE_OK); 77867754Smsmith} 77967754Smsmith 78067754Smsmith 78167754Smsmith/******************************************************************************* 78267754Smsmith * 78367754Smsmith * FUNCTION: AcpiGetDevices 78467754Smsmith * 78567754Smsmith * PARAMETERS: HID - HID to search for. Can be NULL. 78667754Smsmith * UserFunction - Called when a matching object is found 78767754Smsmith * Context - Passed to user function 78867754Smsmith * ReturnValue - Location where return value of 78967754Smsmith * UserFunction is put if terminated early 79067754Smsmith * 79167754Smsmith * RETURNS Return value from the UserFunction if terminated early. 79267754Smsmith * Otherwise, returns NULL. 79367754Smsmith * 79467754Smsmith * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 79567754Smsmith * starting (and ending) at the object specified by StartHandle. 79667754Smsmith * The UserFunction is called whenever an object that matches 79767754Smsmith * the type parameter is found. If the user function returns 79867754Smsmith * a non-zero value, the search is terminated immediately and this 79967754Smsmith * value is returned to the caller. 80067754Smsmith * 80167754Smsmith * This is a wrapper for WalkNamespace, but the callback performs 80267754Smsmith * additional filtering. Please see AcpiGetDeviceCallback. 80367754Smsmith * 80467754Smsmith ******************************************************************************/ 80567754Smsmith 80667754SmsmithACPI_STATUS 80767754SmsmithAcpiGetDevices ( 80867754Smsmith NATIVE_CHAR *HID, 80967754Smsmith WALK_CALLBACK UserFunction, 81067754Smsmith void *Context, 81167754Smsmith void **ReturnValue) 81267754Smsmith{ 81367754Smsmith ACPI_STATUS Status; 81467754Smsmith ACPI_GET_DEVICES_INFO Info; 81567754Smsmith 81667754Smsmith 81767754Smsmith FUNCTION_TRACE ("AcpiGetDevices"); 81867754Smsmith 81967754Smsmith 82067754Smsmith /* Parameter validation */ 82167754Smsmith 82267754Smsmith if (!UserFunction) 82367754Smsmith { 82467754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 82567754Smsmith } 82667754Smsmith 82767754Smsmith /* 82867754Smsmith * We're going to call their callback from OUR callback, so we need 82967754Smsmith * to know what it is, and their context parameter. 83067754Smsmith */ 83167754Smsmith Info.Context = Context; 83267754Smsmith Info.UserFunction = UserFunction; 83367754Smsmith Info.Hid = HID; 83467754Smsmith 83567754Smsmith /* 83667754Smsmith * Lock the namespace around the walk. 83767754Smsmith * The namespace will be unlocked/locked around each call 83867754Smsmith * to the user function - since this function 83967754Smsmith * must be allowed to make Acpi calls itself. 84067754Smsmith */ 84167754Smsmith 84267754Smsmith AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE); 84367754Smsmith Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, 84467754Smsmith ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 84567754Smsmith NS_WALK_UNLOCK, 84667754Smsmith AcpiNsGetDeviceCallback, &Info, 84767754Smsmith ReturnValue); 84867754Smsmith 84967754Smsmith AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 85067754Smsmith 85167754Smsmith return_ACPI_STATUS (Status); 85269450Smsmith} 853