1100966Siwasaki/******************************************************************************* 2100966Siwasaki * 3100966Siwasaki * Module Name: nsxfeval - Public interfaces to the ACPI subsystem 4100966Siwasaki * ACPI Object evaluation interfaces 5100966Siwasaki * 6100966Siwasaki ******************************************************************************/ 7100966Siwasaki 8217365Sjkim/* 9306536Sjkim * Copyright (C) 2000 - 2016, 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 45281075Sdim#define EXPORT_ACPI_INTERFACES 46100966Siwasaki 47193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 48193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 51100966Siwasaki 52100966Siwasaki 53100966Siwasaki#define _COMPONENT ACPI_NAMESPACE 54100966Siwasaki ACPI_MODULE_NAME ("nsxfeval") 55100966Siwasaki 56193267Sjkim/* Local prototypes */ 57100966Siwasaki 58193267Sjkimstatic void 59193267SjkimAcpiNsResolveReferences ( 60193267Sjkim ACPI_EVALUATE_INFO *Info); 61193267Sjkim 62193267Sjkim 63100966Siwasaki/******************************************************************************* 64100966Siwasaki * 65100966Siwasaki * FUNCTION: AcpiEvaluateObjectTyped 66100966Siwasaki * 67100966Siwasaki * PARAMETERS: Handle - Object handle (optional) 68151937Sjkim * Pathname - Object pathname (optional) 69151937Sjkim * ExternalParams - List of parameters to pass to method, 70241973Sjkim * terminated by NULL. May be NULL 71100966Siwasaki * if no parameters are being passed. 72151937Sjkim * ReturnBuffer - Where to put method's return value (if 73241973Sjkim * any). If NULL, no value is returned. 74100966Siwasaki * ReturnType - Expected type of return object 75100966Siwasaki * 76100966Siwasaki * RETURN: Status 77100966Siwasaki * 78100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given 79241973Sjkim * parameters if necessary. One of "Handle" or "Pathname" must 80100966Siwasaki * be valid (non-null) 81100966Siwasaki * 82100966Siwasaki ******************************************************************************/ 83100966Siwasaki 84100966SiwasakiACPI_STATUS 85100966SiwasakiAcpiEvaluateObjectTyped ( 86100966Siwasaki ACPI_HANDLE Handle, 87100966Siwasaki ACPI_STRING Pathname, 88100966Siwasaki ACPI_OBJECT_LIST *ExternalParams, 89100966Siwasaki ACPI_BUFFER *ReturnBuffer, 90100966Siwasaki ACPI_OBJECT_TYPE ReturnType) 91100966Siwasaki{ 92100966Siwasaki ACPI_STATUS Status; 93281075Sdim BOOLEAN FreeBufferOnError = FALSE; 94100966Siwasaki 95100966Siwasaki 96167802Sjkim ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); 97100966Siwasaki 98100966Siwasaki 99100966Siwasaki /* Return buffer must be valid */ 100100966Siwasaki 101100966Siwasaki if (!ReturnBuffer) 102100966Siwasaki { 103100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 104100966Siwasaki } 105100966Siwasaki 106100966Siwasaki if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) 107100966Siwasaki { 108281075Sdim FreeBufferOnError = TRUE; 109100966Siwasaki } 110100966Siwasaki 111100966Siwasaki /* Evaluate the object */ 112100966Siwasaki 113281075Sdim Status = AcpiEvaluateObject (Handle, Pathname, 114281075Sdim 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 149281075Sdim if (FreeBufferOnError) 150100966Siwasaki { 151281075Sdim /* 152281075Sdim * Free a buffer created via ACPI_ALLOCATE_BUFFER. 153281075Sdim * Note: We use AcpiOsFree here because AcpiOsAllocate was used 154281075Sdim * to allocate the buffer. This purposefully bypasses the 155281075Sdim * (optionally enabled) allocation tracking mechanism since we 156281075Sdim * only want to track internal allocations. 157281075Sdim */ 158100966Siwasaki AcpiOsFree (ReturnBuffer->Pointer); 159100966Siwasaki ReturnBuffer->Pointer = NULL; 160100966Siwasaki } 161100966Siwasaki 162100966Siwasaki ReturnBuffer->Length = 0; 163100966Siwasaki return_ACPI_STATUS (AE_TYPE); 164100966Siwasaki} 165100966Siwasaki 166167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped) 167100966Siwasaki 168167802Sjkim 169100966Siwasaki/******************************************************************************* 170100966Siwasaki * 171100966Siwasaki * FUNCTION: AcpiEvaluateObject 172100966Siwasaki * 173100966Siwasaki * PARAMETERS: Handle - Object handle (optional) 174128212Snjl * Pathname - Object pathname (optional) 175128212Snjl * ExternalParams - List of parameters to pass to method, 176241973Sjkim * terminated by NULL. May be NULL 177100966Siwasaki * if no parameters are being passed. 178128212Snjl * ReturnBuffer - Where to put method's return value (if 179241973Sjkim * any). If NULL, no value is returned. 180100966Siwasaki * 181100966Siwasaki * RETURN: Status 182100966Siwasaki * 183100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given 184241973Sjkim * parameters if necessary. One of "Handle" or "Pathname" must 185100966Siwasaki * be valid (non-null) 186100966Siwasaki * 187100966Siwasaki ******************************************************************************/ 188100966Siwasaki 189100966SiwasakiACPI_STATUS 190100966SiwasakiAcpiEvaluateObject ( 191100966Siwasaki ACPI_HANDLE Handle, 192100966Siwasaki ACPI_STRING Pathname, 193100966Siwasaki ACPI_OBJECT_LIST *ExternalParams, 194100966Siwasaki ACPI_BUFFER *ReturnBuffer) 195100966Siwasaki{ 196100966Siwasaki ACPI_STATUS Status; 197167802Sjkim ACPI_EVALUATE_INFO *Info; 198100966Siwasaki ACPI_SIZE BufferSpaceNeeded; 199100966Siwasaki UINT32 i; 200100966Siwasaki 201100966Siwasaki 202167802Sjkim ACPI_FUNCTION_TRACE (AcpiEvaluateObject); 203100966Siwasaki 204100966Siwasaki 205167802Sjkim /* Allocate and initialize the evaluation information block */ 206129684Snjl 207167802Sjkim Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 208167802Sjkim if (!Info) 209167802Sjkim { 210167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 211167802Sjkim } 212167802Sjkim 213167802Sjkim /* Convert and validate the device handle */ 214167802Sjkim 215200553Sjkim Info->PrefixNode = AcpiNsValidateHandle (Handle); 216167802Sjkim if (!Info->PrefixNode) 217167802Sjkim { 218167802Sjkim Status = AE_BAD_PARAMETER; 219167802Sjkim goto Cleanup; 220167802Sjkim } 221167802Sjkim 222100966Siwasaki /* 223249663Sjkim * Get the actual namespace node for the target object. 224249663Sjkim * Handles these cases: 225249663Sjkim * 226249663Sjkim * 1) Null node, valid pathname from root (absolute path) 227249663Sjkim * 2) Node and valid pathname (path relative to Node) 228249663Sjkim * 3) Node, Null pathname 229100966Siwasaki */ 230249663Sjkim if ((Pathname) && 231249663Sjkim (ACPI_IS_ROOT_PREFIX (Pathname[0]))) 232249663Sjkim { 233249663Sjkim /* The path is fully qualified, just evaluate by name */ 234249663Sjkim 235249663Sjkim Info->PrefixNode = NULL; 236249663Sjkim } 237249663Sjkim else if (!Handle) 238249663Sjkim { 239249663Sjkim /* 240249663Sjkim * A handle is optional iff a fully qualified pathname is specified. 241249663Sjkim * Since we've already handled fully qualified names above, this is 242249663Sjkim * an error. 243249663Sjkim */ 244249663Sjkim if (!Pathname) 245249663Sjkim { 246249663Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 247249663Sjkim "Both Handle and Pathname are NULL")); 248249663Sjkim } 249249663Sjkim else 250249663Sjkim { 251249663Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 252249663Sjkim "Null Handle with relative pathname [%s]", Pathname)); 253249663Sjkim } 254249663Sjkim 255249663Sjkim Status = AE_BAD_PARAMETER; 256249663Sjkim goto Cleanup; 257249663Sjkim } 258249663Sjkim 259249663Sjkim Info->RelativePathname = Pathname; 260249663Sjkim 261249663Sjkim /* 262249663Sjkim * Convert all external objects passed as arguments to the 263249663Sjkim * internal version(s). 264249663Sjkim */ 265100966Siwasaki if (ExternalParams && ExternalParams->Count) 266100966Siwasaki { 267249663Sjkim Info->ParamCount = (UINT16) ExternalParams->Count; 268249663Sjkim 269249663Sjkim /* Warn on impossible argument count */ 270249663Sjkim 271249663Sjkim if (Info->ParamCount > ACPI_METHOD_NUM_ARGS) 272249663Sjkim { 273249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 274249663Sjkim "Excess arguments (%u) - using only %u", 275249663Sjkim Info->ParamCount, ACPI_METHOD_NUM_ARGS)); 276249663Sjkim 277249663Sjkim Info->ParamCount = ACPI_METHOD_NUM_ARGS; 278249663Sjkim } 279249663Sjkim 280100966Siwasaki /* 281100966Siwasaki * Allocate a new parameter block for the internal objects 282100966Siwasaki * Add 1 to count to allow for null terminated internal list 283100966Siwasaki */ 284167802Sjkim Info->Parameters = ACPI_ALLOCATE_ZEROED ( 285249663Sjkim ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *)); 286167802Sjkim if (!Info->Parameters) 287100966Siwasaki { 288167802Sjkim Status = AE_NO_MEMORY; 289167802Sjkim goto Cleanup; 290100966Siwasaki } 291100966Siwasaki 292167802Sjkim /* Convert each external object in the list to an internal object */ 293167802Sjkim 294249663Sjkim for (i = 0; i < Info->ParamCount; i++) 295100966Siwasaki { 296167802Sjkim Status = AcpiUtCopyEobjectToIobject ( 297249663Sjkim &ExternalParams->Pointer[i], &Info->Parameters[i]); 298100966Siwasaki if (ACPI_FAILURE (Status)) 299100966Siwasaki { 300167802Sjkim goto Cleanup; 301100966Siwasaki } 302100966Siwasaki } 303249663Sjkim 304249663Sjkim Info->Parameters[Info->ParamCount] = NULL; 305100966Siwasaki } 306100966Siwasaki 307249663Sjkim 308306536Sjkim#ifdef _FUTURE_FEATURE 309249663Sjkim 310100966Siwasaki /* 311249663Sjkim * Begin incoming argument count analysis. Check for too few args 312249663Sjkim * and too many args. 313100966Siwasaki */ 314249663Sjkim switch (AcpiNsGetType (Info->Node)) 315100966Siwasaki { 316249663Sjkim case ACPI_TYPE_METHOD: 317167802Sjkim 318249663Sjkim /* Check incoming argument count against the method definition */ 319249663Sjkim 320249663Sjkim if (Info->ObjDesc->Method.ParamCount > Info->ParamCount) 321249663Sjkim { 322249663Sjkim ACPI_ERROR ((AE_INFO, 323249663Sjkim "Insufficient arguments (%u) - %u are required", 324249663Sjkim Info->ParamCount, 325249663Sjkim Info->ObjDesc->Method.ParamCount)); 326249663Sjkim 327249663Sjkim Status = AE_MISSING_ARGUMENTS; 328249663Sjkim goto Cleanup; 329249663Sjkim } 330249663Sjkim 331249663Sjkim else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount) 332249663Sjkim { 333249663Sjkim ACPI_WARNING ((AE_INFO, 334249663Sjkim "Excess arguments (%u) - only %u are required", 335249663Sjkim Info->ParamCount, 336249663Sjkim Info->ObjDesc->Method.ParamCount)); 337249663Sjkim 338249663Sjkim /* Just pass the required number of arguments */ 339249663Sjkim 340249663Sjkim Info->ParamCount = Info->ObjDesc->Method.ParamCount; 341249663Sjkim } 342249663Sjkim 343100966Siwasaki /* 344249663Sjkim * Any incoming external objects to be passed as arguments to the 345249663Sjkim * method must be converted to internal objects 346100966Siwasaki */ 347249663Sjkim if (Info->ParamCount) 348100966Siwasaki { 349249663Sjkim /* 350249663Sjkim * Allocate a new parameter block for the internal objects 351249663Sjkim * Add 1 to count to allow for null terminated internal list 352249663Sjkim */ 353249663Sjkim Info->Parameters = ACPI_ALLOCATE_ZEROED ( 354249663Sjkim ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *)); 355249663Sjkim if (!Info->Parameters) 356249663Sjkim { 357249663Sjkim Status = AE_NO_MEMORY; 358249663Sjkim goto Cleanup; 359249663Sjkim } 360249663Sjkim 361249663Sjkim /* Convert each external object in the list to an internal object */ 362249663Sjkim 363249663Sjkim for (i = 0; i < Info->ParamCount; i++) 364249663Sjkim { 365249663Sjkim Status = AcpiUtCopyEobjectToIobject ( 366249663Sjkim &ExternalParams->Pointer[i], &Info->Parameters[i]); 367249663Sjkim if (ACPI_FAILURE (Status)) 368249663Sjkim { 369249663Sjkim goto Cleanup; 370249663Sjkim } 371249663Sjkim } 372249663Sjkim 373249663Sjkim Info->Parameters[Info->ParamCount] = NULL; 374100966Siwasaki } 375249663Sjkim break; 376249663Sjkim 377249663Sjkim default: 378249663Sjkim 379249663Sjkim /* Warn if arguments passed to an object that is not a method */ 380249663Sjkim 381249663Sjkim if (Info->ParamCount) 382100966Siwasaki { 383249663Sjkim ACPI_WARNING ((AE_INFO, 384249663Sjkim "%u arguments were passed to a non-method ACPI object", 385249663Sjkim Info->ParamCount)); 386100966Siwasaki } 387249663Sjkim break; 388100966Siwasaki } 389167802Sjkim 390249663Sjkim#endif 391100966Siwasaki 392249663Sjkim 393249663Sjkim /* Now we can evaluate the object */ 394249663Sjkim 395249663Sjkim Status = AcpiNsEvaluate (Info); 396249663Sjkim 397100966Siwasaki /* 398100966Siwasaki * If we are expecting a return value, and all went well above, 399100966Siwasaki * copy the return value to an external object. 400100966Siwasaki */ 401306536Sjkim if (!ReturnBuffer) 402100966Siwasaki { 403306536Sjkim goto CleanupReturnObject; 404306536Sjkim } 405100966Siwasaki 406306536Sjkim if (!Info->ReturnObject) 407306536Sjkim { 408306536Sjkim ReturnBuffer->Length = 0; 409306536Sjkim goto Cleanup; 410306536Sjkim } 411193267Sjkim 412306536Sjkim if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) == 413306536Sjkim ACPI_DESC_TYPE_NAMED) 414306536Sjkim { 415306536Sjkim /* 416306536Sjkim * If we received a NS Node as a return object, this means that 417306536Sjkim * the object we are evaluating has nothing interesting to 418306536Sjkim * return (such as a mutex, etc.) We return an error because 419306536Sjkim * these types are essentially unsupported by this interface. 420306536Sjkim * We don't check up front because this makes it easier to add 421306536Sjkim * support for various types at a later date if necessary. 422306536Sjkim */ 423306536Sjkim Status = AE_TYPE; 424306536Sjkim Info->ReturnObject = NULL; /* No need to delete a NS Node */ 425306536Sjkim ReturnBuffer->Length = 0; 426306536Sjkim } 427193267Sjkim 428306536Sjkim if (ACPI_FAILURE (Status)) 429306536Sjkim { 430306536Sjkim goto CleanupReturnObject; 431306536Sjkim } 432167802Sjkim 433306536Sjkim /* Dereference Index and RefOf references */ 434100966Siwasaki 435306536Sjkim AcpiNsResolveReferences (Info); 436167802Sjkim 437306536Sjkim /* Get the size of the returned object */ 438306536Sjkim 439306536Sjkim Status = AcpiUtGetObjectSize (Info->ReturnObject, 440306536Sjkim &BufferSpaceNeeded); 441306536Sjkim if (ACPI_SUCCESS (Status)) 442306536Sjkim { 443306536Sjkim /* Validate/Allocate/Clear caller buffer */ 444306536Sjkim 445306536Sjkim Status = AcpiUtInitializeBuffer (ReturnBuffer, 446306536Sjkim BufferSpaceNeeded); 447306536Sjkim if (ACPI_FAILURE (Status)) 448306536Sjkim { 449306536Sjkim /* 450306536Sjkim * Caller's buffer is too small or a new one can't 451306536Sjkim * be allocated 452306536Sjkim */ 453306536Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 454306536Sjkim "Needed buffer size %X, %s\n", 455306536Sjkim (UINT32) BufferSpaceNeeded, 456306536Sjkim AcpiFormatException (Status))); 457100966Siwasaki } 458306536Sjkim else 459306536Sjkim { 460306536Sjkim /* We have enough space for the object, build it */ 461306536Sjkim 462306536Sjkim Status = AcpiUtCopyIobjectToEobject ( 463306536Sjkim Info->ReturnObject, ReturnBuffer); 464306536Sjkim } 465100966Siwasaki } 466100966Siwasaki 467306536SjkimCleanupReturnObject: 468306536Sjkim 469167802Sjkim if (Info->ReturnObject) 470100966Siwasaki { 471129684Snjl /* 472167802Sjkim * Delete the internal return object. NOTE: Interpreter must be 473167802Sjkim * locked to avoid race condition. 474100966Siwasaki */ 475167802Sjkim AcpiExEnterInterpreter (); 476167802Sjkim 477167802Sjkim /* Remove one reference on the return object (should delete it) */ 478167802Sjkim 479167802Sjkim AcpiUtRemoveReference (Info->ReturnObject); 480167802Sjkim AcpiExExitInterpreter (); 481100966Siwasaki } 482100966Siwasaki 483167802Sjkim 484167802SjkimCleanup: 485167802Sjkim 486167802Sjkim /* Free the input parameter list (if we created one) */ 487167802Sjkim 488167802Sjkim if (Info->Parameters) 489100966Siwasaki { 490100966Siwasaki /* Free the allocated parameter block */ 491100966Siwasaki 492167802Sjkim AcpiUtDeleteInternalObjectList (Info->Parameters); 493100966Siwasaki } 494100966Siwasaki 495167802Sjkim ACPI_FREE (Info); 496100966Siwasaki return_ACPI_STATUS (Status); 497100966Siwasaki} 498100966Siwasaki 499167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObject) 500100966Siwasaki 501167802Sjkim 502100966Siwasaki/******************************************************************************* 503100966Siwasaki * 504193267Sjkim * FUNCTION: AcpiNsResolveReferences 505193267Sjkim * 506193267Sjkim * PARAMETERS: Info - Evaluation info block 507193267Sjkim * 508193267Sjkim * RETURN: Info->ReturnObject is replaced with the dereferenced object 509193267Sjkim * 510193267Sjkim * DESCRIPTION: Dereference certain reference objects. Called before an 511193267Sjkim * internal return object is converted to an external ACPI_OBJECT. 512193267Sjkim * 513193267Sjkim * Performs an automatic dereference of Index and RefOf reference objects. 514193267Sjkim * These reference objects are not supported by the ACPI_OBJECT, so this is a 515193267Sjkim * last resort effort to return something useful. Also, provides compatibility 516193267Sjkim * with other ACPI implementations. 517193267Sjkim * 518193267Sjkim * NOTE: does not handle references within returned package objects or nested 519193267Sjkim * references, but this support could be added later if found to be necessary. 520193267Sjkim * 521193267Sjkim ******************************************************************************/ 522193267Sjkim 523193267Sjkimstatic void 524193267SjkimAcpiNsResolveReferences ( 525193267Sjkim ACPI_EVALUATE_INFO *Info) 526193267Sjkim{ 527193267Sjkim ACPI_OPERAND_OBJECT *ObjDesc = NULL; 528193267Sjkim ACPI_NAMESPACE_NODE *Node; 529193267Sjkim 530193267Sjkim 531193267Sjkim /* We are interested in reference objects only */ 532193267Sjkim 533193267Sjkim if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) 534193267Sjkim { 535193267Sjkim return; 536193267Sjkim } 537193267Sjkim 538193267Sjkim /* 539193267Sjkim * Two types of references are supported - those created by Index and 540193267Sjkim * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted 541193267Sjkim * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle 542193267Sjkim * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to 543193267Sjkim * an ACPI_OBJECT. 544193267Sjkim */ 545193267Sjkim switch (Info->ReturnObject->Reference.Class) 546193267Sjkim { 547193267Sjkim case ACPI_REFCLASS_INDEX: 548193267Sjkim 549193267Sjkim ObjDesc = *(Info->ReturnObject->Reference.Where); 550193267Sjkim break; 551193267Sjkim 552193267Sjkim case ACPI_REFCLASS_REFOF: 553193267Sjkim 554193267Sjkim Node = Info->ReturnObject->Reference.Object; 555193267Sjkim if (Node) 556193267Sjkim { 557193267Sjkim ObjDesc = Node->Object; 558193267Sjkim } 559193267Sjkim break; 560193267Sjkim 561193267Sjkim default: 562250838Sjkim 563193267Sjkim return; 564193267Sjkim } 565193267Sjkim 566193267Sjkim /* Replace the existing reference object */ 567193267Sjkim 568193267Sjkim if (ObjDesc) 569193267Sjkim { 570193267Sjkim AcpiUtAddReference (ObjDesc); 571193267Sjkim AcpiUtRemoveReference (Info->ReturnObject); 572193267Sjkim Info->ReturnObject = ObjDesc; 573193267Sjkim } 574193267Sjkim 575193267Sjkim return; 576193267Sjkim} 577193267Sjkim 578193267Sjkim 579193267Sjkim/******************************************************************************* 580193267Sjkim * 581100966Siwasaki * FUNCTION: AcpiWalkNamespace 582100966Siwasaki * 583100966Siwasaki * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 584100966Siwasaki * StartObject - Handle in namespace where search begins 585100966Siwasaki * MaxDepth - Depth to which search is to reach 586253690Sjkim * DescendingCallback - Called during tree descent 587199337Sjkim * when an object of "Type" is found 588253690Sjkim * AscendingCallback - Called during tree ascent 589199337Sjkim * when an object of "Type" is found 590199337Sjkim * Context - Passed to user function(s) above 591100966Siwasaki * ReturnValue - Location where return value of 592100966Siwasaki * UserFunction is put if terminated early 593100966Siwasaki * 594100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 595100966Siwasaki * Otherwise, returns NULL. 596100966Siwasaki * 597100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 598100966Siwasaki * starting (and ending) at the object specified by StartHandle. 599199337Sjkim * The callback function is called whenever an object that matches 600199337Sjkim * the type parameter is found. If the callback function returns 601100966Siwasaki * a non-zero value, the search is terminated immediately and this 602100966Siwasaki * value is returned to the caller. 603100966Siwasaki * 604100966Siwasaki * The point of this procedure is to provide a generic namespace 605100966Siwasaki * walk routine that can be called from multiple places to 606199337Sjkim * provide multiple services; the callback function(s) can be 607199337Sjkim * tailored to each task, whether it is a print function, 608199337Sjkim * a compare function, etc. 609100966Siwasaki * 610100966Siwasaki ******************************************************************************/ 611100966Siwasaki 612100966SiwasakiACPI_STATUS 613100966SiwasakiAcpiWalkNamespace ( 614100966Siwasaki ACPI_OBJECT_TYPE Type, 615100966Siwasaki ACPI_HANDLE StartObject, 616100966Siwasaki UINT32 MaxDepth, 617253690Sjkim ACPI_WALK_CALLBACK DescendingCallback, 618253690Sjkim ACPI_WALK_CALLBACK AscendingCallback, 619100966Siwasaki void *Context, 620100966Siwasaki void **ReturnValue) 621100966Siwasaki{ 622100966Siwasaki ACPI_STATUS Status; 623100966Siwasaki 624100966Siwasaki 625167802Sjkim ACPI_FUNCTION_TRACE (AcpiWalkNamespace); 626100966Siwasaki 627100966Siwasaki 628100966Siwasaki /* Parameter validation */ 629100966Siwasaki 630167802Sjkim if ((Type > ACPI_TYPE_LOCAL_MAX) || 631167802Sjkim (!MaxDepth) || 632253690Sjkim (!DescendingCallback && !AscendingCallback)) 633100966Siwasaki { 634100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 635100966Siwasaki } 636100966Siwasaki 637100966Siwasaki /* 638193267Sjkim * Need to acquire the namespace reader lock to prevent interference 639193267Sjkim * with any concurrent table unloads (which causes the deletion of 640193267Sjkim * namespace objects). We cannot allow the deletion of a namespace node 641193267Sjkim * while the user function is using it. The exception to this are the 642193267Sjkim * nodes created and deleted during control method execution -- these 643193267Sjkim * nodes are marked as temporary nodes and are ignored by the namespace 644193267Sjkim * walk. Thus, control methods can be executed while holding the 645193267Sjkim * namespace deletion lock (and the user function can execute control 646193267Sjkim * methods.) 647100966Siwasaki */ 648193267Sjkim Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock); 649193267Sjkim if (ACPI_FAILURE (Status)) 650193267Sjkim { 651241973Sjkim return_ACPI_STATUS (Status); 652193267Sjkim } 653193267Sjkim 654193267Sjkim /* 655193267Sjkim * Lock the namespace around the walk. The namespace will be 656193267Sjkim * unlocked/locked around each call to the user function - since the user 657193267Sjkim * function must be allowed to make ACPICA calls itself (for example, it 658193267Sjkim * will typically execute control methods during device enumeration.) 659193267Sjkim */ 660100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 661100966Siwasaki if (ACPI_FAILURE (Status)) 662100966Siwasaki { 663193267Sjkim goto UnlockAndExit; 664100966Siwasaki } 665100966Siwasaki 666254745Sjkim /* Now we can validate the starting node */ 667254745Sjkim 668254745Sjkim if (!AcpiNsValidateHandle (StartObject)) 669254745Sjkim { 670254745Sjkim Status = AE_BAD_PARAMETER; 671254745Sjkim goto UnlockAndExit2; 672254745Sjkim } 673254745Sjkim 674151937Sjkim Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, 675306536Sjkim ACPI_NS_WALK_UNLOCK, DescendingCallback, 676306536Sjkim AscendingCallback, Context, ReturnValue); 677100966Siwasaki 678254745SjkimUnlockAndExit2: 679100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 680193267Sjkim 681193267SjkimUnlockAndExit: 682193267Sjkim (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock); 683100966Siwasaki return_ACPI_STATUS (Status); 684100966Siwasaki} 685100966Siwasaki 686167802SjkimACPI_EXPORT_SYMBOL (AcpiWalkNamespace) 687100966Siwasaki 688167802Sjkim 689100966Siwasaki/******************************************************************************* 690100966Siwasaki * 691100966Siwasaki * FUNCTION: AcpiNsGetDeviceCallback 692100966Siwasaki * 693100966Siwasaki * PARAMETERS: Callback from AcpiGetDevice 694100966Siwasaki * 695100966Siwasaki * RETURN: Status 696100966Siwasaki * 697100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 698100966Siwasaki * present devices, or if they specified a HID, it filters based 699100966Siwasaki * on that. 700100966Siwasaki * 701100966Siwasaki ******************************************************************************/ 702100966Siwasaki 703100966Siwasakistatic ACPI_STATUS 704100966SiwasakiAcpiNsGetDeviceCallback ( 705100966Siwasaki ACPI_HANDLE ObjHandle, 706100966Siwasaki UINT32 NestingLevel, 707100966Siwasaki void *Context, 708100966Siwasaki void **ReturnValue) 709100966Siwasaki{ 710117521Snjl ACPI_GET_DEVICES_INFO *Info = Context; 711100966Siwasaki ACPI_STATUS Status; 712100966Siwasaki ACPI_NAMESPACE_NODE *Node; 713100966Siwasaki UINT32 Flags; 714241973Sjkim ACPI_PNP_DEVICE_ID *Hid; 715241973Sjkim ACPI_PNP_DEVICE_ID_LIST *Cid; 716193267Sjkim UINT32 i; 717193267Sjkim BOOLEAN Found; 718197104Sjkim int NoMatch; 719100966Siwasaki 720100966Siwasaki 721100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 722100966Siwasaki if (ACPI_FAILURE (Status)) 723100966Siwasaki { 724100966Siwasaki return (Status); 725100966Siwasaki } 726100966Siwasaki 727200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 728100966Siwasaki Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 729100966Siwasaki if (ACPI_FAILURE (Status)) 730100966Siwasaki { 731100966Siwasaki return (Status); 732100966Siwasaki } 733100966Siwasaki 734100966Siwasaki if (!Node) 735100966Siwasaki { 736100966Siwasaki return (AE_BAD_PARAMETER); 737100966Siwasaki } 738100966Siwasaki 739202771Sjkim /* 740202771Sjkim * First, filter based on the device HID and CID. 741202771Sjkim * 742202771Sjkim * 01/2010: For this case where a specific HID is requested, we don't 743202771Sjkim * want to run _STA until we have an actual HID match. Thus, we will 744202771Sjkim * not unnecessarily execute _STA on devices for which the caller 745202771Sjkim * doesn't care about. Previously, _STA was executed unconditionally 746202771Sjkim * on all devices found here. 747202771Sjkim * 748202771Sjkim * A side-effect of this change is that now we will continue to search 749202771Sjkim * for a matching HID even under device trees where the parent device 750202771Sjkim * would have returned a _STA that indicates it is not present or 751202771Sjkim * not functioning (thus aborting the search on that branch). 752202771Sjkim */ 753100966Siwasaki if (Info->Hid != NULL) 754100966Siwasaki { 755100966Siwasaki Status = AcpiUtExecute_HID (Node, &Hid); 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 765306536Sjkim NoMatch = strcmp (Hid->String, Info->Hid); 766197104Sjkim ACPI_FREE (Hid); 767197104Sjkim 768197104Sjkim if (NoMatch) 769100966Siwasaki { 770193267Sjkim /* 771193267Sjkim * HID does not match, attempt match within the 772193267Sjkim * list of Compatible IDs (CIDs) 773193267Sjkim */ 774100966Siwasaki Status = AcpiUtExecute_CID (Node, &Cid); 775100966Siwasaki if (Status == AE_NOT_FOUND) 776100966Siwasaki { 777100966Siwasaki return (AE_OK); 778100966Siwasaki } 779100966Siwasaki else if (ACPI_FAILURE (Status)) 780100966Siwasaki { 781100966Siwasaki return (AE_CTRL_DEPTH); 782100966Siwasaki } 783100966Siwasaki 784117521Snjl /* Walk the CID list */ 785100966Siwasaki 786193267Sjkim Found = FALSE; 787117521Snjl for (i = 0; i < Cid->Count; i++) 788100966Siwasaki { 789306536Sjkim if (strcmp (Cid->Ids[i].String, Info->Hid) == 0) 790117521Snjl { 791193267Sjkim /* Found a matching CID */ 792193267Sjkim 793193267Sjkim Found = TRUE; 794193267Sjkim break; 795117521Snjl } 796100966Siwasaki } 797193267Sjkim 798167802Sjkim ACPI_FREE (Cid); 799193267Sjkim if (!Found) 800193267Sjkim { 801193267Sjkim return (AE_OK); 802193267Sjkim } 803100966Siwasaki } 804100966Siwasaki } 805100966Siwasaki 806202771Sjkim /* Run _STA to determine if device is present */ 807202771Sjkim 808202771Sjkim Status = AcpiUtExecute_STA (Node, &Flags); 809202771Sjkim if (ACPI_FAILURE (Status)) 810202771Sjkim { 811202771Sjkim return (AE_CTRL_DEPTH); 812202771Sjkim } 813202771Sjkim 814202771Sjkim if (!(Flags & ACPI_STA_DEVICE_PRESENT) && 815202771Sjkim !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) 816202771Sjkim { 817202771Sjkim /* 818202771Sjkim * Don't examine the children of the device only when the 819202771Sjkim * device is neither present nor functional. See ACPI spec, 820202771Sjkim * description of _STA for more information. 821202771Sjkim */ 822202771Sjkim return (AE_CTRL_DEPTH); 823202771Sjkim } 824202771Sjkim 825193267Sjkim /* We have a valid device, invoke the user function */ 826193267Sjkim 827306536Sjkim Status = Info->UserFunction (ObjHandle, NestingLevel, 828306536Sjkim Info->Context, ReturnValue); 829100966Siwasaki return (Status); 830100966Siwasaki} 831100966Siwasaki 832100966Siwasaki 833100966Siwasaki/******************************************************************************* 834100966Siwasaki * 835100966Siwasaki * FUNCTION: AcpiGetDevices 836100966Siwasaki * 837100966Siwasaki * PARAMETERS: HID - HID to search for. Can be NULL. 838100966Siwasaki * UserFunction - Called when a matching object is found 839100966Siwasaki * Context - Passed to user function 840100966Siwasaki * ReturnValue - Location where return value of 841100966Siwasaki * UserFunction is put if terminated early 842100966Siwasaki * 843100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 844100966Siwasaki * Otherwise, returns NULL. 845100966Siwasaki * 846100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 847100966Siwasaki * starting (and ending) at the object specified by StartHandle. 848117521Snjl * The UserFunction is called whenever an object of type 849241973Sjkim * Device is found. If the user function returns 850100966Siwasaki * a non-zero value, the search is terminated immediately and this 851100966Siwasaki * value is returned to the caller. 852100966Siwasaki * 853100966Siwasaki * This is a wrapper for WalkNamespace, but the callback performs 854193267Sjkim * additional filtering. Please see AcpiNsGetDeviceCallback. 855100966Siwasaki * 856100966Siwasaki ******************************************************************************/ 857100966Siwasaki 858100966SiwasakiACPI_STATUS 859100966SiwasakiAcpiGetDevices ( 860114237Snjl char *HID, 861100966Siwasaki ACPI_WALK_CALLBACK UserFunction, 862100966Siwasaki void *Context, 863100966Siwasaki void **ReturnValue) 864100966Siwasaki{ 865100966Siwasaki ACPI_STATUS Status; 866100966Siwasaki ACPI_GET_DEVICES_INFO Info; 867100966Siwasaki 868100966Siwasaki 869167802Sjkim ACPI_FUNCTION_TRACE (AcpiGetDevices); 870100966Siwasaki 871100966Siwasaki 872100966Siwasaki /* Parameter validation */ 873100966Siwasaki 874100966Siwasaki if (!UserFunction) 875100966Siwasaki { 876100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 877100966Siwasaki } 878100966Siwasaki 879100966Siwasaki /* 880100966Siwasaki * We're going to call their callback from OUR callback, so we need 881100966Siwasaki * to know what it is, and their context parameter. 882100966Siwasaki */ 883306536Sjkim Info.Hid = HID; 884306536Sjkim Info.Context = Context; 885100966Siwasaki Info.UserFunction = UserFunction; 886100966Siwasaki 887100966Siwasaki /* 888100966Siwasaki * Lock the namespace around the walk. 889100966Siwasaki * The namespace will be unlocked/locked around each call 890100966Siwasaki * to the user function - since this function 891100966Siwasaki * must be allowed to make Acpi calls itself. 892100966Siwasaki */ 893100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 894100966Siwasaki if (ACPI_FAILURE (Status)) 895100966Siwasaki { 896100966Siwasaki return_ACPI_STATUS (Status); 897100966Siwasaki } 898100966Siwasaki 899167802Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 900306536Sjkim ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 901306536Sjkim AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue); 902100966Siwasaki 903100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 904100966Siwasaki return_ACPI_STATUS (Status); 905100966Siwasaki} 906100966Siwasaki 907167802SjkimACPI_EXPORT_SYMBOL (AcpiGetDevices) 908100966Siwasaki 909167802Sjkim 910100966Siwasaki/******************************************************************************* 911100966Siwasaki * 912100966Siwasaki * FUNCTION: AcpiAttachData 913100966Siwasaki * 914114237Snjl * PARAMETERS: ObjHandle - Namespace node 915107325Siwasaki * Handler - Handler for this attachment 916107325Siwasaki * Data - Pointer to data to be attached 917100966Siwasaki * 918100966Siwasaki * RETURN: Status 919100966Siwasaki * 920107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node. 921100966Siwasaki * 922100966Siwasaki ******************************************************************************/ 923100966Siwasaki 924100966SiwasakiACPI_STATUS 925100966SiwasakiAcpiAttachData ( 926100966Siwasaki ACPI_HANDLE ObjHandle, 927100966Siwasaki ACPI_OBJECT_HANDLER Handler, 928100966Siwasaki void *Data) 929100966Siwasaki{ 930100966Siwasaki ACPI_NAMESPACE_NODE *Node; 931100966Siwasaki ACPI_STATUS Status; 932100966Siwasaki 933100966Siwasaki 934100966Siwasaki /* Parameter validation */ 935100966Siwasaki 936100966Siwasaki if (!ObjHandle || 937100966Siwasaki !Handler || 938100966Siwasaki !Data) 939100966Siwasaki { 940100966Siwasaki return (AE_BAD_PARAMETER); 941100966Siwasaki } 942100966Siwasaki 943100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 944100966Siwasaki if (ACPI_FAILURE (Status)) 945100966Siwasaki { 946100966Siwasaki return (Status); 947100966Siwasaki } 948100966Siwasaki 949100966Siwasaki /* Convert and validate the handle */ 950100966Siwasaki 951200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 952100966Siwasaki if (!Node) 953100966Siwasaki { 954100966Siwasaki Status = AE_BAD_PARAMETER; 955100966Siwasaki goto UnlockAndExit; 956100966Siwasaki } 957100966Siwasaki 958100966Siwasaki Status = AcpiNsAttachData (Node, Handler, Data); 959100966Siwasaki 960100966SiwasakiUnlockAndExit: 961100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 962100966Siwasaki return (Status); 963100966Siwasaki} 964100966Siwasaki 965167802SjkimACPI_EXPORT_SYMBOL (AcpiAttachData) 966100966Siwasaki 967167802Sjkim 968100966Siwasaki/******************************************************************************* 969100966Siwasaki * 970100966Siwasaki * FUNCTION: AcpiDetachData 971100966Siwasaki * 972107325Siwasaki * PARAMETERS: ObjHandle - Namespace node handle 973107325Siwasaki * Handler - Handler used in call to AcpiAttachData 974100966Siwasaki * 975100966Siwasaki * RETURN: Status 976100966Siwasaki * 977107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node. 978100966Siwasaki * 979100966Siwasaki ******************************************************************************/ 980100966Siwasaki 981100966SiwasakiACPI_STATUS 982100966SiwasakiAcpiDetachData ( 983100966Siwasaki ACPI_HANDLE ObjHandle, 984100966Siwasaki ACPI_OBJECT_HANDLER Handler) 985100966Siwasaki{ 986100966Siwasaki ACPI_NAMESPACE_NODE *Node; 987100966Siwasaki ACPI_STATUS Status; 988100966Siwasaki 989100966Siwasaki 990100966Siwasaki /* Parameter validation */ 991100966Siwasaki 992100966Siwasaki if (!ObjHandle || 993100966Siwasaki !Handler) 994100966Siwasaki { 995100966Siwasaki return (AE_BAD_PARAMETER); 996100966Siwasaki } 997100966Siwasaki 998100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 999100966Siwasaki if (ACPI_FAILURE (Status)) 1000100966Siwasaki { 1001100966Siwasaki return (Status); 1002100966Siwasaki } 1003100966Siwasaki 1004100966Siwasaki /* Convert and validate the handle */ 1005100966Siwasaki 1006200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 1007100966Siwasaki if (!Node) 1008100966Siwasaki { 1009100966Siwasaki Status = AE_BAD_PARAMETER; 1010100966Siwasaki goto UnlockAndExit; 1011100966Siwasaki } 1012100966Siwasaki 1013100966Siwasaki Status = AcpiNsDetachData (Node, Handler); 1014100966Siwasaki 1015100966SiwasakiUnlockAndExit: 1016100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1017100966Siwasaki return (Status); 1018100966Siwasaki} 1019100966Siwasaki 1020167802SjkimACPI_EXPORT_SYMBOL (AcpiDetachData) 1021100966Siwasaki 1022167802Sjkim 1023100966Siwasaki/******************************************************************************* 1024100966Siwasaki * 1025100966Siwasaki * FUNCTION: AcpiGetData 1026100966Siwasaki * 1027107325Siwasaki * PARAMETERS: ObjHandle - Namespace node 1028107325Siwasaki * Handler - Handler used in call to AttachData 1029107325Siwasaki * Data - Where the data is returned 1030100966Siwasaki * 1031100966Siwasaki * RETURN: Status 1032100966Siwasaki * 1033107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node. 1034100966Siwasaki * 1035100966Siwasaki ******************************************************************************/ 1036100966Siwasaki 1037100966SiwasakiACPI_STATUS 1038100966SiwasakiAcpiGetData ( 1039100966Siwasaki ACPI_HANDLE ObjHandle, 1040100966Siwasaki ACPI_OBJECT_HANDLER Handler, 1041100966Siwasaki void **Data) 1042100966Siwasaki{ 1043100966Siwasaki ACPI_NAMESPACE_NODE *Node; 1044100966Siwasaki ACPI_STATUS Status; 1045100966Siwasaki 1046100966Siwasaki 1047100966Siwasaki /* Parameter validation */ 1048100966Siwasaki 1049100966Siwasaki if (!ObjHandle || 1050100966Siwasaki !Handler || 1051100966Siwasaki !Data) 1052100966Siwasaki { 1053100966Siwasaki return (AE_BAD_PARAMETER); 1054100966Siwasaki } 1055100966Siwasaki 1056100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1057100966Siwasaki if (ACPI_FAILURE (Status)) 1058100966Siwasaki { 1059100966Siwasaki return (Status); 1060100966Siwasaki } 1061100966Siwasaki 1062100966Siwasaki /* Convert and validate the handle */ 1063100966Siwasaki 1064200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 1065100966Siwasaki if (!Node) 1066100966Siwasaki { 1067100966Siwasaki Status = AE_BAD_PARAMETER; 1068100966Siwasaki goto UnlockAndExit; 1069100966Siwasaki } 1070100966Siwasaki 1071100966Siwasaki Status = AcpiNsGetAttachedData (Node, Handler, Data); 1072100966Siwasaki 1073100966SiwasakiUnlockAndExit: 1074100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1075100966Siwasaki return (Status); 1076100966Siwasaki} 1077100966Siwasaki 1078167802SjkimACPI_EXPORT_SYMBOL (AcpiGetData) 1079