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: 553250838Sjkim 554193267Sjkim return; 555193267Sjkim } 556193267Sjkim 557193267Sjkim /* Replace the existing reference object */ 558193267Sjkim 559193267Sjkim if (ObjDesc) 560193267Sjkim { 561193267Sjkim AcpiUtAddReference (ObjDesc); 562193267Sjkim AcpiUtRemoveReference (Info->ReturnObject); 563193267Sjkim Info->ReturnObject = ObjDesc; 564193267Sjkim } 565193267Sjkim 566193267Sjkim return; 567193267Sjkim} 568193267Sjkim 569193267Sjkim 570193267Sjkim/******************************************************************************* 571193267Sjkim * 572100966Siwasaki * FUNCTION: AcpiWalkNamespace 573100966Siwasaki * 574100966Siwasaki * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 575100966Siwasaki * StartObject - Handle in namespace where search begins 576100966Siwasaki * MaxDepth - Depth to which search is to reach 577253690Sjkim * DescendingCallback - Called during tree descent 578199337Sjkim * when an object of "Type" is found 579253690Sjkim * AscendingCallback - Called during tree ascent 580199337Sjkim * when an object of "Type" is found 581199337Sjkim * Context - Passed to user function(s) above 582100966Siwasaki * ReturnValue - Location where return value of 583100966Siwasaki * UserFunction is put if terminated early 584100966Siwasaki * 585100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 586100966Siwasaki * Otherwise, returns NULL. 587100966Siwasaki * 588100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 589100966Siwasaki * starting (and ending) at the object specified by StartHandle. 590199337Sjkim * The callback function is called whenever an object that matches 591199337Sjkim * the type parameter is found. If the callback function returns 592100966Siwasaki * a non-zero value, the search is terminated immediately and this 593100966Siwasaki * value is returned to the caller. 594100966Siwasaki * 595100966Siwasaki * The point of this procedure is to provide a generic namespace 596100966Siwasaki * walk routine that can be called from multiple places to 597199337Sjkim * provide multiple services; the callback function(s) can be 598199337Sjkim * tailored to each task, whether it is a print function, 599199337Sjkim * a compare function, etc. 600100966Siwasaki * 601100966Siwasaki ******************************************************************************/ 602100966Siwasaki 603100966SiwasakiACPI_STATUS 604100966SiwasakiAcpiWalkNamespace ( 605100966Siwasaki ACPI_OBJECT_TYPE Type, 606100966Siwasaki ACPI_HANDLE StartObject, 607100966Siwasaki UINT32 MaxDepth, 608253690Sjkim ACPI_WALK_CALLBACK DescendingCallback, 609253690Sjkim ACPI_WALK_CALLBACK AscendingCallback, 610100966Siwasaki void *Context, 611100966Siwasaki void **ReturnValue) 612100966Siwasaki{ 613100966Siwasaki ACPI_STATUS Status; 614100966Siwasaki 615100966Siwasaki 616167802Sjkim ACPI_FUNCTION_TRACE (AcpiWalkNamespace); 617100966Siwasaki 618100966Siwasaki 619100966Siwasaki /* Parameter validation */ 620100966Siwasaki 621167802Sjkim if ((Type > ACPI_TYPE_LOCAL_MAX) || 622167802Sjkim (!MaxDepth) || 623253690Sjkim (!DescendingCallback && !AscendingCallback)) 624100966Siwasaki { 625100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 626100966Siwasaki } 627100966Siwasaki 628100966Siwasaki /* 629193267Sjkim * Need to acquire the namespace reader lock to prevent interference 630193267Sjkim * with any concurrent table unloads (which causes the deletion of 631193267Sjkim * namespace objects). We cannot allow the deletion of a namespace node 632193267Sjkim * while the user function is using it. The exception to this are the 633193267Sjkim * nodes created and deleted during control method execution -- these 634193267Sjkim * nodes are marked as temporary nodes and are ignored by the namespace 635193267Sjkim * walk. Thus, control methods can be executed while holding the 636193267Sjkim * namespace deletion lock (and the user function can execute control 637193267Sjkim * methods.) 638100966Siwasaki */ 639193267Sjkim Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock); 640193267Sjkim if (ACPI_FAILURE (Status)) 641193267Sjkim { 642241973Sjkim return_ACPI_STATUS (Status); 643193267Sjkim } 644193267Sjkim 645193267Sjkim /* 646193267Sjkim * Lock the namespace around the walk. The namespace will be 647193267Sjkim * unlocked/locked around each call to the user function - since the user 648193267Sjkim * function must be allowed to make ACPICA calls itself (for example, it 649193267Sjkim * will typically execute control methods during device enumeration.) 650193267Sjkim */ 651100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 652100966Siwasaki if (ACPI_FAILURE (Status)) 653100966Siwasaki { 654193267Sjkim goto UnlockAndExit; 655100966Siwasaki } 656100966Siwasaki 657254745Sjkim /* Now we can validate the starting node */ 658254745Sjkim 659254745Sjkim if (!AcpiNsValidateHandle (StartObject)) 660254745Sjkim { 661254745Sjkim Status = AE_BAD_PARAMETER; 662254745Sjkim goto UnlockAndExit2; 663254745Sjkim } 664254745Sjkim 665151937Sjkim Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, 666253690Sjkim ACPI_NS_WALK_UNLOCK, DescendingCallback, 667253690Sjkim AscendingCallback, Context, ReturnValue); 668100966Siwasaki 669254745SjkimUnlockAndExit2: 670100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 671193267Sjkim 672193267SjkimUnlockAndExit: 673193267Sjkim (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock); 674100966Siwasaki return_ACPI_STATUS (Status); 675100966Siwasaki} 676100966Siwasaki 677167802SjkimACPI_EXPORT_SYMBOL (AcpiWalkNamespace) 678100966Siwasaki 679167802Sjkim 680100966Siwasaki/******************************************************************************* 681100966Siwasaki * 682100966Siwasaki * FUNCTION: AcpiNsGetDeviceCallback 683100966Siwasaki * 684100966Siwasaki * PARAMETERS: Callback from AcpiGetDevice 685100966Siwasaki * 686100966Siwasaki * RETURN: Status 687100966Siwasaki * 688100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 689100966Siwasaki * present devices, or if they specified a HID, it filters based 690100966Siwasaki * on that. 691100966Siwasaki * 692100966Siwasaki ******************************************************************************/ 693100966Siwasaki 694100966Siwasakistatic ACPI_STATUS 695100966SiwasakiAcpiNsGetDeviceCallback ( 696100966Siwasaki ACPI_HANDLE ObjHandle, 697100966Siwasaki UINT32 NestingLevel, 698100966Siwasaki void *Context, 699100966Siwasaki void **ReturnValue) 700100966Siwasaki{ 701117521Snjl ACPI_GET_DEVICES_INFO *Info = Context; 702100966Siwasaki ACPI_STATUS Status; 703100966Siwasaki ACPI_NAMESPACE_NODE *Node; 704100966Siwasaki UINT32 Flags; 705241973Sjkim ACPI_PNP_DEVICE_ID *Hid; 706241973Sjkim ACPI_PNP_DEVICE_ID_LIST *Cid; 707193267Sjkim UINT32 i; 708193267Sjkim BOOLEAN Found; 709197104Sjkim int NoMatch; 710100966Siwasaki 711100966Siwasaki 712100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 713100966Siwasaki if (ACPI_FAILURE (Status)) 714100966Siwasaki { 715100966Siwasaki return (Status); 716100966Siwasaki } 717100966Siwasaki 718200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 719100966Siwasaki Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 720100966Siwasaki if (ACPI_FAILURE (Status)) 721100966Siwasaki { 722100966Siwasaki return (Status); 723100966Siwasaki } 724100966Siwasaki 725100966Siwasaki if (!Node) 726100966Siwasaki { 727100966Siwasaki return (AE_BAD_PARAMETER); 728100966Siwasaki } 729100966Siwasaki 730202771Sjkim /* 731202771Sjkim * First, filter based on the device HID and CID. 732202771Sjkim * 733202771Sjkim * 01/2010: For this case where a specific HID is requested, we don't 734202771Sjkim * want to run _STA until we have an actual HID match. Thus, we will 735202771Sjkim * not unnecessarily execute _STA on devices for which the caller 736202771Sjkim * doesn't care about. Previously, _STA was executed unconditionally 737202771Sjkim * on all devices found here. 738202771Sjkim * 739202771Sjkim * A side-effect of this change is that now we will continue to search 740202771Sjkim * for a matching HID even under device trees where the parent device 741202771Sjkim * would have returned a _STA that indicates it is not present or 742202771Sjkim * not functioning (thus aborting the search on that branch). 743202771Sjkim */ 744100966Siwasaki if (Info->Hid != NULL) 745100966Siwasaki { 746100966Siwasaki Status = AcpiUtExecute_HID (Node, &Hid); 747100966Siwasaki if (Status == AE_NOT_FOUND) 748100966Siwasaki { 749100966Siwasaki return (AE_OK); 750100966Siwasaki } 751100966Siwasaki else if (ACPI_FAILURE (Status)) 752100966Siwasaki { 753100966Siwasaki return (AE_CTRL_DEPTH); 754100966Siwasaki } 755100966Siwasaki 756197104Sjkim NoMatch = ACPI_STRCMP (Hid->String, Info->Hid); 757197104Sjkim ACPI_FREE (Hid); 758197104Sjkim 759197104Sjkim if (NoMatch) 760100966Siwasaki { 761193267Sjkim /* 762193267Sjkim * HID does not match, attempt match within the 763193267Sjkim * list of Compatible IDs (CIDs) 764193267Sjkim */ 765100966Siwasaki Status = AcpiUtExecute_CID (Node, &Cid); 766100966Siwasaki if (Status == AE_NOT_FOUND) 767100966Siwasaki { 768100966Siwasaki return (AE_OK); 769100966Siwasaki } 770100966Siwasaki else if (ACPI_FAILURE (Status)) 771100966Siwasaki { 772100966Siwasaki return (AE_CTRL_DEPTH); 773100966Siwasaki } 774100966Siwasaki 775117521Snjl /* Walk the CID list */ 776100966Siwasaki 777193267Sjkim Found = FALSE; 778117521Snjl for (i = 0; i < Cid->Count; i++) 779100966Siwasaki { 780197104Sjkim if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0) 781117521Snjl { 782193267Sjkim /* Found a matching CID */ 783193267Sjkim 784193267Sjkim Found = TRUE; 785193267Sjkim break; 786117521Snjl } 787100966Siwasaki } 788193267Sjkim 789167802Sjkim ACPI_FREE (Cid); 790193267Sjkim if (!Found) 791193267Sjkim { 792193267Sjkim return (AE_OK); 793193267Sjkim } 794100966Siwasaki } 795100966Siwasaki } 796100966Siwasaki 797202771Sjkim /* Run _STA to determine if device is present */ 798202771Sjkim 799202771Sjkim Status = AcpiUtExecute_STA (Node, &Flags); 800202771Sjkim if (ACPI_FAILURE (Status)) 801202771Sjkim { 802202771Sjkim return (AE_CTRL_DEPTH); 803202771Sjkim } 804202771Sjkim 805202771Sjkim if (!(Flags & ACPI_STA_DEVICE_PRESENT) && 806202771Sjkim !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) 807202771Sjkim { 808202771Sjkim /* 809202771Sjkim * Don't examine the children of the device only when the 810202771Sjkim * device is neither present nor functional. See ACPI spec, 811202771Sjkim * description of _STA for more information. 812202771Sjkim */ 813202771Sjkim return (AE_CTRL_DEPTH); 814202771Sjkim } 815202771Sjkim 816193267Sjkim /* We have a valid device, invoke the user function */ 817193267Sjkim 818151937Sjkim Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, 819151937Sjkim ReturnValue); 820100966Siwasaki return (Status); 821100966Siwasaki} 822100966Siwasaki 823100966Siwasaki 824100966Siwasaki/******************************************************************************* 825100966Siwasaki * 826100966Siwasaki * FUNCTION: AcpiGetDevices 827100966Siwasaki * 828100966Siwasaki * PARAMETERS: HID - HID to search for. Can be NULL. 829100966Siwasaki * UserFunction - Called when a matching object is found 830100966Siwasaki * Context - Passed to user function 831100966Siwasaki * ReturnValue - Location where return value of 832100966Siwasaki * UserFunction is put if terminated early 833100966Siwasaki * 834100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 835100966Siwasaki * Otherwise, returns NULL. 836100966Siwasaki * 837100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 838100966Siwasaki * starting (and ending) at the object specified by StartHandle. 839117521Snjl * The UserFunction is called whenever an object of type 840241973Sjkim * Device is found. If the user function returns 841100966Siwasaki * a non-zero value, the search is terminated immediately and this 842100966Siwasaki * value is returned to the caller. 843100966Siwasaki * 844100966Siwasaki * This is a wrapper for WalkNamespace, but the callback performs 845193267Sjkim * additional filtering. Please see AcpiNsGetDeviceCallback. 846100966Siwasaki * 847100966Siwasaki ******************************************************************************/ 848100966Siwasaki 849100966SiwasakiACPI_STATUS 850100966SiwasakiAcpiGetDevices ( 851114237Snjl char *HID, 852100966Siwasaki ACPI_WALK_CALLBACK UserFunction, 853100966Siwasaki void *Context, 854100966Siwasaki void **ReturnValue) 855100966Siwasaki{ 856100966Siwasaki ACPI_STATUS Status; 857100966Siwasaki ACPI_GET_DEVICES_INFO Info; 858100966Siwasaki 859100966Siwasaki 860167802Sjkim ACPI_FUNCTION_TRACE (AcpiGetDevices); 861100966Siwasaki 862100966Siwasaki 863100966Siwasaki /* Parameter validation */ 864100966Siwasaki 865100966Siwasaki if (!UserFunction) 866100966Siwasaki { 867100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 868100966Siwasaki } 869100966Siwasaki 870100966Siwasaki /* 871100966Siwasaki * We're going to call their callback from OUR callback, so we need 872100966Siwasaki * to know what it is, and their context parameter. 873100966Siwasaki */ 874167802Sjkim Info.Hid = HID; 875100966Siwasaki Info.Context = Context; 876100966Siwasaki Info.UserFunction = UserFunction; 877100966Siwasaki 878100966Siwasaki /* 879100966Siwasaki * Lock the namespace around the walk. 880100966Siwasaki * The namespace will be unlocked/locked around each call 881100966Siwasaki * to the user function - since this function 882100966Siwasaki * must be allowed to make Acpi calls itself. 883100966Siwasaki */ 884100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 885100966Siwasaki if (ACPI_FAILURE (Status)) 886100966Siwasaki { 887100966Siwasaki return_ACPI_STATUS (Status); 888100966Siwasaki } 889100966Siwasaki 890167802Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 891167802Sjkim ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 892199337Sjkim AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue); 893100966Siwasaki 894100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 895100966Siwasaki return_ACPI_STATUS (Status); 896100966Siwasaki} 897100966Siwasaki 898167802SjkimACPI_EXPORT_SYMBOL (AcpiGetDevices) 899100966Siwasaki 900167802Sjkim 901100966Siwasaki/******************************************************************************* 902100966Siwasaki * 903100966Siwasaki * FUNCTION: AcpiAttachData 904100966Siwasaki * 905114237Snjl * PARAMETERS: ObjHandle - Namespace node 906107325Siwasaki * Handler - Handler for this attachment 907107325Siwasaki * Data - Pointer to data to be attached 908100966Siwasaki * 909100966Siwasaki * RETURN: Status 910100966Siwasaki * 911107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node. 912100966Siwasaki * 913100966Siwasaki ******************************************************************************/ 914100966Siwasaki 915100966SiwasakiACPI_STATUS 916100966SiwasakiAcpiAttachData ( 917100966Siwasaki ACPI_HANDLE ObjHandle, 918100966Siwasaki ACPI_OBJECT_HANDLER Handler, 919100966Siwasaki void *Data) 920100966Siwasaki{ 921100966Siwasaki ACPI_NAMESPACE_NODE *Node; 922100966Siwasaki ACPI_STATUS Status; 923100966Siwasaki 924100966Siwasaki 925100966Siwasaki /* Parameter validation */ 926100966Siwasaki 927100966Siwasaki if (!ObjHandle || 928100966Siwasaki !Handler || 929100966Siwasaki !Data) 930100966Siwasaki { 931100966Siwasaki return (AE_BAD_PARAMETER); 932100966Siwasaki } 933100966Siwasaki 934100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 935100966Siwasaki if (ACPI_FAILURE (Status)) 936100966Siwasaki { 937100966Siwasaki return (Status); 938100966Siwasaki } 939100966Siwasaki 940100966Siwasaki /* Convert and validate the handle */ 941100966Siwasaki 942200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 943100966Siwasaki if (!Node) 944100966Siwasaki { 945100966Siwasaki Status = AE_BAD_PARAMETER; 946100966Siwasaki goto UnlockAndExit; 947100966Siwasaki } 948100966Siwasaki 949100966Siwasaki Status = AcpiNsAttachData (Node, Handler, Data); 950100966Siwasaki 951100966SiwasakiUnlockAndExit: 952100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 953100966Siwasaki return (Status); 954100966Siwasaki} 955100966Siwasaki 956167802SjkimACPI_EXPORT_SYMBOL (AcpiAttachData) 957100966Siwasaki 958167802Sjkim 959100966Siwasaki/******************************************************************************* 960100966Siwasaki * 961100966Siwasaki * FUNCTION: AcpiDetachData 962100966Siwasaki * 963107325Siwasaki * PARAMETERS: ObjHandle - Namespace node handle 964107325Siwasaki * Handler - Handler used in call to AcpiAttachData 965100966Siwasaki * 966100966Siwasaki * RETURN: Status 967100966Siwasaki * 968107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node. 969100966Siwasaki * 970100966Siwasaki ******************************************************************************/ 971100966Siwasaki 972100966SiwasakiACPI_STATUS 973100966SiwasakiAcpiDetachData ( 974100966Siwasaki ACPI_HANDLE ObjHandle, 975100966Siwasaki ACPI_OBJECT_HANDLER Handler) 976100966Siwasaki{ 977100966Siwasaki ACPI_NAMESPACE_NODE *Node; 978100966Siwasaki ACPI_STATUS Status; 979100966Siwasaki 980100966Siwasaki 981100966Siwasaki /* Parameter validation */ 982100966Siwasaki 983100966Siwasaki if (!ObjHandle || 984100966Siwasaki !Handler) 985100966Siwasaki { 986100966Siwasaki return (AE_BAD_PARAMETER); 987100966Siwasaki } 988100966Siwasaki 989100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 990100966Siwasaki if (ACPI_FAILURE (Status)) 991100966Siwasaki { 992100966Siwasaki return (Status); 993100966Siwasaki } 994100966Siwasaki 995100966Siwasaki /* Convert and validate the handle */ 996100966Siwasaki 997200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 998100966Siwasaki if (!Node) 999100966Siwasaki { 1000100966Siwasaki Status = AE_BAD_PARAMETER; 1001100966Siwasaki goto UnlockAndExit; 1002100966Siwasaki } 1003100966Siwasaki 1004100966Siwasaki Status = AcpiNsDetachData (Node, Handler); 1005100966Siwasaki 1006100966SiwasakiUnlockAndExit: 1007100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1008100966Siwasaki return (Status); 1009100966Siwasaki} 1010100966Siwasaki 1011167802SjkimACPI_EXPORT_SYMBOL (AcpiDetachData) 1012100966Siwasaki 1013167802Sjkim 1014100966Siwasaki/******************************************************************************* 1015100966Siwasaki * 1016100966Siwasaki * FUNCTION: AcpiGetData 1017100966Siwasaki * 1018107325Siwasaki * PARAMETERS: ObjHandle - Namespace node 1019107325Siwasaki * Handler - Handler used in call to AttachData 1020107325Siwasaki * Data - Where the data is returned 1021100966Siwasaki * 1022100966Siwasaki * RETURN: Status 1023100966Siwasaki * 1024107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node. 1025100966Siwasaki * 1026100966Siwasaki ******************************************************************************/ 1027100966Siwasaki 1028100966SiwasakiACPI_STATUS 1029100966SiwasakiAcpiGetData ( 1030100966Siwasaki ACPI_HANDLE ObjHandle, 1031100966Siwasaki ACPI_OBJECT_HANDLER Handler, 1032100966Siwasaki void **Data) 1033100966Siwasaki{ 1034100966Siwasaki ACPI_NAMESPACE_NODE *Node; 1035100966Siwasaki ACPI_STATUS Status; 1036100966Siwasaki 1037100966Siwasaki 1038100966Siwasaki /* Parameter validation */ 1039100966Siwasaki 1040100966Siwasaki if (!ObjHandle || 1041100966Siwasaki !Handler || 1042100966Siwasaki !Data) 1043100966Siwasaki { 1044100966Siwasaki return (AE_BAD_PARAMETER); 1045100966Siwasaki } 1046100966Siwasaki 1047100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1048100966Siwasaki if (ACPI_FAILURE (Status)) 1049100966Siwasaki { 1050100966Siwasaki return (Status); 1051100966Siwasaki } 1052100966Siwasaki 1053100966Siwasaki /* Convert and validate the handle */ 1054100966Siwasaki 1055200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 1056100966Siwasaki if (!Node) 1057100966Siwasaki { 1058100966Siwasaki Status = AE_BAD_PARAMETER; 1059100966Siwasaki goto UnlockAndExit; 1060100966Siwasaki } 1061100966Siwasaki 1062100966Siwasaki Status = AcpiNsGetAttachedData (Node, Handler, Data); 1063100966Siwasaki 1064100966SiwasakiUnlockAndExit: 1065100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1066100966Siwasaki return (Status); 1067100966Siwasaki} 1068100966Siwasaki 1069167802SjkimACPI_EXPORT_SYMBOL (AcpiGetData) 1070