nsxfeval.c revision 249663
1100966Siwasaki/******************************************************************************* 2100966Siwasaki * 3100966Siwasaki * Module Name: nsxfeval - Public interfaces to the ACPI subsystem 4100966Siwasaki * ACPI Object evaluation interfaces 5100966Siwasaki * 6100966Siwasaki ******************************************************************************/ 7100966Siwasaki 8217365Sjkim/* 9245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 10100966Siwasaki * All rights reserved. 11100966Siwasaki * 12217365Sjkim * Redistribution and use in source and binary forms, with or without 13217365Sjkim * modification, are permitted provided that the following conditions 14217365Sjkim * are met: 15217365Sjkim * 1. Redistributions of source code must retain the above copyright 16217365Sjkim * notice, this list of conditions, and the following disclaimer, 17217365Sjkim * without modification. 18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21217365Sjkim * including a substantially similar Disclaimer requirement for further 22217365Sjkim * binary redistribution. 23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24217365Sjkim * of any contributors may be used to endorse or promote products derived 25217365Sjkim * from this software without specific prior written permission. 26100966Siwasaki * 27217365Sjkim * Alternatively, this software may be distributed under the terms of the 28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29217365Sjkim * Software Foundation. 30100966Siwasaki * 31217365Sjkim * NO WARRANTY 32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 43217365Sjkim */ 44100966Siwasaki 45100966Siwasaki 46100966Siwasaki#define __NSXFEVAL_C__ 47100966Siwasaki 48193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 49193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 50193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 51193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 52100966Siwasaki 53100966Siwasaki 54100966Siwasaki#define _COMPONENT ACPI_NAMESPACE 55100966Siwasaki ACPI_MODULE_NAME ("nsxfeval") 56100966Siwasaki 57193267Sjkim/* Local prototypes */ 58100966Siwasaki 59193267Sjkimstatic void 60193267SjkimAcpiNsResolveReferences ( 61193267Sjkim ACPI_EVALUATE_INFO *Info); 62193267Sjkim 63193267Sjkim 64100966Siwasaki/******************************************************************************* 65100966Siwasaki * 66100966Siwasaki * FUNCTION: AcpiEvaluateObjectTyped 67100966Siwasaki * 68100966Siwasaki * PARAMETERS: Handle - Object handle (optional) 69151937Sjkim * Pathname - Object pathname (optional) 70151937Sjkim * ExternalParams - List of parameters to pass to method, 71241973Sjkim * terminated by NULL. May be NULL 72100966Siwasaki * if no parameters are being passed. 73151937Sjkim * ReturnBuffer - Where to put method's return value (if 74241973Sjkim * any). If NULL, no value is returned. 75100966Siwasaki * ReturnType - Expected type of return object 76100966Siwasaki * 77100966Siwasaki * RETURN: Status 78100966Siwasaki * 79100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given 80241973Sjkim * parameters if necessary. One of "Handle" or "Pathname" must 81100966Siwasaki * be valid (non-null) 82100966Siwasaki * 83100966Siwasaki ******************************************************************************/ 84100966Siwasaki 85100966SiwasakiACPI_STATUS 86100966SiwasakiAcpiEvaluateObjectTyped ( 87100966Siwasaki ACPI_HANDLE Handle, 88100966Siwasaki ACPI_STRING Pathname, 89100966Siwasaki ACPI_OBJECT_LIST *ExternalParams, 90100966Siwasaki ACPI_BUFFER *ReturnBuffer, 91100966Siwasaki ACPI_OBJECT_TYPE ReturnType) 92100966Siwasaki{ 93100966Siwasaki ACPI_STATUS Status; 94100966Siwasaki BOOLEAN MustFree = FALSE; 95100966Siwasaki 96100966Siwasaki 97167802Sjkim ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); 98100966Siwasaki 99100966Siwasaki 100100966Siwasaki /* Return buffer must be valid */ 101100966Siwasaki 102100966Siwasaki if (!ReturnBuffer) 103100966Siwasaki { 104100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 105100966Siwasaki } 106100966Siwasaki 107100966Siwasaki if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) 108100966Siwasaki { 109100966Siwasaki MustFree = TRUE; 110100966Siwasaki } 111100966Siwasaki 112100966Siwasaki /* Evaluate the object */ 113100966Siwasaki 114100966Siwasaki Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer); 115100966Siwasaki if (ACPI_FAILURE (Status)) 116100966Siwasaki { 117100966Siwasaki return_ACPI_STATUS (Status); 118100966Siwasaki } 119100966Siwasaki 120100966Siwasaki /* Type ANY means "don't care" */ 121100966Siwasaki 122100966Siwasaki if (ReturnType == ACPI_TYPE_ANY) 123100966Siwasaki { 124100966Siwasaki return_ACPI_STATUS (AE_OK); 125100966Siwasaki } 126100966Siwasaki 127100966Siwasaki if (ReturnBuffer->Length == 0) 128100966Siwasaki { 129100966Siwasaki /* Error because caller specifically asked for a return value */ 130100966Siwasaki 131167802Sjkim ACPI_ERROR ((AE_INFO, "No return value")); 132100966Siwasaki return_ACPI_STATUS (AE_NULL_OBJECT); 133100966Siwasaki } 134100966Siwasaki 135100966Siwasaki /* Examine the object type returned from EvaluateObject */ 136100966Siwasaki 137100966Siwasaki if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) 138100966Siwasaki { 139100966Siwasaki return_ACPI_STATUS (AE_OK); 140100966Siwasaki } 141100966Siwasaki 142100966Siwasaki /* Return object type does not match requested type */ 143100966Siwasaki 144167802Sjkim ACPI_ERROR ((AE_INFO, 145167802Sjkim "Incorrect return type [%s] requested [%s]", 146100966Siwasaki AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), 147100966Siwasaki AcpiUtGetTypeName (ReturnType))); 148100966Siwasaki 149100966Siwasaki if (MustFree) 150100966Siwasaki { 151100966Siwasaki /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ 152100966Siwasaki 153100966Siwasaki AcpiOsFree (ReturnBuffer->Pointer); 154100966Siwasaki ReturnBuffer->Pointer = NULL; 155100966Siwasaki } 156100966Siwasaki 157100966Siwasaki ReturnBuffer->Length = 0; 158100966Siwasaki return_ACPI_STATUS (AE_TYPE); 159100966Siwasaki} 160100966Siwasaki 161167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped) 162100966Siwasaki 163167802Sjkim 164100966Siwasaki/******************************************************************************* 165100966Siwasaki * 166100966Siwasaki * FUNCTION: AcpiEvaluateObject 167100966Siwasaki * 168100966Siwasaki * PARAMETERS: Handle - Object handle (optional) 169128212Snjl * Pathname - Object pathname (optional) 170128212Snjl * ExternalParams - List of parameters to pass to method, 171241973Sjkim * terminated by NULL. May be NULL 172100966Siwasaki * if no parameters are being passed. 173128212Snjl * ReturnBuffer - Where to put method's return value (if 174241973Sjkim * any). If NULL, no value is returned. 175100966Siwasaki * 176100966Siwasaki * RETURN: Status 177100966Siwasaki * 178100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given 179241973Sjkim * parameters if necessary. One of "Handle" or "Pathname" must 180100966Siwasaki * be valid (non-null) 181100966Siwasaki * 182100966Siwasaki ******************************************************************************/ 183100966Siwasaki 184100966SiwasakiACPI_STATUS 185100966SiwasakiAcpiEvaluateObject ( 186100966Siwasaki ACPI_HANDLE Handle, 187100966Siwasaki ACPI_STRING Pathname, 188100966Siwasaki ACPI_OBJECT_LIST *ExternalParams, 189100966Siwasaki ACPI_BUFFER *ReturnBuffer) 190100966Siwasaki{ 191100966Siwasaki ACPI_STATUS Status; 192167802Sjkim ACPI_EVALUATE_INFO *Info; 193100966Siwasaki ACPI_SIZE BufferSpaceNeeded; 194100966Siwasaki UINT32 i; 195100966Siwasaki 196100966Siwasaki 197167802Sjkim ACPI_FUNCTION_TRACE (AcpiEvaluateObject); 198100966Siwasaki 199100966Siwasaki 200167802Sjkim /* Allocate and initialize the evaluation information block */ 201129684Snjl 202167802Sjkim Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 203167802Sjkim if (!Info) 204167802Sjkim { 205167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 206167802Sjkim } 207167802Sjkim 208167802Sjkim /* Convert and validate the device handle */ 209167802Sjkim 210200553Sjkim Info->PrefixNode = AcpiNsValidateHandle (Handle); 211167802Sjkim if (!Info->PrefixNode) 212167802Sjkim { 213167802Sjkim Status = AE_BAD_PARAMETER; 214167802Sjkim goto Cleanup; 215167802Sjkim } 216167802Sjkim 217100966Siwasaki /* 218249663Sjkim * Get the actual namespace node for the target object. 219249663Sjkim * Handles these cases: 220249663Sjkim * 221249663Sjkim * 1) Null node, valid pathname from root (absolute path) 222249663Sjkim * 2) Node and valid pathname (path relative to Node) 223249663Sjkim * 3) Node, Null pathname 224100966Siwasaki */ 225249663Sjkim if ((Pathname) && 226249663Sjkim (ACPI_IS_ROOT_PREFIX (Pathname[0]))) 227249663Sjkim { 228249663Sjkim /* The path is fully qualified, just evaluate by name */ 229249663Sjkim 230249663Sjkim Info->PrefixNode = NULL; 231249663Sjkim } 232249663Sjkim else if (!Handle) 233249663Sjkim { 234249663Sjkim /* 235249663Sjkim * A handle is optional iff a fully qualified pathname is specified. 236249663Sjkim * Since we've already handled fully qualified names above, this is 237249663Sjkim * an error. 238249663Sjkim */ 239249663Sjkim if (!Pathname) 240249663Sjkim { 241249663Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 242249663Sjkim "Both Handle and Pathname are NULL")); 243249663Sjkim } 244249663Sjkim else 245249663Sjkim { 246249663Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 247249663Sjkim "Null Handle with relative pathname [%s]", Pathname)); 248249663Sjkim } 249249663Sjkim 250249663Sjkim Status = AE_BAD_PARAMETER; 251249663Sjkim goto Cleanup; 252249663Sjkim } 253249663Sjkim 254249663Sjkim Info->RelativePathname = Pathname; 255249663Sjkim 256249663Sjkim /* 257249663Sjkim * Convert all external objects passed as arguments to the 258249663Sjkim * internal version(s). 259249663Sjkim */ 260100966Siwasaki if (ExternalParams && ExternalParams->Count) 261100966Siwasaki { 262249663Sjkim Info->ParamCount = (UINT16) ExternalParams->Count; 263249663Sjkim 264249663Sjkim /* Warn on impossible argument count */ 265249663Sjkim 266249663Sjkim if (Info->ParamCount > ACPI_METHOD_NUM_ARGS) 267249663Sjkim { 268249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 269249663Sjkim "Excess arguments (%u) - using only %u", 270249663Sjkim Info->ParamCount, ACPI_METHOD_NUM_ARGS)); 271249663Sjkim 272249663Sjkim Info->ParamCount = ACPI_METHOD_NUM_ARGS; 273249663Sjkim } 274249663Sjkim 275100966Siwasaki /* 276100966Siwasaki * Allocate a new parameter block for the internal objects 277100966Siwasaki * Add 1 to count to allow for null terminated internal list 278100966Siwasaki */ 279167802Sjkim Info->Parameters = ACPI_ALLOCATE_ZEROED ( 280249663Sjkim ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *)); 281167802Sjkim if (!Info->Parameters) 282100966Siwasaki { 283167802Sjkim Status = AE_NO_MEMORY; 284167802Sjkim goto Cleanup; 285100966Siwasaki } 286100966Siwasaki 287167802Sjkim /* Convert each external object in the list to an internal object */ 288167802Sjkim 289249663Sjkim for (i = 0; i < Info->ParamCount; i++) 290100966Siwasaki { 291167802Sjkim Status = AcpiUtCopyEobjectToIobject ( 292249663Sjkim &ExternalParams->Pointer[i], &Info->Parameters[i]); 293100966Siwasaki if (ACPI_FAILURE (Status)) 294100966Siwasaki { 295167802Sjkim goto Cleanup; 296100966Siwasaki } 297100966Siwasaki } 298249663Sjkim 299249663Sjkim Info->Parameters[Info->ParamCount] = NULL; 300100966Siwasaki } 301100966Siwasaki 302249663Sjkim 303249663Sjkim#if 0 304249663Sjkim 305100966Siwasaki /* 306249663Sjkim * Begin incoming argument count analysis. Check for too few args 307249663Sjkim * and too many args. 308100966Siwasaki */ 309249663Sjkim 310249663Sjkim switch (AcpiNsGetType (Info->Node)) 311100966Siwasaki { 312249663Sjkim case ACPI_TYPE_METHOD: 313167802Sjkim 314249663Sjkim /* Check incoming argument count against the method definition */ 315249663Sjkim 316249663Sjkim if (Info->ObjDesc->Method.ParamCount > Info->ParamCount) 317249663Sjkim { 318249663Sjkim ACPI_ERROR ((AE_INFO, 319249663Sjkim "Insufficient arguments (%u) - %u are required", 320249663Sjkim Info->ParamCount, 321249663Sjkim Info->ObjDesc->Method.ParamCount)); 322249663Sjkim 323249663Sjkim Status = AE_MISSING_ARGUMENTS; 324249663Sjkim goto Cleanup; 325249663Sjkim } 326249663Sjkim 327249663Sjkim else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount) 328249663Sjkim { 329249663Sjkim ACPI_WARNING ((AE_INFO, 330249663Sjkim "Excess arguments (%u) - only %u are required", 331249663Sjkim Info->ParamCount, 332249663Sjkim Info->ObjDesc->Method.ParamCount)); 333249663Sjkim 334249663Sjkim /* Just pass the required number of arguments */ 335249663Sjkim 336249663Sjkim Info->ParamCount = Info->ObjDesc->Method.ParamCount; 337249663Sjkim } 338249663Sjkim 339100966Siwasaki /* 340249663Sjkim * Any incoming external objects to be passed as arguments to the 341249663Sjkim * method must be converted to internal objects 342100966Siwasaki */ 343249663Sjkim if (Info->ParamCount) 344100966Siwasaki { 345249663Sjkim /* 346249663Sjkim * Allocate a new parameter block for the internal objects 347249663Sjkim * Add 1 to count to allow for null terminated internal list 348249663Sjkim */ 349249663Sjkim Info->Parameters = ACPI_ALLOCATE_ZEROED ( 350249663Sjkim ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *)); 351249663Sjkim if (!Info->Parameters) 352249663Sjkim { 353249663Sjkim Status = AE_NO_MEMORY; 354249663Sjkim goto Cleanup; 355249663Sjkim } 356249663Sjkim 357249663Sjkim /* Convert each external object in the list to an internal object */ 358249663Sjkim 359249663Sjkim for (i = 0; i < Info->ParamCount; i++) 360249663Sjkim { 361249663Sjkim Status = AcpiUtCopyEobjectToIobject ( 362249663Sjkim &ExternalParams->Pointer[i], &Info->Parameters[i]); 363249663Sjkim if (ACPI_FAILURE (Status)) 364249663Sjkim { 365249663Sjkim goto Cleanup; 366249663Sjkim } 367249663Sjkim } 368249663Sjkim 369249663Sjkim Info->Parameters[Info->ParamCount] = NULL; 370100966Siwasaki } 371249663Sjkim break; 372249663Sjkim 373249663Sjkim default: 374249663Sjkim 375249663Sjkim /* Warn if arguments passed to an object that is not a method */ 376249663Sjkim 377249663Sjkim if (Info->ParamCount) 378100966Siwasaki { 379249663Sjkim ACPI_WARNING ((AE_INFO, 380249663Sjkim "%u arguments were passed to a non-method ACPI object", 381249663Sjkim Info->ParamCount)); 382100966Siwasaki } 383249663Sjkim break; 384100966Siwasaki } 385167802Sjkim 386249663Sjkim#endif 387100966Siwasaki 388249663Sjkim 389249663Sjkim /* Now we can evaluate the object */ 390249663Sjkim 391249663Sjkim Status = AcpiNsEvaluate (Info); 392249663Sjkim 393100966Siwasaki /* 394100966Siwasaki * If we are expecting a return value, and all went well above, 395100966Siwasaki * copy the return value to an external object. 396100966Siwasaki */ 397100966Siwasaki if (ReturnBuffer) 398100966Siwasaki { 399167802Sjkim if (!Info->ReturnObject) 400100966Siwasaki { 401100966Siwasaki ReturnBuffer->Length = 0; 402100966Siwasaki } 403100966Siwasaki else 404100966Siwasaki { 405167802Sjkim if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) == 406167802Sjkim ACPI_DESC_TYPE_NAMED) 407100966Siwasaki { 408100966Siwasaki /* 409100966Siwasaki * If we received a NS Node as a return object, this means that 410100966Siwasaki * the object we are evaluating has nothing interesting to 411100966Siwasaki * return (such as a mutex, etc.) We return an error because 412100966Siwasaki * these types are essentially unsupported by this interface. 413100966Siwasaki * We don't check up front because this makes it easier to add 414100966Siwasaki * support for various types at a later date if necessary. 415100966Siwasaki */ 416100966Siwasaki Status = AE_TYPE; 417167802Sjkim Info->ReturnObject = NULL; /* No need to delete a NS Node */ 418100966Siwasaki ReturnBuffer->Length = 0; 419100966Siwasaki } 420100966Siwasaki 421100966Siwasaki if (ACPI_SUCCESS (Status)) 422100966Siwasaki { 423193267Sjkim /* Dereference Index and RefOf references */ 424193267Sjkim 425193267Sjkim AcpiNsResolveReferences (Info); 426193267Sjkim 427167802Sjkim /* Get the size of the returned object */ 428167802Sjkim 429167802Sjkim Status = AcpiUtGetObjectSize (Info->ReturnObject, 430167802Sjkim &BufferSpaceNeeded); 431100966Siwasaki if (ACPI_SUCCESS (Status)) 432100966Siwasaki { 433100966Siwasaki /* Validate/Allocate/Clear caller buffer */ 434100966Siwasaki 435151937Sjkim Status = AcpiUtInitializeBuffer (ReturnBuffer, 436167802Sjkim BufferSpaceNeeded); 437100966Siwasaki if (ACPI_FAILURE (Status)) 438100966Siwasaki { 439100966Siwasaki /* 440167802Sjkim * Caller's buffer is too small or a new one can't 441167802Sjkim * be allocated 442100966Siwasaki */ 443100966Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 444100966Siwasaki "Needed buffer size %X, %s\n", 445129684Snjl (UINT32) BufferSpaceNeeded, 446129684Snjl AcpiFormatException (Status))); 447100966Siwasaki } 448100966Siwasaki else 449100966Siwasaki { 450167802Sjkim /* We have enough space for the object, build it */ 451167802Sjkim 452167802Sjkim Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject, 453167802Sjkim ReturnBuffer); 454100966Siwasaki } 455100966Siwasaki } 456100966Siwasaki } 457100966Siwasaki } 458100966Siwasaki } 459100966Siwasaki 460167802Sjkim if (Info->ReturnObject) 461100966Siwasaki { 462129684Snjl /* 463167802Sjkim * Delete the internal return object. NOTE: Interpreter must be 464167802Sjkim * locked to avoid race condition. 465100966Siwasaki */ 466167802Sjkim AcpiExEnterInterpreter (); 467167802Sjkim 468167802Sjkim /* Remove one reference on the return object (should delete it) */ 469167802Sjkim 470167802Sjkim AcpiUtRemoveReference (Info->ReturnObject); 471167802Sjkim AcpiExExitInterpreter (); 472100966Siwasaki } 473100966Siwasaki 474167802Sjkim 475167802SjkimCleanup: 476167802Sjkim 477167802Sjkim /* Free the input parameter list (if we created one) */ 478167802Sjkim 479167802Sjkim if (Info->Parameters) 480100966Siwasaki { 481100966Siwasaki /* Free the allocated parameter block */ 482100966Siwasaki 483167802Sjkim AcpiUtDeleteInternalObjectList (Info->Parameters); 484100966Siwasaki } 485100966Siwasaki 486167802Sjkim ACPI_FREE (Info); 487100966Siwasaki return_ACPI_STATUS (Status); 488100966Siwasaki} 489100966Siwasaki 490167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObject) 491100966Siwasaki 492167802Sjkim 493100966Siwasaki/******************************************************************************* 494100966Siwasaki * 495193267Sjkim * FUNCTION: AcpiNsResolveReferences 496193267Sjkim * 497193267Sjkim * PARAMETERS: Info - Evaluation info block 498193267Sjkim * 499193267Sjkim * RETURN: Info->ReturnObject is replaced with the dereferenced object 500193267Sjkim * 501193267Sjkim * DESCRIPTION: Dereference certain reference objects. Called before an 502193267Sjkim * internal return object is converted to an external ACPI_OBJECT. 503193267Sjkim * 504193267Sjkim * Performs an automatic dereference of Index and RefOf reference objects. 505193267Sjkim * These reference objects are not supported by the ACPI_OBJECT, so this is a 506193267Sjkim * last resort effort to return something useful. Also, provides compatibility 507193267Sjkim * with other ACPI implementations. 508193267Sjkim * 509193267Sjkim * NOTE: does not handle references within returned package objects or nested 510193267Sjkim * references, but this support could be added later if found to be necessary. 511193267Sjkim * 512193267Sjkim ******************************************************************************/ 513193267Sjkim 514193267Sjkimstatic void 515193267SjkimAcpiNsResolveReferences ( 516193267Sjkim ACPI_EVALUATE_INFO *Info) 517193267Sjkim{ 518193267Sjkim ACPI_OPERAND_OBJECT *ObjDesc = NULL; 519193267Sjkim ACPI_NAMESPACE_NODE *Node; 520193267Sjkim 521193267Sjkim 522193267Sjkim /* We are interested in reference objects only */ 523193267Sjkim 524193267Sjkim if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) 525193267Sjkim { 526193267Sjkim return; 527193267Sjkim } 528193267Sjkim 529193267Sjkim /* 530193267Sjkim * Two types of references are supported - those created by Index and 531193267Sjkim * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted 532193267Sjkim * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle 533193267Sjkim * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to 534193267Sjkim * an ACPI_OBJECT. 535193267Sjkim */ 536193267Sjkim switch (Info->ReturnObject->Reference.Class) 537193267Sjkim { 538193267Sjkim case ACPI_REFCLASS_INDEX: 539193267Sjkim 540193267Sjkim ObjDesc = *(Info->ReturnObject->Reference.Where); 541193267Sjkim break; 542193267Sjkim 543193267Sjkim case ACPI_REFCLASS_REFOF: 544193267Sjkim 545193267Sjkim Node = Info->ReturnObject->Reference.Object; 546193267Sjkim if (Node) 547193267Sjkim { 548193267Sjkim ObjDesc = Node->Object; 549193267Sjkim } 550193267Sjkim break; 551193267Sjkim 552193267Sjkim default: 553193267Sjkim return; 554193267Sjkim } 555193267Sjkim 556193267Sjkim /* Replace the existing reference object */ 557193267Sjkim 558193267Sjkim if (ObjDesc) 559193267Sjkim { 560193267Sjkim AcpiUtAddReference (ObjDesc); 561193267Sjkim AcpiUtRemoveReference (Info->ReturnObject); 562193267Sjkim Info->ReturnObject = ObjDesc; 563193267Sjkim } 564193267Sjkim 565193267Sjkim return; 566193267Sjkim} 567193267Sjkim 568193267Sjkim 569193267Sjkim/******************************************************************************* 570193267Sjkim * 571100966Siwasaki * FUNCTION: AcpiWalkNamespace 572100966Siwasaki * 573100966Siwasaki * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 574100966Siwasaki * StartObject - Handle in namespace where search begins 575100966Siwasaki * MaxDepth - Depth to which search is to reach 576199337Sjkim * PreOrderVisit - Called during tree pre-order visit 577199337Sjkim * when an object of "Type" is found 578199337Sjkim * PostOrderVisit - Called during tree post-order visit 579199337Sjkim * when an object of "Type" is found 580199337Sjkim * Context - Passed to user function(s) above 581100966Siwasaki * ReturnValue - Location where return value of 582100966Siwasaki * UserFunction is put if terminated early 583100966Siwasaki * 584100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 585100966Siwasaki * Otherwise, returns NULL. 586100966Siwasaki * 587100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 588100966Siwasaki * starting (and ending) at the object specified by StartHandle. 589199337Sjkim * The callback function is called whenever an object that matches 590199337Sjkim * the type parameter is found. If the callback function returns 591100966Siwasaki * a non-zero value, the search is terminated immediately and this 592100966Siwasaki * value is returned to the caller. 593100966Siwasaki * 594100966Siwasaki * The point of this procedure is to provide a generic namespace 595100966Siwasaki * walk routine that can be called from multiple places to 596199337Sjkim * provide multiple services; the callback function(s) can be 597199337Sjkim * tailored to each task, whether it is a print function, 598199337Sjkim * a compare function, etc. 599100966Siwasaki * 600100966Siwasaki ******************************************************************************/ 601100966Siwasaki 602100966SiwasakiACPI_STATUS 603100966SiwasakiAcpiWalkNamespace ( 604100966Siwasaki ACPI_OBJECT_TYPE Type, 605100966Siwasaki ACPI_HANDLE StartObject, 606100966Siwasaki UINT32 MaxDepth, 607199337Sjkim ACPI_WALK_CALLBACK PreOrderVisit, 608199337Sjkim ACPI_WALK_CALLBACK PostOrderVisit, 609100966Siwasaki void *Context, 610100966Siwasaki void **ReturnValue) 611100966Siwasaki{ 612100966Siwasaki ACPI_STATUS Status; 613100966Siwasaki 614100966Siwasaki 615167802Sjkim ACPI_FUNCTION_TRACE (AcpiWalkNamespace); 616100966Siwasaki 617100966Siwasaki 618100966Siwasaki /* Parameter validation */ 619100966Siwasaki 620167802Sjkim if ((Type > ACPI_TYPE_LOCAL_MAX) || 621167802Sjkim (!MaxDepth) || 622199337Sjkim (!PreOrderVisit && !PostOrderVisit)) 623100966Siwasaki { 624100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 625100966Siwasaki } 626100966Siwasaki 627100966Siwasaki /* 628193267Sjkim * Need to acquire the namespace reader lock to prevent interference 629193267Sjkim * with any concurrent table unloads (which causes the deletion of 630193267Sjkim * namespace objects). We cannot allow the deletion of a namespace node 631193267Sjkim * while the user function is using it. The exception to this are the 632193267Sjkim * nodes created and deleted during control method execution -- these 633193267Sjkim * nodes are marked as temporary nodes and are ignored by the namespace 634193267Sjkim * walk. Thus, control methods can be executed while holding the 635193267Sjkim * namespace deletion lock (and the user function can execute control 636193267Sjkim * methods.) 637100966Siwasaki */ 638193267Sjkim Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock); 639193267Sjkim if (ACPI_FAILURE (Status)) 640193267Sjkim { 641241973Sjkim return_ACPI_STATUS (Status); 642193267Sjkim } 643193267Sjkim 644193267Sjkim /* 645193267Sjkim * Lock the namespace around the walk. The namespace will be 646193267Sjkim * unlocked/locked around each call to the user function - since the user 647193267Sjkim * function must be allowed to make ACPICA calls itself (for example, it 648193267Sjkim * will typically execute control methods during device enumeration.) 649193267Sjkim */ 650100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 651100966Siwasaki if (ACPI_FAILURE (Status)) 652100966Siwasaki { 653193267Sjkim goto UnlockAndExit; 654100966Siwasaki } 655100966Siwasaki 656151937Sjkim Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, 657199337Sjkim ACPI_NS_WALK_UNLOCK, PreOrderVisit, 658199337Sjkim PostOrderVisit, Context, ReturnValue); 659100966Siwasaki 660100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 661193267Sjkim 662193267SjkimUnlockAndExit: 663193267Sjkim (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock); 664100966Siwasaki return_ACPI_STATUS (Status); 665100966Siwasaki} 666100966Siwasaki 667167802SjkimACPI_EXPORT_SYMBOL (AcpiWalkNamespace) 668100966Siwasaki 669167802Sjkim 670100966Siwasaki/******************************************************************************* 671100966Siwasaki * 672100966Siwasaki * FUNCTION: AcpiNsGetDeviceCallback 673100966Siwasaki * 674100966Siwasaki * PARAMETERS: Callback from AcpiGetDevice 675100966Siwasaki * 676100966Siwasaki * RETURN: Status 677100966Siwasaki * 678100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 679100966Siwasaki * present devices, or if they specified a HID, it filters based 680100966Siwasaki * on that. 681100966Siwasaki * 682100966Siwasaki ******************************************************************************/ 683100966Siwasaki 684100966Siwasakistatic ACPI_STATUS 685100966SiwasakiAcpiNsGetDeviceCallback ( 686100966Siwasaki ACPI_HANDLE ObjHandle, 687100966Siwasaki UINT32 NestingLevel, 688100966Siwasaki void *Context, 689100966Siwasaki void **ReturnValue) 690100966Siwasaki{ 691117521Snjl ACPI_GET_DEVICES_INFO *Info = Context; 692100966Siwasaki ACPI_STATUS Status; 693100966Siwasaki ACPI_NAMESPACE_NODE *Node; 694100966Siwasaki UINT32 Flags; 695241973Sjkim ACPI_PNP_DEVICE_ID *Hid; 696241973Sjkim ACPI_PNP_DEVICE_ID_LIST *Cid; 697193267Sjkim UINT32 i; 698193267Sjkim BOOLEAN Found; 699197104Sjkim int NoMatch; 700100966Siwasaki 701100966Siwasaki 702100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 703100966Siwasaki if (ACPI_FAILURE (Status)) 704100966Siwasaki { 705100966Siwasaki return (Status); 706100966Siwasaki } 707100966Siwasaki 708200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 709100966Siwasaki Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 710100966Siwasaki if (ACPI_FAILURE (Status)) 711100966Siwasaki { 712100966Siwasaki return (Status); 713100966Siwasaki } 714100966Siwasaki 715100966Siwasaki if (!Node) 716100966Siwasaki { 717100966Siwasaki return (AE_BAD_PARAMETER); 718100966Siwasaki } 719100966Siwasaki 720202771Sjkim /* 721202771Sjkim * First, filter based on the device HID and CID. 722202771Sjkim * 723202771Sjkim * 01/2010: For this case where a specific HID is requested, we don't 724202771Sjkim * want to run _STA until we have an actual HID match. Thus, we will 725202771Sjkim * not unnecessarily execute _STA on devices for which the caller 726202771Sjkim * doesn't care about. Previously, _STA was executed unconditionally 727202771Sjkim * on all devices found here. 728202771Sjkim * 729202771Sjkim * A side-effect of this change is that now we will continue to search 730202771Sjkim * for a matching HID even under device trees where the parent device 731202771Sjkim * would have returned a _STA that indicates it is not present or 732202771Sjkim * not functioning (thus aborting the search on that branch). 733202771Sjkim */ 734100966Siwasaki if (Info->Hid != NULL) 735100966Siwasaki { 736100966Siwasaki Status = AcpiUtExecute_HID (Node, &Hid); 737100966Siwasaki if (Status == AE_NOT_FOUND) 738100966Siwasaki { 739100966Siwasaki return (AE_OK); 740100966Siwasaki } 741100966Siwasaki else if (ACPI_FAILURE (Status)) 742100966Siwasaki { 743100966Siwasaki return (AE_CTRL_DEPTH); 744100966Siwasaki } 745100966Siwasaki 746197104Sjkim NoMatch = ACPI_STRCMP (Hid->String, Info->Hid); 747197104Sjkim ACPI_FREE (Hid); 748197104Sjkim 749197104Sjkim if (NoMatch) 750100966Siwasaki { 751193267Sjkim /* 752193267Sjkim * HID does not match, attempt match within the 753193267Sjkim * list of Compatible IDs (CIDs) 754193267Sjkim */ 755100966Siwasaki Status = AcpiUtExecute_CID (Node, &Cid); 756100966Siwasaki if (Status == AE_NOT_FOUND) 757100966Siwasaki { 758100966Siwasaki return (AE_OK); 759100966Siwasaki } 760100966Siwasaki else if (ACPI_FAILURE (Status)) 761100966Siwasaki { 762100966Siwasaki return (AE_CTRL_DEPTH); 763100966Siwasaki } 764100966Siwasaki 765117521Snjl /* Walk the CID list */ 766100966Siwasaki 767193267Sjkim Found = FALSE; 768117521Snjl for (i = 0; i < Cid->Count; i++) 769100966Siwasaki { 770197104Sjkim if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0) 771117521Snjl { 772193267Sjkim /* Found a matching CID */ 773193267Sjkim 774193267Sjkim Found = TRUE; 775193267Sjkim break; 776117521Snjl } 777100966Siwasaki } 778193267Sjkim 779167802Sjkim ACPI_FREE (Cid); 780193267Sjkim if (!Found) 781193267Sjkim { 782193267Sjkim return (AE_OK); 783193267Sjkim } 784100966Siwasaki } 785100966Siwasaki } 786100966Siwasaki 787202771Sjkim /* Run _STA to determine if device is present */ 788202771Sjkim 789202771Sjkim Status = AcpiUtExecute_STA (Node, &Flags); 790202771Sjkim if (ACPI_FAILURE (Status)) 791202771Sjkim { 792202771Sjkim return (AE_CTRL_DEPTH); 793202771Sjkim } 794202771Sjkim 795202771Sjkim if (!(Flags & ACPI_STA_DEVICE_PRESENT) && 796202771Sjkim !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) 797202771Sjkim { 798202771Sjkim /* 799202771Sjkim * Don't examine the children of the device only when the 800202771Sjkim * device is neither present nor functional. See ACPI spec, 801202771Sjkim * description of _STA for more information. 802202771Sjkim */ 803202771Sjkim return (AE_CTRL_DEPTH); 804202771Sjkim } 805202771Sjkim 806193267Sjkim /* We have a valid device, invoke the user function */ 807193267Sjkim 808151937Sjkim Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, 809151937Sjkim ReturnValue); 810100966Siwasaki return (Status); 811100966Siwasaki} 812100966Siwasaki 813100966Siwasaki 814100966Siwasaki/******************************************************************************* 815100966Siwasaki * 816100966Siwasaki * FUNCTION: AcpiGetDevices 817100966Siwasaki * 818100966Siwasaki * PARAMETERS: HID - HID to search for. Can be NULL. 819100966Siwasaki * UserFunction - Called when a matching object is found 820100966Siwasaki * Context - Passed to user function 821100966Siwasaki * ReturnValue - Location where return value of 822100966Siwasaki * UserFunction is put if terminated early 823100966Siwasaki * 824100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 825100966Siwasaki * Otherwise, returns NULL. 826100966Siwasaki * 827100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 828100966Siwasaki * starting (and ending) at the object specified by StartHandle. 829117521Snjl * The UserFunction is called whenever an object of type 830241973Sjkim * Device is found. If the user function returns 831100966Siwasaki * a non-zero value, the search is terminated immediately and this 832100966Siwasaki * value is returned to the caller. 833100966Siwasaki * 834100966Siwasaki * This is a wrapper for WalkNamespace, but the callback performs 835193267Sjkim * additional filtering. Please see AcpiNsGetDeviceCallback. 836100966Siwasaki * 837100966Siwasaki ******************************************************************************/ 838100966Siwasaki 839100966SiwasakiACPI_STATUS 840100966SiwasakiAcpiGetDevices ( 841114237Snjl char *HID, 842100966Siwasaki ACPI_WALK_CALLBACK UserFunction, 843100966Siwasaki void *Context, 844100966Siwasaki void **ReturnValue) 845100966Siwasaki{ 846100966Siwasaki ACPI_STATUS Status; 847100966Siwasaki ACPI_GET_DEVICES_INFO Info; 848100966Siwasaki 849100966Siwasaki 850167802Sjkim ACPI_FUNCTION_TRACE (AcpiGetDevices); 851100966Siwasaki 852100966Siwasaki 853100966Siwasaki /* Parameter validation */ 854100966Siwasaki 855100966Siwasaki if (!UserFunction) 856100966Siwasaki { 857100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 858100966Siwasaki } 859100966Siwasaki 860100966Siwasaki /* 861100966Siwasaki * We're going to call their callback from OUR callback, so we need 862100966Siwasaki * to know what it is, and their context parameter. 863100966Siwasaki */ 864167802Sjkim Info.Hid = HID; 865100966Siwasaki Info.Context = Context; 866100966Siwasaki Info.UserFunction = UserFunction; 867100966Siwasaki 868100966Siwasaki /* 869100966Siwasaki * Lock the namespace around the walk. 870100966Siwasaki * The namespace will be unlocked/locked around each call 871100966Siwasaki * to the user function - since this function 872100966Siwasaki * must be allowed to make Acpi calls itself. 873100966Siwasaki */ 874100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 875100966Siwasaki if (ACPI_FAILURE (Status)) 876100966Siwasaki { 877100966Siwasaki return_ACPI_STATUS (Status); 878100966Siwasaki } 879100966Siwasaki 880167802Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 881167802Sjkim ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 882199337Sjkim AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue); 883100966Siwasaki 884100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 885100966Siwasaki return_ACPI_STATUS (Status); 886100966Siwasaki} 887100966Siwasaki 888167802SjkimACPI_EXPORT_SYMBOL (AcpiGetDevices) 889100966Siwasaki 890167802Sjkim 891100966Siwasaki/******************************************************************************* 892100966Siwasaki * 893100966Siwasaki * FUNCTION: AcpiAttachData 894100966Siwasaki * 895114237Snjl * PARAMETERS: ObjHandle - Namespace node 896107325Siwasaki * Handler - Handler for this attachment 897107325Siwasaki * Data - Pointer to data to be attached 898100966Siwasaki * 899100966Siwasaki * RETURN: Status 900100966Siwasaki * 901107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node. 902100966Siwasaki * 903100966Siwasaki ******************************************************************************/ 904100966Siwasaki 905100966SiwasakiACPI_STATUS 906100966SiwasakiAcpiAttachData ( 907100966Siwasaki ACPI_HANDLE ObjHandle, 908100966Siwasaki ACPI_OBJECT_HANDLER Handler, 909100966Siwasaki void *Data) 910100966Siwasaki{ 911100966Siwasaki ACPI_NAMESPACE_NODE *Node; 912100966Siwasaki ACPI_STATUS Status; 913100966Siwasaki 914100966Siwasaki 915100966Siwasaki /* Parameter validation */ 916100966Siwasaki 917100966Siwasaki if (!ObjHandle || 918100966Siwasaki !Handler || 919100966Siwasaki !Data) 920100966Siwasaki { 921100966Siwasaki return (AE_BAD_PARAMETER); 922100966Siwasaki } 923100966Siwasaki 924100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 925100966Siwasaki if (ACPI_FAILURE (Status)) 926100966Siwasaki { 927100966Siwasaki return (Status); 928100966Siwasaki } 929100966Siwasaki 930100966Siwasaki /* Convert and validate the handle */ 931100966Siwasaki 932200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 933100966Siwasaki if (!Node) 934100966Siwasaki { 935100966Siwasaki Status = AE_BAD_PARAMETER; 936100966Siwasaki goto UnlockAndExit; 937100966Siwasaki } 938100966Siwasaki 939100966Siwasaki Status = AcpiNsAttachData (Node, Handler, Data); 940100966Siwasaki 941100966SiwasakiUnlockAndExit: 942100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 943100966Siwasaki return (Status); 944100966Siwasaki} 945100966Siwasaki 946167802SjkimACPI_EXPORT_SYMBOL (AcpiAttachData) 947100966Siwasaki 948167802Sjkim 949100966Siwasaki/******************************************************************************* 950100966Siwasaki * 951100966Siwasaki * FUNCTION: AcpiDetachData 952100966Siwasaki * 953107325Siwasaki * PARAMETERS: ObjHandle - Namespace node handle 954107325Siwasaki * Handler - Handler used in call to AcpiAttachData 955100966Siwasaki * 956100966Siwasaki * RETURN: Status 957100966Siwasaki * 958107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node. 959100966Siwasaki * 960100966Siwasaki ******************************************************************************/ 961100966Siwasaki 962100966SiwasakiACPI_STATUS 963100966SiwasakiAcpiDetachData ( 964100966Siwasaki ACPI_HANDLE ObjHandle, 965100966Siwasaki ACPI_OBJECT_HANDLER Handler) 966100966Siwasaki{ 967100966Siwasaki ACPI_NAMESPACE_NODE *Node; 968100966Siwasaki ACPI_STATUS Status; 969100966Siwasaki 970100966Siwasaki 971100966Siwasaki /* Parameter validation */ 972100966Siwasaki 973100966Siwasaki if (!ObjHandle || 974100966Siwasaki !Handler) 975100966Siwasaki { 976100966Siwasaki return (AE_BAD_PARAMETER); 977100966Siwasaki } 978100966Siwasaki 979100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 980100966Siwasaki if (ACPI_FAILURE (Status)) 981100966Siwasaki { 982100966Siwasaki return (Status); 983100966Siwasaki } 984100966Siwasaki 985100966Siwasaki /* Convert and validate the handle */ 986100966Siwasaki 987200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 988100966Siwasaki if (!Node) 989100966Siwasaki { 990100966Siwasaki Status = AE_BAD_PARAMETER; 991100966Siwasaki goto UnlockAndExit; 992100966Siwasaki } 993100966Siwasaki 994100966Siwasaki Status = AcpiNsDetachData (Node, Handler); 995100966Siwasaki 996100966SiwasakiUnlockAndExit: 997100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 998100966Siwasaki return (Status); 999100966Siwasaki} 1000100966Siwasaki 1001167802SjkimACPI_EXPORT_SYMBOL (AcpiDetachData) 1002100966Siwasaki 1003167802Sjkim 1004100966Siwasaki/******************************************************************************* 1005100966Siwasaki * 1006100966Siwasaki * FUNCTION: AcpiGetData 1007100966Siwasaki * 1008107325Siwasaki * PARAMETERS: ObjHandle - Namespace node 1009107325Siwasaki * Handler - Handler used in call to AttachData 1010107325Siwasaki * Data - Where the data is returned 1011100966Siwasaki * 1012100966Siwasaki * RETURN: Status 1013100966Siwasaki * 1014107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node. 1015100966Siwasaki * 1016100966Siwasaki ******************************************************************************/ 1017100966Siwasaki 1018100966SiwasakiACPI_STATUS 1019100966SiwasakiAcpiGetData ( 1020100966Siwasaki ACPI_HANDLE ObjHandle, 1021100966Siwasaki ACPI_OBJECT_HANDLER Handler, 1022100966Siwasaki void **Data) 1023100966Siwasaki{ 1024100966Siwasaki ACPI_NAMESPACE_NODE *Node; 1025100966Siwasaki ACPI_STATUS Status; 1026100966Siwasaki 1027100966Siwasaki 1028100966Siwasaki /* Parameter validation */ 1029100966Siwasaki 1030100966Siwasaki if (!ObjHandle || 1031100966Siwasaki !Handler || 1032100966Siwasaki !Data) 1033100966Siwasaki { 1034100966Siwasaki return (AE_BAD_PARAMETER); 1035100966Siwasaki } 1036100966Siwasaki 1037100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1038100966Siwasaki if (ACPI_FAILURE (Status)) 1039100966Siwasaki { 1040100966Siwasaki return (Status); 1041100966Siwasaki } 1042100966Siwasaki 1043100966Siwasaki /* Convert and validate the handle */ 1044100966Siwasaki 1045200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 1046100966Siwasaki if (!Node) 1047100966Siwasaki { 1048100966Siwasaki Status = AE_BAD_PARAMETER; 1049100966Siwasaki goto UnlockAndExit; 1050100966Siwasaki } 1051100966Siwasaki 1052100966Siwasaki Status = AcpiNsGetAttachedData (Node, Handler, Data); 1053100966Siwasaki 1054100966SiwasakiUnlockAndExit: 1055100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1056100966Siwasaki return (Status); 1057100966Siwasaki} 1058100966Siwasaki 1059167802SjkimACPI_EXPORT_SYMBOL (AcpiGetData) 1060