nsxfeval.c revision 128212
1100966Siwasaki/******************************************************************************* 2100966Siwasaki * 3100966Siwasaki * Module Name: nsxfeval - Public interfaces to the ACPI subsystem 4100966Siwasaki * ACPI Object evaluation interfaces 5128212Snjl * $Revision: 12 $ 6100966Siwasaki * 7100966Siwasaki ******************************************************************************/ 8100966Siwasaki 9100966Siwasaki/****************************************************************************** 10100966Siwasaki * 11100966Siwasaki * 1. Copyright Notice 12100966Siwasaki * 13126372Snjl * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp. 14100966Siwasaki * All rights reserved. 15100966Siwasaki * 16100966Siwasaki * 2. License 17100966Siwasaki * 18100966Siwasaki * 2.1. This is your license from Intel Corp. under its intellectual property 19100966Siwasaki * rights. You may have additional license terms from the party that provided 20100966Siwasaki * you this software, covering your right to use that party's intellectual 21100966Siwasaki * property rights. 22100966Siwasaki * 23100966Siwasaki * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24100966Siwasaki * copy of the source code appearing in this file ("Covered Code") an 25100966Siwasaki * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26100966Siwasaki * base code distributed originally by Intel ("Original Intel Code") to copy, 27100966Siwasaki * make derivatives, distribute, use and display any portion of the Covered 28100966Siwasaki * Code in any form, with the right to sublicense such rights; and 29100966Siwasaki * 30100966Siwasaki * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31100966Siwasaki * license (with the right to sublicense), under only those claims of Intel 32100966Siwasaki * patents that are infringed by the Original Intel Code, to make, use, sell, 33100966Siwasaki * offer to sell, and import the Covered Code and derivative works thereof 34100966Siwasaki * solely to the minimum extent necessary to exercise the above copyright 35100966Siwasaki * license, and in no event shall the patent license extend to any additions 36100966Siwasaki * to or modifications of the Original Intel Code. No other license or right 37100966Siwasaki * is granted directly or by implication, estoppel or otherwise; 38100966Siwasaki * 39100966Siwasaki * The above copyright and patent license is granted only if the following 40100966Siwasaki * conditions are met: 41100966Siwasaki * 42100966Siwasaki * 3. Conditions 43100966Siwasaki * 44100966Siwasaki * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45100966Siwasaki * Redistribution of source code of any substantial portion of the Covered 46100966Siwasaki * Code or modification with rights to further distribute source must include 47100966Siwasaki * the above Copyright Notice, the above License, this list of Conditions, 48100966Siwasaki * and the following Disclaimer and Export Compliance provision. In addition, 49100966Siwasaki * Licensee must cause all Covered Code to which Licensee contributes to 50100966Siwasaki * contain a file documenting the changes Licensee made to create that Covered 51100966Siwasaki * Code and the date of any change. Licensee must include in that file the 52100966Siwasaki * documentation of any changes made by any predecessor Licensee. Licensee 53100966Siwasaki * must include a prominent statement that the modification is derived, 54100966Siwasaki * directly or indirectly, from Original Intel Code. 55100966Siwasaki * 56100966Siwasaki * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57100966Siwasaki * Redistribution of source code of any substantial portion of the Covered 58100966Siwasaki * Code or modification without rights to further distribute source must 59100966Siwasaki * include the following Disclaimer and Export Compliance provision in the 60100966Siwasaki * documentation and/or other materials provided with distribution. In 61100966Siwasaki * addition, Licensee may not authorize further sublicense of source of any 62100966Siwasaki * portion of the Covered Code, and must include terms to the effect that the 63100966Siwasaki * license from Licensee to its licensee is limited to the intellectual 64100966Siwasaki * property embodied in the software Licensee provides to its licensee, and 65100966Siwasaki * not to intellectual property embodied in modifications its licensee may 66100966Siwasaki * make. 67100966Siwasaki * 68100966Siwasaki * 3.3. Redistribution of Executable. Redistribution in executable form of any 69100966Siwasaki * substantial portion of the Covered Code or modification must reproduce the 70100966Siwasaki * above Copyright Notice, and the following Disclaimer and Export Compliance 71100966Siwasaki * provision in the documentation and/or other materials provided with the 72100966Siwasaki * distribution. 73100966Siwasaki * 74100966Siwasaki * 3.4. Intel retains all right, title, and interest in and to the Original 75100966Siwasaki * Intel Code. 76100966Siwasaki * 77100966Siwasaki * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78100966Siwasaki * Intel shall be used in advertising or otherwise to promote the sale, use or 79100966Siwasaki * other dealings in products derived from or relating to the Covered Code 80100966Siwasaki * without prior written authorization from Intel. 81100966Siwasaki * 82100966Siwasaki * 4. Disclaimer and Export Compliance 83100966Siwasaki * 84100966Siwasaki * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85100966Siwasaki * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86100966Siwasaki * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87100966Siwasaki * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88100966Siwasaki * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89100966Siwasaki * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90100966Siwasaki * PARTICULAR PURPOSE. 91100966Siwasaki * 92100966Siwasaki * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93100966Siwasaki * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94100966Siwasaki * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95100966Siwasaki * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96100966Siwasaki * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97100966Siwasaki * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98100966Siwasaki * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99100966Siwasaki * LIMITED REMEDY. 100100966Siwasaki * 101100966Siwasaki * 4.3. Licensee shall not export, either directly or indirectly, any of this 102100966Siwasaki * software or system incorporating such software without first obtaining any 103100966Siwasaki * required license or other approval from the U. S. Department of Commerce or 104100966Siwasaki * any other agency or department of the United States Government. In the 105100966Siwasaki * event Licensee exports any such software from the United States or 106100966Siwasaki * re-exports any such software from a foreign destination, Licensee shall 107100966Siwasaki * ensure that the distribution and export/re-export of the software is in 108100966Siwasaki * compliance with all laws, regulations, orders, or other restrictions of the 109100966Siwasaki * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110100966Siwasaki * any of its subsidiaries will export/re-export any technical data, process, 111100966Siwasaki * software, or service, directly or indirectly, to any country for which the 112100966Siwasaki * United States government or any agency thereof requires an export license, 113100966Siwasaki * other governmental approval, or letter of assurance, without first obtaining 114100966Siwasaki * such license, approval or letter. 115100966Siwasaki * 116100966Siwasaki *****************************************************************************/ 117100966Siwasaki 118100966Siwasaki 119100966Siwasaki#define __NSXFEVAL_C__ 120100966Siwasaki 121100966Siwasaki#include "acpi.h" 122100966Siwasaki#include "acnamesp.h" 123128212Snjl#include "acinterp.h" 124100966Siwasaki 125100966Siwasaki 126100966Siwasaki#define _COMPONENT ACPI_NAMESPACE 127100966Siwasaki ACPI_MODULE_NAME ("nsxfeval") 128100966Siwasaki 129100966Siwasaki 130100966Siwasaki/******************************************************************************* 131100966Siwasaki * 132100966Siwasaki * FUNCTION: AcpiEvaluateObjectTyped 133100966Siwasaki * 134100966Siwasaki * PARAMETERS: Handle - Object handle (optional) 135100966Siwasaki * *Pathname - Object pathname (optional) 136100966Siwasaki * **ExternalParams - List of parameters to pass to method, 137100966Siwasaki * terminated by NULL. May be NULL 138100966Siwasaki * if no parameters are being passed. 139100966Siwasaki * *ReturnBuffer - Where to put method's return value (if 140100966Siwasaki * any). If NULL, no value is returned. 141100966Siwasaki * ReturnType - Expected type of return object 142100966Siwasaki * 143100966Siwasaki * RETURN: Status 144100966Siwasaki * 145100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given 146100966Siwasaki * parameters if necessary. One of "Handle" or "Pathname" must 147100966Siwasaki * be valid (non-null) 148100966Siwasaki * 149100966Siwasaki ******************************************************************************/ 150100966Siwasaki 151100966SiwasakiACPI_STATUS 152100966SiwasakiAcpiEvaluateObjectTyped ( 153100966Siwasaki ACPI_HANDLE Handle, 154100966Siwasaki ACPI_STRING Pathname, 155100966Siwasaki ACPI_OBJECT_LIST *ExternalParams, 156100966Siwasaki ACPI_BUFFER *ReturnBuffer, 157100966Siwasaki ACPI_OBJECT_TYPE ReturnType) 158100966Siwasaki{ 159100966Siwasaki ACPI_STATUS Status; 160100966Siwasaki BOOLEAN MustFree = FALSE; 161100966Siwasaki 162100966Siwasaki 163100966Siwasaki ACPI_FUNCTION_TRACE ("AcpiEvaluateObjectTyped"); 164100966Siwasaki 165100966Siwasaki 166100966Siwasaki /* Return buffer must be valid */ 167100966Siwasaki 168100966Siwasaki if (!ReturnBuffer) 169100966Siwasaki { 170100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 171100966Siwasaki } 172100966Siwasaki 173100966Siwasaki if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) 174100966Siwasaki { 175100966Siwasaki MustFree = TRUE; 176100966Siwasaki } 177100966Siwasaki 178100966Siwasaki /* Evaluate the object */ 179100966Siwasaki 180100966Siwasaki Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer); 181100966Siwasaki if (ACPI_FAILURE (Status)) 182100966Siwasaki { 183100966Siwasaki return_ACPI_STATUS (Status); 184100966Siwasaki } 185100966Siwasaki 186100966Siwasaki /* Type ANY means "don't care" */ 187100966Siwasaki 188100966Siwasaki if (ReturnType == ACPI_TYPE_ANY) 189100966Siwasaki { 190100966Siwasaki return_ACPI_STATUS (AE_OK); 191100966Siwasaki } 192100966Siwasaki 193100966Siwasaki if (ReturnBuffer->Length == 0) 194100966Siwasaki { 195100966Siwasaki /* Error because caller specifically asked for a return value */ 196100966Siwasaki 197100966Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 198100966Siwasaki "No return value\n")); 199100966Siwasaki 200100966Siwasaki return_ACPI_STATUS (AE_NULL_OBJECT); 201100966Siwasaki } 202100966Siwasaki 203100966Siwasaki /* Examine the object type returned from EvaluateObject */ 204100966Siwasaki 205100966Siwasaki if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) 206100966Siwasaki { 207100966Siwasaki return_ACPI_STATUS (AE_OK); 208100966Siwasaki } 209100966Siwasaki 210100966Siwasaki /* Return object type does not match requested type */ 211100966Siwasaki 212100966Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 213100966Siwasaki "Incorrect return type [%s] requested [%s]\n", 214100966Siwasaki AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), 215100966Siwasaki AcpiUtGetTypeName (ReturnType))); 216100966Siwasaki 217100966Siwasaki if (MustFree) 218100966Siwasaki { 219100966Siwasaki /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ 220100966Siwasaki 221100966Siwasaki AcpiOsFree (ReturnBuffer->Pointer); 222100966Siwasaki ReturnBuffer->Pointer = NULL; 223100966Siwasaki } 224100966Siwasaki 225100966Siwasaki ReturnBuffer->Length = 0; 226100966Siwasaki return_ACPI_STATUS (AE_TYPE); 227100966Siwasaki} 228100966Siwasaki 229100966Siwasaki 230100966Siwasaki/******************************************************************************* 231100966Siwasaki * 232100966Siwasaki * FUNCTION: AcpiEvaluateObject 233100966Siwasaki * 234100966Siwasaki * PARAMETERS: Handle - Object handle (optional) 235128212Snjl * Pathname - Object pathname (optional) 236128212Snjl * ExternalParams - List of parameters to pass to method, 237100966Siwasaki * terminated by NULL. May be NULL 238100966Siwasaki * if no parameters are being passed. 239128212Snjl * ReturnBuffer - Where to put method's return value (if 240100966Siwasaki * any). If NULL, no value is returned. 241100966Siwasaki * 242100966Siwasaki * RETURN: Status 243100966Siwasaki * 244100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given 245100966Siwasaki * parameters if necessary. One of "Handle" or "Pathname" must 246100966Siwasaki * be valid (non-null) 247100966Siwasaki * 248100966Siwasaki ******************************************************************************/ 249100966Siwasaki 250100966SiwasakiACPI_STATUS 251100966SiwasakiAcpiEvaluateObject ( 252100966Siwasaki ACPI_HANDLE Handle, 253100966Siwasaki ACPI_STRING Pathname, 254100966Siwasaki ACPI_OBJECT_LIST *ExternalParams, 255100966Siwasaki ACPI_BUFFER *ReturnBuffer) 256100966Siwasaki{ 257100966Siwasaki ACPI_STATUS Status; 258128212Snjl ACPI_STATUS Status2; 259100966Siwasaki ACPI_OPERAND_OBJECT **InternalParams = NULL; 260100966Siwasaki ACPI_OPERAND_OBJECT *InternalReturnObj = NULL; 261100966Siwasaki ACPI_SIZE BufferSpaceNeeded; 262100966Siwasaki UINT32 i; 263100966Siwasaki 264100966Siwasaki 265100966Siwasaki ACPI_FUNCTION_TRACE ("AcpiEvaluateObject"); 266100966Siwasaki 267100966Siwasaki 268100966Siwasaki /* 269100966Siwasaki * If there are parameters to be passed to the object 270100966Siwasaki * (which must be a control method), the external objects 271100966Siwasaki * must be converted to internal objects 272100966Siwasaki */ 273100966Siwasaki if (ExternalParams && ExternalParams->Count) 274100966Siwasaki { 275100966Siwasaki /* 276100966Siwasaki * Allocate a new parameter block for the internal objects 277100966Siwasaki * Add 1 to count to allow for null terminated internal list 278100966Siwasaki */ 279100966Siwasaki InternalParams = ACPI_MEM_CALLOCATE (((ACPI_SIZE) ExternalParams->Count + 1) * 280100966Siwasaki sizeof (void *)); 281100966Siwasaki if (!InternalParams) 282100966Siwasaki { 283100966Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 284100966Siwasaki } 285100966Siwasaki 286100966Siwasaki /* 287100966Siwasaki * Convert each external object in the list to an 288100966Siwasaki * internal object 289100966Siwasaki */ 290100966Siwasaki for (i = 0; i < ExternalParams->Count; i++) 291100966Siwasaki { 292100966Siwasaki Status = AcpiUtCopyEobjectToIobject (&ExternalParams->Pointer[i], 293128212Snjl &InternalParams[i]); 294100966Siwasaki if (ACPI_FAILURE (Status)) 295100966Siwasaki { 296100966Siwasaki AcpiUtDeleteInternalObjectList (InternalParams); 297100966Siwasaki return_ACPI_STATUS (Status); 298100966Siwasaki } 299100966Siwasaki } 300100966Siwasaki InternalParams[ExternalParams->Count] = NULL; 301100966Siwasaki } 302100966Siwasaki 303100966Siwasaki /* 304100966Siwasaki * Three major cases: 305100966Siwasaki * 1) Fully qualified pathname 306100966Siwasaki * 2) No handle, not fully qualified pathname (error) 307100966Siwasaki * 3) Valid handle 308100966Siwasaki */ 309100966Siwasaki if ((Pathname) && 310100966Siwasaki (AcpiNsValidRootPrefix (Pathname[0]))) 311100966Siwasaki { 312100966Siwasaki /* 313100966Siwasaki * The path is fully qualified, just evaluate by name 314100966Siwasaki */ 315100966Siwasaki Status = AcpiNsEvaluateByName (Pathname, InternalParams, 316100966Siwasaki &InternalReturnObj); 317100966Siwasaki } 318100966Siwasaki else if (!Handle) 319100966Siwasaki { 320100966Siwasaki /* 321100966Siwasaki * A handle is optional iff a fully qualified pathname 322100966Siwasaki * is specified. Since we've already handled fully 323100966Siwasaki * qualified names above, this is an error 324100966Siwasaki */ 325100966Siwasaki if (!Pathname) 326100966Siwasaki { 327100966Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 328100966Siwasaki "Both Handle and Pathname are NULL\n")); 329100966Siwasaki } 330100966Siwasaki else 331100966Siwasaki { 332100966Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 333100966Siwasaki "Handle is NULL and Pathname is relative\n")); 334100966Siwasaki } 335100966Siwasaki 336100966Siwasaki Status = AE_BAD_PARAMETER; 337100966Siwasaki } 338100966Siwasaki else 339100966Siwasaki { 340100966Siwasaki /* 341100966Siwasaki * We get here if we have a handle -- and if we have a 342100966Siwasaki * pathname it is relative. The handle will be validated 343100966Siwasaki * in the lower procedures 344100966Siwasaki */ 345100966Siwasaki if (!Pathname) 346100966Siwasaki { 347100966Siwasaki /* 348100966Siwasaki * The null pathname case means the handle is for 349100966Siwasaki * the actual object to be evaluated 350100966Siwasaki */ 351100966Siwasaki Status = AcpiNsEvaluateByHandle (Handle, InternalParams, 352100966Siwasaki &InternalReturnObj); 353100966Siwasaki } 354100966Siwasaki else 355100966Siwasaki { 356100966Siwasaki /* 357100966Siwasaki * Both a Handle and a relative Pathname 358100966Siwasaki */ 359100966Siwasaki Status = AcpiNsEvaluateRelative (Handle, Pathname, InternalParams, 360100966Siwasaki &InternalReturnObj); 361100966Siwasaki } 362100966Siwasaki } 363100966Siwasaki 364100966Siwasaki 365100966Siwasaki /* 366100966Siwasaki * If we are expecting a return value, and all went well above, 367100966Siwasaki * copy the return value to an external object. 368100966Siwasaki */ 369100966Siwasaki if (ReturnBuffer) 370100966Siwasaki { 371100966Siwasaki if (!InternalReturnObj) 372100966Siwasaki { 373100966Siwasaki ReturnBuffer->Length = 0; 374100966Siwasaki } 375100966Siwasaki else 376100966Siwasaki { 377100966Siwasaki if (ACPI_GET_DESCRIPTOR_TYPE (InternalReturnObj) == ACPI_DESC_TYPE_NAMED) 378100966Siwasaki { 379100966Siwasaki /* 380100966Siwasaki * If we received a NS Node as a return object, this means that 381100966Siwasaki * the object we are evaluating has nothing interesting to 382100966Siwasaki * return (such as a mutex, etc.) We return an error because 383100966Siwasaki * these types are essentially unsupported by this interface. 384100966Siwasaki * We don't check up front because this makes it easier to add 385100966Siwasaki * support for various types at a later date if necessary. 386100966Siwasaki */ 387100966Siwasaki Status = AE_TYPE; 388100966Siwasaki InternalReturnObj = NULL; /* No need to delete a NS Node */ 389100966Siwasaki ReturnBuffer->Length = 0; 390100966Siwasaki } 391100966Siwasaki 392100966Siwasaki if (ACPI_SUCCESS (Status)) 393100966Siwasaki { 394100966Siwasaki /* 395100966Siwasaki * Find out how large a buffer is needed 396100966Siwasaki * to contain the returned object 397100966Siwasaki */ 398100966Siwasaki Status = AcpiUtGetObjectSize (InternalReturnObj, 399100966Siwasaki &BufferSpaceNeeded); 400100966Siwasaki if (ACPI_SUCCESS (Status)) 401100966Siwasaki { 402100966Siwasaki /* Validate/Allocate/Clear caller buffer */ 403100966Siwasaki 404100966Siwasaki Status = AcpiUtInitializeBuffer (ReturnBuffer, BufferSpaceNeeded); 405100966Siwasaki if (ACPI_FAILURE (Status)) 406100966Siwasaki { 407100966Siwasaki /* 408100966Siwasaki * Caller's buffer is too small or a new one can't be allocated 409100966Siwasaki */ 410100966Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 411100966Siwasaki "Needed buffer size %X, %s\n", 412100966Siwasaki (UINT32) BufferSpaceNeeded, AcpiFormatException (Status))); 413100966Siwasaki } 414100966Siwasaki else 415100966Siwasaki { 416100966Siwasaki /* 417100966Siwasaki * We have enough space for the object, build it 418100966Siwasaki */ 419100966Siwasaki Status = AcpiUtCopyIobjectToEobject (InternalReturnObj, 420100966Siwasaki ReturnBuffer); 421100966Siwasaki } 422100966Siwasaki } 423100966Siwasaki } 424100966Siwasaki } 425100966Siwasaki } 426100966Siwasaki 427100966Siwasaki if (InternalReturnObj) 428100966Siwasaki { 429128212Snjl /* 430128212Snjl * Delete the internal return object. NOTE: Interpreter 431128212Snjl * must be locked to avoid race condition. 432100966Siwasaki */ 433128212Snjl Status2 = AcpiExEnterInterpreter (); 434128212Snjl if (ACPI_SUCCESS (Status2)) 435128212Snjl { 436128212Snjl /* 437128212Snjl * Delete the internal return object. (Or at least 438128212Snjl * decrement the reference count by one) 439128212Snjl */ 440128212Snjl AcpiUtRemoveReference (InternalReturnObj); 441128212Snjl AcpiExExitInterpreter (); 442128212Snjl } 443100966Siwasaki } 444100966Siwasaki 445100966Siwasaki /* 446100966Siwasaki * Free the input parameter list (if we created one), 447100966Siwasaki */ 448100966Siwasaki if (InternalParams) 449100966Siwasaki { 450100966Siwasaki /* Free the allocated parameter block */ 451100966Siwasaki 452100966Siwasaki AcpiUtDeleteInternalObjectList (InternalParams); 453100966Siwasaki } 454100966Siwasaki 455100966Siwasaki return_ACPI_STATUS (Status); 456100966Siwasaki} 457100966Siwasaki 458100966Siwasaki 459100966Siwasaki/******************************************************************************* 460100966Siwasaki * 461100966Siwasaki * FUNCTION: AcpiWalkNamespace 462100966Siwasaki * 463100966Siwasaki * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 464100966Siwasaki * StartObject - Handle in namespace where search begins 465100966Siwasaki * MaxDepth - Depth to which search is to reach 466100966Siwasaki * UserFunction - Called when an object of "Type" is found 467100966Siwasaki * Context - Passed to user function 468100966Siwasaki * ReturnValue - Location where return value of 469100966Siwasaki * UserFunction is put if terminated early 470100966Siwasaki * 471100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 472100966Siwasaki * Otherwise, returns NULL. 473100966Siwasaki * 474100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 475100966Siwasaki * starting (and ending) at the object specified by StartHandle. 476100966Siwasaki * The UserFunction is called whenever an object that matches 477100966Siwasaki * the type parameter is found. If the user function returns 478100966Siwasaki * a non-zero value, the search is terminated immediately and this 479100966Siwasaki * value is returned to the caller. 480100966Siwasaki * 481100966Siwasaki * The point of this procedure is to provide a generic namespace 482100966Siwasaki * walk routine that can be called from multiple places to 483100966Siwasaki * provide multiple services; the User Function can be tailored 484100966Siwasaki * to each task, whether it is a print function, a compare 485100966Siwasaki * function, etc. 486100966Siwasaki * 487100966Siwasaki ******************************************************************************/ 488100966Siwasaki 489100966SiwasakiACPI_STATUS 490100966SiwasakiAcpiWalkNamespace ( 491100966Siwasaki ACPI_OBJECT_TYPE Type, 492100966Siwasaki ACPI_HANDLE StartObject, 493100966Siwasaki UINT32 MaxDepth, 494100966Siwasaki ACPI_WALK_CALLBACK UserFunction, 495100966Siwasaki void *Context, 496100966Siwasaki void **ReturnValue) 497100966Siwasaki{ 498100966Siwasaki ACPI_STATUS Status; 499100966Siwasaki 500100966Siwasaki 501100966Siwasaki ACPI_FUNCTION_TRACE ("AcpiWalkNamespace"); 502100966Siwasaki 503100966Siwasaki 504100966Siwasaki /* Parameter validation */ 505100966Siwasaki 506107325Siwasaki if ((Type > ACPI_TYPE_EXTERNAL_MAX) || 507107325Siwasaki (!MaxDepth) || 508100966Siwasaki (!UserFunction)) 509100966Siwasaki { 510100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 511100966Siwasaki } 512100966Siwasaki 513100966Siwasaki /* 514100966Siwasaki * Lock the namespace around the walk. 515100966Siwasaki * The namespace will be unlocked/locked around each call 516100966Siwasaki * to the user function - since this function 517100966Siwasaki * must be allowed to make Acpi calls itself. 518100966Siwasaki */ 519100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 520100966Siwasaki if (ACPI_FAILURE (Status)) 521100966Siwasaki { 522100966Siwasaki return_ACPI_STATUS (Status); 523100966Siwasaki } 524100966Siwasaki 525100966Siwasaki Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, ACPI_NS_WALK_UNLOCK, 526100966Siwasaki UserFunction, Context, ReturnValue); 527100966Siwasaki 528100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 529100966Siwasaki return_ACPI_STATUS (Status); 530100966Siwasaki} 531100966Siwasaki 532100966Siwasaki 533100966Siwasaki/******************************************************************************* 534100966Siwasaki * 535100966Siwasaki * FUNCTION: AcpiNsGetDeviceCallback 536100966Siwasaki * 537100966Siwasaki * PARAMETERS: Callback from AcpiGetDevice 538100966Siwasaki * 539100966Siwasaki * RETURN: Status 540100966Siwasaki * 541100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 542100966Siwasaki * present devices, or if they specified a HID, it filters based 543100966Siwasaki * on that. 544100966Siwasaki * 545100966Siwasaki ******************************************************************************/ 546100966Siwasaki 547100966Siwasakistatic ACPI_STATUS 548100966SiwasakiAcpiNsGetDeviceCallback ( 549100966Siwasaki ACPI_HANDLE ObjHandle, 550100966Siwasaki UINT32 NestingLevel, 551100966Siwasaki void *Context, 552100966Siwasaki void **ReturnValue) 553100966Siwasaki{ 554117521Snjl ACPI_GET_DEVICES_INFO *Info = Context; 555100966Siwasaki ACPI_STATUS Status; 556100966Siwasaki ACPI_NAMESPACE_NODE *Node; 557100966Siwasaki UINT32 Flags; 558100966Siwasaki ACPI_DEVICE_ID Hid; 559117521Snjl ACPI_COMPATIBLE_ID_LIST *Cid; 560117521Snjl ACPI_NATIVE_UINT i; 561100966Siwasaki 562100966Siwasaki 563100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 564100966Siwasaki if (ACPI_FAILURE (Status)) 565100966Siwasaki { 566100966Siwasaki return (Status); 567100966Siwasaki } 568100966Siwasaki 569100966Siwasaki Node = AcpiNsMapHandleToNode (ObjHandle); 570100966Siwasaki Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 571100966Siwasaki if (ACPI_FAILURE (Status)) 572100966Siwasaki { 573100966Siwasaki return (Status); 574100966Siwasaki } 575100966Siwasaki 576100966Siwasaki if (!Node) 577100966Siwasaki { 578100966Siwasaki return (AE_BAD_PARAMETER); 579100966Siwasaki } 580100966Siwasaki 581117521Snjl /* Run _STA to determine if device is present */ 582117521Snjl 583100966Siwasaki Status = AcpiUtExecute_STA (Node, &Flags); 584100966Siwasaki if (ACPI_FAILURE (Status)) 585100966Siwasaki { 586100966Siwasaki return (AE_CTRL_DEPTH); 587100966Siwasaki } 588100966Siwasaki 589100966Siwasaki if (!(Flags & 0x01)) 590100966Siwasaki { 591100966Siwasaki /* Don't return at the device or children of the device if not there */ 592117521Snjl 593100966Siwasaki return (AE_CTRL_DEPTH); 594100966Siwasaki } 595100966Siwasaki 596117521Snjl /* Filter based on device HID & CID */ 597117521Snjl 598100966Siwasaki if (Info->Hid != NULL) 599100966Siwasaki { 600100966Siwasaki Status = AcpiUtExecute_HID (Node, &Hid); 601100966Siwasaki if (Status == AE_NOT_FOUND) 602100966Siwasaki { 603100966Siwasaki return (AE_OK); 604100966Siwasaki } 605100966Siwasaki else if (ACPI_FAILURE (Status)) 606100966Siwasaki { 607100966Siwasaki return (AE_CTRL_DEPTH); 608100966Siwasaki } 609100966Siwasaki 610117521Snjl if (ACPI_STRNCMP (Hid.Value, Info->Hid, sizeof (Hid.Value)) != 0) 611100966Siwasaki { 612117521Snjl /* Get the list of Compatible IDs */ 613117521Snjl 614100966Siwasaki Status = AcpiUtExecute_CID (Node, &Cid); 615100966Siwasaki if (Status == AE_NOT_FOUND) 616100966Siwasaki { 617100966Siwasaki return (AE_OK); 618100966Siwasaki } 619100966Siwasaki else if (ACPI_FAILURE (Status)) 620100966Siwasaki { 621100966Siwasaki return (AE_CTRL_DEPTH); 622100966Siwasaki } 623100966Siwasaki 624117521Snjl /* Walk the CID list */ 625100966Siwasaki 626117521Snjl for (i = 0; i < Cid->Count; i++) 627100966Siwasaki { 628117521Snjl if (ACPI_STRNCMP (Cid->Id[i].Value, Info->Hid, 629117521Snjl sizeof (ACPI_COMPATIBLE_ID)) != 0) 630117521Snjl { 631117521Snjl ACPI_MEM_FREE (Cid); 632117521Snjl return (AE_OK); 633117521Snjl } 634100966Siwasaki } 635117521Snjl ACPI_MEM_FREE (Cid); 636100966Siwasaki } 637100966Siwasaki } 638100966Siwasaki 639100966Siwasaki Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue); 640100966Siwasaki return (Status); 641100966Siwasaki} 642100966Siwasaki 643100966Siwasaki 644100966Siwasaki/******************************************************************************* 645100966Siwasaki * 646100966Siwasaki * FUNCTION: AcpiGetDevices 647100966Siwasaki * 648100966Siwasaki * PARAMETERS: HID - HID to search for. Can be NULL. 649100966Siwasaki * UserFunction - Called when a matching object is found 650100966Siwasaki * Context - Passed to user function 651100966Siwasaki * ReturnValue - Location where return value of 652100966Siwasaki * UserFunction is put if terminated early 653100966Siwasaki * 654100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 655100966Siwasaki * Otherwise, returns NULL. 656100966Siwasaki * 657100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 658100966Siwasaki * starting (and ending) at the object specified by StartHandle. 659117521Snjl * The UserFunction is called whenever an object of type 660117521Snjl * Device is found. If the user function returns 661100966Siwasaki * a non-zero value, the search is terminated immediately and this 662100966Siwasaki * value is returned to the caller. 663100966Siwasaki * 664100966Siwasaki * This is a wrapper for WalkNamespace, but the callback performs 665100966Siwasaki * additional filtering. Please see AcpiGetDeviceCallback. 666100966Siwasaki * 667100966Siwasaki ******************************************************************************/ 668100966Siwasaki 669100966SiwasakiACPI_STATUS 670100966SiwasakiAcpiGetDevices ( 671114237Snjl char *HID, 672100966Siwasaki ACPI_WALK_CALLBACK UserFunction, 673100966Siwasaki void *Context, 674100966Siwasaki void **ReturnValue) 675100966Siwasaki{ 676100966Siwasaki ACPI_STATUS Status; 677100966Siwasaki ACPI_GET_DEVICES_INFO Info; 678100966Siwasaki 679100966Siwasaki 680100966Siwasaki ACPI_FUNCTION_TRACE ("AcpiGetDevices"); 681100966Siwasaki 682100966Siwasaki 683100966Siwasaki /* Parameter validation */ 684100966Siwasaki 685100966Siwasaki if (!UserFunction) 686100966Siwasaki { 687100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 688100966Siwasaki } 689100966Siwasaki 690100966Siwasaki /* 691100966Siwasaki * We're going to call their callback from OUR callback, so we need 692100966Siwasaki * to know what it is, and their context parameter. 693100966Siwasaki */ 694100966Siwasaki Info.Context = Context; 695100966Siwasaki Info.UserFunction = UserFunction; 696100966Siwasaki Info.Hid = HID; 697100966Siwasaki 698100966Siwasaki /* 699100966Siwasaki * Lock the namespace around the walk. 700100966Siwasaki * The namespace will be unlocked/locked around each call 701100966Siwasaki * to the user function - since this function 702100966Siwasaki * must be allowed to make Acpi calls itself. 703100966Siwasaki */ 704100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 705100966Siwasaki if (ACPI_FAILURE (Status)) 706100966Siwasaki { 707100966Siwasaki return_ACPI_STATUS (Status); 708100966Siwasaki } 709100966Siwasaki 710100966Siwasaki Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, 711100966Siwasaki ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 712100966Siwasaki ACPI_NS_WALK_UNLOCK, 713100966Siwasaki AcpiNsGetDeviceCallback, &Info, 714100966Siwasaki ReturnValue); 715100966Siwasaki 716100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 717100966Siwasaki return_ACPI_STATUS (Status); 718100966Siwasaki} 719100966Siwasaki 720100966Siwasaki 721100966Siwasaki/******************************************************************************* 722100966Siwasaki * 723100966Siwasaki * FUNCTION: AcpiAttachData 724100966Siwasaki * 725114237Snjl * PARAMETERS: ObjHandle - Namespace node 726107325Siwasaki * Handler - Handler for this attachment 727107325Siwasaki * Data - Pointer to data to be attached 728100966Siwasaki * 729100966Siwasaki * RETURN: Status 730100966Siwasaki * 731107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node. 732100966Siwasaki * 733100966Siwasaki ******************************************************************************/ 734100966Siwasaki 735100966SiwasakiACPI_STATUS 736100966SiwasakiAcpiAttachData ( 737100966Siwasaki ACPI_HANDLE ObjHandle, 738100966Siwasaki ACPI_OBJECT_HANDLER Handler, 739100966Siwasaki void *Data) 740100966Siwasaki{ 741100966Siwasaki ACPI_NAMESPACE_NODE *Node; 742100966Siwasaki ACPI_STATUS Status; 743100966Siwasaki 744100966Siwasaki 745100966Siwasaki /* Parameter validation */ 746100966Siwasaki 747100966Siwasaki if (!ObjHandle || 748100966Siwasaki !Handler || 749100966Siwasaki !Data) 750100966Siwasaki { 751100966Siwasaki return (AE_BAD_PARAMETER); 752100966Siwasaki } 753100966Siwasaki 754100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 755100966Siwasaki if (ACPI_FAILURE (Status)) 756100966Siwasaki { 757100966Siwasaki return (Status); 758100966Siwasaki } 759100966Siwasaki 760100966Siwasaki /* Convert and validate the handle */ 761100966Siwasaki 762100966Siwasaki Node = AcpiNsMapHandleToNode (ObjHandle); 763100966Siwasaki if (!Node) 764100966Siwasaki { 765100966Siwasaki Status = AE_BAD_PARAMETER; 766100966Siwasaki goto UnlockAndExit; 767100966Siwasaki } 768100966Siwasaki 769100966Siwasaki Status = AcpiNsAttachData (Node, Handler, Data); 770100966Siwasaki 771100966SiwasakiUnlockAndExit: 772100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 773100966Siwasaki return (Status); 774100966Siwasaki} 775100966Siwasaki 776100966Siwasaki 777100966Siwasaki/******************************************************************************* 778100966Siwasaki * 779100966Siwasaki * FUNCTION: AcpiDetachData 780100966Siwasaki * 781107325Siwasaki * PARAMETERS: ObjHandle - Namespace node handle 782107325Siwasaki * Handler - Handler used in call to AcpiAttachData 783100966Siwasaki * 784100966Siwasaki * RETURN: Status 785100966Siwasaki * 786107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node. 787100966Siwasaki * 788100966Siwasaki ******************************************************************************/ 789100966Siwasaki 790100966SiwasakiACPI_STATUS 791100966SiwasakiAcpiDetachData ( 792100966Siwasaki ACPI_HANDLE ObjHandle, 793100966Siwasaki ACPI_OBJECT_HANDLER Handler) 794100966Siwasaki{ 795100966Siwasaki ACPI_NAMESPACE_NODE *Node; 796100966Siwasaki ACPI_STATUS Status; 797100966Siwasaki 798100966Siwasaki 799100966Siwasaki /* Parameter validation */ 800100966Siwasaki 801100966Siwasaki if (!ObjHandle || 802100966Siwasaki !Handler) 803100966Siwasaki { 804100966Siwasaki return (AE_BAD_PARAMETER); 805100966Siwasaki } 806100966Siwasaki 807100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 808100966Siwasaki if (ACPI_FAILURE (Status)) 809100966Siwasaki { 810100966Siwasaki return (Status); 811100966Siwasaki } 812100966Siwasaki 813100966Siwasaki /* Convert and validate the handle */ 814100966Siwasaki 815100966Siwasaki Node = AcpiNsMapHandleToNode (ObjHandle); 816100966Siwasaki if (!Node) 817100966Siwasaki { 818100966Siwasaki Status = AE_BAD_PARAMETER; 819100966Siwasaki goto UnlockAndExit; 820100966Siwasaki } 821100966Siwasaki 822100966Siwasaki Status = AcpiNsDetachData (Node, Handler); 823100966Siwasaki 824100966SiwasakiUnlockAndExit: 825100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 826100966Siwasaki return (Status); 827100966Siwasaki} 828100966Siwasaki 829100966Siwasaki 830100966Siwasaki/******************************************************************************* 831100966Siwasaki * 832100966Siwasaki * FUNCTION: AcpiGetData 833100966Siwasaki * 834107325Siwasaki * PARAMETERS: ObjHandle - Namespace node 835107325Siwasaki * Handler - Handler used in call to AttachData 836107325Siwasaki * Data - Where the data is returned 837100966Siwasaki * 838100966Siwasaki * RETURN: Status 839100966Siwasaki * 840107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node. 841100966Siwasaki * 842100966Siwasaki ******************************************************************************/ 843100966Siwasaki 844100966SiwasakiACPI_STATUS 845100966SiwasakiAcpiGetData ( 846100966Siwasaki ACPI_HANDLE ObjHandle, 847100966Siwasaki ACPI_OBJECT_HANDLER Handler, 848100966Siwasaki void **Data) 849100966Siwasaki{ 850100966Siwasaki ACPI_NAMESPACE_NODE *Node; 851100966Siwasaki ACPI_STATUS Status; 852100966Siwasaki 853100966Siwasaki 854100966Siwasaki /* Parameter validation */ 855100966Siwasaki 856100966Siwasaki if (!ObjHandle || 857100966Siwasaki !Handler || 858100966Siwasaki !Data) 859100966Siwasaki { 860100966Siwasaki return (AE_BAD_PARAMETER); 861100966Siwasaki } 862100966Siwasaki 863100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 864100966Siwasaki if (ACPI_FAILURE (Status)) 865100966Siwasaki { 866100966Siwasaki return (Status); 867100966Siwasaki } 868100966Siwasaki 869100966Siwasaki /* Convert and validate the handle */ 870100966Siwasaki 871100966Siwasaki Node = AcpiNsMapHandleToNode (ObjHandle); 872100966Siwasaki if (!Node) 873100966Siwasaki { 874100966Siwasaki Status = AE_BAD_PARAMETER; 875100966Siwasaki goto UnlockAndExit; 876100966Siwasaki } 877100966Siwasaki 878100966Siwasaki Status = AcpiNsGetAttachedData (Node, Handler, Data); 879100966Siwasaki 880100966SiwasakiUnlockAndExit: 881100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 882100966Siwasaki return (Status); 883100966Siwasaki} 884100966Siwasaki 885100966Siwasaki 886