nsxfobj.c revision 91116
133965Sjdp/******************************************************************************* 278828Sobrien * 3218822Sdim * Module Name: nsxfobj - Public interfaces to the ACPI subsystem 438889Sjdp * ACPI Object oriented interfaces 533965Sjdp * $Revision: 108 $ 633965Sjdp * 791041Sobrien ******************************************************************************/ 833965Sjdp 991041Sobrien/****************************************************************************** 1091041Sobrien * 1191041Sobrien * 1. Copyright Notice 1291041Sobrien * 1333965Sjdp * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 1491041Sobrien * All rights reserved. 1591041Sobrien * 1691041Sobrien * 2. License 1791041Sobrien * 1833965Sjdp * 2.1. This is your license from Intel Corp. under its intellectual property 1991041Sobrien * rights. You may have additional license terms from the party that provided 2091041Sobrien * you this software, covering your right to use that party's intellectual 21218822Sdim * property rights. 2233965Sjdp * 23218822Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2433965Sjdp * copy of the source code appearing in this file ("Covered Code") an 2533965Sjdp * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2633965Sjdp * base code distributed originally by Intel ("Original Intel Code") to copy, 2733965Sjdp * make derivatives, distribute, use and display any portion of the Covered 2833965Sjdp * Code in any form, with the right to sublicense such rights; and 2933965Sjdp * 3033965Sjdp * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3133965Sjdp * license (with the right to sublicense), under only those claims of Intel 3233965Sjdp * patents that are infringed by the Original Intel Code, to make, use, sell, 33218822Sdim * offer to sell, and import the Covered Code and derivative works thereof 34218822Sdim * solely to the minimum extent necessary to exercise the above copyright 35218822Sdim * license, and in no event shall the patent license extend to any additions 3633965Sjdp * to or modifications of the Original Intel Code. No other license or right 3733965Sjdp * is granted directly or by implication, estoppel or otherwise; 3833965Sjdp * 3933965Sjdp * The above copyright and patent license is granted only if the following 4033965Sjdp * conditions are met: 4133965Sjdp * 4233965Sjdp * 3. Conditions 4333965Sjdp * 4433965Sjdp * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4533965Sjdp * Redistribution of source code of any substantial portion of the Covered 4633965Sjdp * Code or modification with rights to further distribute source must include 47130561Sobrien * the above Copyright Notice, the above License, this list of Conditions, 48130561Sobrien * and the following Disclaimer and Export Compliance provision. In addition, 4933965Sjdp * Licensee must cause all Covered Code to which Licensee contributes to 5033965Sjdp * contain a file documenting the changes Licensee made to create that Covered 51130561Sobrien * Code and the date of any change. Licensee must include in that file the 5233965Sjdp * documentation of any changes made by any predecessor Licensee. Licensee 5333965Sjdp * must include a prominent statement that the modification is derived, 5433965Sjdp * directly or indirectly, from Original Intel Code. 5533965Sjdp * 5633965Sjdp * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57130561Sobrien * Redistribution of source code of any substantial portion of the Covered 58130561Sobrien * Code or modification without rights to further distribute source must 5933965Sjdp * include the following Disclaimer and Export Compliance provision in the 60130561Sobrien * documentation and/or other materials provided with distribution. In 6133965Sjdp * addition, Licensee may not authorize further sublicense of source of any 6233965Sjdp * portion of the Covered Code, and must include terms to the effect that the 6333965Sjdp * license from Licensee to its licensee is limited to the intellectual 6433965Sjdp * property embodied in the software Licensee provides to its licensee, and 6533965Sjdp * not to intellectual property embodied in modifications its licensee may 66130561Sobrien * make. 67130561Sobrien * 6833965Sjdp * 3.3. Redistribution of Executable. Redistribution in executable form of any 6933965Sjdp * substantial portion of the Covered Code or modification must reproduce the 7033965Sjdp * above Copyright Notice, and the following Disclaimer and Export Compliance 7133965Sjdp * provision in the documentation and/or other materials provided with the 7233965Sjdp * distribution. 7377298Sobrien * 74130561Sobrien * 3.4. Intel retains all right, title, and interest in and to the Original 7533965Sjdp * Intel Code. 7633965Sjdp * 7733965Sjdp * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7833965Sjdp * Intel shall be used in advertising or otherwise to promote the sale, use or 7977298Sobrien * other dealings in products derived from or relating to the Covered Code 80130561Sobrien * without prior written authorization from Intel. 8133965Sjdp * 8233965Sjdp * 4. Disclaimer and Export Compliance 8333965Sjdp * 8433965Sjdp * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8533965Sjdp * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86130561Sobrien * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8733965Sjdp * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8833965Sjdp * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8933965Sjdp * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9033965Sjdp * PARTICULAR PURPOSE. 9133965Sjdp * 9233965Sjdp * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9333965Sjdp * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9433965Sjdp * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95130561Sobrien * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9633965Sjdp * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9733965Sjdp * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9833965Sjdp * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9933965Sjdp * LIMITED REMEDY. 10033965Sjdp * 10177298Sobrien * 4.3. Licensee shall not export, either directly or indirectly, any of this 102130561Sobrien * software or system incorporating such software without first obtaining any 10333965Sjdp * required license or other approval from the U. S. Department of Commerce or 10433965Sjdp * any other agency or department of the United States Government. In the 10533965Sjdp * event Licensee exports any such software from the United States or 106218822Sdim * re-exports any such software from a foreign destination, Licensee shall 107218822Sdim * ensure that the distribution and export/re-export of the software is in 108218822Sdim * compliance with all laws, regulations, orders, or other restrictions of the 109218822Sdim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110218822Sdim * any of its subsidiaries will export/re-export any technical data, process, 111218822Sdim * software, or service, directly or indirectly, to any country for which the 112218822Sdim * United States government or any agency thereof requires an export license, 113218822Sdim * other governmental approval, or letter of assurance, without first obtaining 114218822Sdim * such license, approval or letter. 115218822Sdim * 116218822Sdim *****************************************************************************/ 117218822Sdim 118218822Sdim 119218822Sdim#define __NSXFOBJ_C__ 120218822Sdim 121218822Sdim#include "acpi.h" 122218822Sdim#include "acinterp.h" 123130561Sobrien#include "acnamesp.h" 124130561Sobrien#include "acdispat.h" 125130561Sobrien 126130561Sobrien 12733965Sjdp#define _COMPONENT ACPI_NAMESPACE 12833965Sjdp ACPI_MODULE_NAME ("nsxfobj") 129130561Sobrien 13033965Sjdp 13133965Sjdp/******************************************************************************* 13233965Sjdp * 13333965Sjdp * FUNCTION: AcpiEvaluateObject 13433965Sjdp * 13533965Sjdp * PARAMETERS: Handle - Object handle (optional) 136130561Sobrien * *Pathname - Object pathname (optional) 13733965Sjdp * **ExternalParams - List of parameters to pass to method, 13833965Sjdp * terminated by NULL. May be NULL 139130561Sobrien * if no parameters are being passed. 14033965Sjdp * *ReturnBuffer - Where to put method's return value (if 14133965Sjdp * any). If NULL, no value is returned. 14233965Sjdp * 14333965Sjdp * RETURN: Status 14433965Sjdp * 14533965Sjdp * DESCRIPTION: Find and evaluate the given object, passing the given 146130561Sobrien * parameters if necessary. One of "Handle" or "Pathname" must 14733965Sjdp * be valid (non-null) 14833965Sjdp * 14933965Sjdp ******************************************************************************/ 15033965Sjdp 15133965SjdpACPI_STATUS 15233965SjdpAcpiEvaluateObject ( 153130561Sobrien ACPI_HANDLE Handle, 15433965Sjdp ACPI_STRING Pathname, 15533965Sjdp ACPI_OBJECT_LIST *ExternalParams, 15633965Sjdp ACPI_BUFFER *ReturnBuffer) 15733965Sjdp{ 15833965Sjdp ACPI_STATUS Status; 15933965Sjdp ACPI_OPERAND_OBJECT **InternalParams = NULL; 16033965Sjdp ACPI_OPERAND_OBJECT *InternalReturnObj = NULL; 161130561Sobrien ACPI_SIZE BufferSpaceNeeded; 162130561Sobrien UINT32 i; 16333965Sjdp 164130561Sobrien 16533965Sjdp ACPI_FUNCTION_TRACE ("AcpiEvaluateObject"); 16689857Sobrien 16789857Sobrien 16889857Sobrien /* 16989857Sobrien * If there are parameters to be passed to the object 17089857Sobrien * (which must be a control method), the external objects 17189857Sobrien * must be converted to internal objects 172130561Sobrien */ 17389857Sobrien if (ExternalParams && ExternalParams->Count) 17433965Sjdp { 17589857Sobrien /* 17633965Sjdp * Allocate a new parameter block for the internal objects 17733965Sjdp * Add 1 to count to allow for null terminated internal list 17833965Sjdp */ 179218822Sdim InternalParams = ACPI_MEM_CALLOCATE ((ExternalParams->Count + 1) * 180218822Sdim sizeof (void *)); 181218822Sdim if (!InternalParams) 182218822Sdim { 183218822Sdim return_ACPI_STATUS (AE_NO_MEMORY); 184218822Sdim } 185218822Sdim 186218822Sdim /* 187218822Sdim * Convert each external object in the list to an 188218822Sdim * internal object 189218822Sdim */ 190218822Sdim for (i = 0; i < ExternalParams->Count; i++) 191218822Sdim { 192218822Sdim Status = AcpiUtCopyEobjectToIobject (&ExternalParams->Pointer[i], 193218822Sdim &InternalParams[i]); 194218822Sdim if (ACPI_FAILURE (Status)) 195218822Sdim { 196218822Sdim AcpiUtDeleteInternalObjectList (InternalParams); 197218822Sdim return_ACPI_STATUS (Status); 198218822Sdim } 199218822Sdim } 200218822Sdim InternalParams[ExternalParams->Count] = NULL; 201218822Sdim } 202218822Sdim 203218822Sdim /* 204218822Sdim * Three major cases: 205218822Sdim * 1) Fully qualified pathname 206218822Sdim * 2) No handle, not fully qualified pathname (error) 207218822Sdim * 3) Valid handle 208218822Sdim */ 20933965Sjdp if ((Pathname) && 21033965Sjdp (AcpiNsValidRootPrefix (Pathname[0]))) 211130561Sobrien { 212130561Sobrien /* 21333965Sjdp * The path is fully qualified, just evaluate by name 214130561Sobrien */ 21533965Sjdp Status = AcpiNsEvaluateByName (Pathname, InternalParams, 21689857Sobrien &InternalReturnObj); 21789857Sobrien } 21889857Sobrien else if (!Handle) 21989857Sobrien { 22089857Sobrien /* 22189857Sobrien * A handle is optional iff a fully qualified pathname 22233965Sjdp * is specified. Since we've already handled fully 223130561Sobrien * qualified names above, this is an error 22433965Sjdp */ 225130561Sobrien if (!Pathname) 22633965Sjdp { 22789857Sobrien ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 22833965Sjdp "Both Handle and Pathname are NULL\n")); 22933965Sjdp } 23033965Sjdp else 23133965Sjdp { 23233965Sjdp ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 233218822Sdim "Handle is NULL and Pathname is relative\n")); 234218822Sdim } 235218822Sdim 236218822Sdim Status = AE_BAD_PARAMETER; 237218822Sdim } 238218822Sdim else 239218822Sdim { 240218822Sdim /* 241218822Sdim * We get here if we have a handle -- and if we have a 242218822Sdim * pathname it is relative. The handle will be validated 243218822Sdim * in the lower procedures 244218822Sdim */ 245218822Sdim if (!Pathname) 246218822Sdim { 247218822Sdim /* 248218822Sdim * The null pathname case means the handle is for 249218822Sdim * the actual object to be evaluated 250218822Sdim */ 251218822Sdim Status = AcpiNsEvaluateByHandle (Handle, InternalParams, 252218822Sdim &InternalReturnObj); 253218822Sdim } 254218822Sdim else 255218822Sdim { 256218822Sdim /* 257218822Sdim * Both a Handle and a relative Pathname 258218822Sdim */ 259218822Sdim Status = AcpiNsEvaluateRelative (Handle, Pathname, InternalParams, 260218822Sdim &InternalReturnObj); 261218822Sdim } 262218822Sdim } 263218822Sdim 264218822Sdim 265218822Sdim /* 266218822Sdim * If we are expecting a return value, and all went well above, 26733965Sjdp * copy the return value to an external object. 26833965Sjdp */ 269130561Sobrien if (ReturnBuffer) 270130561Sobrien { 27133965Sjdp if (!InternalReturnObj) 272130561Sobrien { 27333965Sjdp ReturnBuffer->Length = 0; 27489857Sobrien } 27589857Sobrien else 27689857Sobrien { 27789857Sobrien if (ACPI_GET_DESCRIPTOR_TYPE (InternalReturnObj) == ACPI_DESC_TYPE_NAMED) 27889857Sobrien { 27933965Sjdp /* 280130561Sobrien * If we received a NS Node as a return object, this means that 28189857Sobrien * the object we are evaluating has nothing interesting to 28289857Sobrien * return (such as a mutex, etc.) We return an error because 28333965Sjdp * these types are essentially unsupported by this interface. 28433965Sjdp * We don't check up front because this makes it easier to add 28533965Sjdp * support for various types at a later date if necessary. 28633965Sjdp */ 28789857Sobrien Status = AE_TYPE; 28833965Sjdp InternalReturnObj = NULL; /* No need to delete a NS Node */ 28933965Sjdp ReturnBuffer->Length = 0; 29033965Sjdp } 29133965Sjdp 292218822Sdim if (ACPI_SUCCESS (Status)) 293218822Sdim { 294218822Sdim /* 295218822Sdim * Find out how large a buffer is needed 296218822Sdim * to contain the returned object 297218822Sdim */ 298218822Sdim Status = AcpiUtGetObjectSize (InternalReturnObj, 299218822Sdim &BufferSpaceNeeded); 300218822Sdim if (ACPI_SUCCESS (Status)) 301218822Sdim { 302218822Sdim /* Validate/Allocate/Clear caller buffer */ 303218822Sdim 304218822Sdim Status = AcpiUtInitializeBuffer (ReturnBuffer, BufferSpaceNeeded); 305218822Sdim if (ACPI_FAILURE (Status)) 306218822Sdim { 307218822Sdim /* 308218822Sdim * Caller's buffer is too small or a new one can't be allocated 309218822Sdim */ 310218822Sdim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 311218822Sdim "Needed buffer size %X, %s\n", 312218822Sdim BufferSpaceNeeded, AcpiFormatException (Status))); 313218822Sdim } 314218822Sdim else 315218822Sdim { 316218822Sdim /* 317218822Sdim * We have enough space for the object, build it 318218822Sdim */ 319218822Sdim Status = AcpiUtCopyIobjectToEobject (InternalReturnObj, 320218822Sdim ReturnBuffer); 321218822Sdim } 322218822Sdim } 323218822Sdim } 324218822Sdim } 325218822Sdim } 326218822Sdim 327218822Sdim /* Delete the return and parameter objects */ 328218822Sdim 329218822Sdim if (InternalReturnObj) 33033965Sjdp { 33133965Sjdp /* 33233965Sjdp * Delete the internal return object. (Or at least 33333965Sjdp * decrement the reference count by one) 33433965Sjdp */ 335130561Sobrien AcpiUtRemoveReference (InternalReturnObj); 33633965Sjdp } 33733965Sjdp 33833965Sjdp /* 33933965Sjdp * Free the input parameter list (if we created one), 34033965Sjdp */ 34133965Sjdp if (InternalParams) 34233965Sjdp { 343130561Sobrien /* Free the allocated parameter block */ 344130561Sobrien 34533965Sjdp AcpiUtDeleteInternalObjectList (InternalParams); 34633965Sjdp } 34789857Sobrien 348130561Sobrien return_ACPI_STATUS (Status); 34933965Sjdp} 35033965Sjdp 35133965Sjdp 35233965Sjdp/******************************************************************************* 35333965Sjdp * 35433965Sjdp * FUNCTION: AcpiGetNextObject 35533965Sjdp * 35633965Sjdp * PARAMETERS: Type - Type of object to be searched for 35733965Sjdp * Parent - Parent object whose children we are getting 35833965Sjdp * LastChild - Previous child that was found. 35933965Sjdp * The NEXT child will be returned 36077298Sobrien * RetHandle - Where handle to the next object is placed 36133965Sjdp * 36233965Sjdp * RETURN: Status 36333965Sjdp * 36433965Sjdp * DESCRIPTION: Return the next peer object within the namespace. If Handle is 36533965Sjdp * valid, Scope is ignored. Otherwise, the first object within 36633965Sjdp * Scope is returned. 36733965Sjdp * 36833965Sjdp ******************************************************************************/ 36933965Sjdp 37033965SjdpACPI_STATUS 37133965SjdpAcpiGetNextObject ( 37233965Sjdp ACPI_OBJECT_TYPE Type, 37333965Sjdp ACPI_HANDLE Parent, 37433965Sjdp ACPI_HANDLE Child, 37533965Sjdp ACPI_HANDLE *RetHandle) 37633965Sjdp{ 37733965Sjdp ACPI_STATUS Status; 37833965Sjdp ACPI_NAMESPACE_NODE *Node; 37933965Sjdp ACPI_NAMESPACE_NODE *ParentNode = NULL; 38033965Sjdp ACPI_NAMESPACE_NODE *ChildNode = NULL; 38133965Sjdp 38233965Sjdp 38333965Sjdp /* Parameter validation */ 38433965Sjdp 38533965Sjdp if (Type > ACPI_TYPE_MAX) 38633965Sjdp { 38733965Sjdp return (AE_BAD_PARAMETER); 38833965Sjdp } 38933965Sjdp 39033965Sjdp Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 391130561Sobrien if (ACPI_FAILURE (Status)) 39233965Sjdp { 393130561Sobrien return (Status); 39433965Sjdp } 395130561Sobrien 39633965Sjdp /* If null handle, use the parent */ 397130561Sobrien 39833965Sjdp if (!Child) 39933965Sjdp { 400130561Sobrien /* Start search at the beginning of the specified scope */ 40133965Sjdp 402130561Sobrien ParentNode = AcpiNsMapHandleToNode (Parent); 40333965Sjdp if (!ParentNode) 404130561Sobrien { 40533965Sjdp Status = AE_BAD_PARAMETER; 406130561Sobrien goto UnlockAndExit; 40733965Sjdp } 40833965Sjdp } 409130561Sobrien else 41033965Sjdp { 411130561Sobrien /* Non-null handle, ignore the parent */ 41233965Sjdp /* Convert and validate the handle */ 413130561Sobrien 41433965Sjdp ChildNode = AcpiNsMapHandleToNode (Child); 415130561Sobrien if (!ChildNode) 41633965Sjdp { 41733965Sjdp Status = AE_BAD_PARAMETER; 418130561Sobrien goto UnlockAndExit; 41933965Sjdp } 420130561Sobrien } 42133965Sjdp 422130561Sobrien /* Internal function does the real work */ 42333965Sjdp 424130561Sobrien Node = AcpiNsGetNextNode (Type, ParentNode, ChildNode); 42533965Sjdp if (!Node) 426130561Sobrien { 427130561Sobrien Status = AE_NOT_FOUND; 428130561Sobrien goto UnlockAndExit; 429130561Sobrien } 430130561Sobrien 431130561Sobrien if (RetHandle) 43260484Sobrien { 433130561Sobrien *RetHandle = AcpiNsConvertEntryToHandle (Node); 434130561Sobrien } 435130561Sobrien 436130561Sobrien 437130561SobrienUnlockAndExit: 438130561Sobrien 43960484Sobrien (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 44077298Sobrien return (Status); 44133965Sjdp} 44233965Sjdp 44333965Sjdp 44433965Sjdp/******************************************************************************* 44533965Sjdp * 44633965Sjdp * FUNCTION: AcpiGetType 44733965Sjdp * 44833965Sjdp * PARAMETERS: Handle - Handle of object whose type is desired 44989857Sobrien * *RetType - Where the type will be placed 45033965Sjdp * 45133965Sjdp * RETURN: Status 45233965Sjdp * 45333965Sjdp * DESCRIPTION: This routine returns the type associatd with a particular handle 45433965Sjdp * 45533965Sjdp ******************************************************************************/ 45633965Sjdp 45789857SobrienACPI_STATUS 45833965SjdpAcpiGetType ( 45989857Sobrien ACPI_HANDLE Handle, 46033965Sjdp ACPI_OBJECT_TYPE *RetType) 46189857Sobrien{ 46233965Sjdp ACPI_NAMESPACE_NODE *Node; 46389857Sobrien ACPI_STATUS Status; 46433965Sjdp 46533965Sjdp 46689857Sobrien /* Parameter Validation */ 46733965Sjdp 46889857Sobrien if (!RetType) 46933965Sjdp { 47089857Sobrien return (AE_BAD_PARAMETER); 47133965Sjdp } 47289857Sobrien 47333965Sjdp /* 47433965Sjdp * Special case for the predefined Root Node 47589857Sobrien * (return type ANY) 47633965Sjdp */ 47789857Sobrien if (Handle == ACPI_ROOT_OBJECT) 47833965Sjdp { 47989857Sobrien *RetType = ACPI_TYPE_ANY; 48033965Sjdp return (AE_OK); 48189857Sobrien } 48233965Sjdp 48333965Sjdp Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 48489857Sobrien if (ACPI_FAILURE (Status)) 48533965Sjdp { 48689857Sobrien return (Status); 48733965Sjdp } 48889857Sobrien 48933965Sjdp /* Convert and validate the handle */ 49089857Sobrien 49133965Sjdp Node = AcpiNsMapHandleToNode (Handle); 492130561Sobrien if (!Node) 49389857Sobrien { 494130561Sobrien (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 495130561Sobrien return (AE_BAD_PARAMETER); 496130561Sobrien } 497130561Sobrien 498130561Sobrien *RetType = Node->Type; 499130561Sobrien 500130561Sobrien 501130561Sobrien Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 502130561Sobrien return (Status); 503130561Sobrien} 504130561Sobrien 505130561Sobrien 506130561Sobrien/******************************************************************************* 507130561Sobrien * 508130561Sobrien * FUNCTION: AcpiGetParent 509130561Sobrien * 51089857Sobrien * PARAMETERS: Handle - Handle of object whose parent is desired 51189857Sobrien * RetHandle - Where the parent handle will be placed 51233965Sjdp * 51333965Sjdp * RETURN: Status 51433965Sjdp * 515130561Sobrien * DESCRIPTION: Returns a handle to the parent of the object represented by 516130561Sobrien * Handle. 51733965Sjdp * 518130561Sobrien ******************************************************************************/ 51933965Sjdp 52033965SjdpACPI_STATUS 521130561SobrienAcpiGetParent ( 52233965Sjdp ACPI_HANDLE Handle, 523130561Sobrien ACPI_HANDLE *RetHandle) 52433965Sjdp{ 52533965Sjdp ACPI_NAMESPACE_NODE *Node; 52633965Sjdp ACPI_STATUS Status; 52733965Sjdp 528130561Sobrien 52933965Sjdp if (!RetHandle) 530130561Sobrien { 53133965Sjdp return (AE_BAD_PARAMETER); 53233965Sjdp } 53333965Sjdp 53433965Sjdp /* Special case for the predefined Root Node (no parent) */ 535130561Sobrien 53633965Sjdp if (Handle == ACPI_ROOT_OBJECT) 537130561Sobrien { 538130561Sobrien return (AE_NULL_ENTRY); 53933965Sjdp } 54033965Sjdp 54133965Sjdp Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 542130561Sobrien if (ACPI_FAILURE (Status)) 54333965Sjdp { 544130561Sobrien return (Status); 545130561Sobrien } 54633965Sjdp 54733965Sjdp /* Convert and validate the handle */ 54833965Sjdp 549130561Sobrien Node = AcpiNsMapHandleToNode (Handle); 55033965Sjdp if (!Node) 551130561Sobrien { 552130561Sobrien Status = AE_BAD_PARAMETER; 553130561Sobrien goto UnlockAndExit; 55433965Sjdp } 55533965Sjdp 55633965Sjdp /* Get the parent entry */ 557130561Sobrien 55833965Sjdp *RetHandle = 559130561Sobrien AcpiNsConvertEntryToHandle (AcpiNsGetParentNode (Node)); 560130561Sobrien 561130561Sobrien /* Return exeption if parent is null */ 56233965Sjdp 56333965Sjdp if (!AcpiNsGetParentNode (Node)) 56433965Sjdp { 565130561Sobrien Status = AE_NULL_ENTRY; 56633965Sjdp } 567130561Sobrien 56860484Sobrien 56960484SobrienUnlockAndExit: 57060484Sobrien 57160484Sobrien (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 57260484Sobrien return (Status); 57360484Sobrien} 574130561Sobrien 57533965Sjdp 57633965Sjdp/******************************************************************************* 57733965Sjdp * 578130561Sobrien * FUNCTION: AcpiWalkNamespace 57933965Sjdp * 580130561Sobrien * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 58160484Sobrien * StartObject - Handle in namespace where search begins 58260484Sobrien * MaxDepth - Depth to which search is to reach 58360484Sobrien * UserFunction - Called when an object of "Type" is found 58460484Sobrien * Context - Passed to user function 58560484Sobrien * ReturnValue - Location where return value of 58660484Sobrien * UserFunction is put if terminated early 587130561Sobrien * 58833965Sjdp * RETURNS Return value from the UserFunction if terminated early. 58933965Sjdp * Otherwise, returns NULL. 59033965Sjdp * 591130561Sobrien * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 59233965Sjdp * starting (and ending) at the object specified by StartHandle. 593130561Sobrien * The UserFunction is called whenever an object that matches 59460484Sobrien * the type parameter is found. If the user function returns 59560484Sobrien * a non-zero value, the search is terminated immediately and this 59660484Sobrien * value is returned to the caller. 59760484Sobrien * 59860484Sobrien * The point of this procedure is to provide a generic namespace 59960484Sobrien * walk routine that can be called from multiple places to 60060484Sobrien * provide multiple services; the User Function can be tailored 60133965Sjdp * to each task, whether it is a print function, a compare 60233965Sjdp * function, etc. 60333965Sjdp * 604130561Sobrien ******************************************************************************/ 60533965Sjdp 606130561SobrienACPI_STATUS 60760484SobrienAcpiWalkNamespace ( 60860484Sobrien ACPI_OBJECT_TYPE Type, 60960484Sobrien ACPI_HANDLE StartObject, 61060484Sobrien UINT32 MaxDepth, 61160484Sobrien ACPI_WALK_CALLBACK UserFunction, 61260484Sobrien void *Context, 61360484Sobrien void **ReturnValue) 61433965Sjdp{ 61533965Sjdp ACPI_STATUS Status; 616130561Sobrien 617130561Sobrien 61833965Sjdp ACPI_FUNCTION_TRACE ("AcpiWalkNamespace"); 619130561Sobrien 620130561Sobrien 621130561Sobrien /* Parameter validation */ 62233965Sjdp 623130561Sobrien if ((Type > ACPI_TYPE_MAX) || 624130561Sobrien (!MaxDepth) || 625130561Sobrien (!UserFunction)) 626130561Sobrien { 627130561Sobrien return_ACPI_STATUS (AE_BAD_PARAMETER); 628130561Sobrien } 629130561Sobrien 630130561Sobrien /* 63133965Sjdp * Lock the namespace around the walk. 632130561Sobrien * The namespace will be unlocked/locked around each call 63333965Sjdp * to the user function - since this function 63433965Sjdp * must be allowed to make Acpi calls itself. 63533965Sjdp */ 63633965Sjdp Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 63733965Sjdp if (ACPI_FAILURE (Status)) 63833965Sjdp { 639130561Sobrien return_ACPI_STATUS (Status); 640130561Sobrien } 64133965Sjdp 642130561Sobrien Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, ACPI_NS_WALK_UNLOCK, 643130561Sobrien UserFunction, Context, ReturnValue); 644130561Sobrien 64533965Sjdp (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 646130561Sobrien return_ACPI_STATUS (Status); 647130561Sobrien} 648130561Sobrien 649130561Sobrien 650130561Sobrien/******************************************************************************* 651130561Sobrien * 652130561Sobrien * FUNCTION: AcpiNsGetDeviceCallback 653130561Sobrien * 65433965Sjdp * PARAMETERS: Callback from AcpiGetDevice 655130561Sobrien * 65633965Sjdp * RETURN: Status 65733965Sjdp * 65833965Sjdp * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 65933965Sjdp * present devices, or if they specified a HID, it filters based 66033965Sjdp * on that. 66133965Sjdp * 66233965Sjdp ******************************************************************************/ 663130561Sobrien 664130561Sobrienstatic ACPI_STATUS 66533965SjdpAcpiNsGetDeviceCallback ( 666130561Sobrien ACPI_HANDLE ObjHandle, 667130561Sobrien UINT32 NestingLevel, 668130561Sobrien void *Context, 66933965Sjdp void **ReturnValue) 670130561Sobrien{ 671130561Sobrien ACPI_STATUS Status; 672130561Sobrien ACPI_NAMESPACE_NODE *Node; 673130561Sobrien UINT32 Flags; 674130561Sobrien ACPI_DEVICE_ID Hid; 675130561Sobrien ACPI_DEVICE_ID Cid; 676130561Sobrien ACPI_GET_DEVICES_INFO *Info; 677130561Sobrien 67833965Sjdp 679130561Sobrien Info = Context; 68033965Sjdp 68133965Sjdp Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 68233965Sjdp if (ACPI_FAILURE (Status)) 68333965Sjdp { 68433965Sjdp return (Status); 68533965Sjdp } 686130561Sobrien 687130561Sobrien Node = AcpiNsMapHandleToNode (ObjHandle); 68833965Sjdp Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 689130561Sobrien if (ACPI_FAILURE (Status)) 690130561Sobrien { 691130561Sobrien return (Status); 69233965Sjdp } 693130561Sobrien 694130561Sobrien if (!Node) 695130561Sobrien { 696130561Sobrien return (AE_BAD_PARAMETER); 697130561Sobrien } 698130561Sobrien 699130561Sobrien /* 700130561Sobrien * Run _STA to determine if device is present 70133965Sjdp */ 702130561Sobrien Status = AcpiUtExecute_STA (Node, &Flags); 70333965Sjdp if (ACPI_FAILURE (Status)) 70433965Sjdp { 70533965Sjdp return (AE_CTRL_DEPTH); 70633965Sjdp } 70733965Sjdp 70833965Sjdp if (!(Flags & 0x01)) 70933965Sjdp { 710130561Sobrien /* Don't return at the device or children of the device if not there */ 71133965Sjdp return (AE_CTRL_DEPTH); 712130561Sobrien } 713130561Sobrien 714130561Sobrien /* 715130561Sobrien * Filter based on device HID & CID 716130561Sobrien */ 71733965Sjdp if (Info->Hid != NULL) 71833965Sjdp { 71933965Sjdp Status = AcpiUtExecute_HID (Node, &Hid); 720130561Sobrien if (Status == AE_NOT_FOUND) 72133965Sjdp { 722130561Sobrien return (AE_OK); 723130561Sobrien } 724130561Sobrien else if (ACPI_FAILURE (Status)) 725130561Sobrien { 726130561Sobrien return (AE_CTRL_DEPTH); 72733965Sjdp } 72833965Sjdp 72933965Sjdp if (ACPI_STRNCMP (Hid.Buffer, Info->Hid, sizeof (Hid.Buffer)) != 0) 730130561Sobrien { 73133965Sjdp Status = AcpiUtExecute_CID (Node, &Cid); 732130561Sobrien if (Status == AE_NOT_FOUND) 733130561Sobrien { 734130561Sobrien return (AE_OK); 735130561Sobrien } 736130561Sobrien else if (ACPI_FAILURE (Status)) 737130561Sobrien { 738130561Sobrien return (AE_CTRL_DEPTH); 739130561Sobrien } 740130561Sobrien 741130561Sobrien /* TBD: Handle CID packages */ 74233965Sjdp 74333965Sjdp if (ACPI_STRNCMP (Cid.Buffer, Info->Hid, sizeof (Cid.Buffer)) != 0) 74433965Sjdp { 74533965Sjdp return (AE_OK); 74633965Sjdp } 74733965Sjdp } 748130561Sobrien } 74933965Sjdp 750130561Sobrien Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue); 751130561Sobrien return (AE_OK); 752130561Sobrien} 753130561Sobrien 754130561Sobrien 755130561Sobrien/******************************************************************************* 756130561Sobrien * 757130561Sobrien * FUNCTION: AcpiGetDevices 758130561Sobrien * 759130561Sobrien * PARAMETERS: HID - HID to search for. Can be NULL. 76033965Sjdp * UserFunction - Called when a matching object is found 76133965Sjdp * Context - Passed to user function 76233965Sjdp * ReturnValue - Location where return value of 76333965Sjdp * UserFunction is put if terminated early 76477298Sobrien * 76577298Sobrien * RETURNS Return value from the UserFunction if terminated early. 766130561Sobrien * Otherwise, returns NULL. 76777298Sobrien * 768130561Sobrien * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 76977298Sobrien * starting (and ending) at the object specified by StartHandle. 77077298Sobrien * The UserFunction is called whenever an object that matches 77177298Sobrien * the type parameter is found. If the user function returns 77277298Sobrien * a non-zero value, the search is terminated immediately and this 77377298Sobrien * value is returned to the caller. 77477298Sobrien * 77577298Sobrien * This is a wrapper for WalkNamespace, but the callback performs 77677298Sobrien * additional filtering. Please see AcpiGetDeviceCallback. 77777298Sobrien * 77877298Sobrien ******************************************************************************/ 77977298Sobrien 780130561SobrienACPI_STATUS 78177298SobrienAcpiGetDevices ( 78277298Sobrien NATIVE_CHAR *HID, 78377298Sobrien ACPI_WALK_CALLBACK UserFunction, 78477298Sobrien void *Context, 785130561Sobrien void **ReturnValue) 786130561Sobrien{ 78777298Sobrien ACPI_STATUS Status; 788130561Sobrien ACPI_GET_DEVICES_INFO Info; 789130561Sobrien 79077298Sobrien 79177298Sobrien ACPI_FUNCTION_TRACE ("AcpiGetDevices"); 79277298Sobrien 79377298Sobrien 79477298Sobrien /* Parameter validation */ 79577298Sobrien 79677298Sobrien if (!UserFunction) 79777298Sobrien { 79877298Sobrien return_ACPI_STATUS (AE_BAD_PARAMETER); 79977298Sobrien } 80077298Sobrien 80177298Sobrien /* 80277298Sobrien * We're going to call their callback from OUR callback, so we need 80377298Sobrien * to know what it is, and their context parameter. 80477298Sobrien */ 80577298Sobrien Info.Context = Context; 80677298Sobrien Info.UserFunction = UserFunction; 80733965Sjdp Info.Hid = HID; 80833965Sjdp 80933965Sjdp /* 810130561Sobrien * Lock the namespace around the walk. 811130561Sobrien * The namespace will be unlocked/locked around each call 812130561Sobrien * to the user function - since this function 813130561Sobrien * must be allowed to make Acpi calls itself. 814130561Sobrien */ 815130561Sobrien Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 81633965Sjdp if (ACPI_FAILURE (Status)) 817218822Sdim { 81860484Sobrien return_ACPI_STATUS (Status); 819130561Sobrien } 82060484Sobrien 821218822Sdim Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, 822218822Sdim ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 82360484Sobrien ACPI_NS_WALK_UNLOCK, 82460484Sobrien AcpiNsGetDeviceCallback, &Info, 825130561Sobrien ReturnValue); 82660484Sobrien 82760484Sobrien (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 82860484Sobrien return_ACPI_STATUS (Status); 82989857Sobrien} 830130561Sobrien 83160484Sobrien 832130561Sobrien/******************************************************************************* 83333965Sjdp * 83433965Sjdp * FUNCTION: AcpiAttachData 835130561Sobrien * 836130561Sobrien * PARAMETERS: 837130561Sobrien * 838130561Sobrien * RETURN: Status 839130561Sobrien * 840130561Sobrien * DESCRIPTION: 841130561Sobrien * 84233965Sjdp ******************************************************************************/ 84333965Sjdp 844218822SdimACPI_STATUS 845218822SdimAcpiAttachData ( 84633965Sjdp ACPI_HANDLE ObjHandle, 847130561Sobrien ACPI_OBJECT_HANDLER Handler, 848130561Sobrien void *Data) 849130561Sobrien{ 85033965Sjdp ACPI_NAMESPACE_NODE *Node; 85133965Sjdp ACPI_STATUS Status; 85233965Sjdp 85333965Sjdp 85433965Sjdp /* Parameter validation */ 85533965Sjdp 85633965Sjdp if (!ObjHandle || 857130561Sobrien !Handler || 85833965Sjdp !Data) 859130561Sobrien { 860130561Sobrien return (AE_BAD_PARAMETER); 86133965Sjdp } 86233965Sjdp 86333965Sjdp Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 86433965Sjdp if (ACPI_FAILURE (Status)) 865130561Sobrien { 86633965Sjdp return (Status); 86733965Sjdp } 86833965Sjdp 86933965Sjdp /* Convert and validate the handle */ 87033965Sjdp 87133965Sjdp Node = AcpiNsMapHandleToNode (ObjHandle); 87233965Sjdp if (!Node) 873218822Sdim { 874218822Sdim Status = AE_BAD_PARAMETER; 875104834Sobrien goto UnlockAndExit; 876130561Sobrien } 877130561Sobrien 878130561Sobrien Status = AcpiNsAttachData (Node, Handler, Data); 87933965Sjdp 88033965SjdpUnlockAndExit: 88133965Sjdp (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 88233965Sjdp return (Status); 88333965Sjdp} 88433965Sjdp 88533965Sjdp 88633965Sjdp/******************************************************************************* 88733965Sjdp * 888130561Sobrien * FUNCTION: AcpiDetachData 889130561Sobrien * 890130561Sobrien * PARAMETERS: 891130561Sobrien * 892130561Sobrien * RETURN: Status 893130561Sobrien * 89433965Sjdp * DESCRIPTION: 89533965Sjdp * 896130561Sobrien ******************************************************************************/ 89733965Sjdp 89889857SobrienACPI_STATUS 89989857SobrienAcpiDetachData ( 900130561Sobrien ACPI_HANDLE ObjHandle, 90133965Sjdp ACPI_OBJECT_HANDLER Handler) 902130561Sobrien{ 90333965Sjdp ACPI_NAMESPACE_NODE *Node; 90433965Sjdp ACPI_STATUS Status; 90533965Sjdp 90633965Sjdp 90733965Sjdp /* Parameter validation */ 90833965Sjdp 90933965Sjdp if (!ObjHandle || 91089857Sobrien !Handler) 91133965Sjdp { 91233965Sjdp return (AE_BAD_PARAMETER); 91333965Sjdp } 91489857Sobrien 91533965Sjdp Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 91633965Sjdp if (ACPI_FAILURE (Status)) 91760484Sobrien { 918130561Sobrien return (Status); 91933965Sjdp } 92060484Sobrien 92160484Sobrien /* Convert and validate the handle */ 92260484Sobrien 92360484Sobrien Node = AcpiNsMapHandleToNode (ObjHandle); 92433965Sjdp if (!Node) 92533965Sjdp { 92633965Sjdp Status = AE_BAD_PARAMETER; 927130561Sobrien goto UnlockAndExit; 928130561Sobrien } 92933965Sjdp 93033965Sjdp Status = AcpiNsDetachData (Node, Handler); 93133965Sjdp 932130561SobrienUnlockAndExit: 93333965Sjdp (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 93433965Sjdp return (Status); 93560484Sobrien} 93660484Sobrien 937130561Sobrien 938130561Sobrien/******************************************************************************* 939130561Sobrien * 94060484Sobrien * FUNCTION: AcpiGetData 94160484Sobrien * 94277298Sobrien * PARAMETERS: 94360484Sobrien * 94460484Sobrien * RETURN: Status 94577298Sobrien * 94660484Sobrien * DESCRIPTION: 94777298Sobrien * 948218822Sdim ******************************************************************************/ 94977298Sobrien 950218822SdimACPI_STATUS 95177298SobrienAcpiGetData ( 952218822Sdim ACPI_HANDLE ObjHandle, 95377298Sobrien ACPI_OBJECT_HANDLER Handler, 95460484Sobrien void **Data) 955130561Sobrien{ 95660484Sobrien ACPI_NAMESPACE_NODE *Node; 95760484Sobrien ACPI_STATUS Status; 958130561Sobrien 95960484Sobrien 96089857Sobrien /* Parameter validation */ 96189857Sobrien 96289857Sobrien if (!ObjHandle || 96391041Sobrien !Handler || 96489857Sobrien !Data) 965130561Sobrien { 966130561Sobrien return (AE_BAD_PARAMETER); 967130561Sobrien } 968130561Sobrien 96989857Sobrien Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 97089857Sobrien if (ACPI_FAILURE (Status)) 97189857Sobrien { 97289857Sobrien return (Status); 97389857Sobrien } 97489857Sobrien 975130561Sobrien /* Convert and validate the handle */ 97691041Sobrien 97789857Sobrien Node = AcpiNsMapHandleToNode (ObjHandle); 97891041Sobrien if (!Node) 97991041Sobrien { 98089857Sobrien Status = AE_BAD_PARAMETER; 98191041Sobrien goto UnlockAndExit; 98289857Sobrien } 98389857Sobrien 98489857Sobrien Status = AcpiNsGetAttachedData (Node, Handler, Data); 985218822Sdim 986218822SdimUnlockAndExit: 987218822Sdim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 988218822Sdim return (Status); 989218822Sdim} 990218822Sdim 991218822Sdim 992218822Sdim