Print this page
update to acpica-unix2-20140114
update to acpica-unix2-20131218
update to acpica-unix2-20130927
acpica-unix2-20130823
PANKOVs restructure

@@ -4,11 +4,11 @@
  *                         ACPI Object evaluation interfaces
  *
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2011, Intel Corp.
+ * Copyright (C) 2000 - 2014, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:

@@ -42,10 +42,11 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
 
 #define __NSXFEVAL_C__
+#define EXPORT_ACPI_INTERFACES
 
 #include "acpi.h"
 #include "accommon.h"
 #include "acnamesp.h"
 #include "acinterp.h"

@@ -89,11 +90,11 @@
     ACPI_OBJECT_LIST        *ExternalParams,
     ACPI_BUFFER             *ReturnBuffer,
     ACPI_OBJECT_TYPE        ReturnType)
 {
     ACPI_STATUS             Status;
-    BOOLEAN                 MustFree = FALSE;
+    BOOLEAN                 FreeBufferOnError = FALSE;
 
 
     ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
 
 

@@ -104,16 +105,17 @@
         return_ACPI_STATUS (AE_BAD_PARAMETER);
     }
 
     if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
     {
-        MustFree = TRUE;
+        FreeBufferOnError = TRUE;
     }
 
     /* Evaluate the object */
 
-    Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
+    Status = AcpiEvaluateObject (Handle, Pathname,
+        ExternalParams, ReturnBuffer);
     if (ACPI_FAILURE (Status))
     {
         return_ACPI_STATUS (Status);
     }
 

@@ -144,14 +146,19 @@
     ACPI_ERROR ((AE_INFO,
         "Incorrect return type [%s] requested [%s]",
         AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
         AcpiUtGetTypeName (ReturnType)));
 
-    if (MustFree)
+    if (FreeBufferOnError)
     {
-        /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
-
+        /*
+         * Free a buffer created via ACPI_ALLOCATE_BUFFER.
+         * Note: We use AcpiOsFree here because AcpiOsAllocate was used
+         * to allocate the buffer. This purposefully bypasses the
+         * (optionally enabled) allocation tracking mechanism since we
+         * only want to track internal allocations.
+         */
         AcpiOsFree (ReturnBuffer->Pointer);
         ReturnBuffer->Pointer = NULL;
     }
 
     ReturnBuffer->Length = 0;

@@ -203,12 +210,10 @@
     if (!Info)
     {
         return_ACPI_STATUS (AE_NO_MEMORY);
     }
 
-    Info->Pathname = Pathname;
-
     /* Convert and validate the device handle */
 
     Info->PrefixNode = AcpiNsValidateHandle (Handle);
     if (!Info->PrefixNode)
     {

@@ -215,81 +220,184 @@
         Status = AE_BAD_PARAMETER;
         goto Cleanup;
     }
 
     /*
-     * If there are parameters to be passed to a control method, the external
-     * objects must all be converted to internal objects
+     * Get the actual namespace node for the target object.
+     * Handles these cases:
+     *
+     * 1) Null node, valid pathname from root (absolute path)
+     * 2) Node and valid pathname (path relative to Node)
+     * 3) Node, Null pathname
      */
+    if ((Pathname) &&
+        (ACPI_IS_ROOT_PREFIX (Pathname[0])))
+    {
+        /* The path is fully qualified, just evaluate by name */
+
+        Info->PrefixNode = NULL;
+    }
+    else if (!Handle)
+    {
+        /*
+         * A handle is optional iff a fully qualified pathname is specified.
+         * Since we've already handled fully qualified names above, this is
+         * an error.
+         */
+        if (!Pathname)
+        {
+            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+                "Both Handle and Pathname are NULL"));
+        }
+        else
+        {
+            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+                "Null Handle with relative pathname [%s]", Pathname));
+        }
+
+        Status = AE_BAD_PARAMETER;
+        goto Cleanup;
+    }
+
+    Info->RelativePathname = Pathname;
+
+    /*
+     * Convert all external objects passed as arguments to the
+     * internal version(s).
+     */
     if (ExternalParams && ExternalParams->Count)
     {
+        Info->ParamCount = (UINT16) ExternalParams->Count;
+
+        /* Warn on impossible argument count */
+
+        if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
+        {
+            ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+                "Excess arguments (%u) - using only %u",
+                Info->ParamCount, ACPI_METHOD_NUM_ARGS));
+
+            Info->ParamCount = ACPI_METHOD_NUM_ARGS;
+        }
+
         /*
          * Allocate a new parameter block for the internal objects
          * Add 1 to count to allow for null terminated internal list
          */
         Info->Parameters = ACPI_ALLOCATE_ZEROED (
-            ((ACPI_SIZE) ExternalParams->Count + 1) * sizeof (void *));
+            ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
         if (!Info->Parameters)
         {
             Status = AE_NO_MEMORY;
             goto Cleanup;
         }
 
         /* Convert each external object in the list to an internal object */
 
-        for (i = 0; i < ExternalParams->Count; i++)
+        for (i = 0; i < Info->ParamCount; i++)
         {
             Status = AcpiUtCopyEobjectToIobject (
                         &ExternalParams->Pointer[i], &Info->Parameters[i]);
             if (ACPI_FAILURE (Status))
             {
                 goto Cleanup;
             }
         }
-        Info->Parameters[ExternalParams->Count] = NULL;
+
+        Info->Parameters[Info->ParamCount] = NULL;
     }
 
+
+#if 0
+
     /*
-     * Three major cases:
-     * 1) Fully qualified pathname
-     * 2) No handle, not fully qualified pathname (error)
-     * 3) Valid handle
+     * Begin incoming argument count analysis. Check for too few args
+     * and too many args.
      */
-    if ((Pathname) &&
-        (AcpiNsValidRootPrefix (Pathname[0])))
+
+    switch (AcpiNsGetType (Info->Node))
     {
-        /* The path is fully qualified, just evaluate by name */
+    case ACPI_TYPE_METHOD:
 
-        Info->PrefixNode = NULL;
-        Status = AcpiNsEvaluate (Info);
+        /* Check incoming argument count against the method definition */
+
+        if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)
+        {
+            ACPI_ERROR ((AE_INFO,
+                "Insufficient arguments (%u) - %u are required",
+                Info->ParamCount,
+                Info->ObjDesc->Method.ParamCount));
+
+            Status = AE_MISSING_ARGUMENTS;
+            goto Cleanup;
     }
-    else if (!Handle)
+
+        else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)
     {
+            ACPI_WARNING ((AE_INFO,
+                "Excess arguments (%u) - only %u are required",
+                Info->ParamCount,
+                Info->ObjDesc->Method.ParamCount));
+
+            /* Just pass the required number of arguments */
+
+            Info->ParamCount = Info->ObjDesc->Method.ParamCount;
+        }
+
         /*
-         * A handle is optional iff a fully qualified pathname is specified.
-         * Since we've already handled fully qualified names above, this is
-         * an error
+         * Any incoming external objects to be passed as arguments to the
+         * method must be converted to internal objects
          */
-        if (!Pathname)
+        if (Info->ParamCount)
         {
-            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-                "Both Handle and Pathname are NULL"));
+            /*
+             * Allocate a new parameter block for the internal objects
+             * Add 1 to count to allow for null terminated internal list
+             */
+            Info->Parameters = ACPI_ALLOCATE_ZEROED (
+                ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
+            if (!Info->Parameters)
+            {
+                Status = AE_NO_MEMORY;
+                goto Cleanup;
         }
-        else
+
+            /* Convert each external object in the list to an internal object */
+
+            for (i = 0; i < Info->ParamCount; i++)
         {
-            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-                "Null Handle with relative pathname [%s]", Pathname));
+                Status = AcpiUtCopyEobjectToIobject (
+                    &ExternalParams->Pointer[i], &Info->Parameters[i]);
+                if (ACPI_FAILURE (Status))
+                {
+                    goto Cleanup;
         }
+            }
 
-        Status = AE_BAD_PARAMETER;
+            Info->Parameters[Info->ParamCount] = NULL;
     }
-    else
+        break;
+
+    default:
+
+        /* Warn if arguments passed to an object that is not a method */
+
+        if (Info->ParamCount)
     {
-        /* We have a namespace a node and a possible relative path */
+            ACPI_WARNING ((AE_INFO,
+                "%u arguments were passed to a non-method ACPI object",
+                Info->ParamCount));
+        }
+        break;
+    }
 
+#endif
+
+
+    /* Now we can evaluate the object */
+
         Status = AcpiNsEvaluate (Info);
-    }
 
     /*
      * If we are expecting a return value, and all went well above,
      * copy the return value to an external object.
      */

@@ -447,10 +555,11 @@
             ObjDesc = Node->Object;
         }
         break;
 
     default:
+
         return;
     }
 
     /* Replace the existing reference object */
 

@@ -470,13 +579,13 @@
  * FUNCTION:    AcpiWalkNamespace
  *
  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
  *              StartObject         - Handle in namespace where search begins
  *              MaxDepth            - Depth to which search is to reach
- *              PreOrderVisit       - Called during tree pre-order visit
+ *              DescendingCallback  - Called during tree descent
  *                                    when an object of "Type" is found
- *              PostOrderVisit      - Called during tree post-order visit
+ *              AscendingCallback   - Called during tree ascent
  *                                    when an object of "Type" is found
  *              Context             - Passed to user function(s) above
  *              ReturnValue         - Location where return value of
  *                                    UserFunction is put if terminated early
  *

@@ -501,12 +610,12 @@
 ACPI_STATUS
 AcpiWalkNamespace (
     ACPI_OBJECT_TYPE        Type,
     ACPI_HANDLE             StartObject,
     UINT32                  MaxDepth,
-    ACPI_WALK_CALLBACK      PreOrderVisit,
-    ACPI_WALK_CALLBACK      PostOrderVisit,
+    ACPI_WALK_CALLBACK      DescendingCallback,
+    ACPI_WALK_CALLBACK      AscendingCallback,
     void                    *Context,
     void                    **ReturnValue)
 {
     ACPI_STATUS             Status;
 

@@ -516,11 +625,11 @@
 
     /* Parameter validation */
 
     if ((Type > ACPI_TYPE_LOCAL_MAX) ||
         (!MaxDepth)                  ||
-        (!PreOrderVisit && !PostOrderVisit))
+        (!DescendingCallback && !AscendingCallback))
     {
         return_ACPI_STATUS (AE_BAD_PARAMETER);
     }
 
     /*

@@ -535,11 +644,11 @@
      * methods.)
      */
     Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
     if (ACPI_FAILURE (Status))
     {
-        return (Status);
+        return_ACPI_STATUS (Status);
     }
 
     /*
      * Lock the namespace around the walk. The namespace will be
      * unlocked/locked around each call to the user function - since the user

@@ -550,14 +659,23 @@
     if (ACPI_FAILURE (Status))
     {
         goto UnlockAndExit;
     }
 
+    /* Now we can validate the starting node */
+
+    if (!AcpiNsValidateHandle (StartObject))
+    {
+        Status = AE_BAD_PARAMETER;
+        goto UnlockAndExit2;
+    }
+
     Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
-                ACPI_NS_WALK_UNLOCK, PreOrderVisit,
-                PostOrderVisit, Context, ReturnValue);
+                ACPI_NS_WALK_UNLOCK, DescendingCallback,
+                AscendingCallback, Context, ReturnValue);
 
+UnlockAndExit2:
     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
 
 UnlockAndExit:
     (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
     return_ACPI_STATUS (Status);

@@ -589,12 +707,12 @@
 {
     ACPI_GET_DEVICES_INFO   *Info = Context;
     ACPI_STATUS             Status;
     ACPI_NAMESPACE_NODE     *Node;
     UINT32                  Flags;
-    ACPI_DEVICE_ID          *Hid;
-    ACPI_DEVICE_ID_LIST     *Cid;
+    ACPI_PNP_DEVICE_ID      *Hid;
+    ACPI_PNP_DEVICE_ID_LIST *Cid;
     UINT32                  i;
     BOOLEAN                 Found;
     int                     NoMatch;
 
 

@@ -954,7 +1072,5 @@
     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
     return (Status);
 }
 
 ACPI_EXPORT_SYMBOL (AcpiGetData)
-
-