1100966Siwasaki/******************************************************************************* 2100966Siwasaki * 3100966Siwasaki * Module Name: nsxfeval - Public interfaces to the ACPI subsystem 4100966Siwasaki * ACPI Object evaluation interfaces 5100966Siwasaki * 6100966Siwasaki ******************************************************************************/ 7100966Siwasaki 8316303Sjkim/****************************************************************************** 9316303Sjkim * 10316303Sjkim * 1. Copyright Notice 11316303Sjkim * 12316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 13100966Siwasaki * All rights reserved. 14100966Siwasaki * 15316303Sjkim * 2. License 16316303Sjkim * 17316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 18316303Sjkim * rights. You may have additional license terms from the party that provided 19316303Sjkim * you this software, covering your right to use that party's intellectual 20316303Sjkim * property rights. 21316303Sjkim * 22316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 24316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 26316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 27316303Sjkim * Code in any form, with the right to sublicense such rights; and 28316303Sjkim * 29316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30316303Sjkim * license (with the right to sublicense), under only those claims of Intel 31316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 32316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 33316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 34316303Sjkim * license, and in no event shall the patent license extend to any additions 35316303Sjkim * to or modifications of the Original Intel Code. No other license or right 36316303Sjkim * is granted directly or by implication, estoppel or otherwise; 37316303Sjkim * 38316303Sjkim * The above copyright and patent license is granted only if the following 39316303Sjkim * conditions are met: 40316303Sjkim * 41316303Sjkim * 3. Conditions 42316303Sjkim * 43316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44316303Sjkim * Redistribution of source code of any substantial portion of the Covered 45316303Sjkim * Code or modification with rights to further distribute source must include 46316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 47316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 48316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 49316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 50316303Sjkim * Code and the date of any change. Licensee must include in that file the 51316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 52316303Sjkim * must include a prominent statement that the modification is derived, 53316303Sjkim * directly or indirectly, from Original Intel Code. 54316303Sjkim * 55316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56316303Sjkim * Redistribution of source code of any substantial portion of the Covered 57316303Sjkim * Code or modification without rights to further distribute source must 58316303Sjkim * include the following Disclaimer and Export Compliance provision in the 59316303Sjkim * documentation and/or other materials provided with distribution. In 60316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 61316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 62316303Sjkim * license from Licensee to its licensee is limited to the intellectual 63316303Sjkim * property embodied in the software Licensee provides to its licensee, and 64316303Sjkim * not to intellectual property embodied in modifications its licensee may 65316303Sjkim * make. 66316303Sjkim * 67316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 68316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 69316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 70316303Sjkim * provision in the documentation and/or other materials provided with the 71316303Sjkim * distribution. 72316303Sjkim * 73316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 74316303Sjkim * Intel Code. 75316303Sjkim * 76316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 78316303Sjkim * other dealings in products derived from or relating to the Covered Code 79316303Sjkim * without prior written authorization from Intel. 80316303Sjkim * 81316303Sjkim * 4. Disclaimer and Export Compliance 82316303Sjkim * 83316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89316303Sjkim * PARTICULAR PURPOSE. 90316303Sjkim * 91316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98316303Sjkim * LIMITED REMEDY. 99316303Sjkim * 100316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 101316303Sjkim * software or system incorporating such software without first obtaining any 102316303Sjkim * required license or other approval from the U. S. Department of Commerce or 103316303Sjkim * any other agency or department of the United States Government. In the 104316303Sjkim * event Licensee exports any such software from the United States or 105316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 106316303Sjkim * ensure that the distribution and export/re-export of the software is in 107316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 108316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 110316303Sjkim * software, or service, directly or indirectly, to any country for which the 111316303Sjkim * United States government or any agency thereof requires an export license, 112316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 113316303Sjkim * such license, approval or letter. 114316303Sjkim * 115316303Sjkim ***************************************************************************** 116316303Sjkim * 117316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 118316303Sjkim * following license: 119316303Sjkim * 120217365Sjkim * Redistribution and use in source and binary forms, with or without 121217365Sjkim * modification, are permitted provided that the following conditions 122217365Sjkim * are met: 123217365Sjkim * 1. Redistributions of source code must retain the above copyright 124217365Sjkim * notice, this list of conditions, and the following disclaimer, 125217365Sjkim * without modification. 126217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 127217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 128217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 129217365Sjkim * including a substantially similar Disclaimer requirement for further 130217365Sjkim * binary redistribution. 131217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 132217365Sjkim * of any contributors may be used to endorse or promote products derived 133217365Sjkim * from this software without specific prior written permission. 134100966Siwasaki * 135316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 136316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 137316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 138316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 139316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 140316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 141316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 142316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 143316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 144316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 145316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 146316303Sjkim * 147316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 148217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 149217365Sjkim * Software Foundation. 150100966Siwasaki * 151316303Sjkim *****************************************************************************/ 152100966Siwasaki 153272444Sjkim#define EXPORT_ACPI_INTERFACES 154100966Siwasaki 155193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 156193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 157193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 158193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 159100966Siwasaki 160100966Siwasaki 161100966Siwasaki#define _COMPONENT ACPI_NAMESPACE 162100966Siwasaki ACPI_MODULE_NAME ("nsxfeval") 163100966Siwasaki 164193267Sjkim/* Local prototypes */ 165100966Siwasaki 166193267Sjkimstatic void 167193267SjkimAcpiNsResolveReferences ( 168193267Sjkim ACPI_EVALUATE_INFO *Info); 169193267Sjkim 170193267Sjkim 171100966Siwasaki/******************************************************************************* 172100966Siwasaki * 173100966Siwasaki * FUNCTION: AcpiEvaluateObjectTyped 174100966Siwasaki * 175100966Siwasaki * PARAMETERS: Handle - Object handle (optional) 176151937Sjkim * Pathname - Object pathname (optional) 177327557Sjkim * ExternalParams - List of parameters to pass to a method, 178241973Sjkim * terminated by NULL. May be NULL 179100966Siwasaki * if no parameters are being passed. 180327557Sjkim * ReturnBuffer - Where to put the object return value (if 181327557Sjkim * any). Required. 182100966Siwasaki * ReturnType - Expected type of return object 183100966Siwasaki * 184100966Siwasaki * RETURN: Status 185100966Siwasaki * 186100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given 187241973Sjkim * parameters if necessary. One of "Handle" or "Pathname" must 188100966Siwasaki * be valid (non-null) 189100966Siwasaki * 190100966Siwasaki ******************************************************************************/ 191100966Siwasaki 192100966SiwasakiACPI_STATUS 193100966SiwasakiAcpiEvaluateObjectTyped ( 194100966Siwasaki ACPI_HANDLE Handle, 195100966Siwasaki ACPI_STRING Pathname, 196100966Siwasaki ACPI_OBJECT_LIST *ExternalParams, 197100966Siwasaki ACPI_BUFFER *ReturnBuffer, 198100966Siwasaki ACPI_OBJECT_TYPE ReturnType) 199100966Siwasaki{ 200100966Siwasaki ACPI_STATUS Status; 201272444Sjkim BOOLEAN FreeBufferOnError = FALSE; 202322877Sjkim ACPI_HANDLE TargetHandle; 203322877Sjkim char *FullPathname; 204100966Siwasaki 205100966Siwasaki 206167802Sjkim ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); 207100966Siwasaki 208100966Siwasaki 209100966Siwasaki /* Return buffer must be valid */ 210100966Siwasaki 211100966Siwasaki if (!ReturnBuffer) 212100966Siwasaki { 213100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 214100966Siwasaki } 215100966Siwasaki 216100966Siwasaki if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) 217100966Siwasaki { 218272444Sjkim FreeBufferOnError = TRUE; 219100966Siwasaki } 220100966Siwasaki 221327557Sjkim /* Get a handle here, in order to build an error message if needed */ 222327557Sjkim 223327557Sjkim TargetHandle = Handle; 224327557Sjkim if (Pathname) 225322877Sjkim { 226327557Sjkim Status = AcpiGetHandle (Handle, Pathname, &TargetHandle); 227327557Sjkim if (ACPI_FAILURE (Status)) 228327557Sjkim { 229327557Sjkim return_ACPI_STATUS (Status); 230327557Sjkim } 231322877Sjkim } 232322877Sjkim 233322877Sjkim FullPathname = AcpiNsGetExternalPathname (TargetHandle); 234322877Sjkim if (!FullPathname) 235322877Sjkim { 236322877Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 237322877Sjkim } 238322877Sjkim 239100966Siwasaki /* Evaluate the object */ 240100966Siwasaki 241322877Sjkim Status = AcpiEvaluateObject (TargetHandle, NULL, ExternalParams, 242322877Sjkim ReturnBuffer); 243100966Siwasaki if (ACPI_FAILURE (Status)) 244100966Siwasaki { 245322877Sjkim goto Exit; 246100966Siwasaki } 247100966Siwasaki 248322877Sjkim /* Type ANY means "don't care about return value type" */ 249100966Siwasaki 250100966Siwasaki if (ReturnType == ACPI_TYPE_ANY) 251100966Siwasaki { 252322877Sjkim goto Exit; 253100966Siwasaki } 254100966Siwasaki 255100966Siwasaki if (ReturnBuffer->Length == 0) 256100966Siwasaki { 257100966Siwasaki /* Error because caller specifically asked for a return value */ 258100966Siwasaki 259322877Sjkim ACPI_ERROR ((AE_INFO, "%s did not return any object", 260322877Sjkim FullPathname)); 261322877Sjkim Status = AE_NULL_OBJECT; 262322877Sjkim goto Exit; 263100966Siwasaki } 264100966Siwasaki 265100966Siwasaki /* Examine the object type returned from EvaluateObject */ 266100966Siwasaki 267100966Siwasaki if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) 268100966Siwasaki { 269322877Sjkim goto Exit; 270100966Siwasaki } 271100966Siwasaki 272100966Siwasaki /* Return object type does not match requested type */ 273100966Siwasaki 274167802Sjkim ACPI_ERROR ((AE_INFO, 275322877Sjkim "Incorrect return type from %s - received [%s], requested [%s]", 276322877Sjkim FullPathname, 277100966Siwasaki AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), 278100966Siwasaki AcpiUtGetTypeName (ReturnType))); 279100966Siwasaki 280272444Sjkim if (FreeBufferOnError) 281100966Siwasaki { 282272444Sjkim /* 283272444Sjkim * Free a buffer created via ACPI_ALLOCATE_BUFFER. 284272444Sjkim * Note: We use AcpiOsFree here because AcpiOsAllocate was used 285272444Sjkim * to allocate the buffer. This purposefully bypasses the 286272444Sjkim * (optionally enabled) allocation tracking mechanism since we 287272444Sjkim * only want to track internal allocations. 288272444Sjkim */ 289100966Siwasaki AcpiOsFree (ReturnBuffer->Pointer); 290100966Siwasaki ReturnBuffer->Pointer = NULL; 291100966Siwasaki } 292100966Siwasaki 293100966Siwasaki ReturnBuffer->Length = 0; 294322877Sjkim Status = AE_TYPE; 295322877Sjkim 296322877SjkimExit: 297322877Sjkim ACPI_FREE (FullPathname); 298322877Sjkim return_ACPI_STATUS (Status); 299100966Siwasaki} 300100966Siwasaki 301167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped) 302100966Siwasaki 303167802Sjkim 304100966Siwasaki/******************************************************************************* 305100966Siwasaki * 306100966Siwasaki * FUNCTION: AcpiEvaluateObject 307100966Siwasaki * 308100966Siwasaki * PARAMETERS: Handle - Object handle (optional) 309128212Snjl * Pathname - Object pathname (optional) 310128212Snjl * ExternalParams - List of parameters to pass to method, 311241973Sjkim * terminated by NULL. May be NULL 312100966Siwasaki * if no parameters are being passed. 313128212Snjl * ReturnBuffer - Where to put method's return value (if 314241973Sjkim * any). If NULL, no value is returned. 315100966Siwasaki * 316100966Siwasaki * RETURN: Status 317100966Siwasaki * 318100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given 319241973Sjkim * parameters if necessary. One of "Handle" or "Pathname" must 320100966Siwasaki * be valid (non-null) 321100966Siwasaki * 322100966Siwasaki ******************************************************************************/ 323100966Siwasaki 324100966SiwasakiACPI_STATUS 325100966SiwasakiAcpiEvaluateObject ( 326100966Siwasaki ACPI_HANDLE Handle, 327100966Siwasaki ACPI_STRING Pathname, 328100966Siwasaki ACPI_OBJECT_LIST *ExternalParams, 329100966Siwasaki ACPI_BUFFER *ReturnBuffer) 330100966Siwasaki{ 331100966Siwasaki ACPI_STATUS Status; 332167802Sjkim ACPI_EVALUATE_INFO *Info; 333100966Siwasaki ACPI_SIZE BufferSpaceNeeded; 334100966Siwasaki UINT32 i; 335100966Siwasaki 336100966Siwasaki 337167802Sjkim ACPI_FUNCTION_TRACE (AcpiEvaluateObject); 338100966Siwasaki 339100966Siwasaki 340167802Sjkim /* Allocate and initialize the evaluation information block */ 341129684Snjl 342167802Sjkim Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 343167802Sjkim if (!Info) 344167802Sjkim { 345167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 346167802Sjkim } 347167802Sjkim 348167802Sjkim /* Convert and validate the device handle */ 349167802Sjkim 350200553Sjkim Info->PrefixNode = AcpiNsValidateHandle (Handle); 351167802Sjkim if (!Info->PrefixNode) 352167802Sjkim { 353167802Sjkim Status = AE_BAD_PARAMETER; 354167802Sjkim goto Cleanup; 355167802Sjkim } 356167802Sjkim 357100966Siwasaki /* 358249663Sjkim * Get the actual namespace node for the target object. 359249663Sjkim * Handles these cases: 360249663Sjkim * 361249663Sjkim * 1) Null node, valid pathname from root (absolute path) 362249663Sjkim * 2) Node and valid pathname (path relative to Node) 363249663Sjkim * 3) Node, Null pathname 364100966Siwasaki */ 365249663Sjkim if ((Pathname) && 366249663Sjkim (ACPI_IS_ROOT_PREFIX (Pathname[0]))) 367249663Sjkim { 368249663Sjkim /* The path is fully qualified, just evaluate by name */ 369249663Sjkim 370249663Sjkim Info->PrefixNode = NULL; 371249663Sjkim } 372249663Sjkim else if (!Handle) 373249663Sjkim { 374249663Sjkim /* 375249663Sjkim * A handle is optional iff a fully qualified pathname is specified. 376249663Sjkim * Since we've already handled fully qualified names above, this is 377249663Sjkim * an error. 378249663Sjkim */ 379249663Sjkim if (!Pathname) 380249663Sjkim { 381249663Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 382249663Sjkim "Both Handle and Pathname are NULL")); 383249663Sjkim } 384249663Sjkim else 385249663Sjkim { 386249663Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 387249663Sjkim "Null Handle with relative pathname [%s]", Pathname)); 388249663Sjkim } 389249663Sjkim 390249663Sjkim Status = AE_BAD_PARAMETER; 391249663Sjkim goto Cleanup; 392249663Sjkim } 393249663Sjkim 394249663Sjkim Info->RelativePathname = Pathname; 395249663Sjkim 396249663Sjkim /* 397249663Sjkim * Convert all external objects passed as arguments to the 398249663Sjkim * internal version(s). 399249663Sjkim */ 400100966Siwasaki if (ExternalParams && ExternalParams->Count) 401100966Siwasaki { 402249663Sjkim Info->ParamCount = (UINT16) ExternalParams->Count; 403249663Sjkim 404249663Sjkim /* Warn on impossible argument count */ 405249663Sjkim 406249663Sjkim if (Info->ParamCount > ACPI_METHOD_NUM_ARGS) 407249663Sjkim { 408249663Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 409249663Sjkim "Excess arguments (%u) - using only %u", 410249663Sjkim Info->ParamCount, ACPI_METHOD_NUM_ARGS)); 411249663Sjkim 412249663Sjkim Info->ParamCount = ACPI_METHOD_NUM_ARGS; 413249663Sjkim } 414249663Sjkim 415100966Siwasaki /* 416100966Siwasaki * Allocate a new parameter block for the internal objects 417100966Siwasaki * Add 1 to count to allow for null terminated internal list 418100966Siwasaki */ 419167802Sjkim Info->Parameters = ACPI_ALLOCATE_ZEROED ( 420249663Sjkim ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *)); 421167802Sjkim if (!Info->Parameters) 422100966Siwasaki { 423167802Sjkim Status = AE_NO_MEMORY; 424167802Sjkim goto Cleanup; 425100966Siwasaki } 426100966Siwasaki 427167802Sjkim /* Convert each external object in the list to an internal object */ 428167802Sjkim 429249663Sjkim for (i = 0; i < Info->ParamCount; i++) 430100966Siwasaki { 431167802Sjkim Status = AcpiUtCopyEobjectToIobject ( 432249663Sjkim &ExternalParams->Pointer[i], &Info->Parameters[i]); 433100966Siwasaki if (ACPI_FAILURE (Status)) 434100966Siwasaki { 435167802Sjkim goto Cleanup; 436100966Siwasaki } 437100966Siwasaki } 438249663Sjkim 439249663Sjkim Info->Parameters[Info->ParamCount] = NULL; 440100966Siwasaki } 441100966Siwasaki 442249663Sjkim 443298714Sjkim#ifdef _FUTURE_FEATURE 444249663Sjkim 445100966Siwasaki /* 446249663Sjkim * Begin incoming argument count analysis. Check for too few args 447249663Sjkim * and too many args. 448100966Siwasaki */ 449249663Sjkim switch (AcpiNsGetType (Info->Node)) 450100966Siwasaki { 451249663Sjkim case ACPI_TYPE_METHOD: 452167802Sjkim 453249663Sjkim /* Check incoming argument count against the method definition */ 454249663Sjkim 455249663Sjkim if (Info->ObjDesc->Method.ParamCount > Info->ParamCount) 456249663Sjkim { 457249663Sjkim ACPI_ERROR ((AE_INFO, 458249663Sjkim "Insufficient arguments (%u) - %u are required", 459249663Sjkim Info->ParamCount, 460249663Sjkim Info->ObjDesc->Method.ParamCount)); 461249663Sjkim 462249663Sjkim Status = AE_MISSING_ARGUMENTS; 463249663Sjkim goto Cleanup; 464249663Sjkim } 465249663Sjkim 466249663Sjkim else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount) 467249663Sjkim { 468249663Sjkim ACPI_WARNING ((AE_INFO, 469249663Sjkim "Excess arguments (%u) - only %u are required", 470249663Sjkim Info->ParamCount, 471249663Sjkim Info->ObjDesc->Method.ParamCount)); 472249663Sjkim 473249663Sjkim /* Just pass the required number of arguments */ 474249663Sjkim 475249663Sjkim Info->ParamCount = Info->ObjDesc->Method.ParamCount; 476249663Sjkim } 477249663Sjkim 478100966Siwasaki /* 479249663Sjkim * Any incoming external objects to be passed as arguments to the 480249663Sjkim * method must be converted to internal objects 481100966Siwasaki */ 482249663Sjkim if (Info->ParamCount) 483100966Siwasaki { 484249663Sjkim /* 485249663Sjkim * Allocate a new parameter block for the internal objects 486249663Sjkim * Add 1 to count to allow for null terminated internal list 487249663Sjkim */ 488249663Sjkim Info->Parameters = ACPI_ALLOCATE_ZEROED ( 489249663Sjkim ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *)); 490249663Sjkim if (!Info->Parameters) 491249663Sjkim { 492249663Sjkim Status = AE_NO_MEMORY; 493249663Sjkim goto Cleanup; 494249663Sjkim } 495249663Sjkim 496249663Sjkim /* Convert each external object in the list to an internal object */ 497249663Sjkim 498249663Sjkim for (i = 0; i < Info->ParamCount; i++) 499249663Sjkim { 500249663Sjkim Status = AcpiUtCopyEobjectToIobject ( 501249663Sjkim &ExternalParams->Pointer[i], &Info->Parameters[i]); 502249663Sjkim if (ACPI_FAILURE (Status)) 503249663Sjkim { 504249663Sjkim goto Cleanup; 505249663Sjkim } 506249663Sjkim } 507249663Sjkim 508249663Sjkim Info->Parameters[Info->ParamCount] = NULL; 509100966Siwasaki } 510249663Sjkim break; 511249663Sjkim 512249663Sjkim default: 513249663Sjkim 514249663Sjkim /* Warn if arguments passed to an object that is not a method */ 515249663Sjkim 516249663Sjkim if (Info->ParamCount) 517100966Siwasaki { 518249663Sjkim ACPI_WARNING ((AE_INFO, 519249663Sjkim "%u arguments were passed to a non-method ACPI object", 520249663Sjkim Info->ParamCount)); 521100966Siwasaki } 522249663Sjkim break; 523100966Siwasaki } 524167802Sjkim 525249663Sjkim#endif 526100966Siwasaki 527249663Sjkim 528249663Sjkim /* Now we can evaluate the object */ 529249663Sjkim 530249663Sjkim Status = AcpiNsEvaluate (Info); 531249663Sjkim 532100966Siwasaki /* 533100966Siwasaki * If we are expecting a return value, and all went well above, 534100966Siwasaki * copy the return value to an external object. 535100966Siwasaki */ 536298714Sjkim if (!ReturnBuffer) 537100966Siwasaki { 538298714Sjkim goto CleanupReturnObject; 539298714Sjkim } 540100966Siwasaki 541298714Sjkim if (!Info->ReturnObject) 542298714Sjkim { 543298714Sjkim ReturnBuffer->Length = 0; 544298714Sjkim goto Cleanup; 545298714Sjkim } 546193267Sjkim 547298714Sjkim if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) == 548298714Sjkim ACPI_DESC_TYPE_NAMED) 549298714Sjkim { 550298714Sjkim /* 551298714Sjkim * If we received a NS Node as a return object, this means that 552298714Sjkim * the object we are evaluating has nothing interesting to 553298714Sjkim * return (such as a mutex, etc.) We return an error because 554298714Sjkim * these types are essentially unsupported by this interface. 555298714Sjkim * We don't check up front because this makes it easier to add 556298714Sjkim * support for various types at a later date if necessary. 557298714Sjkim */ 558298714Sjkim Status = AE_TYPE; 559298714Sjkim Info->ReturnObject = NULL; /* No need to delete a NS Node */ 560298714Sjkim ReturnBuffer->Length = 0; 561298714Sjkim } 562193267Sjkim 563298714Sjkim if (ACPI_FAILURE (Status)) 564298714Sjkim { 565298714Sjkim goto CleanupReturnObject; 566298714Sjkim } 567167802Sjkim 568298714Sjkim /* Dereference Index and RefOf references */ 569100966Siwasaki 570298714Sjkim AcpiNsResolveReferences (Info); 571167802Sjkim 572298714Sjkim /* Get the size of the returned object */ 573298714Sjkim 574298714Sjkim Status = AcpiUtGetObjectSize (Info->ReturnObject, 575298714Sjkim &BufferSpaceNeeded); 576298714Sjkim if (ACPI_SUCCESS (Status)) 577298714Sjkim { 578298714Sjkim /* Validate/Allocate/Clear caller buffer */ 579298714Sjkim 580298714Sjkim Status = AcpiUtInitializeBuffer (ReturnBuffer, 581298714Sjkim BufferSpaceNeeded); 582298714Sjkim if (ACPI_FAILURE (Status)) 583298714Sjkim { 584298714Sjkim /* 585298714Sjkim * Caller's buffer is too small or a new one can't 586298714Sjkim * be allocated 587298714Sjkim */ 588298714Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 589298714Sjkim "Needed buffer size %X, %s\n", 590298714Sjkim (UINT32) BufferSpaceNeeded, 591298714Sjkim AcpiFormatException (Status))); 592100966Siwasaki } 593298714Sjkim else 594298714Sjkim { 595298714Sjkim /* We have enough space for the object, build it */ 596298714Sjkim 597298714Sjkim Status = AcpiUtCopyIobjectToEobject ( 598298714Sjkim Info->ReturnObject, ReturnBuffer); 599298714Sjkim } 600100966Siwasaki } 601100966Siwasaki 602298714SjkimCleanupReturnObject: 603298714Sjkim 604167802Sjkim if (Info->ReturnObject) 605100966Siwasaki { 606129684Snjl /* 607167802Sjkim * Delete the internal return object. NOTE: Interpreter must be 608167802Sjkim * locked to avoid race condition. 609100966Siwasaki */ 610167802Sjkim AcpiExEnterInterpreter (); 611167802Sjkim 612167802Sjkim /* Remove one reference on the return object (should delete it) */ 613167802Sjkim 614167802Sjkim AcpiUtRemoveReference (Info->ReturnObject); 615167802Sjkim AcpiExExitInterpreter (); 616100966Siwasaki } 617100966Siwasaki 618167802Sjkim 619167802SjkimCleanup: 620167802Sjkim 621167802Sjkim /* Free the input parameter list (if we created one) */ 622167802Sjkim 623167802Sjkim if (Info->Parameters) 624100966Siwasaki { 625100966Siwasaki /* Free the allocated parameter block */ 626100966Siwasaki 627167802Sjkim AcpiUtDeleteInternalObjectList (Info->Parameters); 628100966Siwasaki } 629100966Siwasaki 630167802Sjkim ACPI_FREE (Info); 631100966Siwasaki return_ACPI_STATUS (Status); 632100966Siwasaki} 633100966Siwasaki 634167802SjkimACPI_EXPORT_SYMBOL (AcpiEvaluateObject) 635100966Siwasaki 636167802Sjkim 637100966Siwasaki/******************************************************************************* 638100966Siwasaki * 639193267Sjkim * FUNCTION: AcpiNsResolveReferences 640193267Sjkim * 641193267Sjkim * PARAMETERS: Info - Evaluation info block 642193267Sjkim * 643193267Sjkim * RETURN: Info->ReturnObject is replaced with the dereferenced object 644193267Sjkim * 645193267Sjkim * DESCRIPTION: Dereference certain reference objects. Called before an 646193267Sjkim * internal return object is converted to an external ACPI_OBJECT. 647193267Sjkim * 648193267Sjkim * Performs an automatic dereference of Index and RefOf reference objects. 649193267Sjkim * These reference objects are not supported by the ACPI_OBJECT, so this is a 650193267Sjkim * last resort effort to return something useful. Also, provides compatibility 651193267Sjkim * with other ACPI implementations. 652193267Sjkim * 653193267Sjkim * NOTE: does not handle references within returned package objects or nested 654193267Sjkim * references, but this support could be added later if found to be necessary. 655193267Sjkim * 656193267Sjkim ******************************************************************************/ 657193267Sjkim 658193267Sjkimstatic void 659193267SjkimAcpiNsResolveReferences ( 660193267Sjkim ACPI_EVALUATE_INFO *Info) 661193267Sjkim{ 662193267Sjkim ACPI_OPERAND_OBJECT *ObjDesc = NULL; 663193267Sjkim ACPI_NAMESPACE_NODE *Node; 664193267Sjkim 665193267Sjkim 666193267Sjkim /* We are interested in reference objects only */ 667193267Sjkim 668193267Sjkim if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) 669193267Sjkim { 670193267Sjkim return; 671193267Sjkim } 672193267Sjkim 673193267Sjkim /* 674193267Sjkim * Two types of references are supported - those created by Index and 675193267Sjkim * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted 676193267Sjkim * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle 677193267Sjkim * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to 678193267Sjkim * an ACPI_OBJECT. 679193267Sjkim */ 680193267Sjkim switch (Info->ReturnObject->Reference.Class) 681193267Sjkim { 682193267Sjkim case ACPI_REFCLASS_INDEX: 683193267Sjkim 684193267Sjkim ObjDesc = *(Info->ReturnObject->Reference.Where); 685193267Sjkim break; 686193267Sjkim 687193267Sjkim case ACPI_REFCLASS_REFOF: 688193267Sjkim 689193267Sjkim Node = Info->ReturnObject->Reference.Object; 690193267Sjkim if (Node) 691193267Sjkim { 692193267Sjkim ObjDesc = Node->Object; 693193267Sjkim } 694193267Sjkim break; 695193267Sjkim 696193267Sjkim default: 697250838Sjkim 698193267Sjkim return; 699193267Sjkim } 700193267Sjkim 701193267Sjkim /* Replace the existing reference object */ 702193267Sjkim 703193267Sjkim if (ObjDesc) 704193267Sjkim { 705193267Sjkim AcpiUtAddReference (ObjDesc); 706193267Sjkim AcpiUtRemoveReference (Info->ReturnObject); 707193267Sjkim Info->ReturnObject = ObjDesc; 708193267Sjkim } 709193267Sjkim 710193267Sjkim return; 711193267Sjkim} 712193267Sjkim 713193267Sjkim 714193267Sjkim/******************************************************************************* 715193267Sjkim * 716100966Siwasaki * FUNCTION: AcpiWalkNamespace 717100966Siwasaki * 718100966Siwasaki * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 719100966Siwasaki * StartObject - Handle in namespace where search begins 720100966Siwasaki * MaxDepth - Depth to which search is to reach 721253690Sjkim * DescendingCallback - Called during tree descent 722199337Sjkim * when an object of "Type" is found 723253690Sjkim * AscendingCallback - Called during tree ascent 724199337Sjkim * when an object of "Type" is found 725199337Sjkim * Context - Passed to user function(s) above 726100966Siwasaki * ReturnValue - Location where return value of 727100966Siwasaki * UserFunction is put if terminated early 728100966Siwasaki * 729100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 730100966Siwasaki * Otherwise, returns NULL. 731100966Siwasaki * 732100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 733100966Siwasaki * starting (and ending) at the object specified by StartHandle. 734199337Sjkim * The callback function is called whenever an object that matches 735199337Sjkim * the type parameter is found. If the callback function returns 736100966Siwasaki * a non-zero value, the search is terminated immediately and this 737100966Siwasaki * value is returned to the caller. 738100966Siwasaki * 739100966Siwasaki * The point of this procedure is to provide a generic namespace 740100966Siwasaki * walk routine that can be called from multiple places to 741199337Sjkim * provide multiple services; the callback function(s) can be 742199337Sjkim * tailored to each task, whether it is a print function, 743199337Sjkim * a compare function, etc. 744100966Siwasaki * 745100966Siwasaki ******************************************************************************/ 746100966Siwasaki 747100966SiwasakiACPI_STATUS 748100966SiwasakiAcpiWalkNamespace ( 749100966Siwasaki ACPI_OBJECT_TYPE Type, 750100966Siwasaki ACPI_HANDLE StartObject, 751100966Siwasaki UINT32 MaxDepth, 752253690Sjkim ACPI_WALK_CALLBACK DescendingCallback, 753253690Sjkim ACPI_WALK_CALLBACK AscendingCallback, 754100966Siwasaki void *Context, 755100966Siwasaki void **ReturnValue) 756100966Siwasaki{ 757100966Siwasaki ACPI_STATUS Status; 758100966Siwasaki 759100966Siwasaki 760167802Sjkim ACPI_FUNCTION_TRACE (AcpiWalkNamespace); 761100966Siwasaki 762100966Siwasaki 763100966Siwasaki /* Parameter validation */ 764100966Siwasaki 765167802Sjkim if ((Type > ACPI_TYPE_LOCAL_MAX) || 766167802Sjkim (!MaxDepth) || 767253690Sjkim (!DescendingCallback && !AscendingCallback)) 768100966Siwasaki { 769100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 770100966Siwasaki } 771100966Siwasaki 772100966Siwasaki /* 773193267Sjkim * Need to acquire the namespace reader lock to prevent interference 774193267Sjkim * with any concurrent table unloads (which causes the deletion of 775193267Sjkim * namespace objects). We cannot allow the deletion of a namespace node 776193267Sjkim * while the user function is using it. The exception to this are the 777193267Sjkim * nodes created and deleted during control method execution -- these 778193267Sjkim * nodes are marked as temporary nodes and are ignored by the namespace 779193267Sjkim * walk. Thus, control methods can be executed while holding the 780193267Sjkim * namespace deletion lock (and the user function can execute control 781193267Sjkim * methods.) 782100966Siwasaki */ 783193267Sjkim Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock); 784193267Sjkim if (ACPI_FAILURE (Status)) 785193267Sjkim { 786241973Sjkim return_ACPI_STATUS (Status); 787193267Sjkim } 788193267Sjkim 789193267Sjkim /* 790193267Sjkim * Lock the namespace around the walk. The namespace will be 791193267Sjkim * unlocked/locked around each call to the user function - since the user 792193267Sjkim * function must be allowed to make ACPICA calls itself (for example, it 793193267Sjkim * will typically execute control methods during device enumeration.) 794193267Sjkim */ 795100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 796100966Siwasaki if (ACPI_FAILURE (Status)) 797100966Siwasaki { 798193267Sjkim goto UnlockAndExit; 799100966Siwasaki } 800100966Siwasaki 801254745Sjkim /* Now we can validate the starting node */ 802254745Sjkim 803254745Sjkim if (!AcpiNsValidateHandle (StartObject)) 804254745Sjkim { 805254745Sjkim Status = AE_BAD_PARAMETER; 806254745Sjkim goto UnlockAndExit2; 807254745Sjkim } 808254745Sjkim 809151937Sjkim Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, 810298714Sjkim ACPI_NS_WALK_UNLOCK, DescendingCallback, 811298714Sjkim AscendingCallback, Context, ReturnValue); 812100966Siwasaki 813254745SjkimUnlockAndExit2: 814100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 815193267Sjkim 816193267SjkimUnlockAndExit: 817193267Sjkim (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock); 818100966Siwasaki return_ACPI_STATUS (Status); 819100966Siwasaki} 820100966Siwasaki 821167802SjkimACPI_EXPORT_SYMBOL (AcpiWalkNamespace) 822100966Siwasaki 823167802Sjkim 824100966Siwasaki/******************************************************************************* 825100966Siwasaki * 826100966Siwasaki * FUNCTION: AcpiNsGetDeviceCallback 827100966Siwasaki * 828100966Siwasaki * PARAMETERS: Callback from AcpiGetDevice 829100966Siwasaki * 830100966Siwasaki * RETURN: Status 831100966Siwasaki * 832100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 833100966Siwasaki * present devices, or if they specified a HID, it filters based 834100966Siwasaki * on that. 835100966Siwasaki * 836100966Siwasaki ******************************************************************************/ 837100966Siwasaki 838100966Siwasakistatic ACPI_STATUS 839100966SiwasakiAcpiNsGetDeviceCallback ( 840100966Siwasaki ACPI_HANDLE ObjHandle, 841100966Siwasaki UINT32 NestingLevel, 842100966Siwasaki void *Context, 843100966Siwasaki void **ReturnValue) 844100966Siwasaki{ 845117521Snjl ACPI_GET_DEVICES_INFO *Info = Context; 846100966Siwasaki ACPI_STATUS Status; 847100966Siwasaki ACPI_NAMESPACE_NODE *Node; 848100966Siwasaki UINT32 Flags; 849241973Sjkim ACPI_PNP_DEVICE_ID *Hid; 850241973Sjkim ACPI_PNP_DEVICE_ID_LIST *Cid; 851193267Sjkim UINT32 i; 852193267Sjkim BOOLEAN Found; 853197104Sjkim int NoMatch; 854100966Siwasaki 855100966Siwasaki 856100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 857100966Siwasaki if (ACPI_FAILURE (Status)) 858100966Siwasaki { 859100966Siwasaki return (Status); 860100966Siwasaki } 861100966Siwasaki 862200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 863100966Siwasaki Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 864100966Siwasaki if (ACPI_FAILURE (Status)) 865100966Siwasaki { 866100966Siwasaki return (Status); 867100966Siwasaki } 868100966Siwasaki 869100966Siwasaki if (!Node) 870100966Siwasaki { 871100966Siwasaki return (AE_BAD_PARAMETER); 872100966Siwasaki } 873100966Siwasaki 874202771Sjkim /* 875202771Sjkim * First, filter based on the device HID and CID. 876202771Sjkim * 877202771Sjkim * 01/2010: For this case where a specific HID is requested, we don't 878202771Sjkim * want to run _STA until we have an actual HID match. Thus, we will 879202771Sjkim * not unnecessarily execute _STA on devices for which the caller 880202771Sjkim * doesn't care about. Previously, _STA was executed unconditionally 881202771Sjkim * on all devices found here. 882202771Sjkim * 883202771Sjkim * A side-effect of this change is that now we will continue to search 884202771Sjkim * for a matching HID even under device trees where the parent device 885202771Sjkim * would have returned a _STA that indicates it is not present or 886202771Sjkim * not functioning (thus aborting the search on that branch). 887202771Sjkim */ 888100966Siwasaki if (Info->Hid != NULL) 889100966Siwasaki { 890100966Siwasaki Status = AcpiUtExecute_HID (Node, &Hid); 891100966Siwasaki if (Status == AE_NOT_FOUND) 892100966Siwasaki { 893100966Siwasaki return (AE_OK); 894100966Siwasaki } 895100966Siwasaki else if (ACPI_FAILURE (Status)) 896100966Siwasaki { 897100966Siwasaki return (AE_CTRL_DEPTH); 898100966Siwasaki } 899100966Siwasaki 900284583Sjkim NoMatch = strcmp (Hid->String, Info->Hid); 901197104Sjkim ACPI_FREE (Hid); 902197104Sjkim 903197104Sjkim if (NoMatch) 904100966Siwasaki { 905193267Sjkim /* 906193267Sjkim * HID does not match, attempt match within the 907193267Sjkim * list of Compatible IDs (CIDs) 908193267Sjkim */ 909100966Siwasaki Status = AcpiUtExecute_CID (Node, &Cid); 910100966Siwasaki if (Status == AE_NOT_FOUND) 911100966Siwasaki { 912100966Siwasaki return (AE_OK); 913100966Siwasaki } 914100966Siwasaki else if (ACPI_FAILURE (Status)) 915100966Siwasaki { 916100966Siwasaki return (AE_CTRL_DEPTH); 917100966Siwasaki } 918100966Siwasaki 919117521Snjl /* Walk the CID list */ 920100966Siwasaki 921193267Sjkim Found = FALSE; 922117521Snjl for (i = 0; i < Cid->Count; i++) 923100966Siwasaki { 924284583Sjkim if (strcmp (Cid->Ids[i].String, Info->Hid) == 0) 925117521Snjl { 926193267Sjkim /* Found a matching CID */ 927193267Sjkim 928193267Sjkim Found = TRUE; 929193267Sjkim break; 930117521Snjl } 931100966Siwasaki } 932193267Sjkim 933167802Sjkim ACPI_FREE (Cid); 934193267Sjkim if (!Found) 935193267Sjkim { 936193267Sjkim return (AE_OK); 937193267Sjkim } 938100966Siwasaki } 939100966Siwasaki } 940100966Siwasaki 941202771Sjkim /* Run _STA to determine if device is present */ 942202771Sjkim 943202771Sjkim Status = AcpiUtExecute_STA (Node, &Flags); 944202771Sjkim if (ACPI_FAILURE (Status)) 945202771Sjkim { 946202771Sjkim return (AE_CTRL_DEPTH); 947202771Sjkim } 948202771Sjkim 949202771Sjkim if (!(Flags & ACPI_STA_DEVICE_PRESENT) && 950202771Sjkim !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) 951202771Sjkim { 952202771Sjkim /* 953202771Sjkim * Don't examine the children of the device only when the 954202771Sjkim * device is neither present nor functional. See ACPI spec, 955202771Sjkim * description of _STA for more information. 956202771Sjkim */ 957202771Sjkim return (AE_CTRL_DEPTH); 958202771Sjkim } 959202771Sjkim 960193267Sjkim /* We have a valid device, invoke the user function */ 961193267Sjkim 962298714Sjkim Status = Info->UserFunction (ObjHandle, NestingLevel, 963298714Sjkim Info->Context, ReturnValue); 964100966Siwasaki return (Status); 965100966Siwasaki} 966100966Siwasaki 967100966Siwasaki 968100966Siwasaki/******************************************************************************* 969100966Siwasaki * 970100966Siwasaki * FUNCTION: AcpiGetDevices 971100966Siwasaki * 972100966Siwasaki * PARAMETERS: HID - HID to search for. Can be NULL. 973100966Siwasaki * UserFunction - Called when a matching object is found 974100966Siwasaki * Context - Passed to user function 975100966Siwasaki * ReturnValue - Location where return value of 976100966Siwasaki * UserFunction is put if terminated early 977100966Siwasaki * 978100966Siwasaki * RETURNS Return value from the UserFunction if terminated early. 979100966Siwasaki * Otherwise, returns NULL. 980100966Siwasaki * 981100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 982100966Siwasaki * starting (and ending) at the object specified by StartHandle. 983117521Snjl * The UserFunction is called whenever an object of type 984241973Sjkim * Device is found. If the user function returns 985100966Siwasaki * a non-zero value, the search is terminated immediately and this 986100966Siwasaki * value is returned to the caller. 987100966Siwasaki * 988100966Siwasaki * This is a wrapper for WalkNamespace, but the callback performs 989193267Sjkim * additional filtering. Please see AcpiNsGetDeviceCallback. 990100966Siwasaki * 991100966Siwasaki ******************************************************************************/ 992100966Siwasaki 993100966SiwasakiACPI_STATUS 994100966SiwasakiAcpiGetDevices ( 995114237Snjl char *HID, 996100966Siwasaki ACPI_WALK_CALLBACK UserFunction, 997100966Siwasaki void *Context, 998100966Siwasaki void **ReturnValue) 999100966Siwasaki{ 1000100966Siwasaki ACPI_STATUS Status; 1001100966Siwasaki ACPI_GET_DEVICES_INFO Info; 1002100966Siwasaki 1003100966Siwasaki 1004167802Sjkim ACPI_FUNCTION_TRACE (AcpiGetDevices); 1005100966Siwasaki 1006100966Siwasaki 1007100966Siwasaki /* Parameter validation */ 1008100966Siwasaki 1009100966Siwasaki if (!UserFunction) 1010100966Siwasaki { 1011100966Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 1012100966Siwasaki } 1013100966Siwasaki 1014100966Siwasaki /* 1015100966Siwasaki * We're going to call their callback from OUR callback, so we need 1016100966Siwasaki * to know what it is, and their context parameter. 1017100966Siwasaki */ 1018298714Sjkim Info.Hid = HID; 1019298714Sjkim Info.Context = Context; 1020100966Siwasaki Info.UserFunction = UserFunction; 1021100966Siwasaki 1022100966Siwasaki /* 1023100966Siwasaki * Lock the namespace around the walk. 1024100966Siwasaki * The namespace will be unlocked/locked around each call 1025100966Siwasaki * to the user function - since this function 1026100966Siwasaki * must be allowed to make Acpi calls itself. 1027100966Siwasaki */ 1028100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1029100966Siwasaki if (ACPI_FAILURE (Status)) 1030100966Siwasaki { 1031100966Siwasaki return_ACPI_STATUS (Status); 1032100966Siwasaki } 1033100966Siwasaki 1034167802Sjkim Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1035298714Sjkim ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 1036298714Sjkim AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue); 1037100966Siwasaki 1038100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1039100966Siwasaki return_ACPI_STATUS (Status); 1040100966Siwasaki} 1041100966Siwasaki 1042167802SjkimACPI_EXPORT_SYMBOL (AcpiGetDevices) 1043100966Siwasaki 1044167802Sjkim 1045100966Siwasaki/******************************************************************************* 1046100966Siwasaki * 1047100966Siwasaki * FUNCTION: AcpiAttachData 1048100966Siwasaki * 1049114237Snjl * PARAMETERS: ObjHandle - Namespace node 1050107325Siwasaki * Handler - Handler for this attachment 1051107325Siwasaki * Data - Pointer to data to be attached 1052100966Siwasaki * 1053100966Siwasaki * RETURN: Status 1054100966Siwasaki * 1055107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node. 1056100966Siwasaki * 1057100966Siwasaki ******************************************************************************/ 1058100966Siwasaki 1059100966SiwasakiACPI_STATUS 1060100966SiwasakiAcpiAttachData ( 1061100966Siwasaki ACPI_HANDLE ObjHandle, 1062100966Siwasaki ACPI_OBJECT_HANDLER Handler, 1063100966Siwasaki void *Data) 1064100966Siwasaki{ 1065100966Siwasaki ACPI_NAMESPACE_NODE *Node; 1066100966Siwasaki ACPI_STATUS Status; 1067100966Siwasaki 1068100966Siwasaki 1069100966Siwasaki /* Parameter validation */ 1070100966Siwasaki 1071100966Siwasaki if (!ObjHandle || 1072100966Siwasaki !Handler || 1073100966Siwasaki !Data) 1074100966Siwasaki { 1075100966Siwasaki return (AE_BAD_PARAMETER); 1076100966Siwasaki } 1077100966Siwasaki 1078100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1079100966Siwasaki if (ACPI_FAILURE (Status)) 1080100966Siwasaki { 1081100966Siwasaki return (Status); 1082100966Siwasaki } 1083100966Siwasaki 1084100966Siwasaki /* Convert and validate the handle */ 1085100966Siwasaki 1086200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 1087100966Siwasaki if (!Node) 1088100966Siwasaki { 1089100966Siwasaki Status = AE_BAD_PARAMETER; 1090100966Siwasaki goto UnlockAndExit; 1091100966Siwasaki } 1092100966Siwasaki 1093100966Siwasaki Status = AcpiNsAttachData (Node, Handler, Data); 1094100966Siwasaki 1095100966SiwasakiUnlockAndExit: 1096100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1097100966Siwasaki return (Status); 1098100966Siwasaki} 1099100966Siwasaki 1100167802SjkimACPI_EXPORT_SYMBOL (AcpiAttachData) 1101100966Siwasaki 1102167802Sjkim 1103100966Siwasaki/******************************************************************************* 1104100966Siwasaki * 1105100966Siwasaki * FUNCTION: AcpiDetachData 1106100966Siwasaki * 1107107325Siwasaki * PARAMETERS: ObjHandle - Namespace node handle 1108107325Siwasaki * Handler - Handler used in call to AcpiAttachData 1109100966Siwasaki * 1110100966Siwasaki * RETURN: Status 1111100966Siwasaki * 1112107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node. 1113100966Siwasaki * 1114100966Siwasaki ******************************************************************************/ 1115100966Siwasaki 1116100966SiwasakiACPI_STATUS 1117100966SiwasakiAcpiDetachData ( 1118100966Siwasaki ACPI_HANDLE ObjHandle, 1119100966Siwasaki ACPI_OBJECT_HANDLER Handler) 1120100966Siwasaki{ 1121100966Siwasaki ACPI_NAMESPACE_NODE *Node; 1122100966Siwasaki ACPI_STATUS Status; 1123100966Siwasaki 1124100966Siwasaki 1125100966Siwasaki /* Parameter validation */ 1126100966Siwasaki 1127100966Siwasaki if (!ObjHandle || 1128100966Siwasaki !Handler) 1129100966Siwasaki { 1130100966Siwasaki return (AE_BAD_PARAMETER); 1131100966Siwasaki } 1132100966Siwasaki 1133100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1134100966Siwasaki if (ACPI_FAILURE (Status)) 1135100966Siwasaki { 1136100966Siwasaki return (Status); 1137100966Siwasaki } 1138100966Siwasaki 1139100966Siwasaki /* Convert and validate the handle */ 1140100966Siwasaki 1141200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 1142100966Siwasaki if (!Node) 1143100966Siwasaki { 1144100966Siwasaki Status = AE_BAD_PARAMETER; 1145100966Siwasaki goto UnlockAndExit; 1146100966Siwasaki } 1147100966Siwasaki 1148100966Siwasaki Status = AcpiNsDetachData (Node, Handler); 1149100966Siwasaki 1150100966SiwasakiUnlockAndExit: 1151100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1152100966Siwasaki return (Status); 1153100966Siwasaki} 1154100966Siwasaki 1155167802SjkimACPI_EXPORT_SYMBOL (AcpiDetachData) 1156100966Siwasaki 1157167802Sjkim 1158100966Siwasaki/******************************************************************************* 1159100966Siwasaki * 1160100966Siwasaki * FUNCTION: AcpiGetData 1161100966Siwasaki * 1162107325Siwasaki * PARAMETERS: ObjHandle - Namespace node 1163107325Siwasaki * Handler - Handler used in call to AttachData 1164107325Siwasaki * Data - Where the data is returned 1165100966Siwasaki * 1166100966Siwasaki * RETURN: Status 1167100966Siwasaki * 1168107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node. 1169100966Siwasaki * 1170100966Siwasaki ******************************************************************************/ 1171100966Siwasaki 1172100966SiwasakiACPI_STATUS 1173100966SiwasakiAcpiGetData ( 1174100966Siwasaki ACPI_HANDLE ObjHandle, 1175100966Siwasaki ACPI_OBJECT_HANDLER Handler, 1176100966Siwasaki void **Data) 1177100966Siwasaki{ 1178100966Siwasaki ACPI_NAMESPACE_NODE *Node; 1179100966Siwasaki ACPI_STATUS Status; 1180100966Siwasaki 1181100966Siwasaki 1182100966Siwasaki /* Parameter validation */ 1183100966Siwasaki 1184100966Siwasaki if (!ObjHandle || 1185100966Siwasaki !Handler || 1186100966Siwasaki !Data) 1187100966Siwasaki { 1188100966Siwasaki return (AE_BAD_PARAMETER); 1189100966Siwasaki } 1190100966Siwasaki 1191100966Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1192100966Siwasaki if (ACPI_FAILURE (Status)) 1193100966Siwasaki { 1194100966Siwasaki return (Status); 1195100966Siwasaki } 1196100966Siwasaki 1197100966Siwasaki /* Convert and validate the handle */ 1198100966Siwasaki 1199200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 1200100966Siwasaki if (!Node) 1201100966Siwasaki { 1202100966Siwasaki Status = AE_BAD_PARAMETER; 1203100966Siwasaki goto UnlockAndExit; 1204100966Siwasaki } 1205100966Siwasaki 1206100966Siwasaki Status = AcpiNsGetAttachedData (Node, Handler, Data); 1207100966Siwasaki 1208100966SiwasakiUnlockAndExit: 1209100966Siwasaki (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1210100966Siwasaki return (Status); 1211100966Siwasaki} 1212100966Siwasaki 1213167802SjkimACPI_EXPORT_SYMBOL (AcpiGetData) 1214