You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
833 lines
24 KiB
833 lines
24 KiB
/*** acpins.c - ACPI Name Space functions
|
|
*
|
|
* Copyright (c) 1996,1997 Microsoft Corporation
|
|
* Author: Michael Tsang (MikeTs)
|
|
* Created 09/09/96
|
|
*
|
|
* MODIFICATION HISTORY
|
|
*/
|
|
|
|
#include "pch.h"
|
|
|
|
#ifdef LOCKABLE_PRAGMA
|
|
#pragma ACPI_LOCKABLE_DATA
|
|
#pragma ACPI_LOCKABLE_CODE
|
|
#endif
|
|
|
|
/***LP GetNameSpaceObject - Find a name space object
|
|
*
|
|
* ENTRY
|
|
* pszObjPath -> object path string
|
|
* pnsScope - object scope to start the search (NULL means root)
|
|
* ppnsObj -> to hold the object found
|
|
* dwfNS - flags
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL GetNameSpaceObject(PSZ pszObjPath, PNSOBJ pnsScope, PPNSOBJ ppns,
|
|
ULONG dwfNS)
|
|
{
|
|
TRACENAME("GETNAMESPACEOBJECT")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
PSZ psz;
|
|
|
|
ENTER(3, ("GetNameSpaceObject(ObjPath=%s,Scope=%s,ppns=%x,Flags=%x)\n",
|
|
pszObjPath, GetObjectPath(pnsScope), ppns, dwfNS));
|
|
|
|
if (pnsScope == NULL)
|
|
pnsScope = gpnsNameSpaceRoot;
|
|
|
|
if (*pszObjPath == '\\')
|
|
{
|
|
psz = &pszObjPath[1];
|
|
pnsScope = gpnsNameSpaceRoot;
|
|
}
|
|
else
|
|
{
|
|
psz = pszObjPath;
|
|
|
|
while ((*psz == '^') && (pnsScope != NULL))
|
|
{
|
|
psz++;
|
|
pnsScope = pnsScope->pnsParent;
|
|
}
|
|
}
|
|
|
|
*ppns = pnsScope;
|
|
|
|
if (pnsScope == NULL)
|
|
rc = AMLIERR_OBJ_NOT_FOUND;
|
|
else if (*psz != '\0')
|
|
{
|
|
BOOLEAN fSearchUp;
|
|
PNSOBJ pns;
|
|
|
|
fSearchUp = (BOOLEAN)(!(dwfNS & NSF_LOCAL_SCOPE) &&
|
|
(pszObjPath[0] != '\\') &&
|
|
(pszObjPath[0] != '^') &&
|
|
(STRLEN(pszObjPath) <= sizeof(NAMESEG)));
|
|
for (;;)
|
|
{
|
|
do
|
|
{
|
|
if ((pns = pnsScope->pnsFirstChild) == NULL)
|
|
rc = AMLIERR_OBJ_NOT_FOUND;
|
|
else
|
|
{
|
|
BOOLEAN fFound;
|
|
PSZ pszEnd;
|
|
ULONG dwLen;
|
|
NAMESEG dwName;
|
|
|
|
if ((pszEnd = STRCHR(psz, '.')) != NULL)
|
|
dwLen = (ULONG)(pszEnd - psz);
|
|
else
|
|
dwLen = STRLEN(psz);
|
|
|
|
if (dwLen > sizeof(NAMESEG))
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_NAME,
|
|
("GetNameSpaceObject: invalid name - %s",
|
|
pszObjPath));
|
|
|
|
// Satisfy the compiler...
|
|
fFound = FALSE;
|
|
}
|
|
else
|
|
{
|
|
dwName = NAMESEG_BLANK;
|
|
MEMCPY(&dwName, psz, dwLen);
|
|
//
|
|
// Search all siblings for a matching NameSeg.
|
|
//
|
|
fFound = FALSE;
|
|
do
|
|
{
|
|
if (pns->dwNameSeg == dwName)
|
|
{
|
|
pnsScope = pns;
|
|
fFound = TRUE;
|
|
break;
|
|
}
|
|
pns = (PNSOBJ)pns->list.plistNext;
|
|
} while (pns != pns->pnsParent->pnsFirstChild);
|
|
}
|
|
|
|
if (rc == STATUS_SUCCESS)
|
|
{
|
|
if (!fFound)
|
|
rc = AMLIERR_OBJ_NOT_FOUND;
|
|
else
|
|
{
|
|
psz += dwLen;
|
|
if (*psz == '.')
|
|
{
|
|
psz++;
|
|
}
|
|
else if (*psz == '\0')
|
|
{
|
|
*ppns = pnsScope;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} while (rc == STATUS_SUCCESS);
|
|
|
|
if ((rc == AMLIERR_OBJ_NOT_FOUND) && fSearchUp &&
|
|
(pnsScope != NULL) && (pnsScope->pnsParent != NULL))
|
|
{
|
|
pnsScope = pnsScope->pnsParent;
|
|
rc = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((dwfNS & NSF_WARN_NOTFOUND) && (rc == AMLIERR_OBJ_NOT_FOUND))
|
|
{
|
|
rc = AMLI_LOGERR(rc, ("GetNameSpaceObject: object %s not found",
|
|
pszObjPath));
|
|
}
|
|
|
|
if (rc != STATUS_SUCCESS)
|
|
{
|
|
*ppns = NULL;
|
|
}
|
|
|
|
EXIT(3, ("GetNameSpaceObject=%x (pns=%x)\n", rc, *ppns));
|
|
return rc;
|
|
} //GetNameSpaceObject
|
|
|
|
/***LP CreateNameSpaceObject - Create a name space object under current scope
|
|
*
|
|
* ENTRY
|
|
* pheap -> HEAP
|
|
* pszName -> name string of the object (NULL if creating noname object)
|
|
* pnsScope - scope to create object under (NULL means root)
|
|
* powner -> object owner
|
|
* ppns -> to hold the pointer to the new object (can be NULL)
|
|
* dwfNS - flags
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL CreateNameSpaceObject(PHEAP pheap, PSZ pszName, PNSOBJ pnsScope,
|
|
POBJOWNER powner, PPNSOBJ ppns,
|
|
ULONG dwfNS)
|
|
{
|
|
TRACENAME("CREATENAMESPACEOBJECT")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
PNSOBJ pns = NULL;
|
|
|
|
ENTER(3, ("CreateNameSpaceObject(pheap=%x,Name=%s,pnsScope=%x,powner=%x,ppns=%x,Flags=%x)\n",
|
|
pheap, pszName? pszName: "<null>", pnsScope, powner, ppns, dwfNS));
|
|
|
|
if (pnsScope == NULL)
|
|
pnsScope = gpnsNameSpaceRoot;
|
|
|
|
if (pszName == NULL)
|
|
{
|
|
if ((pns = NEWNSOBJ(pheap, sizeof(NSOBJ))) == NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
|
|
("CreateNameSpaceObject: fail to allocate name space object"));
|
|
}
|
|
else
|
|
{
|
|
ASSERT(gpnsNameSpaceRoot != NULL);
|
|
MEMZERO(pns, sizeof(NSOBJ));
|
|
pns->pnsParent = pnsScope;
|
|
InsertOwnerObjList(powner, pns);
|
|
ListInsertTail(&pns->list,
|
|
(PPLIST)&pnsScope->pnsFirstChild);
|
|
}
|
|
}
|
|
else if ((*pszName != '\0') &&
|
|
((rc = GetNameSpaceObject(pszName, pnsScope, &pns,
|
|
NSF_LOCAL_SCOPE)) == STATUS_SUCCESS))
|
|
{
|
|
if (!(dwfNS & NSF_EXIST_OK))
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_OBJ_ALREADY_EXIST,
|
|
("CreateNameSpaceObject: object already exist - %s",
|
|
pszName));
|
|
}
|
|
}
|
|
else if ((*pszName == '\0') || (rc == AMLIERR_OBJ_NOT_FOUND))
|
|
{
|
|
rc = STATUS_SUCCESS;
|
|
//
|
|
// Are we creating root?
|
|
//
|
|
if (STRCMP(pszName, "\\") == 0)
|
|
{
|
|
ASSERT(gpnsNameSpaceRoot == NULL);
|
|
ASSERT(powner == NULL);
|
|
if ((pns = NEWNSOBJ(pheap, sizeof(NSOBJ))) == NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
|
|
("CreateNameSpaceObject: fail to allocate name space object"));
|
|
}
|
|
else
|
|
{
|
|
MEMZERO(pns, sizeof(NSOBJ));
|
|
pns->dwNameSeg = NAMESEG_ROOT;
|
|
gpnsNameSpaceRoot = pns;
|
|
InsertOwnerObjList(powner, pns);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PSZ psz;
|
|
PNSOBJ pnsParent;
|
|
|
|
if ((psz = STRRCHR(pszName, '.')) != NULL)
|
|
{
|
|
*psz = '\0';
|
|
psz++;
|
|
rc = GetNameSpaceObject(pszName, pnsScope, &pnsParent,
|
|
NSF_LOCAL_SCOPE | NSF_WARN_NOTFOUND);
|
|
}
|
|
else if (*pszName == '\\')
|
|
{
|
|
psz = &pszName[1];
|
|
//
|
|
// By this time, we'd better created root already.
|
|
//
|
|
ASSERT(gpnsNameSpaceRoot != NULL);
|
|
pnsParent = gpnsNameSpaceRoot;
|
|
}
|
|
else if (*pszName == '^')
|
|
{
|
|
psz = pszName;
|
|
pnsParent = pnsScope;
|
|
while ((*psz == '^') && (pnsParent != NULL))
|
|
{
|
|
pnsParent = pnsParent->pnsParent;
|
|
psz++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ASSERT(pnsScope != NULL);
|
|
psz = pszName;
|
|
pnsParent = pnsScope;
|
|
}
|
|
|
|
if (rc == STATUS_SUCCESS)
|
|
{
|
|
int iLen = STRLEN(psz);
|
|
|
|
if ((*psz != '\0') && (iLen > sizeof(NAMESEG)))
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_NAME,
|
|
("CreateNameSpaceObject: invalid name - %s",
|
|
psz));
|
|
}
|
|
else if ((pns = NEWNSOBJ(pheap, sizeof(NSOBJ)))
|
|
== NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
|
|
("CreateNameSpaceObject: fail to allocate name space object"));
|
|
}
|
|
else
|
|
{
|
|
MEMZERO(pns, sizeof(NSOBJ));
|
|
|
|
if (*pszName == '\0')
|
|
pns->dwNameSeg = NAMESEG_NONE;
|
|
else
|
|
{
|
|
pns->dwNameSeg = NAMESEG_BLANK;
|
|
MEMCPY(&pns->dwNameSeg, psz, iLen);
|
|
}
|
|
|
|
pns->pnsParent = pnsParent;
|
|
InsertOwnerObjList(powner, pns);
|
|
ListInsertTail(&pns->list,
|
|
(PPLIST)&pnsParent->pnsFirstChild);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((rc == STATUS_SUCCESS) && (ppns != NULL))
|
|
*ppns = pns;
|
|
|
|
EXIT(3, ("CreateNameSpaceObject=%x (pns=%x)\n", rc, pns));
|
|
return rc;
|
|
} //CreateNameSpaceObject
|
|
|
|
/***LP FreeNameSpaceObjects - Free Name Space object and its children
|
|
*
|
|
* ENTRY
|
|
* pnsObj -> name space object
|
|
*
|
|
* EXIT
|
|
* None
|
|
*/
|
|
|
|
VOID LOCAL FreeNameSpaceObjects(PNSOBJ pnsObj)
|
|
{
|
|
TRACENAME("FREENAMESPACEOBJECTS")
|
|
PNSOBJ pns, pnsSibling, pnsParent;
|
|
#ifdef DEBUGGER
|
|
POBJSYM pos;
|
|
#endif
|
|
|
|
ENTER(3, ("FreeNameSpaceObjects(Obj=%s)\n", GetObjectPath(pnsObj)));
|
|
|
|
ASSERT(pnsObj != NULL);
|
|
|
|
for (pns = pnsObj; pns != NULL;)
|
|
{
|
|
while (pns->pnsFirstChild != NULL)
|
|
{
|
|
pns = pns->pnsFirstChild;
|
|
}
|
|
|
|
pnsSibling = NSGETNEXTSIBLING(pns);
|
|
pnsParent = NSGETPARENT(pns);
|
|
|
|
ENTER(4, ("FreeNSObj(Obj=%s)\n", GetObjectPath(pns)));
|
|
#ifdef DEBUGGER
|
|
//
|
|
// If I am in the symbol list, get rid of it before I die.
|
|
//
|
|
for (pos = gDebugger.posSymbolList; pos != NULL; pos = pos->posNext)
|
|
{
|
|
if (pns == pos->pnsObj)
|
|
{
|
|
if (pos->posPrev != NULL)
|
|
pos->posPrev->posNext = pos->posNext;
|
|
|
|
if (pos->posNext != NULL)
|
|
pos->posNext->posPrev = pos->posPrev;
|
|
|
|
if (pos == gDebugger.posSymbolList)
|
|
gDebugger.posSymbolList = pos->posNext;
|
|
|
|
FREESYOBJ(pos);
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// All my children are gone, I must die now.
|
|
//
|
|
ASSERT(pns->pnsFirstChild == NULL);
|
|
|
|
if ((pns->ObjData.dwDataType == OBJTYPE_OPREGION) &&
|
|
(((POPREGIONOBJ)pns->ObjData.pbDataBuff)->bRegionSpace ==
|
|
REGSPACE_MEM))
|
|
{
|
|
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
|
|
|
if(((POPREGIONOBJ)pns->ObjData.pbDataBuff)->dwLen)
|
|
{
|
|
MmUnmapIoSpace((PVOID)
|
|
((POPREGIONOBJ)pns->ObjData.pbDataBuff)->uipOffset,
|
|
((POPREGIONOBJ)pns->ObjData.pbDataBuff)->dwLen);
|
|
}
|
|
}
|
|
|
|
if (pns->pnsParent == NULL)
|
|
{
|
|
//
|
|
// I am root!
|
|
//
|
|
ASSERT(pns == gpnsNameSpaceRoot);
|
|
gpnsNameSpaceRoot = NULL;
|
|
}
|
|
else
|
|
{
|
|
ListRemoveEntry(&pns->list,
|
|
(PPLIST)&pns->pnsParent->pnsFirstChild);
|
|
}
|
|
//
|
|
// Free any attached data buffer if any
|
|
//
|
|
FreeDataBuffs(&pns->ObjData, 1);
|
|
//
|
|
// Free myself
|
|
//
|
|
if (pns->dwRefCount == 0)
|
|
{
|
|
FREENSOBJ(pns);
|
|
}
|
|
else
|
|
{
|
|
pns->ObjData.dwfData |= DATAF_NSOBJ_DEFUNC;
|
|
ListInsertTail(&pns->list, &gplistDefuncNSObjs);
|
|
}
|
|
EXIT(4, ("FreeNSObj!\n"));
|
|
|
|
if (pns == pnsObj)
|
|
{
|
|
//
|
|
// I was the last one, done!
|
|
//
|
|
pns = NULL;
|
|
}
|
|
else if (pnsSibling != NULL)
|
|
{
|
|
//
|
|
// I have siblings, go kill them.
|
|
//
|
|
pns = pnsSibling;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(pnsParent != NULL);
|
|
pns = pnsParent;
|
|
}
|
|
}
|
|
|
|
EXIT(3, ("FreeNameSpaceObjects!\n"));
|
|
} //FreeNameSpaceObjects
|
|
|
|
/***LP LoadDDB - Load and parse Differentiated Definition Block
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pdsdt -> DSDT block
|
|
* pnsScope -> current scope
|
|
* ppowner -> to hold new object owner
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS
|
|
LOCAL
|
|
LoadDDB(
|
|
PCTXT pctxt,
|
|
PDSDT pdsdt,
|
|
PNSOBJ pnsScope,
|
|
POBJOWNER *ppowner
|
|
)
|
|
{
|
|
BOOLEAN freeTable = FALSE;
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
|
|
if (!ValidateTable(pdsdt)) {
|
|
|
|
rc = AMLI_LOGERR(
|
|
AMLIERR_INVALID_TABLE,
|
|
("LoadDDB: invalid table %s at 0x%08x",
|
|
NameSegString(pdsdt->Header.Signature), pdsdt)
|
|
);
|
|
freeTable = TRUE;
|
|
|
|
} else {
|
|
|
|
rc = NewObjOwner( gpheapGlobal, ppowner);
|
|
if (rc == STATUS_SUCCESS) {
|
|
|
|
if (pctxt->pcall == NULL) {
|
|
|
|
rc = PushCall(pctxt, NULL, &pctxt->Result);
|
|
|
|
}
|
|
if (rc == STATUS_SUCCESS) {
|
|
|
|
#ifdef DEBUGGER
|
|
gDebugger.pbBlkBegin = pdsdt->DiffDefBlock;
|
|
gDebugger.pbBlkEnd = (PUCHAR)pdsdt + pdsdt->Header.Length;
|
|
#endif
|
|
|
|
rc = PushScope(
|
|
pctxt,
|
|
pdsdt->DiffDefBlock,
|
|
(PUCHAR)pdsdt + pdsdt->Header.Length, pctxt->pbOp,
|
|
pnsScope, *ppowner, gpheapGlobal, &pctxt->Result
|
|
);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
freeTable = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (freeTable) {
|
|
|
|
pctxt->powner = NULL;
|
|
FreeContext(pctxt);
|
|
|
|
}
|
|
return rc;
|
|
} //LoadDDB
|
|
|
|
/***LP LoadMemDDB - Load DDB from physical memory
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pDDB -> beginning of DDB
|
|
* ppowner -> to hold owner handle
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL LoadMemDDB(PCTXT pctxt, PDSDT pDDB, POBJOWNER *ppowner)
|
|
{
|
|
TRACENAME("LOADMEMDDB")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
|
|
ENTER(3, ("LoadMemDDB(pctxt=%x,Addr=%x,ppowner=%x)\n",
|
|
pctxt, pDDB, ppowner));
|
|
|
|
if ((ghValidateTable.pfnHandler != NULL) &&
|
|
((rc = ((PFNVT)ghValidateTable.pfnHandler)(pDDB,
|
|
ghValidateTable.uipParam)) !=
|
|
STATUS_SUCCESS))
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_TABLE,
|
|
("LoadMemDDB: table validation failed (rc=%x)",
|
|
rc));
|
|
}
|
|
else
|
|
{
|
|
rc = LoadDDB(pctxt, pDDB, pctxt->pnsScope, ppowner);
|
|
}
|
|
|
|
EXIT(3, ("LoadMemDDB=%x (powner=%x)\n", rc, *ppowner));
|
|
return rc;
|
|
} //LoadMemDDB
|
|
|
|
/***LP LoadFieldUnitDDB - Load DDB from a FieldUnit object
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pdataObj -> FieldUnit object
|
|
* ppowner -> to hold owner handle
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL LoadFieldUnitDDB(PCTXT pctxt, POBJDATA pdataObj,
|
|
POBJOWNER *ppowner)
|
|
{
|
|
TRACENAME("LOADFIELDUNITDDB")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
POBJDATA pdataTmp;
|
|
DESCRIPTION_HEADER *pdh;
|
|
|
|
ENTER(3, ("LoadFieldUnitDDB(pctxt=%x,pdataObj=%x,ppowner=%x)\n",
|
|
pctxt, pdataObj, ppowner));
|
|
|
|
if ((pdataTmp = NEWODOBJ(pctxt->pheapCurrent, sizeof(OBJDATA))) == NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
|
|
("LoadFieldUnitDDB: failed to allocate temp. object data"));
|
|
}
|
|
else if ((pdh = NEWBDOBJ(gpheapGlobal, sizeof(DESCRIPTION_HEADER))) == NULL)
|
|
{
|
|
FREEODOBJ(pdataTmp);
|
|
rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
|
|
("LoadFieldUnitDDB: failed to allocate description header"));
|
|
}
|
|
else
|
|
{
|
|
PUCHAR pbTable;
|
|
|
|
MEMZERO(pdataTmp, sizeof(OBJDATA));
|
|
pdataTmp->dwDataType = OBJTYPE_BUFFDATA;
|
|
pdataTmp->dwDataLen = sizeof(DESCRIPTION_HEADER);
|
|
pdataTmp->pbDataBuff = (PUCHAR)pdh;
|
|
|
|
if ((rc = ReadObject(pctxt, pdataObj, pdataTmp)) == STATUS_SUCCESS)
|
|
{
|
|
if ((pbTable = NEWBDOBJ(gpheapGlobal, pdh->Length)) == NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
|
|
("LoadFieldUnitDDB: failed to allocate buffer"));
|
|
}
|
|
else
|
|
{
|
|
MEMCPY(pbTable, pdh, sizeof(DESCRIPTION_HEADER));
|
|
pdataTmp->dwDataLen = pdh->Length - sizeof(DESCRIPTION_HEADER);
|
|
pdataTmp->pbDataBuff = pbTable + sizeof(DESCRIPTION_HEADER);
|
|
|
|
if ((rc = ReadObject(pctxt, pdataObj, pdataTmp)) ==
|
|
STATUS_SUCCESS)
|
|
{
|
|
if ((ghValidateTable.pfnHandler != NULL) &&
|
|
((rc = ((PFNVT)ghValidateTable.pfnHandler)(
|
|
(PDSDT)pbTable, ghValidateTable.uipParam)) !=
|
|
STATUS_SUCCESS))
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_TABLE,
|
|
("LoadFieldUnitDDB: table validation failed (rc=%x)",
|
|
rc));
|
|
}
|
|
else
|
|
{
|
|
rc = LoadDDB(pctxt, (PDSDT)pbTable, pctxt->pnsScope,
|
|
ppowner);
|
|
}
|
|
}
|
|
else if (rc == AMLISTA_PENDING)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_FATAL,
|
|
("LoadFieldUnitDDB: definition block loading cannot block"));
|
|
}
|
|
|
|
FREEBDOBJ(pbTable);
|
|
}
|
|
}
|
|
else if (rc == AMLISTA_PENDING)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_FATAL,
|
|
("LoadFieldUnitDDB: definition block loading cannot block"));
|
|
}
|
|
|
|
FREEBDOBJ(pdh);
|
|
FREEODOBJ(pdataTmp);
|
|
}
|
|
|
|
EXIT(3, ("LoadFieldUnitDDB=%x (powner=%x)\n", rc, *ppowner));
|
|
return rc;
|
|
} //LoadFieldUnitDDB
|
|
|
|
/***LP UnloadDDB - Unload Differentiated Definition Block
|
|
*
|
|
* ENTRY
|
|
* powner -> OBJOWNER
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
VOID LOCAL UnloadDDB(POBJOWNER powner)
|
|
{
|
|
TRACENAME("UNLOADDDB")
|
|
|
|
ENTER(3, ("UnloadDDB(powner=%x)\n", powner));
|
|
//
|
|
// Walk name space and remove all objects belongs to this DDB.
|
|
//
|
|
FreeObjOwner(powner, TRUE);
|
|
#ifdef DEBUG
|
|
{
|
|
KIRQL oldIrql;
|
|
|
|
KeAcquireSpinLock( &gdwGHeapSpinLock, &oldIrql );
|
|
gdwGHeapSnapshot = gdwGlobalHeapSize;
|
|
KeReleaseSpinLock( &gdwGHeapSpinLock, oldIrql );
|
|
}
|
|
#endif
|
|
|
|
EXIT(3, ("UnloadDDB!\n"));
|
|
} //UnloadDDB
|
|
|
|
/***LP EvalPackageElement - Evaluate a package element
|
|
*
|
|
* ENTRY
|
|
* ppkg -> package object
|
|
* iPkgIndex - package index (0-based)
|
|
* pdataResult -> result object
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL EvalPackageElement(PPACKAGEOBJ ppkg, int iPkgIndex,
|
|
POBJDATA pdataResult)
|
|
{
|
|
TRACENAME("EVALPACKAGEELEMENT")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
|
|
ENTER(3, ("EvalPackageElement(ppkg=%x,Index=%d,pdataResult=%x)\n",
|
|
ppkg, iPkgIndex, pdataResult));
|
|
|
|
ASSERT(pdataResult != NULL);
|
|
if (iPkgIndex >= (int)ppkg->dwcElements)
|
|
{
|
|
rc = AMLIERR_INDEX_TOO_BIG;
|
|
}
|
|
else
|
|
{
|
|
rc = DupObjData(gpheapGlobal, pdataResult, &ppkg->adata[iPkgIndex]);
|
|
}
|
|
|
|
EXIT(3, ("EvalPackageElement=%x (Type=%s,Value=%x,Len=%d,Buff=%x)\n",
|
|
rc, GetObjectTypeName(pdataResult->dwDataType),
|
|
pdataResult->uipDataValue, pdataResult->dwDataLen,
|
|
pdataResult->pbDataBuff));
|
|
return rc;
|
|
} //EvalPackageElement
|
|
|
|
#ifdef DEBUGGER
|
|
/***LP DumpNameSpaceObject - Dump name space object
|
|
*
|
|
* ENTRY
|
|
* pszPath -> name space path string
|
|
* fRecursive - TRUE if also dump the subtree recursively
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
LONG LOCAL DumpNameSpaceObject(PSZ pszPath, BOOLEAN fRecursive)
|
|
{
|
|
TRACENAME("DUMPNAMESPACEOBJECT")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
PNSOBJ pns;
|
|
char szName[sizeof(NAMESEG) + 1];
|
|
|
|
ENTER(3, ("DumpNameSpaceObject(Path=%s,fRecursive=%x)\n",
|
|
pszPath, fRecursive));
|
|
|
|
if ((rc = GetNameSpaceObject(pszPath, NULL, &pns,
|
|
NSF_LOCAL_SCOPE)) == STATUS_SUCCESS)
|
|
{
|
|
PRINTF("\nACPI Name Space: %s (%p)\n", pszPath, pns);
|
|
if (!fRecursive)
|
|
{
|
|
STRCPYN(szName, (PSZ)&pns->dwNameSeg, sizeof(NAMESEG));
|
|
DumpObject(&pns->ObjData, szName, 0);
|
|
}
|
|
else
|
|
DumpNameSpaceTree(pns, 0);
|
|
}
|
|
else if (rc == AMLIERR_OBJ_NOT_FOUND)
|
|
{
|
|
PRINTF(MODNAME "_ERROR: object %s not found\n", pszPath);
|
|
}
|
|
|
|
EXIT(3, ("DumpNameSpaceObject=%x\n", rc));
|
|
return rc;
|
|
} //DumpNameSpaceObject
|
|
|
|
/***LP DumpNameSpaceTree - Dump all the name space objects in the subtree
|
|
*
|
|
* ENTRY
|
|
* pnsObj -> name space subtree root
|
|
* dwLevel - indent level
|
|
*
|
|
* EXIT
|
|
* None
|
|
*/
|
|
|
|
VOID LOCAL DumpNameSpaceTree(PNSOBJ pnsObj, ULONG dwLevel)
|
|
{
|
|
TRACENAME("DUMPNAMESPACETREE")
|
|
PNSOBJ pns, pnsNext;
|
|
char szName[sizeof(NAMESEG) + 1];
|
|
|
|
ENTER(3, ("DumpNameSpaceTree(pns=%x,level=%d)\n", pnsObj, dwLevel));
|
|
//
|
|
// First, dump myself
|
|
//
|
|
STRCPYN(szName, (PSZ)&pnsObj->dwNameSeg, sizeof(NAMESEG));
|
|
DumpObject(&pnsObj->ObjData, szName, dwLevel);
|
|
//
|
|
// Then, recursively dump each of my children
|
|
//
|
|
for (pns = pnsObj->pnsFirstChild; pns != NULL; pns = pnsNext)
|
|
{
|
|
//
|
|
// If this is the last child, we have no more.
|
|
//
|
|
if ((pnsNext = (PNSOBJ)pns->list.plistNext) == pnsObj->pnsFirstChild)
|
|
pnsNext = NULL;
|
|
//
|
|
// Dump a child
|
|
//
|
|
DumpNameSpaceTree(pns, dwLevel + 1);
|
|
}
|
|
|
|
EXIT(3, ("DumpNameSpaceTree!\n"));
|
|
} //DumpNameSpaceTree
|
|
|
|
#endif //ifdef DEBUGGER
|