Added type info to TBDs

date	2000.06.06.22.25.00;	author rmoore1;	state Exp;
This commit is contained in:
aystarik 2005-06-29 18:33:21 +00:00
parent 6bacf67731
commit ab17c45beb
4 changed files with 962 additions and 548 deletions

View File

@ -151,7 +151,7 @@ ACPI_STATUS
NsSearchOneScope (
UINT32 EntryName,
NAME_TABLE_ENTRY *NameTable,
ACPI_OBJECT_TYPE Type,
OBJECT_TYPE_INTERNAL Type,
NAME_TABLE_ENTRY **RetEntry,
NS_SEARCH_DATA *RetInfo)
{
@ -326,7 +326,7 @@ ACPI_STATUS
NsSearchParentTree (
UINT32 EntryName,
NAME_TABLE_ENTRY *NameTable,
ACPI_OBJECT_TYPE Type,
OBJECT_TYPE_INTERNAL Type,
NAME_TABLE_ENTRY **RetEntry)
{
ACPI_STATUS Status;
@ -355,7 +355,7 @@ NsSearchParentTree (
while (ParentEntry)
{
/* Search parent scope */
/* TBD: Why ACPI_TYPE_Any? */
/* TBD: [Investigate] Why ACPI_TYPE_Any? */
Status = NsSearchOneScope (EntryName, ParentEntry->Scope, ACPI_TYPE_Any, RetEntry, NULL);
if (Status == AE_OK)
@ -522,7 +522,7 @@ NsInitializeEntry (
NAME_TABLE_ENTRY *NameTable,
UINT32 Position,
UINT32 EntryName,
ACPI_OBJECT_TYPE Type,
OBJECT_TYPE_INTERNAL Type,
NAME_TABLE_ENTRY *PreviousEntry)
{
NAME_TABLE_ENTRY *NewEntry;
@ -648,7 +648,7 @@ NsSearchAndEnter (
ACPI_WALK_STATE *WalkState,
NAME_TABLE_ENTRY *NameTable,
OPERATING_MODE InterpreterMode,
ACPI_OBJECT_TYPE Type,
OBJECT_TYPE_INTERNAL Type,
UINT32 Flags,
NAME_TABLE_ENTRY **RetEntry)
{

View File

@ -27,7 +27,7 @@
* Code in any form, with the right to sublicense such rights; and
*
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
* license (without the right to sublicense), under only those claims of Intel
* license (with the right to sublicense), under only those claims of Intel
* patents that are infringed by the Original Intel Code, to make, use, sell,
* offer to sell, and import the Covered Code and derivative works thereof
* solely to the minimum extent necessary to exercise the above copyright
@ -117,102 +117,59 @@
#define __NSUTILS_C__
#include <acpi.h>
#include <namespace.h>
#include <interpreter.h>
#include <namesp.h>
#include <interp.h>
#include <amlcode.h>
#include <tables.h>
#define _THIS_MODULE "nsutils.c"
#define _COMPONENT NAMESPACE
MODULE_NAME ("nsutils");
/******************************************************************************
/****************************************************************************
*
* FUNCTION: NsChecksum
* FUNCTION: NsValidRootPrefix
*
* PARAMETERS: Buffer - Buffer to checksum
* Length - Size of the buffer
* PARAMETERS: Prefix - Character to be checked
*
* RETURNS 8 bit checksum of buffer
* RETURN: TRUE if a valid prefix
*
* DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
* DESCRIPTION: Check if a character is a valid ACPI Root prefix
*
******************************************************************************/
***************************************************************************/
UINT8
NsChecksum (
void *Buffer,
UINT32 Length)
BOOLEAN
NsValidRootPrefix (
char Prefix)
{
UINT8 *limit;
UINT8 *rover;
UINT8 sum = 0;
if (Buffer && Length)
{
/* Buffer and Length are valid */
limit = (UINT8 *) Buffer + Length;
for (rover = Buffer; rover < limit; rover++)
sum += *rover;
}
return sum;
return ((BOOLEAN) (Prefix == '\\'));
}
/****************************************************************************
*
* FUNCTION: NsAllocateNteDesc
* FUNCTION: NsValidPathSeparator
*
* PARAMETERS: NteCount - Count of NTEs to allocate
* PARAMETERS: Sep - Character to be checked
*
* DESCRIPTION: Allocate an array of nte, including prepended link space
* Array is set to all zeros via OsdCallcate().
* RETURN: TRUE if a valid path separator
*
* RETURN: The address of the first nte in the array, or NULL
* DESCRIPTION: Check if a character is a valid ACPI path separator
*
***************************************************************************/
NAME_TABLE_ENTRY *
NsAllocateNteDesc (
INT32 NteCount)
BOOLEAN
NsValidPathSeparator (
char Sep)
{
NAME_TABLE_ENTRY *NewNteDesc = NULL;
ACPI_SIZE AllocSize;
FUNCTION_TRACE ("AllocateNteDesc");
AllocSize = (ACPI_SIZE) NteCount * sizeof (NAME_TABLE_ENTRY);
/* Allow room for link to appendage */
AllocSize += sizeof (NAME_TABLE_ENTRY *);
NewNteDesc = LocalCallocate (AllocSize);
if (NewNteDesc)
{
/* Move past the appendage pointer */
NewNteDesc = (NAME_TABLE_ENTRY *) (((UINT8 *) NewNteDesc) +
sizeof (NAME_TABLE_ENTRY *));
}
DEBUG_PRINT (TRACE_EXEC, ("AllocateNteDesc: NewNteDesc=%p\n", NewNteDesc));
FUNCTION_EXIT;
return NewNteDesc;
return ((BOOLEAN) (Sep == '.'));
}
/****************************************************************************
*
* FUNCTION: NsGetType
@ -223,7 +180,7 @@ NsAllocateNteDesc (
*
***************************************************************************/
ACPI_OBJECT_TYPE
OBJECT_TYPE_INTERNAL
NsGetType (
ACPI_HANDLE handle)
{
@ -235,70 +192,10 @@ NsGetType (
/* Handle invalid */
REPORT_WARNING ("NsGetType: Null handle");
FUNCTION_EXIT;
return TYPE_Any;
return_VALUE (ACPI_TYPE_Any);
}
FUNCTION_EXIT;
return ((NAME_TABLE_ENTRY *) handle)->Type;
}
/****************************************************************************
*
* FUNCTION: NsGetValue
*
* PARAMETERS: Handle - Handle of nte to be examined
*
* RETURN: Value field from nte whose handle is passed
*
***************************************************************************/
void *
NsGetValue (
ACPI_HANDLE handle)
{
FUNCTION_TRACE ("NsGetValue");
if (!handle)
{
/* handle invalid */
REPORT_WARNING ("NsGetValue: Null handle");
FUNCTION_EXIT;
return NULL;
}
FUNCTION_EXIT;
return ((NAME_TABLE_ENTRY *) handle)->Value;
}
/*****************************************************************************
*
* FUNCTION: IsNsValue
*
* PARAMETERS: *ObjDesc - An object descriptor
*
* RETURN: TRUE if the passed descriptor is the value of a Name in
* the name space, else FALSE
*
****************************************************************************/
INT32
IsNsValue (
ACPI_OBJECT_INTERNAL *ObjDesc)
{
ACPI_HANDLE RetHandle;
FUNCTION_TRACE ("IsNsValue");
RetHandle = NsFindValue (ObjDesc, NS_ALL, ACPI_INT_MAX);
FUNCTION_EXIT;
return (RetHandle != (ACPI_HANDLE) 0);
return_VALUE (((NAME_TABLE_ENTRY *) handle)->Type);
}
@ -315,30 +212,30 @@ IsNsValue (
INT32
NsLocal (
ACPI_OBJECT_TYPE Type)
OBJECT_TYPE_INTERNAL Type)
{
FUNCTION_TRACE ("NsLocal");
if (OUTRANGE (Type, NsProperties))
if (!CmValidObjectType (Type))
{
/* type code out of range */
REPORT_WARNING ("NsLocal: Type code out of range");
FUNCTION_EXIT;
return 0;
REPORT_WARNING ("NsLocal: Invalid Object Type");
return_VALUE (NSP_NORMAL);
}
FUNCTION_EXIT;
return NsProperties[Type] & LOCAL;
return_VALUE ((INT32) Gbl_NsProperties[Type] & NSP_LOCAL);
}
/****************************************************************************
*
* FUNCTION: NsInternalizeName
*
* PARAMETERS: *DottedName - External representation of name
* PARAMETERS: *ExternalName - External representation of name
* **Converted Name - Where to return the resulting
* internal represention of the name
*
@ -351,22 +248,24 @@ NsLocal (
ACPI_STATUS
NsInternalizeName (
char *DottedName,
char *ExternalName,
char **ConvertedName)
{
char *Result = NULL;
char *InternalName;
ACPI_SIZE i;
ACPI_SIZE NumSegments;
BOOLEAN FullyQualified = FALSE;
UINT32 i;
FUNCTION_TRACE ("NsInternalizeName");
if (!DottedName || !ConvertedName)
if ((!ExternalName) ||
(*ExternalName == 0) ||
(!ConvertedName))
{
FUNCTION_STATUS_EXIT (AE_BAD_PARAMETER);
return AE_BAD_PARAMETER;
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
@ -378,19 +277,36 @@ NsInternalizeName (
* strlen() + 1 covers the first NameSeg, which has no path separator
*/
if (DottedName[0] == '\\')
if (NsValidRootPrefix (ExternalName[0]))
{
FullyQualified = TRUE;
DottedName++;
ExternalName++;
}
i = (strlen (DottedName) + 1) / PATH_SEGMENT_LENGTH; /* i = number of NameSegs in the path */
InternalName = LocalCallocate ((ACPI_NAME_SIZE * i) + 4);
/*
* Determine the number of ACPI name "segments" by counting the number
* of path separators within the string. Start with one segment since
* the segment count is (# separators) + 1, and zero separators is ok.
*/
NumSegments = 1;
for (i = 0; ExternalName[i]; i++)
{
if (NsValidPathSeparator (ExternalName[i]))
{
NumSegments++;
}
}
/* We need a segment to store the internal version of the name */
InternalName = CmCallocate ((ACPI_NAME_SIZE * NumSegments) + 4);
if (!InternalName)
{
FUNCTION_STATUS_EXIT (AE_NO_MEMORY);
return AE_NO_MEMORY;
return_ACPI_STATUS (AE_NO_MEMORY);
}
@ -400,30 +316,60 @@ NsInternalizeName (
{
InternalName[0] = '\\';
InternalName[1] = AML_MultiNamePrefixOp;
InternalName[2] = i;
InternalName[2] = (char) NumSegments;
Result = &InternalName[3];
}
else
{
InternalName[0] = AML_MultiNamePrefixOp;
InternalName[1] = i;
InternalName[1] = (char) NumSegments;
Result = &InternalName[2];
}
/* Build the name (minus path separators) */
for (; i; i--)
for (; NumSegments; NumSegments--)
{
strncpy (Result, DottedName, ACPI_NAME_SIZE);
for (i = 0; i < ACPI_NAME_SIZE; i++) //STRNCPY (Result, ExternalName, ACPI_NAME_SIZE);
{
if (NsValidPathSeparator (*ExternalName) ||
(*ExternalName == 0))
{
/* Pad the segment with underscore(s) if segment is short */
Result[i] = '_';
}
else
{
/* Convert char to uppercase and save it */
Result[i] = (char) TOUPPER (*ExternalName);
ExternalName++;
}
}
/* Now we must have a path separator, or the pathname is bad */
if (!NsValidPathSeparator (*ExternalName) &&
(*ExternalName != 0))
{
CmFree (InternalName);
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Move on the next segment */
ExternalName++;
Result += ACPI_NAME_SIZE;
DottedName += PATH_SEGMENT_LENGTH;
}
/* Return the completed name */
*Result = '\0'; /* Terminate the string! */
*Result = 0; /* Terminate the string! */
*ConvertedName = InternalName;
@ -438,8 +384,164 @@ NsInternalizeName (
InternalName, &InternalName[2]));
}
FUNCTION_STATUS_EXIT (AE_OK);
return AE_OK;
return_ACPI_STATUS (AE_OK);
}
/****************************************************************************
*
* FUNCTION: NsExternalizeName
*
* PARAMETERS: *InternalName - Internal representation of name
* **ConvertedName - Where to return the resulting
* external representation of name
*
* RETURN: Status
*
* DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
* to its external form (e.g. "\_PR_.CPU0")
*
****************************************************************************/
ACPI_STATUS
NsExternalizeName (
UINT32 InternalNameLength,
char *InternalName,
UINT32 *ConvertedNameLength,
char **ConvertedName)
{
UINT32 PrefixLength = 0;
UINT32 NamesIndex = 0;
UINT32 NamesCount = 0;
UINT32 i = 0;
UINT32 j = 0;
FUNCTION_TRACE ("NsExternalizeName");
if (InternalNameLength < 0 || !InternalName || !ConvertedNameLength || !ConvertedName)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* Check for a prefix (one '\' | one or more '^').
*/
switch (InternalName[0])
{
case '\\':
PrefixLength = 1;
break;
case '^':
for (i = 0; i < InternalNameLength; i++)
{
if (InternalName[i] != '^')
{
PrefixLength = i + 1;
}
}
if (i == InternalNameLength)
{
PrefixLength = i;
}
break;
}
/*
* Check for object names. Note that there could be 0-255 of these
* 4-byte elements.
*/
if (PrefixLength < InternalNameLength)
{
switch (InternalName[PrefixLength])
{
/* <count> 4-byte names */
case AML_MultiNamePrefixOp:
NamesIndex = PrefixLength + 2;
NamesCount = (UINT32) InternalName[PrefixLength + 1];
break;
/* two 4-byte names */
case AML_DualNamePrefix:
NamesIndex = PrefixLength + 1;
NamesCount = 2;
break;
/* NullName */
case 0:
NamesIndex = 0;
NamesCount = 0;
break;
/* one 4-byte name */
default:
NamesIndex = PrefixLength;
NamesCount = 1;
break;
}
}
/*
* Calculate the length of ConvertedName, which equals the length
* of the prefix, length of all object names, length of any required
* punctuation ('.') between object names, plus the NULL terminator.
*/
*ConvertedNameLength = PrefixLength + (4 * NamesCount) + ((NamesCount > 0) ? (NamesCount - 1) : 0) + 1;
/*
* Check to see if we're still in bounds. If not, there's a problem
* with InternalName (invalid format).
*/
if (*ConvertedNameLength > InternalNameLength)
{
REPORT_ERROR ("NsExternalizeName: Invalid internal name.\n");
return_ACPI_STATUS (AE_BAD_PATHNAME);
}
/*
* Build ConvertedName...
*/
(*ConvertedName) = CmCallocate (*ConvertedNameLength);
if (!(*ConvertedName))
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
j = 0;
for (i = 0; i < PrefixLength; i++)
{
(*ConvertedName)[j++] = InternalName[i];
}
if (NamesCount > 0)
{
for (i = 0; i < NamesCount; i++)
{
if (i > 0)
{
(*ConvertedName)[j++] = '.';
}
(*ConvertedName)[j++] = InternalName[NamesIndex++];
(*ConvertedName)[j++] = InternalName[NamesIndex++];
(*ConvertedName)[j++] = InternalName[NamesIndex++];
(*ConvertedName)[j++] = InternalName[NamesIndex++];
}
}
return_ACPI_STATUS (AE_OK);
}
@ -462,7 +564,7 @@ NsConvertHandleToEntry (
/*
* Simple implementation for now;
* TBD: Real integer handles allow for more verification
* TBD: [Future] Real integer handles allow for more verification
* and keep all pointers within this subsystem!
*/
@ -471,6 +573,126 @@ NsConvertHandleToEntry (
return NULL;
}
if (Handle == ACPI_ROOT_OBJECT)
{
return Gbl_RootObject;
}
/* We can at least attempt to verify the handle */
if (!VALID_DESCRIPTOR_TYPE (Handle, DESC_TYPE_NTE))
{
return NULL;
}
return (NAME_TABLE_ENTRY *) Handle;
}
/****************************************************************************
*
* FUNCTION: NsConvertEntryToHandle
*
* PARAMETERS: Nte - NTE to be converted to a Handle
*
* RETURN: An USER ACPI_HANDLE
*
* DESCRIPTION: Convert a real NTE to a namespace handle
*
****************************************************************************/
ACPI_HANDLE
NsConvertEntryToHandle(NAME_TABLE_ENTRY *Nte)
{
/*
* Simple implementation for now;
* TBD: [Future] Real integer handles allow for more verification
* and keep all pointers within this subsystem!
*/
return (ACPI_HANDLE) Nte;
/* ---------------------------------------------------
if (!Nte)
{
return NULL;
}
if (Nte == Gbl_RootObject)
{
return ACPI_ROOT_OBJECT;
}
return (ACPI_HANDLE) Nte;
------------------------------------------------------*/
}
/******************************************************************************
*
* FUNCTION: NsTerminate
*
* PARAMETERS: none
*
* RETURN: none
*
* DESCRIPTION: free memory allocated for table storage.
*
******************************************************************************/
void
NsTerminate (void)
{
ACPI_OBJECT_INTERNAL *ObjDesc;
NAME_TABLE_ENTRY *Entry;
FUNCTION_TRACE ("NsTerminate");
Entry = Gbl_RootObject;
/*
* 1) Free the entire namespace -- all objects, tables, and stacks
*/
/* Delete all objects linked to the root (additional table descriptors) */
NsDeleteNamespaceSubtree (Entry);
/* Detach any object(s) attached to the root */
ObjDesc = NsGetAttachedObject (Entry);
if (ObjDesc)
{
NsDetachObject (Entry);
CmRemoveReference (ObjDesc);
}
NsDeleteScope (Entry->Scope);
Entry->Scope = NULL;
REPORT_SUCCESS ("Entire namespace and objects deleted");
DEBUG_PRINT (ACPI_INFO, ("NsTerminate: Namespace freed\n"));
/*
* 2) Now we can delete the ACPI tables
*/
TbDeleteAcpiTables ();
DEBUG_PRINT (ACPI_INFO, ("NsTerminate: ACPI Tables freed\n"));
return_VOID;
}

View File

@ -118,16 +118,19 @@
#define __NSAPINAM_C__
#include <acpi.h>
#include <interpreter.h>
#include <namespace.h>
#include <methods.h>
#include <interp.h>
#include <namesp.h>
#include <amlcode.h>
#include <acpiobj.h>
#include <pnp.h>
#include <parser.h>
#include <dispatch.h>
#include <events.h>
#define _THIS_MODULE "nsapinam.c"
#define _COMPONENT NAMESPACE
MODULE_NAME ("nsapinam");
/******************************************************************************
*
@ -152,7 +155,7 @@ AcpiLoadNamespace (
FUNCTION_TRACE ("AcpiLoadNameSpace");
/* Are the tables loaded yet? */
/* There must be at least a DSDT installed */
if (Gbl_DSDT == NULL)
{
@ -160,12 +163,11 @@ AcpiLoadNamespace (
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
/*
* Now that the tables are loaded, finish some other initialization
*/
/* Everything OK, now init the hardware */
/* Init the hardware */
/* TBD: [Restructure] Should this should be moved elsewhere, like AcpiEnable! ??*/
/* we need to be able to call this interface repeatedly! */
/* Does H/W require init before loading the namespace? */
Status = CmHardwareInitialize ();
if (ACPI_FAILURE (Status))
@ -173,52 +175,42 @@ AcpiLoadNamespace (
return_ACPI_STATUS (Status);
}
/* Initialize the namespace */
Status = NsSetup ();
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/*
* Load the namespace via the interpreter. The DSDT is required,
* Load the namespace. The DSDT is required,
* but the SSDT and PSDT tables are optional.
*/
Status = AmlLoadTable (TABLE_DSDT);
Status = NsLoadTableByType (TABLE_DSDT);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
Status = AmlLoadTable (TABLE_SSDT);
Status = AmlLoadTable (TABLE_PSDT);
/* Ignore exceptions from these */
NsLoadTableByType (TABLE_SSDT);
NsLoadTableByType (TABLE_PSDT);
DUMP_TABLES (NS_ALL, ACPI_INT_MAX);
DEBUG_PRINT (ACPI_OK, ("**** ACPI Namespace successfully loaded! [%p]\n",
DEBUG_PRINT_RAW (ACPI_OK, ("ACPI Namespace successfully loaded at root 0x%p\n",
Gbl_RootObject->Scope));
/* Install the default OpRegion handlers, ignore the return code right now. */
EvInstallDefaultAddressSpaceHandlers ();
return_ACPI_STATUS (Status);
}
/****************************************************************************
*
* FUNCTION: AcpiNameToHandle
* FUNCTION: AcpiGetHandle
*
* PARAMETERS: Parent - Object to search under (search scope).
* Name - Pointer to an ascii string containing the name
* PathName - Pointer to an asciiz string containing the name
* RetHandle - Where the return handle is placed
*
* RETURN: Status
@ -231,154 +223,52 @@ AcpiLoadNamespace (
******************************************************************************/
ACPI_STATUS
AcpiNameToHandle (
AcpiGetHandle (
ACPI_HANDLE Parent,
ACPI_NAME Name,
ACPI_HANDLE *RetHandle)
{
NAME_TABLE_ENTRY *ThisEntry;
ACPI_HANDLE LocalParent = Parent;
if (!RetHandle)
{
return AE_BAD_PARAMETER;
}
/* Special case for root, since we can't search for it */
if (Name == NS_ROOT)
{
*RetHandle = NsConvertEntryToHandle(Gbl_RootObject);
return AE_OK;
}
/* Null parent means root object */
if (!Parent)
{
LocalParent = Gbl_RootObject;
}
/* Validate the Parent handle */
if (!(ThisEntry = NsConvertHandleToEntry (LocalParent)))
{
return AE_BAD_PARAMETER;
}
/* It is the scope that we are really after */
ThisEntry = ThisEntry->Scope;
/* Search for the name within this Parent */
while (ThisEntry)
{
if (ThisEntry->Name == Name)
{
*RetHandle = NsConvertEntryToHandle(ThisEntry);
return AE_OK;
}
ThisEntry = ThisEntry->NextEntry;
}
*RetHandle = NULL;
return AE_NOT_FOUND;
}
/****************************************************************************
*
* FUNCTION: AcpiHandleToName
*
* PARAMETERS: Handle - Handle to be converted to a name
* RetName - Where the 4 char (UINT32) name is placed
*
* RETURN: Status
*
* DESCRIPTION: This routine returns the name associated with ACPI_HANDLE. This
* and the AcpiNameToHandle are complementary functions.
*
* Handle == AcpiNameToHandle(AcpiHandleToName(Handle))
* and
* Name == AcpiHandleToName(AcpiNameToHandle(Name, NULL))
*
******************************************************************************/
ACPI_STATUS
AcpiHandleToName (
ACPI_HANDLE Handle,
ACPI_NAME *RetName)
{
NAME_TABLE_ENTRY *ObjEntry;
if (!RetName)
{
return AE_BAD_PARAMETER;
}
/* Validate handle and convert to and NTE */
if (!(ObjEntry = NsConvertHandleToEntry (Handle)))
{
*RetName = 0;
return AE_BAD_PARAMETER;
}
/* Just extract the name field */
*RetName = ObjEntry->Name;
return AE_OK;
}
/****************************************************************************
*
* FUNCTION: AcpiPathnameToHandle
*
* PARAMETERS: Pathname - pointer to ascii string containing full pathname
* RetHandle - Where the return handle is stored
*
* RETURN: Status
*
* DESCRIPTION: This routine will search for a caller specified name in the
* name space. The pathname provided must be a fully qualified
* path from the root of the namespace.
*
******************************************************************************/
ACPI_STATUS
AcpiPathnameToHandle (
ACPI_STRING Pathname,
ACPI_HANDLE *RetHandle)
{
NAME_TABLE_ENTRY *TmpNte;
ACPI_STATUS Status;
ACPI_STATUS Status;
NAME_TABLE_ENTRY *ThisEntry;
NAME_TABLE_ENTRY *Scope = NULL;
if (!RetHandle || !Pathname)
{
return AE_BAD_PARAMETER;
}
if (Parent)
{
CmAcquireMutex (MTX_NAMESPACE);
ThisEntry = NsConvertHandleToEntry (Parent);
if (!ThisEntry)
{
CmReleaseMutex (MTX_NAMESPACE);
return AE_BAD_PARAMETER;
}
Scope = ThisEntry->Scope;
CmReleaseMutex (MTX_NAMESPACE);
}
/* Special case for root, since we can't search for it */
/* TBD: [Investigate] Check for both forward and backslash?? */
if (STRCMP (Pathname, NS_ROOT_PATH) == 0)
{
*RetHandle = NsConvertEntryToHandle(Gbl_RootObject);
*RetHandle = NsConvertEntryToHandle (Gbl_RootObject);
return AE_OK;
}
/*
* Find the Nte and convert to the user format
*/
TmpNte = NULL;
Status = NsGetNte (Pathname, NS_ALL, &TmpNte);
ThisEntry = NULL;
Status = NsGetNte (Pathname, Scope, &ThisEntry);
*RetHandle = NsConvertEntryToHandle(TmpNte);
*RetHandle = NsConvertEntryToHandle (ThisEntry);
return (Status);
}
@ -386,12 +276,13 @@ AcpiPathnameToHandle (
/****************************************************************************
*
* FUNCTION: AcpiHandleToPathname
* FUNCTION: AcpiGetPathname
*
* PARAMETERS: Handle - Handle to be converted to a pathname
* NameType - Full pathname or single segment
* RetPathPtr - Buffer for returned path
*
* RETURN: pointer to a string containing the fully qualified Name.
* RETURN: Pointer to a string containing the fully qualified Name.
*
* DESCRIPTION: This routine returns the fully qualified name associated with
* the Handle parameter. This and the AcpiPathnameToHandle are
@ -399,18 +290,19 @@ AcpiPathnameToHandle (
*
******************************************************************************/
ACPI_STATUS
AcpiHandleToPathname (
AcpiGetName (
ACPI_HANDLE Handle,
UINT32 NameType,
ACPI_BUFFER *RetPathPtr)
{
ACPI_STATUS Status;
NAME_TABLE_ENTRY *ObjEntry;
/* Buffer pointer must be valid always */
if (!RetPathPtr)
if (!RetPathPtr || (NameType > ACPI_NAME_TYPE_MAX))
{
return AE_BAD_PARAMETER;
}
@ -423,22 +315,60 @@ AcpiHandleToPathname (
return AE_BAD_PARAMETER;
}
Status = NsHandleToPathname (Handle, &RetPathPtr->Length, RetPathPtr->Pointer);
if (NameType == ACPI_FULL_PATHNAME)
{
/* Get the full pathname (From the namespace root) */
Status = NsHandleToPathname (Handle, &RetPathPtr->Length, RetPathPtr->Pointer);
return Status;
}
/*
* Wants the single segment ACPI name.
* Validate handle and convert to an NTE
*/
CmAcquireMutex (MTX_NAMESPACE);
ObjEntry = NsConvertHandleToEntry (Handle);
if (!ObjEntry)
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
}
/* Check if name will fit in buffer */
if (RetPathPtr->Length < PATH_SEGMENT_LENGTH)
{
RetPathPtr->Length = PATH_SEGMENT_LENGTH;
Status = AE_BUFFER_OVERFLOW;
goto UnlockAndExit;
}
/* Just copy the ACPI name from the NTE and zero terminate it */
STRNCPY (RetPathPtr->Pointer, (char *) &ObjEntry->Name, ACPI_NAME_SIZE);
((char *) RetPathPtr->Pointer) [ACPI_NAME_SIZE] = 0;
Status = AE_OK;
UnlockAndExit:
CmReleaseMutex (MTX_NAMESPACE);
return Status;
}
/****************************************************************************
*
* FUNCTION: AcpiGetDeviceInfo
* FUNCTION: AcpiGetObjectInfo
*
* PARAMETERS: Handle - Handle to a device
* Info - Where the device info is returned
* PARAMETERS: Handle - Object Handle
* Info - Where the info is returned
*
* RETURN: Status
*
* DESCRIPTION: Returns information about the device as gleaned from running
* DESCRIPTION: Returns information about an object as gleaned from running
* several standard control methods.
*
******************************************************************************/
@ -463,39 +393,65 @@ AcpiGetObjectInfo (
return AE_BAD_PARAMETER;
}
if (!(DeviceEntry = NsConvertHandleToEntry (Device)))
CmAcquireMutex (MTX_NAMESPACE);
DeviceEntry = NsConvertHandleToEntry (Device);
if (!DeviceEntry)
{
CmReleaseMutex (MTX_NAMESPACE);
return AE_BAD_PARAMETER;
}
Info->Type = DeviceEntry->Type;
Info->Name = DeviceEntry->Name;
Info->Parent = NsConvertEntryToHandle(DeviceEntry->ParentEntry);
Info->Type = DeviceEntry->Type;
Info->Name = DeviceEntry->Name;
Info->Parent = NsConvertEntryToHandle (DeviceEntry->ParentEntry);
if (DeviceEntry->Type != ACPI_TYPE_Device)
CmReleaseMutex (MTX_NAMESPACE);
/*
* If not a device, we are all done.
*/
if (Info->Type != ACPI_TYPE_Device)
{
/*
* We're done, get out
*/
return AE_OK;
}
Info->Valid = 0;
/* Get extra info for ACPI devices */
Info->Valid = 0;
/* Execute the _HID method and save the result */
Status = Execute_HID (DeviceEntry, &Hid);
Status = CmExecute_HID (DeviceEntry, &Hid);
if (ACPI_SUCCESS (Status))
{
Info->HardwareId = Hid.Data.Number;
if (Hid.Type == STRING_PTR_DEVICE_ID)
{
STRCPY (Info->HardwareId, Hid.Data.StringPtr);
}
else
{
STRCPY (Info->HardwareId, Hid.Data.Buffer);
}
Info->Valid |= ACPI_VALID_HID;
}
/* Execute the _UID method and save the result */
Status = Execute_UID (DeviceEntry, &Uid);
Status = CmExecute_UID (DeviceEntry, &Uid);
if (ACPI_SUCCESS (Status))
{
Info->UniqueId = Uid.Data.Number;
if (Hid.Type == STRING_PTR_DEVICE_ID)
{
STRCPY (Info->UniqueId, Uid.Data.StringPtr);
}
else
{
STRCPY (Info->UniqueId, Uid.Data.Buffer);
}
Info->Valid |= ACPI_VALID_UID;
}
@ -504,7 +460,7 @@ AcpiGetObjectInfo (
* _STA is not always present
*/
Status = Execute_STA (DeviceEntry, &DeviceStatus);
Status = CmExecute_STA (DeviceEntry, &DeviceStatus);
if (ACPI_SUCCESS (Status))
{
Info->CurrentStatus = DeviceStatus;
@ -516,7 +472,7 @@ AcpiGetObjectInfo (
* _ADR is not always present
*/
Status = Execute_ADR (DeviceEntry, &Address);
Status = CmEvaluateNumericObject (METHOD_NAME__ADR, DeviceEntry, &Address);
if (ACPI_SUCCESS (Status))
{
Info->Address = Address;
@ -526,75 +482,3 @@ AcpiGetObjectInfo (
return AE_OK;
}
/* OBSOLETE FUNCTIONS */
/****************************************************************************
*
* FUNCTION: AcpiEnumerateDevice
*
* PARAMETERS: DevHandle - handle to the device to enumerate
* HidPtr - Pointer to a DEVICE_ID structure to return
* the device's HID
* EnumPtr - Pointer to a BOOLEAN flag that if set to TRUE
* indicate that the enumeration of this device
* is owned by ACPI.
*
* RETURN: Status
*
* DESCRIPTION: Returns HID in the HidPtr structure and an indication that the
* device should be enumerated in the field pointed to by EnumPtr
*
******************************************************************************/
ACPI_STATUS
AcpiEnumerateDevice (
ACPI_HANDLE DevHandle,
DEVICE_ID *HidPtr,
BOOLEAN *EnumPtr)
{
HidPtr->Data.String = NULL;
*EnumPtr = FALSE;
return (AE_OK);
}
/****************************************************************************
*
* FUNCTION: AcpiGetNextSubDevice
*
* PARAMETERS: DevHandle - handle to the device to enumerate
* Count - zero based counter of the sub-device to locate
* RetHandle - Where handle for next device is placed
*
* RETURN: Status
*
* DESCRIPTION: This routine is used in the enumeration process to locate devices
* located within the namespace of another device.
*
******************************************************************************/
ACPI_STATUS
AcpiGetNextSubDevice (
ACPI_HANDLE DevHandle,
UINT32 Count,
ACPI_HANDLE *RetHandle)
{
if (!RetHandle)
{
return AE_BAD_PARAMETER;
}
*RetHandle = NULL;
return (AE_OK);
}

View File

@ -1,17 +1,17 @@
/*******************************************************************************
*
* Module Name: nsxfobj - Public interfaces to the ACPI subsystem
/******************************************************************************
*
* Module Name: nsapiobj - Public interfaces to the ACPI subsystem
* ACPI Object oriented interfaces
* $Revision: 1.114 $
*
******************************************************************************/
*****************************************************************************/
/******************************************************************************
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp.
* All rights reserved.
* Some or all of this work - Copyright (c) 1999, Intel Corp. All rights
* reserved.
*
* 2. License
*
@ -39,9 +39,9 @@
* The above copyright and patent license is granted only if the following
* conditions are met:
*
* 3. Conditions
* 3. Conditions
*
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
* Redistribution of source code of any substantial portion of the Covered
* Code or modification with rights to further distribute source must include
* the above Copyright Notice, the above License, this list of Conditions,
@ -49,11 +49,11 @@
* Licensee must cause all Covered Code to which Licensee contributes to
* contain a file documenting the changes Licensee made to create that Covered
* Code and the date of any change. Licensee must include in that file the
* documentation of any changes made by any predecessor Licensee. Licensee
* documentation of any changes made by any predecessor Licensee. Licensee
* must include a prominent statement that the modification is derived,
* directly or indirectly, from Original Intel Code.
*
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
* Redistribution of source code of any substantial portion of the Covered
* Code or modification without rights to further distribute source must
* include the following Disclaimer and Export Compliance provision in the
@ -87,7 +87,7 @@
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
* PARTICULAR PURPOSE.
* PARTICULAR PURPOSE.
*
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
@ -116,16 +116,356 @@
*****************************************************************************/
#define __NSXFOBJ_C__
#define __NSAPIOBJ_C__
#include "acpi.h"
#include "acnamesp.h"
#include <acpi.h>
#include <interp.h>
#include <namesp.h>
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsxfobj")
#define _COMPONENT NAMESPACE
MODULE_NAME ("nsapiobj");
/*******************************************************************************
/****************************************************************************
*
* FUNCTION: AcpiEvaluateObject
*
* PARAMETERS: Handle - Object handle (optional)
* *Pathname - Object pathname (optional)
* **Params - List of parameters to pass to
* method, terminated by NULL.
* Params itself may be NULL
* if no parameters are being
* passed.
* *ReturnObject - Where to put method's return value (if
* any). If NULL, no value is returned.
*
* RETURN: Status
*
* DESCRIPTION: Find and evaluate the given object, passing the given
* parameters if necessary. One of "Handle" or "Pathname" must
* be valid (non-null)
*
****************************************************************************/
ACPI_STATUS
AcpiEvaluateObject (
ACPI_HANDLE Handle,
ACPI_STRING Pathname,
ACPI_OBJECT_LIST *ParamObjects,
ACPI_BUFFER *ReturnBuffer)
{
ACPI_STATUS Status;
ACPI_OBJECT_INTERNAL **ParamPtr = NULL;
ACPI_OBJECT_INTERNAL *ReturnObj = NULL;
ACPI_OBJECT_INTERNAL *ObjectPtr = NULL;
UINT32 BufferSpaceNeeded;
UINT32 UserBufferLength;
UINT32 Count;
UINT32 i;
UINT32 ParamLength;
UINT32 ObjectLength;
FUNCTION_TRACE ("AcpiEvaluateObject");
/*
* If there are parameters to be passed to the object (which must be a control method),
* the external objects must be converted to internal objects
*/
if (ParamObjects && ParamObjects->Count)
{
/*
* Allocate a new parameter block for the internal objects
* Add 1 to count to allow for null terminated internal list
* TBD: [Restructure] merge into single allocation!
*/
Count = ParamObjects->Count;
ParamLength = (Count + 1) * sizeof (void *);
ObjectLength = Count * sizeof (ACPI_OBJECT_INTERNAL);
ParamPtr = CmCallocate (ParamLength + /* Parameter List part */
ObjectLength); /* Actual objects */
if (!ParamPtr)
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
ObjectPtr = (ACPI_OBJECT_INTERNAL *) ((UINT8 *) ParamPtr + ParamLength);
/*
* Init the param array of pointers and NULL terminate the list
*/
for (i = 0; i < Count; i++)
{
ParamPtr[i] = &ObjectPtr[i];
CmInitStaticObject (&ObjectPtr[i]);
}
ParamPtr[Count] = NULL;
/*
* Convert each external object in the list to an internal object
*/
for (i = 0; i < Count; i++)
{
Status = CmBuildInternalObject (&ParamObjects->Pointer[i], ParamPtr[i]);
if (ACPI_FAILURE (Status))
{
CmDeleteInternalObjectList (ParamPtr);
return_ACPI_STATUS (Status);
}
}
}
/*
* Three major cases:
* 1) Fully qualified pathname
* 2) No handle, not fully qualified pathname (error)
* 3) Valid handle
*/
if ((Pathname) &&
(NsValidRootPrefix (Pathname[0])))
{
/*
* The path is fully qualified, just evaluate by name
*/
Status = NsEvaluateByName (Pathname, ParamPtr, &ReturnObj);
}
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)
{
DEBUG_PRINT (ACPI_ERROR, ("AcpiEvaluateObject: Both Handle and Pathname are NULL\n"));
}
else
{
DEBUG_PRINT (ACPI_ERROR, ("AcpiEvaluateObject: Handle is NULL and Pathname is relative\n"));
}
Status = AE_BAD_PARAMETER;
}
else
{
/*
* We get here if we have a handle -- and if we have a pathname it is relative.
* The handle will be validated in the lower procedures
*/
if (!Pathname)
{
/*
* The null pathname case means the handle is for the actual object to be evaluated
*/
Status = NsEvaluateByHandle (Handle, ParamPtr, &ReturnObj);
}
else
{
/*
* Both a Handle and a relative Pathname
*/
Status = NsEvaluateRelative (Handle, Pathname, ParamPtr, &ReturnObj);
}
}
/*
* If we are expecting a return value, and all went well above,
* copy the return value to an external object.
*/
if (ReturnBuffer)
{
UserBufferLength = ReturnBuffer->Length;
ReturnBuffer->Length = 0;
if (ReturnObj)
{
if (VALID_DESCRIPTOR_TYPE (ReturnObj, DESC_TYPE_NTE))
{
/*
* If we got an NTE as a return object, this means the object we are evaluating has nothing
* interesting to return (such as a mutex, etc.) We return an error because these types
* are essentially unsupported by this interface. We don't check up front because this makes
* it easier to add support for various types at a later date if necessary.
*/
Status = AE_TYPE;
ReturnObj = NULL; /* No need to delete an NTE */
}
if (ACPI_SUCCESS (Status))
{
/*
* Find out how large a buffer is needed to contain the
* returned object
*/
Status = CmGetObjectSize (ReturnObj, &BufferSpaceNeeded);
if (ACPI_SUCCESS (Status))
{
/* Check if there is enough room in the caller's buffer */
if (UserBufferLength < BufferSpaceNeeded)
{
/*
* Caller's buffer is too small, can't give him partial results
* fail the call but return the buffer size needed
*/
DEBUG_PRINT (ACPI_ERROR, ("AcpiEvaluateObject: Needed buffer size %d, received %d\n",
BufferSpaceNeeded, UserBufferLength));
ReturnBuffer->Length = BufferSpaceNeeded;
Status = AE_BUFFER_OVERFLOW;
}
else
{
/*
* We have enough space for the object, build it
*/
Status = CmBuildExternalObject (ReturnObj, ReturnBuffer);
ReturnBuffer->Length = BufferSpaceNeeded;
}
}
}
}
}
/* Delete the return and parameter objects */
if (ReturnObj)
{
/*
* Delete the internal return object. (Or at least
* decrement the reference count by one)
*/
CmRemoveReference (ReturnObj);
}
/*
* Free the input parameter list (if we created one),
*/
if (ParamPtr)
{
/* Free the allocated parameter block */
CmDeleteInternalObjectList (ParamPtr);
}
return_ACPI_STATUS (Status);
}
/****************************************************************************
*
* FUNCTION: AcpiGetNextObject
*
* PARAMETERS: Type - Type of object to be searched for
* Parent - Parent object whose children we are getting
* LastChild - Previous child that was found.
* The NEXT child will be returned
* RetHandle - Where handle to the next object is placed
*
* RETURN: Status
*
* DESCRIPTION: Return the next peer object within the namespace. If Handle is
* valid, Scope is ignored. Otherwise, the first object within
* Scope is returned.
*
******************************************************************************/
ACPI_STATUS
AcpiGetNextObject (
ACPI_OBJECT_TYPE Type,
ACPI_HANDLE Parent,
ACPI_HANDLE Child,
ACPI_HANDLE *RetHandle)
{
ACPI_STATUS Status = AE_OK;
NAME_TABLE_ENTRY *Entry;
NAME_TABLE_ENTRY *ParentEntry = NULL;
NAME_TABLE_ENTRY *ChildEntry = NULL;
/* Parameter validation */
if (Type > ACPI_TYPE_MAX)
{
return AE_BAD_PARAMETER;
}
CmAcquireMutex (MTX_NAMESPACE);
/* If null handle, use the parent */
if (!Child)
{
/* Start search at the beginning of the specified scope */
ParentEntry = NsConvertHandleToEntry (Parent);
if (!ParentEntry)
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
}
}
/* Non-null handle, ignore the parent */
else
{
/* Convert and validate the handle */
ChildEntry = NsConvertHandleToEntry (Child);
if (!ChildEntry)
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
}
}
/* Internal function does the real work */
Entry = NsGetNextObject ((OBJECT_TYPE_INTERNAL) Type, ParentEntry, ChildEntry);
if (!Entry)
{
Status = AE_NOT_FOUND;
goto UnlockAndExit;
}
if (RetHandle)
{
*RetHandle = NsConvertEntryToHandle (Entry);
}
UnlockAndExit:
CmReleaseMutex (MTX_NAMESPACE);
return Status;
}
/****************************************************************************
*
* FUNCTION: AcpiGetType
*
@ -138,56 +478,49 @@
*
******************************************************************************/
ACPI_STATUS
ACPI_STATUS
AcpiGetType (
ACPI_HANDLE Handle,
ACPI_OBJECT_TYPE *RetType)
{
ACPI_NAMESPACE_NODE *Node;
ACPI_STATUS Status;
NAME_TABLE_ENTRY *Object;
/* Parameter Validation */
if (!RetType)
{
return (AE_BAD_PARAMETER);
return AE_BAD_PARAMETER;
}
/*
* Special case for the predefined Root Node
* (return type ANY)
*/
/* Special case for the predefined Root Object (return type ANY) */
if (Handle == ACPI_ROOT_OBJECT)
{
*RetType = ACPI_TYPE_ANY;
return (AE_OK);
*RetType = ACPI_TYPE_Any;
return AE_OK;
}
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
return (Status);
}
CmAcquireMutex (MTX_NAMESPACE);
/* Convert and validate the handle */
Node = AcpiNsMapHandleToNode (Handle);
if (!Node)
Object = NsConvertHandleToEntry (Handle);
if (!Object)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
return (AE_BAD_PARAMETER);
CmReleaseMutex (MTX_NAMESPACE);
return AE_BAD_PARAMETER;
}
*RetType = Node->Type;
*RetType = Object->Type;
Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
return (Status);
CmReleaseMutex (MTX_NAMESPACE);
return AE_OK;
}
/*******************************************************************************
/****************************************************************************
*
* FUNCTION: AcpiGetParent
*
@ -203,48 +536,48 @@ AcpiGetType (
ACPI_STATUS
AcpiGetParent (
ACPI_HANDLE Handle,
ACPI_HANDLE Handle,
ACPI_HANDLE *RetHandle)
{
ACPI_NAMESPACE_NODE *Node;
ACPI_STATUS Status;
NAME_TABLE_ENTRY *Object;
ACPI_STATUS Status = AE_OK;
/* No trace macro, too verbose */
if (!RetHandle)
{
return (AE_BAD_PARAMETER);
return AE_BAD_PARAMETER;
}
/* Special case for the predefined Root Node (no parent) */
/* Special case for the predefined Root Object (no parent) */
if (Handle == ACPI_ROOT_OBJECT)
{
return (AE_NULL_ENTRY);
return AE_NULL_ENTRY;
}
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
return (Status);
}
CmAcquireMutex (MTX_NAMESPACE);
/* Convert and validate the handle */
Node = AcpiNsMapHandleToNode (Handle);
if (!Node)
Object = NsConvertHandleToEntry (Handle);
if (!Object)
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
}
/* Get the parent entry */
*RetHandle =
AcpiNsConvertEntryToHandle (AcpiNsGetParentNode (Node));
*RetHandle = NsConvertEntryToHandle(Object->ParentEntry);
/* Return exeption if parent is null */
if (!AcpiNsGetParentNode (Node))
if (!Object->ParentEntry)
{
Status = AE_NULL_ENTRY;
}
@ -252,100 +585,75 @@ AcpiGetParent (
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
return (Status);
CmReleaseMutex (MTX_NAMESPACE);
return AE_OK;
}
/*******************************************************************************
/******************************************************************************
*
* FUNCTION: AcpiGetNextObject
* FUNCTION: AcpiWalkNamespace
*
* PARAMETERS: Type - Type of object to be searched for
* Parent - Parent object whose children we are getting
* LastChild - Previous child that was found.
* The NEXT child will be returned
* RetHandle - Where handle to the next object is placed
* PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
* StartObject - Handle in namespace where search begins
* MaxDepth - Depth to which search is to reach
* UserFunction - Called when an object of "Type" is found
* Context - Passed to user function
*
* RETURN: Status
* RETURNS Return value from the UserFunction if terminated early.
* Otherwise, returns NULL.
*
* DESCRIPTION: Return the next peer object within the namespace. If Handle is
* valid, Scope is ignored. Otherwise, the first object within
* Scope is returned.
* DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
* starting (and ending) at the object specified by StartHandle.
* The UserFunction is called whenever an object that matches
* the type parameter is found. If the user function returns
* a non-zero value, the search is terminated immediately and this
* value is returned to the caller.
*
* The point of this procedure is to provide a generic namespace
* walk routine that can be called from multiple places to
* provide multiple services; the User Function can be tailored
* to each task, whether it is a print function, a compare
* function, etc.
*
******************************************************************************/
ACPI_STATUS
AcpiGetNextObject (
ACPI_OBJECT_TYPE Type,
ACPI_HANDLE Parent,
ACPI_HANDLE Child,
ACPI_HANDLE *RetHandle)
AcpiWalkNamespace (
ACPI_OBJECT_TYPE Type,
ACPI_HANDLE StartObject,
UINT32 MaxDepth,
WALK_CALLBACK UserFunction,
void *Context,
void **ReturnValue)
{
ACPI_STATUS Status;
ACPI_NAMESPACE_NODE *Node;
ACPI_NAMESPACE_NODE *ParentNode = NULL;
ACPI_NAMESPACE_NODE *ChildNode = NULL;
FUNCTION_TRACE ("AcpiWalkNamespace");
/* Parameter validation */
if (Type > ACPI_TYPE_EXTERNAL_MAX)
if ((Type > ACPI_TYPE_MAX) ||
(!MaxDepth) ||
(!UserFunction))
{
return (AE_BAD_PARAMETER);
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
return (Status);
}
/*
* Lock the namespace around the walk.
* The namespace will be unlocked/locked around each call to the user function - since this function
* must be allowed to make Acpi calls itself.
*/
/* If null handle, use the parent */
CmAcquireMutex (MTX_NAMESPACE);
Status = NsWalkNamespace ((OBJECT_TYPE_INTERNAL) Type, StartObject, MaxDepth, NS_WALK_UNLOCK,
UserFunction, Context, ReturnValue);
CmReleaseMutex (MTX_NAMESPACE);
if (!Child)
{
/* Start search at the beginning of the specified scope */
ParentNode = AcpiNsMapHandleToNode (Parent);
if (!ParentNode)
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
}
}
else
{
/* Non-null handle, ignore the parent */
/* Convert and validate the handle */
ChildNode = AcpiNsMapHandleToNode (Child);
if (!ChildNode)
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
}
}
/* Internal function does the real work */
Node = AcpiNsGetNextNode (Type, ParentNode, ChildNode);
if (!Node)
{
Status = AE_NOT_FOUND;
goto UnlockAndExit;
}
if (RetHandle)
{
*RetHandle = AcpiNsConvertEntryToHandle (Node);
}
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
return (Status);
return_ACPI_STATUS (Status);
}