ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

nsxfeval.c
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
00004  *                         ACPI Object evaluation interfaces
00005  *
00006  ******************************************************************************/
00007 
00008 /******************************************************************************
00009  *
00010  * 1. Copyright Notice
00011  *
00012  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00013  * All rights reserved.
00014  *
00015  * 2. License
00016  *
00017  * 2.1. This is your license from Intel Corp. under its intellectual property
00018  * rights.  You may have additional license terms from the party that provided
00019  * you this software, covering your right to use that party's intellectual
00020  * property rights.
00021  *
00022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00023  * copy of the source code appearing in this file ("Covered Code") an
00024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00025  * base code distributed originally by Intel ("Original Intel Code") to copy,
00026  * make derivatives, distribute, use and display any portion of the Covered
00027  * Code in any form, with the right to sublicense such rights; and
00028  *
00029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00030  * license (with the right to sublicense), under only those claims of Intel
00031  * patents that are infringed by the Original Intel Code, to make, use, sell,
00032  * offer to sell, and import the Covered Code and derivative works thereof
00033  * solely to the minimum extent necessary to exercise the above copyright
00034  * license, and in no event shall the patent license extend to any additions
00035  * to or modifications of the Original Intel Code.  No other license or right
00036  * is granted directly or by implication, estoppel or otherwise;
00037  *
00038  * The above copyright and patent license is granted only if the following
00039  * conditions are met:
00040  *
00041  * 3. Conditions
00042  *
00043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00044  * Redistribution of source code of any substantial portion of the Covered
00045  * Code or modification with rights to further distribute source must include
00046  * the above Copyright Notice, the above License, this list of Conditions,
00047  * and the following Disclaimer and Export Compliance provision.  In addition,
00048  * Licensee must cause all Covered Code to which Licensee contributes to
00049  * contain a file documenting the changes Licensee made to create that Covered
00050  * Code and the date of any change.  Licensee must include in that file the
00051  * documentation of any changes made by any predecessor Licensee.  Licensee
00052  * must include a prominent statement that the modification is derived,
00053  * directly or indirectly, from Original Intel Code.
00054  *
00055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00056  * Redistribution of source code of any substantial portion of the Covered
00057  * Code or modification without rights to further distribute source must
00058  * include the following Disclaimer and Export Compliance provision in the
00059  * documentation and/or other materials provided with distribution.  In
00060  * addition, Licensee may not authorize further sublicense of source of any
00061  * portion of the Covered Code, and must include terms to the effect that the
00062  * license from Licensee to its licensee is limited to the intellectual
00063  * property embodied in the software Licensee provides to its licensee, and
00064  * not to intellectual property embodied in modifications its licensee may
00065  * make.
00066  *
00067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00068  * substantial portion of the Covered Code or modification must reproduce the
00069  * above Copyright Notice, and the following Disclaimer and Export Compliance
00070  * provision in the documentation and/or other materials provided with the
00071  * distribution.
00072  *
00073  * 3.4. Intel retains all right, title, and interest in and to the Original
00074  * Intel Code.
00075  *
00076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00077  * Intel shall be used in advertising or otherwise to promote the sale, use or
00078  * other dealings in products derived from or relating to the Covered Code
00079  * without prior written authorization from Intel.
00080  *
00081  * 4. Disclaimer and Export Compliance
00082  *
00083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00084  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00086  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00089  * PARTICULAR PURPOSE.
00090  *
00091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00098  * LIMITED REMEDY.
00099  *
00100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00101  * software or system incorporating such software without first obtaining any
00102  * required license or other approval from the U. S. Department of Commerce or
00103  * any other agency or department of the United States Government.  In the
00104  * event Licensee exports any such software from the United States or
00105  * re-exports any such software from a foreign destination, Licensee shall
00106  * ensure that the distribution and export/re-export of the software is in
00107  * compliance with all laws, regulations, orders, or other restrictions of the
00108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00109  * any of its subsidiaries will export/re-export any technical data, process,
00110  * software, or service, directly or indirectly, to any country for which the
00111  * United States government or any agency thereof requires an export license,
00112  * other governmental approval, or letter of assurance, without first obtaining
00113  * such license, approval or letter.
00114  *
00115  *****************************************************************************/
00116 
00117 
00118 #define __NSXFEVAL_C__
00119 
00120 #include "acpi.h"
00121 #include "accommon.h"
00122 #include "acnamesp.h"
00123 #include "acinterp.h"
00124 
00125 
00126 #define _COMPONENT          ACPI_NAMESPACE
00127         ACPI_MODULE_NAME    ("nsxfeval")
00128 
00129 /* Local prototypes */
00130 
00131 static void
00132 AcpiNsResolveReferences (
00133     ACPI_EVALUATE_INFO      *Info);
00134 
00135 
00136 /*******************************************************************************
00137  *
00138  * FUNCTION:    AcpiEvaluateObjectTyped
00139  *
00140  * PARAMETERS:  Handle              - Object handle (optional)
00141  *              Pathname            - Object pathname (optional)
00142  *              ExternalParams      - List of parameters to pass to method,
00143  *                                    terminated by NULL.  May be NULL
00144  *                                    if no parameters are being passed.
00145  *              ReturnBuffer        - Where to put method's return value (if
00146  *                                    any).  If NULL, no value is returned.
00147  *              ReturnType          - Expected type of return object
00148  *
00149  * RETURN:      Status
00150  *
00151  * DESCRIPTION: Find and evaluate the given object, passing the given
00152  *              parameters if necessary.  One of "Handle" or "Pathname" must
00153  *              be valid (non-null)
00154  *
00155  ******************************************************************************/
00156 
00157 ACPI_STATUS
00158 AcpiEvaluateObjectTyped (
00159     ACPI_HANDLE             Handle,
00160     ACPI_STRING             Pathname,
00161     ACPI_OBJECT_LIST        *ExternalParams,
00162     ACPI_BUFFER             *ReturnBuffer,
00163     ACPI_OBJECT_TYPE        ReturnType)
00164 {
00165     ACPI_STATUS             Status;
00166     BOOLEAN                 MustFree = FALSE;
00167 
00168 
00169     ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
00170 
00171 
00172     /* Return buffer must be valid */
00173 
00174     if (!ReturnBuffer)
00175     {
00176         return_ACPI_STATUS (AE_BAD_PARAMETER);
00177     }
00178 
00179     if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
00180     {
00181         MustFree = TRUE;
00182     }
00183 
00184     /* Evaluate the object */
00185 
00186     Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
00187     if (ACPI_FAILURE (Status))
00188     {
00189         return_ACPI_STATUS (Status);
00190     }
00191 
00192     /* Type ANY means "don't care" */
00193 
00194     if (ReturnType == ACPI_TYPE_ANY)
00195     {
00196         return_ACPI_STATUS (AE_OK);
00197     }
00198 
00199     if (ReturnBuffer->Length == 0)
00200     {
00201         /* Error because caller specifically asked for a return value */
00202 
00203         ACPI_ERROR ((AE_INFO, "No return value"));
00204         return_ACPI_STATUS (AE_NULL_OBJECT);
00205     }
00206 
00207     /* Examine the object type returned from EvaluateObject */
00208 
00209     if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
00210     {
00211         return_ACPI_STATUS (AE_OK);
00212     }
00213 
00214     /* Return object type does not match requested type */
00215 
00216     ACPI_ERROR ((AE_INFO,
00217         "Incorrect return type [%s] requested [%s]",
00218         AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
00219         AcpiUtGetTypeName (ReturnType)));
00220 
00221     if (MustFree)
00222     {
00223         /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
00224 
00225         AcpiOsFree (ReturnBuffer->Pointer);
00226         ReturnBuffer->Pointer = NULL;
00227     }
00228 
00229     ReturnBuffer->Length = 0;
00230     return_ACPI_STATUS (AE_TYPE);
00231 }
00232 
00233 ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
00234 
00235 
00236 /*******************************************************************************
00237  *
00238  * FUNCTION:    AcpiEvaluateObject
00239  *
00240  * PARAMETERS:  Handle              - Object handle (optional)
00241  *              Pathname            - Object pathname (optional)
00242  *              ExternalParams      - List of parameters to pass to method,
00243  *                                    terminated by NULL.  May be NULL
00244  *                                    if no parameters are being passed.
00245  *              ReturnBuffer        - Where to put method's return value (if
00246  *                                    any).  If NULL, no value is returned.
00247  *
00248  * RETURN:      Status
00249  *
00250  * DESCRIPTION: Find and evaluate the given object, passing the given
00251  *              parameters if necessary.  One of "Handle" or "Pathname" must
00252  *              be valid (non-null)
00253  *
00254  ******************************************************************************/
00255 
00256 ACPI_STATUS
00257 AcpiEvaluateObject (
00258     ACPI_HANDLE             Handle,
00259     ACPI_STRING             Pathname,
00260     ACPI_OBJECT_LIST        *ExternalParams,
00261     ACPI_BUFFER             *ReturnBuffer)
00262 {
00263     ACPI_STATUS             Status;
00264     ACPI_EVALUATE_INFO      *Info;
00265     ACPI_SIZE               BufferSpaceNeeded;
00266     UINT32                  i;
00267 
00268 
00269     ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
00270 
00271 
00272     /* Allocate and initialize the evaluation information block */
00273 
00274     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
00275     if (!Info)
00276     {
00277         return_ACPI_STATUS (AE_NO_MEMORY);
00278     }
00279 
00280     Info->Pathname = Pathname;
00281 
00282     /* Convert and validate the device handle */
00283 
00284     Info->PrefixNode = AcpiNsValidateHandle (Handle);
00285     if (!Info->PrefixNode)
00286     {
00287         Status = AE_BAD_PARAMETER;
00288         goto Cleanup;
00289     }
00290 
00291     /*
00292      * If there are parameters to be passed to a control method, the external
00293      * objects must all be converted to internal objects
00294      */
00295     if (ExternalParams && ExternalParams->Count)
00296     {
00297         /*
00298          * Allocate a new parameter block for the internal objects
00299          * Add 1 to count to allow for null terminated internal list
00300          */
00301         Info->Parameters = ACPI_ALLOCATE_ZEROED (
00302             ((ACPI_SIZE) ExternalParams->Count + 1) * sizeof (void *));
00303         if (!Info->Parameters)
00304         {
00305             Status = AE_NO_MEMORY;
00306             goto Cleanup;
00307         }
00308 
00309         /* Convert each external object in the list to an internal object */
00310 
00311         for (i = 0; i < ExternalParams->Count; i++)
00312         {
00313             Status = AcpiUtCopyEobjectToIobject (
00314                         &ExternalParams->Pointer[i], &Info->Parameters[i]);
00315             if (ACPI_FAILURE (Status))
00316             {
00317                 goto Cleanup;
00318             }
00319         }
00320         Info->Parameters[ExternalParams->Count] = NULL;
00321     }
00322 
00323     /*
00324      * Three major cases:
00325      * 1) Fully qualified pathname
00326      * 2) No handle, not fully qualified pathname (error)
00327      * 3) Valid handle
00328      */
00329     if ((Pathname) &&
00330         (AcpiNsValidRootPrefix (Pathname[0])))
00331     {
00332         /* The path is fully qualified, just evaluate by name */
00333 
00334         Info->PrefixNode = NULL;
00335         Status = AcpiNsEvaluate (Info);
00336     }
00337     else if (!Handle)
00338     {
00339         /*
00340          * A handle is optional iff a fully qualified pathname is specified.
00341          * Since we've already handled fully qualified names above, this is
00342          * an error
00343          */
00344         if (!Pathname)
00345         {
00346             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
00347                 "Both Handle and Pathname are NULL"));
00348         }
00349         else
00350         {
00351             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
00352                 "Null Handle with relative pathname [%s]", Pathname));
00353         }
00354 
00355         Status = AE_BAD_PARAMETER;
00356     }
00357     else
00358     {
00359         /* We have a namespace a node and a possible relative path */
00360 
00361         Status = AcpiNsEvaluate (Info);
00362     }
00363 
00364     /*
00365      * If we are expecting a return value, and all went well above,
00366      * copy the return value to an external object.
00367      */
00368     if (ReturnBuffer)
00369     {
00370         if (!Info->ReturnObject)
00371         {
00372             ReturnBuffer->Length = 0;
00373         }
00374         else
00375         {
00376             if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
00377                 ACPI_DESC_TYPE_NAMED)
00378             {
00379                 /*
00380                  * If we received a NS Node as a return object, this means that
00381                  * the object we are evaluating has nothing interesting to
00382                  * return (such as a mutex, etc.)  We return an error because
00383                  * these types are essentially unsupported by this interface.
00384                  * We don't check up front because this makes it easier to add
00385                  * support for various types at a later date if necessary.
00386                  */
00387                 Status = AE_TYPE;
00388                 Info->ReturnObject = NULL;   /* No need to delete a NS Node */
00389                 ReturnBuffer->Length = 0;
00390             }
00391 
00392             if (ACPI_SUCCESS (Status))
00393             {
00394                 /* Dereference Index and RefOf references */
00395 
00396                 AcpiNsResolveReferences (Info);
00397 
00398                 /* Get the size of the returned object */
00399 
00400                 Status = AcpiUtGetObjectSize (Info->ReturnObject,
00401                             &BufferSpaceNeeded);
00402                 if (ACPI_SUCCESS (Status))
00403                 {
00404                     /* Validate/Allocate/Clear caller buffer */
00405 
00406                     Status = AcpiUtInitializeBuffer (ReturnBuffer,
00407                                 BufferSpaceNeeded);
00408                     if (ACPI_FAILURE (Status))
00409                     {
00410                         /*
00411                          * Caller's buffer is too small or a new one can't
00412                          * be allocated
00413                          */
00414                         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
00415                             "Needed buffer size %X, %s\n",
00416                             (UINT32) BufferSpaceNeeded,
00417                             AcpiFormatException (Status)));
00418                     }
00419                     else
00420                     {
00421                         /* We have enough space for the object, build it */
00422 
00423                         Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject,
00424                                     ReturnBuffer);
00425                     }
00426                 }
00427             }
00428         }
00429     }
00430 
00431     if (Info->ReturnObject)
00432     {
00433         /*
00434          * Delete the internal return object. NOTE: Interpreter must be
00435          * locked to avoid race condition.
00436          */
00437         AcpiExEnterInterpreter ();
00438 
00439         /* Remove one reference on the return object (should delete it) */
00440 
00441         AcpiUtRemoveReference (Info->ReturnObject);
00442         AcpiExExitInterpreter ();
00443     }
00444 
00445 
00446 Cleanup:
00447 
00448     /* Free the input parameter list (if we created one) */
00449 
00450     if (Info->Parameters)
00451     {
00452         /* Free the allocated parameter block */
00453 
00454         AcpiUtDeleteInternalObjectList (Info->Parameters);
00455     }
00456 
00457     ACPI_FREE (Info);
00458     return_ACPI_STATUS (Status);
00459 }
00460 
00461 ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
00462 
00463 
00464 /*******************************************************************************
00465  *
00466  * FUNCTION:    AcpiNsResolveReferences
00467  *
00468  * PARAMETERS:  Info                    - Evaluation info block
00469  *
00470  * RETURN:      Info->ReturnObject is replaced with the dereferenced object
00471  *
00472  * DESCRIPTION: Dereference certain reference objects. Called before an
00473  *              internal return object is converted to an external ACPI_OBJECT.
00474  *
00475  * Performs an automatic dereference of Index and RefOf reference objects.
00476  * These reference objects are not supported by the ACPI_OBJECT, so this is a
00477  * last resort effort to return something useful. Also, provides compatibility
00478  * with other ACPI implementations.
00479  *
00480  * NOTE: does not handle references within returned package objects or nested
00481  * references, but this support could be added later if found to be necessary.
00482  *
00483  ******************************************************************************/
00484 
00485 static void
00486 AcpiNsResolveReferences (
00487     ACPI_EVALUATE_INFO      *Info)
00488 {
00489     ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
00490     ACPI_NAMESPACE_NODE     *Node;
00491 
00492 
00493     /* We are interested in reference objects only */
00494 
00495     if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
00496     {
00497         return;
00498     }
00499 
00500     /*
00501      * Two types of references are supported - those created by Index and
00502      * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
00503      * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
00504      * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
00505      * an ACPI_OBJECT.
00506      */
00507     switch (Info->ReturnObject->Reference.Class)
00508     {
00509     case ACPI_REFCLASS_INDEX:
00510 
00511         ObjDesc = *(Info->ReturnObject->Reference.Where);
00512         break;
00513 
00514     case ACPI_REFCLASS_REFOF:
00515 
00516         Node = Info->ReturnObject->Reference.Object;
00517         if (Node)
00518         {
00519             ObjDesc = Node->Object;
00520         }
00521         break;
00522 
00523     default:
00524         return;
00525     }
00526 
00527     /* Replace the existing reference object */
00528 
00529     if (ObjDesc)
00530     {
00531         AcpiUtAddReference (ObjDesc);
00532         AcpiUtRemoveReference (Info->ReturnObject);
00533         Info->ReturnObject = ObjDesc;
00534     }
00535 
00536     return;
00537 }
00538 
00539 
00540 /*******************************************************************************
00541  *
00542  * FUNCTION:    AcpiWalkNamespace
00543  *
00544  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
00545  *              StartObject         - Handle in namespace where search begins
00546  *              MaxDepth            - Depth to which search is to reach
00547  *              PreOrderVisit       - Called during tree pre-order visit
00548  *                                    when an object of "Type" is found
00549  *              PostOrderVisit      - Called during tree post-order visit
00550  *                                    when an object of "Type" is found
00551  *              Context             - Passed to user function(s) above
00552  *              ReturnValue         - Location where return value of
00553  *                                    UserFunction is put if terminated early
00554  *
00555  * RETURNS      Return value from the UserFunction if terminated early.
00556  *              Otherwise, returns NULL.
00557  *
00558  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
00559  *              starting (and ending) at the object specified by StartHandle.
00560  *              The callback function is called whenever an object that matches
00561  *              the type parameter is found. If the callback function returns
00562  *              a non-zero value, the search is terminated immediately and this
00563  *              value is returned to the caller.
00564  *
00565  *              The point of this procedure is to provide a generic namespace
00566  *              walk routine that can be called from multiple places to
00567  *              provide multiple services; the callback function(s) can be
00568  *              tailored to each task, whether it is a print function,
00569  *              a compare function, etc.
00570  *
00571  ******************************************************************************/
00572 
00573 ACPI_STATUS
00574 AcpiWalkNamespace (
00575     ACPI_OBJECT_TYPE        Type,
00576     ACPI_HANDLE             StartObject,
00577     UINT32                  MaxDepth,
00578     ACPI_WALK_CALLBACK      PreOrderVisit,
00579     ACPI_WALK_CALLBACK      PostOrderVisit,
00580     void                    *Context,
00581     void                    **ReturnValue)
00582 {
00583     ACPI_STATUS             Status;
00584 
00585 
00586     ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
00587 
00588 
00589     /* Parameter validation */
00590 
00591     if ((Type > ACPI_TYPE_LOCAL_MAX) ||
00592         (!MaxDepth)                  ||
00593         (!PreOrderVisit && !PostOrderVisit))
00594     {
00595         return_ACPI_STATUS (AE_BAD_PARAMETER);
00596     }
00597 
00598     /*
00599      * Need to acquire the namespace reader lock to prevent interference
00600      * with any concurrent table unloads (which causes the deletion of
00601      * namespace objects). We cannot allow the deletion of a namespace node
00602      * while the user function is using it. The exception to this are the
00603      * nodes created and deleted during control method execution -- these
00604      * nodes are marked as temporary nodes and are ignored by the namespace
00605      * walk. Thus, control methods can be executed while holding the
00606      * namespace deletion lock (and the user function can execute control
00607      * methods.)
00608      */
00609     Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
00610     if (ACPI_FAILURE (Status))
00611     {
00612         return (Status);
00613     }
00614 
00615     /*
00616      * Lock the namespace around the walk. The namespace will be
00617      * unlocked/locked around each call to the user function - since the user
00618      * function must be allowed to make ACPICA calls itself (for example, it
00619      * will typically execute control methods during device enumeration.)
00620      */
00621     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
00622     if (ACPI_FAILURE (Status))
00623     {
00624         goto UnlockAndExit;
00625     }
00626 
00627     Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
00628                 ACPI_NS_WALK_UNLOCK, PreOrderVisit,
00629                 PostOrderVisit, Context, ReturnValue);
00630 
00631     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
00632 
00633 UnlockAndExit:
00634     (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
00635     return_ACPI_STATUS (Status);
00636 }
00637 
00638 ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
00639 
00640 
00641 /*******************************************************************************
00642  *
00643  * FUNCTION:    AcpiNsGetDeviceCallback
00644  *
00645  * PARAMETERS:  Callback from AcpiGetDevice
00646  *
00647  * RETURN:      Status
00648  *
00649  * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
00650  *              present devices, or if they specified a HID, it filters based
00651  *              on that.
00652  *
00653  ******************************************************************************/
00654 
00655 static ACPI_STATUS
00656 AcpiNsGetDeviceCallback (
00657     ACPI_HANDLE             ObjHandle,
00658     UINT32                  NestingLevel,
00659     void                    *Context,
00660     void                    **ReturnValue)
00661 {
00662     ACPI_GET_DEVICES_INFO   *Info = Context;
00663     ACPI_STATUS             Status;
00664     ACPI_NAMESPACE_NODE     *Node;
00665     UINT32                  Flags;
00666     ACPI_DEVICE_ID          *Hid;
00667     ACPI_DEVICE_ID_LIST     *Cid;
00668     UINT32                  i;
00669     BOOLEAN                 Found;
00670     int                     NoMatch;
00671 
00672 
00673     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
00674     if (ACPI_FAILURE (Status))
00675     {
00676         return (Status);
00677     }
00678 
00679     Node = AcpiNsValidateHandle (ObjHandle);
00680     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
00681     if (ACPI_FAILURE (Status))
00682     {
00683         return (Status);
00684     }
00685 
00686     if (!Node)
00687     {
00688         return (AE_BAD_PARAMETER);
00689     }
00690 
00691     /*
00692      * First, filter based on the device HID and CID.
00693      *
00694      * 01/2010: For this case where a specific HID is requested, we don't
00695      * want to run _STA until we have an actual HID match. Thus, we will
00696      * not unnecessarily execute _STA on devices for which the caller
00697      * doesn't care about. Previously, _STA was executed unconditionally
00698      * on all devices found here.
00699      *
00700      * A side-effect of this change is that now we will continue to search
00701      * for a matching HID even under device trees where the parent device
00702      * would have returned a _STA that indicates it is not present or
00703      * not functioning (thus aborting the search on that branch).
00704      */
00705     if (Info->Hid != NULL)
00706     {
00707         Status = AcpiUtExecute_HID (Node, &Hid);
00708         if (Status == AE_NOT_FOUND)
00709         {
00710             return (AE_OK);
00711         }
00712         else if (ACPI_FAILURE (Status))
00713         {
00714             return (AE_CTRL_DEPTH);
00715         }
00716 
00717         NoMatch = ACPI_STRCMP (Hid->String, Info->Hid);
00718         ACPI_FREE (Hid);
00719 
00720         if (NoMatch)
00721         {
00722             /*
00723              * HID does not match, attempt match within the
00724              * list of Compatible IDs (CIDs)
00725              */
00726             Status = AcpiUtExecute_CID (Node, &Cid);
00727             if (Status == AE_NOT_FOUND)
00728             {
00729                 return (AE_OK);
00730             }
00731             else if (ACPI_FAILURE (Status))
00732             {
00733                 return (AE_CTRL_DEPTH);
00734             }
00735 
00736             /* Walk the CID list */
00737 
00738             Found = FALSE;
00739             for (i = 0; i < Cid->Count; i++)
00740             {
00741                 if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
00742                 {
00743                     /* Found a matching CID */
00744 
00745                     Found = TRUE;
00746                     break;
00747                 }
00748             }
00749 
00750             ACPI_FREE (Cid);
00751             if (!Found)
00752             {
00753                 return (AE_OK);
00754             }
00755         }
00756     }
00757 
00758     /* Run _STA to determine if device is present */
00759 
00760     Status = AcpiUtExecute_STA (Node, &Flags);
00761     if (ACPI_FAILURE (Status))
00762     {
00763         return (AE_CTRL_DEPTH);
00764     }
00765 
00766     if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
00767         !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
00768     {
00769         /*
00770          * Don't examine the children of the device only when the
00771          * device is neither present nor functional. See ACPI spec,
00772          * description of _STA for more information.
00773          */
00774         return (AE_CTRL_DEPTH);
00775     }
00776 
00777     /* We have a valid device, invoke the user function */
00778 
00779     Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
00780                 ReturnValue);
00781     return (Status);
00782 }
00783 
00784 
00785 /*******************************************************************************
00786  *
00787  * FUNCTION:    AcpiGetDevices
00788  *
00789  * PARAMETERS:  HID                 - HID to search for. Can be NULL.
00790  *              UserFunction        - Called when a matching object is found
00791  *              Context             - Passed to user function
00792  *              ReturnValue         - Location where return value of
00793  *                                    UserFunction is put if terminated early
00794  *
00795  * RETURNS      Return value from the UserFunction if terminated early.
00796  *              Otherwise, returns NULL.
00797  *
00798  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
00799  *              starting (and ending) at the object specified by StartHandle.
00800  *              The UserFunction is called whenever an object of type
00801  *              Device is found.  If the user function returns
00802  *              a non-zero value, the search is terminated immediately and this
00803  *              value is returned to the caller.
00804  *
00805  *              This is a wrapper for WalkNamespace, but the callback performs
00806  *              additional filtering. Please see AcpiNsGetDeviceCallback.
00807  *
00808  ******************************************************************************/
00809 
00810 ACPI_STATUS
00811 AcpiGetDevices (
00812     char                    *HID,
00813     ACPI_WALK_CALLBACK      UserFunction,
00814     void                    *Context,
00815     void                    **ReturnValue)
00816 {
00817     ACPI_STATUS             Status;
00818     ACPI_GET_DEVICES_INFO   Info;
00819 
00820 
00821     ACPI_FUNCTION_TRACE (AcpiGetDevices);
00822 
00823 
00824     /* Parameter validation */
00825 
00826     if (!UserFunction)
00827     {
00828         return_ACPI_STATUS (AE_BAD_PARAMETER);
00829     }
00830 
00831     /*
00832      * We're going to call their callback from OUR callback, so we need
00833      * to know what it is, and their context parameter.
00834      */
00835     Info.Hid          = HID;
00836     Info.Context      = Context;
00837     Info.UserFunction = UserFunction;
00838 
00839     /*
00840      * Lock the namespace around the walk.
00841      * The namespace will be unlocked/locked around each call
00842      * to the user function - since this function
00843      * must be allowed to make Acpi calls itself.
00844      */
00845     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
00846     if (ACPI_FAILURE (Status))
00847     {
00848         return_ACPI_STATUS (Status);
00849     }
00850 
00851     Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
00852                 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
00853                 AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
00854 
00855     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
00856     return_ACPI_STATUS (Status);
00857 }
00858 
00859 ACPI_EXPORT_SYMBOL (AcpiGetDevices)
00860 
00861 
00862 /*******************************************************************************
00863  *
00864  * FUNCTION:    AcpiAttachData
00865  *
00866  * PARAMETERS:  ObjHandle           - Namespace node
00867  *              Handler             - Handler for this attachment
00868  *              Data                - Pointer to data to be attached
00869  *
00870  * RETURN:      Status
00871  *
00872  * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
00873  *
00874  ******************************************************************************/
00875 
00876 ACPI_STATUS
00877 AcpiAttachData (
00878     ACPI_HANDLE             ObjHandle,
00879     ACPI_OBJECT_HANDLER     Handler,
00880     void                    *Data)
00881 {
00882     ACPI_NAMESPACE_NODE     *Node;
00883     ACPI_STATUS             Status;
00884 
00885 
00886     /* Parameter validation */
00887 
00888     if (!ObjHandle  ||
00889         !Handler    ||
00890         !Data)
00891     {
00892         return (AE_BAD_PARAMETER);
00893     }
00894 
00895     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
00896     if (ACPI_FAILURE (Status))
00897     {
00898         return (Status);
00899     }
00900 
00901     /* Convert and validate the handle */
00902 
00903     Node = AcpiNsValidateHandle (ObjHandle);
00904     if (!Node)
00905     {
00906         Status = AE_BAD_PARAMETER;
00907         goto UnlockAndExit;
00908     }
00909 
00910     Status = AcpiNsAttachData (Node, Handler, Data);
00911 
00912 UnlockAndExit:
00913     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
00914     return (Status);
00915 }
00916 
00917 ACPI_EXPORT_SYMBOL (AcpiAttachData)
00918 
00919 
00920 /*******************************************************************************
00921  *
00922  * FUNCTION:    AcpiDetachData
00923  *
00924  * PARAMETERS:  ObjHandle           - Namespace node handle
00925  *              Handler             - Handler used in call to AcpiAttachData
00926  *
00927  * RETURN:      Status
00928  *
00929  * DESCRIPTION: Remove data that was previously attached to a node.
00930  *
00931  ******************************************************************************/
00932 
00933 ACPI_STATUS
00934 AcpiDetachData (
00935     ACPI_HANDLE             ObjHandle,
00936     ACPI_OBJECT_HANDLER     Handler)
00937 {
00938     ACPI_NAMESPACE_NODE     *Node;
00939     ACPI_STATUS             Status;
00940 
00941 
00942     /* Parameter validation */
00943 
00944     if (!ObjHandle  ||
00945         !Handler)
00946     {
00947         return (AE_BAD_PARAMETER);
00948     }
00949 
00950     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
00951     if (ACPI_FAILURE (Status))
00952     {
00953         return (Status);
00954     }
00955 
00956     /* Convert and validate the handle */
00957 
00958     Node = AcpiNsValidateHandle (ObjHandle);
00959     if (!Node)
00960     {
00961         Status = AE_BAD_PARAMETER;
00962         goto UnlockAndExit;
00963     }
00964 
00965     Status = AcpiNsDetachData (Node, Handler);
00966 
00967 UnlockAndExit:
00968     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
00969     return (Status);
00970 }
00971 
00972 ACPI_EXPORT_SYMBOL (AcpiDetachData)
00973 
00974 
00975 /*******************************************************************************
00976  *
00977  * FUNCTION:    AcpiGetData
00978  *
00979  * PARAMETERS:  ObjHandle           - Namespace node
00980  *              Handler             - Handler used in call to AttachData
00981  *              Data                - Where the data is returned
00982  *
00983  * RETURN:      Status
00984  *
00985  * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
00986  *
00987  ******************************************************************************/
00988 
00989 ACPI_STATUS
00990 AcpiGetData (
00991     ACPI_HANDLE             ObjHandle,
00992     ACPI_OBJECT_HANDLER     Handler,
00993     void                    **Data)
00994 {
00995     ACPI_NAMESPACE_NODE     *Node;
00996     ACPI_STATUS             Status;
00997 
00998 
00999     /* Parameter validation */
01000 
01001     if (!ObjHandle  ||
01002         !Handler    ||
01003         !Data)
01004     {
01005         return (AE_BAD_PARAMETER);
01006     }
01007 
01008     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
01009     if (ACPI_FAILURE (Status))
01010     {
01011         return (Status);
01012     }
01013 
01014     /* Convert and validate the handle */
01015 
01016     Node = AcpiNsValidateHandle (ObjHandle);
01017     if (!Node)
01018     {
01019         Status = AE_BAD_PARAMETER;
01020         goto UnlockAndExit;
01021     }
01022 
01023     Status = AcpiNsGetAttachedData (Node, Handler, Data);
01024 
01025 UnlockAndExit:
01026     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
01027     return (Status);
01028 }
01029 
01030 ACPI_EXPORT_SYMBOL (AcpiGetData)
01031 
01032 

Generated on Sun May 27 2012 04:27:21 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.