Path: blob/main/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
48524 views
/*******************************************************************************1*2* Module Name: nsxfeval - Public interfaces to the ACPI subsystem3* ACPI Object evaluation interfaces4*5******************************************************************************/67/******************************************************************************8*9* 1. Copyright Notice10*11* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.12* All rights reserved.13*14* 2. License15*16* 2.1. This is your license from Intel Corp. under its intellectual property17* rights. You may have additional license terms from the party that provided18* you this software, covering your right to use that party's intellectual19* property rights.20*21* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a22* copy of the source code appearing in this file ("Covered Code") an23* irrevocable, perpetual, worldwide license under Intel's copyrights in the24* base code distributed originally by Intel ("Original Intel Code") to copy,25* make derivatives, distribute, use and display any portion of the Covered26* Code in any form, with the right to sublicense such rights; and27*28* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent29* license (with the right to sublicense), under only those claims of Intel30* patents that are infringed by the Original Intel Code, to make, use, sell,31* offer to sell, and import the Covered Code and derivative works thereof32* solely to the minimum extent necessary to exercise the above copyright33* license, and in no event shall the patent license extend to any additions34* to or modifications of the Original Intel Code. No other license or right35* is granted directly or by implication, estoppel or otherwise;36*37* The above copyright and patent license is granted only if the following38* conditions are met:39*40* 3. Conditions41*42* 3.1. Redistribution of Source with Rights to Further Distribute Source.43* Redistribution of source code of any substantial portion of the Covered44* Code or modification with rights to further distribute source must include45* the above Copyright Notice, the above License, this list of Conditions,46* and the following Disclaimer and Export Compliance provision. In addition,47* Licensee must cause all Covered Code to which Licensee contributes to48* contain a file documenting the changes Licensee made to create that Covered49* Code and the date of any change. Licensee must include in that file the50* documentation of any changes made by any predecessor Licensee. Licensee51* must include a prominent statement that the modification is derived,52* directly or indirectly, from Original Intel Code.53*54* 3.2. Redistribution of Source with no Rights to Further Distribute Source.55* Redistribution of source code of any substantial portion of the Covered56* Code or modification without rights to further distribute source must57* include the following Disclaimer and Export Compliance provision in the58* documentation and/or other materials provided with distribution. In59* addition, Licensee may not authorize further sublicense of source of any60* portion of the Covered Code, and must include terms to the effect that the61* license from Licensee to its licensee is limited to the intellectual62* property embodied in the software Licensee provides to its licensee, and63* not to intellectual property embodied in modifications its licensee may64* make.65*66* 3.3. Redistribution of Executable. Redistribution in executable form of any67* substantial portion of the Covered Code or modification must reproduce the68* above Copyright Notice, and the following Disclaimer and Export Compliance69* provision in the documentation and/or other materials provided with the70* distribution.71*72* 3.4. Intel retains all right, title, and interest in and to the Original73* Intel Code.74*75* 3.5. Neither the name Intel nor any other trademark owned or controlled by76* Intel shall be used in advertising or otherwise to promote the sale, use or77* other dealings in products derived from or relating to the Covered Code78* without prior written authorization from Intel.79*80* 4. Disclaimer and Export Compliance81*82* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED83* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE84* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,85* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY86* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY87* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A88* PARTICULAR PURPOSE.89*90* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES91* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR92* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,93* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY94* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL95* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS96* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY97* LIMITED REMEDY.98*99* 4.3. Licensee shall not export, either directly or indirectly, any of this100* software or system incorporating such software without first obtaining any101* required license or other approval from the U. S. Department of Commerce or102* any other agency or department of the United States Government. In the103* event Licensee exports any such software from the United States or104* re-exports any such software from a foreign destination, Licensee shall105* ensure that the distribution and export/re-export of the software is in106* compliance with all laws, regulations, orders, or other restrictions of the107* U.S. Export Administration Regulations. Licensee agrees that neither it nor108* any of its subsidiaries will export/re-export any technical data, process,109* software, or service, directly or indirectly, to any country for which the110* United States government or any agency thereof requires an export license,111* other governmental approval, or letter of assurance, without first obtaining112* such license, approval or letter.113*114*****************************************************************************115*116* Alternatively, you may choose to be licensed under the terms of the117* following license:118*119* Redistribution and use in source and binary forms, with or without120* modification, are permitted provided that the following conditions121* are met:122* 1. Redistributions of source code must retain the above copyright123* notice, this list of conditions, and the following disclaimer,124* without modification.125* 2. Redistributions in binary form must reproduce at minimum a disclaimer126* substantially similar to the "NO WARRANTY" disclaimer below127* ("Disclaimer") and any redistribution must be conditioned upon128* including a substantially similar Disclaimer requirement for further129* binary redistribution.130* 3. Neither the names of the above-listed copyright holders nor the names131* of any contributors may be used to endorse or promote products derived132* from this software without specific prior written permission.133*134* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS135* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT136* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR137* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT138* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,139* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT140* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,141* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY142* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT143* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE144* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.145*146* Alternatively, you may choose to be licensed under the terms of the147* GNU General Public License ("GPL") version 2 as published by the Free148* Software Foundation.149*150*****************************************************************************/151152#define EXPORT_ACPI_INTERFACES153154#include <contrib/dev/acpica/include/acpi.h>155#include <contrib/dev/acpica/include/accommon.h>156#include <contrib/dev/acpica/include/acnamesp.h>157#include <contrib/dev/acpica/include/acinterp.h>158159160#define _COMPONENT ACPI_NAMESPACE161ACPI_MODULE_NAME ("nsxfeval")162163/* Local prototypes */164165static void166AcpiNsResolveReferences (167ACPI_EVALUATE_INFO *Info);168169170/*******************************************************************************171*172* FUNCTION: AcpiEvaluateObjectTyped173*174* PARAMETERS: Handle - Object handle (optional)175* Pathname - Object pathname (optional)176* ExternalParams - List of parameters to pass to a method,177* terminated by NULL. May be NULL178* if no parameters are being passed.179* ReturnBuffer - Where to put the object return value (if180* any). Required.181* ReturnType - Expected type of return object182*183* RETURN: Status184*185* DESCRIPTION: Find and evaluate the given object, passing the given186* parameters if necessary. One of "Handle" or "Pathname" must187* be valid (non-null)188*189******************************************************************************/190191ACPI_STATUS192AcpiEvaluateObjectTyped (193ACPI_HANDLE Handle,194ACPI_STRING Pathname,195ACPI_OBJECT_LIST *ExternalParams,196ACPI_BUFFER *ReturnBuffer,197ACPI_OBJECT_TYPE ReturnType)198{199ACPI_STATUS Status;200BOOLEAN FreeBufferOnError = FALSE;201ACPI_HANDLE TargetHandle;202char *FullPathname;203204205ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);206207208/* Return buffer must be valid */209210if (!ReturnBuffer)211{212return_ACPI_STATUS (AE_BAD_PARAMETER);213}214215if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)216{217FreeBufferOnError = TRUE;218}219220/* Get a handle here, in order to build an error message if needed */221222TargetHandle = Handle;223if (Pathname)224{225Status = AcpiGetHandle (Handle, Pathname, &TargetHandle);226if (ACPI_FAILURE (Status))227{228return_ACPI_STATUS (Status);229}230}231232FullPathname = AcpiNsGetExternalPathname (TargetHandle);233if (!FullPathname)234{235return_ACPI_STATUS (AE_NO_MEMORY);236}237238/* Evaluate the object */239240Status = AcpiEvaluateObject (TargetHandle, NULL, ExternalParams,241ReturnBuffer);242if (ACPI_FAILURE (Status))243{244goto Exit;245}246247/* Type ANY means "don't care about return value type" */248249if (ReturnType == ACPI_TYPE_ANY)250{251goto Exit;252}253254if (ReturnBuffer->Length == 0)255{256/* Error because caller specifically asked for a return value */257258ACPI_ERROR ((AE_INFO, "%s did not return any object",259FullPathname));260Status = AE_NULL_OBJECT;261goto Exit;262}263264/* Examine the object type returned from EvaluateObject */265266if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)267{268goto Exit;269}270271/* Return object type does not match requested type */272273ACPI_ERROR ((AE_INFO,274"Incorrect return type from %s - received [%s], requested [%s]",275FullPathname,276AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),277AcpiUtGetTypeName (ReturnType)));278279if (FreeBufferOnError)280{281/*282* Free a buffer created via ACPI_ALLOCATE_BUFFER.283* Note: We use AcpiOsFree here because AcpiOsAllocate was used284* to allocate the buffer. This purposefully bypasses the285* (optionally enabled) allocation tracking mechanism since we286* only want to track internal allocations.287*/288AcpiOsFree (ReturnBuffer->Pointer);289ReturnBuffer->Pointer = NULL;290}291292ReturnBuffer->Length = 0;293Status = AE_TYPE;294295Exit:296ACPI_FREE (FullPathname);297return_ACPI_STATUS (Status);298}299300ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)301302303/*******************************************************************************304*305* FUNCTION: AcpiEvaluateObject306*307* PARAMETERS: Handle - Object handle (optional)308* Pathname - Object pathname (optional)309* ExternalParams - List of parameters to pass to method,310* terminated by NULL. May be NULL311* if no parameters are being passed.312* ReturnBuffer - Where to put method's return value (if313* any). If NULL, no value is returned.314*315* RETURN: Status316*317* DESCRIPTION: Find and evaluate the given object, passing the given318* parameters if necessary. One of "Handle" or "Pathname" must319* be valid (non-null)320*321******************************************************************************/322323ACPI_STATUS324AcpiEvaluateObject (325ACPI_HANDLE Handle,326ACPI_STRING Pathname,327ACPI_OBJECT_LIST *ExternalParams,328ACPI_BUFFER *ReturnBuffer)329{330ACPI_STATUS Status;331ACPI_EVALUATE_INFO *Info;332ACPI_SIZE BufferSpaceNeeded;333UINT32 i;334335336ACPI_FUNCTION_TRACE (AcpiEvaluateObject);337338339/* Allocate and initialize the evaluation information block */340341Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));342if (!Info)343{344return_ACPI_STATUS (AE_NO_MEMORY);345}346347/* Convert and validate the device handle */348349Info->PrefixNode = AcpiNsValidateHandle (Handle);350if (!Info->PrefixNode)351{352Status = AE_BAD_PARAMETER;353goto Cleanup;354}355356/*357* Get the actual namespace node for the target object.358* Handles these cases:359*360* 1) Null node, valid pathname from root (absolute path)361* 2) Node and valid pathname (path relative to Node)362* 3) Node, Null pathname363*/364if ((Pathname) &&365(ACPI_IS_ROOT_PREFIX (Pathname[0])))366{367/* The path is fully qualified, just evaluate by name */368369Info->PrefixNode = NULL;370}371else if (!Handle)372{373/*374* A handle is optional iff a fully qualified pathname is specified.375* Since we've already handled fully qualified names above, this is376* an error.377*/378if (!Pathname)379{380ACPI_DEBUG_PRINT ((ACPI_DB_INFO,381"Both Handle and Pathname are NULL"));382}383else384{385ACPI_DEBUG_PRINT ((ACPI_DB_INFO,386"Null Handle with relative pathname [%s]", Pathname));387}388389Status = AE_BAD_PARAMETER;390goto Cleanup;391}392393Info->RelativePathname = Pathname;394395/*396* Convert all external objects passed as arguments to the397* internal version(s).398*/399if (ExternalParams && ExternalParams->Count)400{401Info->ParamCount = (UINT16) ExternalParams->Count;402403/* Warn on impossible argument count */404405if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)406{407ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,408"Excess arguments (%u) - using only %u",409Info->ParamCount, ACPI_METHOD_NUM_ARGS));410411Info->ParamCount = ACPI_METHOD_NUM_ARGS;412}413414/*415* Allocate a new parameter block for the internal objects416* Add 1 to count to allow for null terminated internal list417*/418Info->Parameters = ACPI_ALLOCATE_ZEROED (419((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));420if (!Info->Parameters)421{422Status = AE_NO_MEMORY;423goto Cleanup;424}425426/* Convert each external object in the list to an internal object */427428for (i = 0; i < Info->ParamCount; i++)429{430Status = AcpiUtCopyEobjectToIobject (431&ExternalParams->Pointer[i], &Info->Parameters[i]);432if (ACPI_FAILURE (Status))433{434goto Cleanup;435}436}437438Info->Parameters[Info->ParamCount] = NULL;439}440441442#ifdef _FUTURE_FEATURE443444/*445* Begin incoming argument count analysis. Check for too few args446* and too many args.447*/448switch (AcpiNsGetType (Info->Node))449{450case ACPI_TYPE_METHOD:451452/* Check incoming argument count against the method definition */453454if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)455{456ACPI_ERROR ((AE_INFO,457"Insufficient arguments (%u) - %u are required",458Info->ParamCount,459Info->ObjDesc->Method.ParamCount));460461Status = AE_MISSING_ARGUMENTS;462goto Cleanup;463}464465else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)466{467ACPI_WARNING ((AE_INFO,468"Excess arguments (%u) - only %u are required",469Info->ParamCount,470Info->ObjDesc->Method.ParamCount));471472/* Just pass the required number of arguments */473474Info->ParamCount = Info->ObjDesc->Method.ParamCount;475}476477/*478* Any incoming external objects to be passed as arguments to the479* method must be converted to internal objects480*/481if (Info->ParamCount)482{483/*484* Allocate a new parameter block for the internal objects485* Add 1 to count to allow for null terminated internal list486*/487Info->Parameters = ACPI_ALLOCATE_ZEROED (488((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));489if (!Info->Parameters)490{491Status = AE_NO_MEMORY;492goto Cleanup;493}494495/* Convert each external object in the list to an internal object */496497for (i = 0; i < Info->ParamCount; i++)498{499Status = AcpiUtCopyEobjectToIobject (500&ExternalParams->Pointer[i], &Info->Parameters[i]);501if (ACPI_FAILURE (Status))502{503goto Cleanup;504}505}506507Info->Parameters[Info->ParamCount] = NULL;508}509break;510511default:512513/* Warn if arguments passed to an object that is not a method */514515if (Info->ParamCount)516{517ACPI_WARNING ((AE_INFO,518"%u arguments were passed to a non-method ACPI object",519Info->ParamCount));520}521break;522}523524#endif525526527/* Now we can evaluate the object */528529Status = AcpiNsEvaluate (Info);530531/*532* If we are expecting a return value, and all went well above,533* copy the return value to an external object.534*/535if (!ReturnBuffer)536{537goto CleanupReturnObject;538}539540if (!Info->ReturnObject)541{542ReturnBuffer->Length = 0;543goto Cleanup;544}545546if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==547ACPI_DESC_TYPE_NAMED)548{549/*550* If we received a NS Node as a return object, this means that551* the object we are evaluating has nothing interesting to552* return (such as a mutex, etc.) We return an error because553* these types are essentially unsupported by this interface.554* We don't check up front because this makes it easier to add555* support for various types at a later date if necessary.556*/557Status = AE_TYPE;558Info->ReturnObject = NULL; /* No need to delete a NS Node */559ReturnBuffer->Length = 0;560}561562if (ACPI_FAILURE (Status))563{564goto CleanupReturnObject;565}566567/* Dereference Index and RefOf references */568569AcpiNsResolveReferences (Info);570571/* Get the size of the returned object */572573Status = AcpiUtGetObjectSize (Info->ReturnObject,574&BufferSpaceNeeded);575if (ACPI_SUCCESS (Status))576{577/* Validate/Allocate/Clear caller buffer */578579Status = AcpiUtInitializeBuffer (ReturnBuffer,580BufferSpaceNeeded);581if (ACPI_FAILURE (Status))582{583/*584* Caller's buffer is too small or a new one can't585* be allocated586*/587ACPI_DEBUG_PRINT ((ACPI_DB_INFO,588"Needed buffer size %X, %s\n",589(UINT32) BufferSpaceNeeded,590AcpiFormatException (Status)));591}592else593{594/* We have enough space for the object, build it */595596Status = AcpiUtCopyIobjectToEobject (597Info->ReturnObject, ReturnBuffer);598}599}600601CleanupReturnObject:602603if (Info->ReturnObject)604{605/*606* Delete the internal return object. NOTE: Interpreter must be607* locked to avoid race condition.608*/609AcpiExEnterInterpreter ();610611/* Remove one reference on the return object (should delete it) */612613AcpiUtRemoveReference (Info->ReturnObject);614AcpiExExitInterpreter ();615}616617618Cleanup:619620/* Free the input parameter list (if we created one) */621622if (Info->Parameters)623{624/* Free the allocated parameter block */625626AcpiUtDeleteInternalObjectList (Info->Parameters);627}628629ACPI_FREE (Info);630return_ACPI_STATUS (Status);631}632633ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)634635636/*******************************************************************************637*638* FUNCTION: AcpiNsResolveReferences639*640* PARAMETERS: Info - Evaluation info block641*642* RETURN: Info->ReturnObject is replaced with the dereferenced object643*644* DESCRIPTION: Dereference certain reference objects. Called before an645* internal return object is converted to an external ACPI_OBJECT.646*647* Performs an automatic dereference of Index and RefOf reference objects.648* These reference objects are not supported by the ACPI_OBJECT, so this is a649* last resort effort to return something useful. Also, provides compatibility650* with other ACPI implementations.651*652* NOTE: does not handle references within returned package objects or nested653* references, but this support could be added later if found to be necessary.654*655******************************************************************************/656657static void658AcpiNsResolveReferences (659ACPI_EVALUATE_INFO *Info)660{661ACPI_OPERAND_OBJECT *ObjDesc = NULL;662ACPI_NAMESPACE_NODE *Node;663664665/* We are interested in reference objects only */666667if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)668{669return;670}671672/*673* Two types of references are supported - those created by Index and674* RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted675* to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle676* (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to677* an ACPI_OBJECT.678*/679switch (Info->ReturnObject->Reference.Class)680{681case ACPI_REFCLASS_INDEX:682683ObjDesc = *(Info->ReturnObject->Reference.Where);684break;685686case ACPI_REFCLASS_REFOF:687688Node = Info->ReturnObject->Reference.Object;689if (Node)690{691ObjDesc = Node->Object;692}693break;694695default:696697return;698}699700/* Replace the existing reference object */701702if (ObjDesc)703{704AcpiUtAddReference (ObjDesc);705AcpiUtRemoveReference (Info->ReturnObject);706Info->ReturnObject = ObjDesc;707}708709return;710}711712713/*******************************************************************************714*715* FUNCTION: AcpiWalkNamespace716*717* PARAMETERS: Type - ACPI_OBJECT_TYPE to search for718* StartObject - Handle in namespace where search begins719* MaxDepth - Depth to which search is to reach720* DescendingCallback - Called during tree descent721* when an object of "Type" is found722* AscendingCallback - Called during tree ascent723* when an object of "Type" is found724* Context - Passed to user function(s) above725* ReturnValue - Location where return value of726* UserFunction is put if terminated early727*728* RETURNS Return value from the UserFunction if terminated early.729* Otherwise, returns NULL.730*731* DESCRIPTION: Performs a modified depth-first walk of the namespace tree,732* starting (and ending) at the object specified by StartHandle.733* The callback function is called whenever an object that matches734* the type parameter is found. If the callback function returns735* a non-zero value, the search is terminated immediately and this736* value is returned to the caller.737*738* The point of this procedure is to provide a generic namespace739* walk routine that can be called from multiple places to740* provide multiple services; the callback function(s) can be741* tailored to each task, whether it is a print function,742* a compare function, etc.743*744******************************************************************************/745746ACPI_STATUS747AcpiWalkNamespace (748ACPI_OBJECT_TYPE Type,749ACPI_HANDLE StartObject,750UINT32 MaxDepth,751ACPI_WALK_CALLBACK DescendingCallback,752ACPI_WALK_CALLBACK AscendingCallback,753void *Context,754void **ReturnValue)755{756ACPI_STATUS Status;757758759ACPI_FUNCTION_TRACE (AcpiWalkNamespace);760761762/* Parameter validation */763764if ((Type > ACPI_TYPE_LOCAL_MAX) ||765(!MaxDepth) ||766(!DescendingCallback && !AscendingCallback))767{768return_ACPI_STATUS (AE_BAD_PARAMETER);769}770771/*772* Need to acquire the namespace reader lock to prevent interference773* with any concurrent table unloads (which causes the deletion of774* namespace objects). We cannot allow the deletion of a namespace node775* while the user function is using it. The exception to this are the776* nodes created and deleted during control method execution -- these777* nodes are marked as temporary nodes and are ignored by the namespace778* walk. Thus, control methods can be executed while holding the779* namespace deletion lock (and the user function can execute control780* methods.)781*/782Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);783if (ACPI_FAILURE (Status))784{785return_ACPI_STATUS (Status);786}787788/*789* Lock the namespace around the walk. The namespace will be790* unlocked/locked around each call to the user function - since the user791* function must be allowed to make ACPICA calls itself (for example, it792* will typically execute control methods during device enumeration.)793*/794Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);795if (ACPI_FAILURE (Status))796{797goto UnlockAndExit;798}799800/* Now we can validate the starting node */801802if (!AcpiNsValidateHandle (StartObject))803{804Status = AE_BAD_PARAMETER;805goto UnlockAndExit2;806}807808Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,809ACPI_NS_WALK_UNLOCK, DescendingCallback,810AscendingCallback, Context, ReturnValue);811812UnlockAndExit2:813(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);814815UnlockAndExit:816(void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);817return_ACPI_STATUS (Status);818}819820ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)821822823/*******************************************************************************824*825* FUNCTION: AcpiNsGetDeviceCallback826*827* PARAMETERS: Callback from AcpiGetDevice828*829* RETURN: Status830*831* DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-832* present devices, or if they specified a HID, it filters based833* on that.834*835******************************************************************************/836837static ACPI_STATUS838AcpiNsGetDeviceCallback (839ACPI_HANDLE ObjHandle,840UINT32 NestingLevel,841void *Context,842void **ReturnValue)843{844ACPI_GET_DEVICES_INFO *Info = Context;845ACPI_STATUS Status;846ACPI_NAMESPACE_NODE *Node;847UINT32 Flags;848ACPI_PNP_DEVICE_ID *Hid;849ACPI_PNP_DEVICE_ID_LIST *Cid;850UINT32 i;851BOOLEAN Found;852int NoMatch;853854855Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);856if (ACPI_FAILURE (Status))857{858return (Status);859}860861Node = AcpiNsValidateHandle (ObjHandle);862Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);863if (ACPI_FAILURE (Status))864{865return (Status);866}867868if (!Node)869{870return (AE_BAD_PARAMETER);871}872873/*874* First, filter based on the device HID and CID.875*876* 01/2010: For this case where a specific HID is requested, we don't877* want to run _STA until we have an actual HID match. Thus, we will878* not unnecessarily execute _STA on devices for which the caller879* doesn't care about. Previously, _STA was executed unconditionally880* on all devices found here.881*882* A side-effect of this change is that now we will continue to search883* for a matching HID even under device trees where the parent device884* would have returned a _STA that indicates it is not present or885* not functioning (thus aborting the search on that branch).886*/887if (Info->Hid != NULL)888{889Status = AcpiUtExecute_HID (Node, &Hid);890if (Status == AE_NOT_FOUND)891{892return (AE_OK);893}894else if (ACPI_FAILURE (Status))895{896return (AE_CTRL_DEPTH);897}898899NoMatch = strcmp (Hid->String, Info->Hid);900ACPI_FREE (Hid);901902if (NoMatch)903{904/*905* HID does not match, attempt match within the906* list of Compatible IDs (CIDs)907*/908Status = AcpiUtExecute_CID (Node, &Cid);909if (Status == AE_NOT_FOUND)910{911return (AE_OK);912}913else if (ACPI_FAILURE (Status))914{915return (AE_CTRL_DEPTH);916}917918/* Walk the CID list */919920Found = FALSE;921for (i = 0; i < Cid->Count; i++)922{923if (strcmp (Cid->Ids[i].String, Info->Hid) == 0)924{925/* Found a matching CID */926927Found = TRUE;928break;929}930}931932ACPI_FREE (Cid);933if (!Found)934{935return (AE_OK);936}937}938}939940/* Run _STA to determine if device is present */941942Status = AcpiUtExecute_STA (Node, &Flags);943if (ACPI_FAILURE (Status))944{945return (AE_CTRL_DEPTH);946}947948if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&949!(Flags & ACPI_STA_DEVICE_FUNCTIONING))950{951/*952* Don't examine the children of the device only when the953* device is neither present nor functional. See ACPI spec,954* description of _STA for more information.955*/956return (AE_CTRL_DEPTH);957}958959/* We have a valid device, invoke the user function */960961Status = Info->UserFunction (ObjHandle, NestingLevel,962Info->Context, ReturnValue);963return (Status);964}965966967/*******************************************************************************968*969* FUNCTION: AcpiGetDevices970*971* PARAMETERS: HID - HID to search for. Can be NULL.972* UserFunction - Called when a matching object is found973* Context - Passed to user function974* ReturnValue - Location where return value of975* UserFunction is put if terminated early976*977* RETURNS Return value from the UserFunction if terminated early.978* Otherwise, returns NULL.979*980* DESCRIPTION: Performs a modified depth-first walk of the namespace tree,981* starting (and ending) at the object specified by StartHandle.982* The UserFunction is called whenever an object of type983* Device is found. If the user function returns984* a non-zero value, the search is terminated immediately and this985* value is returned to the caller.986*987* This is a wrapper for WalkNamespace, but the callback performs988* additional filtering. Please see AcpiNsGetDeviceCallback.989*990******************************************************************************/991992ACPI_STATUS993AcpiGetDevices (994char *HID,995ACPI_WALK_CALLBACK UserFunction,996void *Context,997void **ReturnValue)998{999ACPI_STATUS Status;1000ACPI_GET_DEVICES_INFO Info;100110021003ACPI_FUNCTION_TRACE (AcpiGetDevices);100410051006/* Parameter validation */10071008if (!UserFunction)1009{1010return_ACPI_STATUS (AE_BAD_PARAMETER);1011}10121013/*1014* We're going to call their callback from OUR callback, so we need1015* to know what it is, and their context parameter.1016*/1017Info.Hid = HID;1018Info.Context = Context;1019Info.UserFunction = UserFunction;10201021/*1022* Lock the namespace around the walk.1023* The namespace will be unlocked/locked around each call1024* to the user function - since this function1025* must be allowed to make Acpi calls itself.1026*/1027Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);1028if (ACPI_FAILURE (Status))1029{1030return_ACPI_STATUS (Status);1031}10321033Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,1034ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,1035AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);10361037(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);1038return_ACPI_STATUS (Status);1039}10401041ACPI_EXPORT_SYMBOL (AcpiGetDevices)104210431044/*******************************************************************************1045*1046* FUNCTION: AcpiAttachData1047*1048* PARAMETERS: ObjHandle - Namespace node1049* Handler - Handler for this attachment1050* Data - Pointer to data to be attached1051*1052* RETURN: Status1053*1054* DESCRIPTION: Attach arbitrary data and handler to a namespace node.1055*1056******************************************************************************/10571058ACPI_STATUS1059AcpiAttachData (1060ACPI_HANDLE ObjHandle,1061ACPI_OBJECT_HANDLER Handler,1062void *Data)1063{1064ACPI_NAMESPACE_NODE *Node;1065ACPI_STATUS Status;106610671068/* Parameter validation */10691070if (!ObjHandle ||1071!Handler ||1072!Data)1073{1074return (AE_BAD_PARAMETER);1075}10761077Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);1078if (ACPI_FAILURE (Status))1079{1080return (Status);1081}10821083/* Convert and validate the handle */10841085Node = AcpiNsValidateHandle (ObjHandle);1086if (!Node)1087{1088Status = AE_BAD_PARAMETER;1089goto UnlockAndExit;1090}10911092Status = AcpiNsAttachData (Node, Handler, Data);10931094UnlockAndExit:1095(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);1096return (Status);1097}10981099ACPI_EXPORT_SYMBOL (AcpiAttachData)110011011102/*******************************************************************************1103*1104* FUNCTION: AcpiDetachData1105*1106* PARAMETERS: ObjHandle - Namespace node handle1107* Handler - Handler used in call to AcpiAttachData1108*1109* RETURN: Status1110*1111* DESCRIPTION: Remove data that was previously attached to a node.1112*1113******************************************************************************/11141115ACPI_STATUS1116AcpiDetachData (1117ACPI_HANDLE ObjHandle,1118ACPI_OBJECT_HANDLER Handler)1119{1120ACPI_NAMESPACE_NODE *Node;1121ACPI_STATUS Status;112211231124/* Parameter validation */11251126if (!ObjHandle ||1127!Handler)1128{1129return (AE_BAD_PARAMETER);1130}11311132Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);1133if (ACPI_FAILURE (Status))1134{1135return (Status);1136}11371138/* Convert and validate the handle */11391140Node = AcpiNsValidateHandle (ObjHandle);1141if (!Node)1142{1143Status = AE_BAD_PARAMETER;1144goto UnlockAndExit;1145}11461147Status = AcpiNsDetachData (Node, Handler);11481149UnlockAndExit:1150(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);1151return (Status);1152}11531154ACPI_EXPORT_SYMBOL (AcpiDetachData)115511561157/*******************************************************************************1158*1159* FUNCTION: AcpiGetData1160*1161* PARAMETERS: ObjHandle - Namespace node1162* Handler - Handler used in call to AttachData1163* Data - Where the data is returned1164*1165* RETURN: Status1166*1167* DESCRIPTION: Retrieve data that was previously attached to a namespace node.1168*1169******************************************************************************/11701171ACPI_STATUS1172AcpiGetData (1173ACPI_HANDLE ObjHandle,1174ACPI_OBJECT_HANDLER Handler,1175void **Data)1176{1177ACPI_NAMESPACE_NODE *Node;1178ACPI_STATUS Status;117911801181/* Parameter validation */11821183if (!ObjHandle ||1184!Handler ||1185!Data)1186{1187return (AE_BAD_PARAMETER);1188}11891190Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);1191if (ACPI_FAILURE (Status))1192{1193return (Status);1194}11951196/* Convert and validate the handle */11971198Node = AcpiNsValidateHandle (ObjHandle);1199if (!Node)1200{1201Status = AE_BAD_PARAMETER;1202goto UnlockAndExit;1203}12041205Status = AcpiNsGetAttachedData (Node, Handler, Data);12061207UnlockAndExit:1208(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);1209return (Status);1210}12111212ACPI_EXPORT_SYMBOL (AcpiGetData)121312141215