Windows2003-3790/base/busdrv/acpi/asl/acpins.c
2020-09-30 16:53:55 +02:00

549 lines
16 KiB
C

/*** acpins.c - ACPI Name Space functions
*
* Copyright (c) 1996,1997 Microsoft Corporation
* Author: Michael Tsang (MikeTs)
* Created 10/18/96
*
* MODIFICATION HISTORY
*/
#include "pch.h"
/***LP InitNameSpace - Initialize NameSpace
*
* ENTRY
* None
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL InitNameSpace(VOID)
{
int rc = ASLERR_NONE;
ENTER((1, "InitNameSpace()\n"));
if ((rc = CreateNameSpaceObj(NULL, "\\", NULL, NULL, NULL, NSF_EXIST_ERR))
== ASLERR_NONE)
{
static struct _defobj {
PSZ pszName;
USHORT dwObjType;
} DefinedRootObjs[] = {
"_GPE", OBJTYPE_UNKNOWN,
"_PR", OBJTYPE_UNKNOWN,
"_SB", OBJTYPE_UNKNOWN,
"_SI", OBJTYPE_UNKNOWN,
"_TZ", OBJTYPE_UNKNOWN,
"_REV", OBJTYPE_INTDATA,
"_OS", OBJTYPE_STRDATA,
"_GL", OBJTYPE_MUTEX,
NULL, 0
};
int i;
PNSOBJ pns;
gpnsCurrentScope = gpnsNameSpaceRoot;
for (i = 0; DefinedRootObjs[i].pszName != NULL; ++i)
{
if ((rc = CreateNameSpaceObj(NULL, DefinedRootObjs[i].pszName, NULL,
NULL, &pns, NSF_EXIST_ERR)) ==
ASLERR_NONE)
{
pns->ObjData.dwDataType = DefinedRootObjs[i].dwObjType;
}
else
{
break;
}
}
}
EXIT((1, "InitNameSpace=%d\n", rc));
return rc;
} //InitNameSpace
/***LP GetNameSpaceObj - Find a name space object
*
* ENTRY
* pszObjPath -> name path string
* pnsScope -> scope to start the search (NULL means root)
* ppns -> to hold the nsobj pointer found
* dwfNS - flags
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL GetNameSpaceObj(PSZ pszObjPath, PNSOBJ pnsScope, PPNSOBJ ppns,
DWORD dwfNS)
{
int rc = ASLERR_NONE;
PSZ psz;
ENTER((1, "GetNameSpaceObj(ObjPath=%s,Scope=%s,ppns=%p,Flags=%x)\n",
pszObjPath, pnsScope? 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 = ASLERR_NSOBJ_NOT_FOUND;
else if (*psz != '\0')
{
BOOL fSearchUp;
PNSOBJ pns;
fSearchUp = !(dwfNS & NSF_LOCAL_SCOPE) &&
(pszObjPath[0] != '\\') &&
(pszObjPath[0] != '^') &&
(strlen(pszObjPath) <= sizeof(NAMESEG));
for (;;)
{
do
{
if ((pns = pnsScope->pnsFirstChild) == NULL)
rc = ASLERR_NSOBJ_NOT_FOUND;
else
{
BOOL fFound;
PSZ pszEnd;
DWORD dwLen;
NAMESEG dwName;
if ((pszEnd = strchr(psz, '.')) != NULL)
dwLen = (DWORD)(pszEnd - psz);
else
dwLen = strlen(psz);
if (dwLen > sizeof(NAMESEG))
{
ERROR(("GetNameSpaceObj: invalid name - %s",
pszObjPath));
rc = ASLERR_INVALID_NAME;
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 == ASLERR_NONE)
{
if (!fFound)
rc = ASLERR_NSOBJ_NOT_FOUND;
else
{
psz += dwLen;
if (*psz == '.')
{
psz++;
}
else if (*psz == '\0')
{
*ppns = pnsScope;
break;
}
}
}
}
} while (rc == ASLERR_NONE);
if ((rc == ASLERR_NSOBJ_NOT_FOUND) && fSearchUp &&
(pnsScope != NULL) && (pnsScope->pnsParent != NULL))
{
pnsScope = pnsScope->pnsParent;
rc = ASLERR_NONE;
}
else
{
break;
}
}
}
if (rc != ASLERR_NONE)
{
*ppns = NULL;
}
EXIT((1, "GetNameSpaceObj=%d (pns=%p)\n", rc, *ppns));
return rc;
} //GetNameSpaceObj
/***LP CreateNameSpaceObj - Create a name space object under current scope
*
* ENTRY
* ptoken -> TOKEN
* pszName -> name path string
* pnsScope -> scope to start the search (NULL means root)
* pnsOwner -> owner object
* ppns -> to hold the nsobj pointer found
* dwfNS - flags
*
* EXIT-SUCCESS
* returns ASLERR_NONE
* EXIT-FAILURE
* returns negative error code
*/
int LOCAL CreateNameSpaceObj(PTOKEN ptoken, PSZ pszName, PNSOBJ pnsScope,
PNSOBJ pnsOwner, PPNSOBJ ppns, DWORD dwfNS)
{
int rc = ASLERR_NONE;
PNSOBJ pns;
#ifndef _UNASM_LIB
char szMsg[MAX_MSG_LEN + 1];
#endif
ENTER((1, "CreateNameSpaceObj(ptoken=%p,Name=%s,pnsScope=%s,pnsOwner=%p,ppns=%p,Flags=%x)\n",
ptoken, pszName, pnsScope? GetObjectPath(pnsScope): "", pnsOwner,
ppns, dwfNS));
#ifdef _UNASM_LIB
DEREF(ptoken);
#endif
ASSERT((pszName != NULL) && (*pszName != '\0'));
if (pnsScope == NULL)
pnsScope = gpnsNameSpaceRoot;
if ((rc = GetNameSpaceObj(pszName, pnsScope, &pns, NSF_LOCAL_SCOPE)) ==
ASLERR_NONE)
{
if (!(dwfNS & NSF_EXIST_OK))
{
#ifndef _UNASM_LIB
if (ptoken != NULL)
{
sprintf(szMsg, "%s already exist", pszName);
PrintTokenErr(ptoken, szMsg, dwfNS & NSF_EXIST_ERR);
}
else
{
ERROR(("%s: error: %s already exist",
gpszASLFile? gpszASLFile: gpszAMLFile, pszName));
}
#endif
rc = ASLERR_NSOBJ_EXIST;
}
}
else if (rc == ASLERR_NSOBJ_NOT_FOUND)
{
rc = ASLERR_NONE;
//
// Are we creating root?
//
if (strcmp(pszName, "\\") == 0)
{
ASSERT(gpnsNameSpaceRoot == NULL);
ASSERT(pnsOwner == NULL);
if ((pns = MEMALLOC(sizeof(NSOBJ))) == NULL)
{
ERROR(("CreateNameSpaceObj: fail to allocate name space object"));
rc = ASLERR_OUT_OF_MEM;
}
else
{
memset(pns, 0, sizeof(NSOBJ));
pns->dwNameSeg = NAMESEG_ROOT;
pns->hOwner = (HANDLE)pnsOwner;
gpnsNameSpaceRoot = pns;
}
}
else
{
PSZ psz;
PNSOBJ pnsParent;
if ((psz = strrchr(pszName, '.')) != NULL)
{
*psz = '\0';
psz++;
if ((rc = GetNameSpaceObj(pszName, pnsScope, &pnsParent,
NSF_LOCAL_SCOPE)) ==
ASLERR_NSOBJ_NOT_FOUND)
{
#ifndef _UNASM_LIB
if (ptoken != NULL)
{
sprintf(szMsg, "parent object %s does not exist",
pszName);
PrintTokenErr(ptoken, szMsg, TRUE);
}
else
{
ERROR(("%s: error: parent object %s does not exist",
gpszASLFile? gpszASLFile: gpszAMLFile, pszName));
}
#endif
}
}
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 == ASLERR_NONE)
{
int iLen = strlen(psz);
if ((*psz != '\0') && (iLen > sizeof(NAMESEG)))
{
ERROR(("CreateNameSpaceObj: invalid name - %s", psz));
rc = ASLERR_INVALID_NAME;
}
else if ((pns = MEMALLOC(sizeof(NSOBJ))) == NULL)
{
ERROR(("CreateNameSpaceObj: fail to allocate name space object"));
rc = ASLERR_OUT_OF_MEM;
}
else
{
memset(pns, 0, sizeof(NSOBJ));
pns->dwNameSeg = NAMESEG_BLANK;
memcpy(&(pns->dwNameSeg), psz, iLen);
pns->hOwner = (HANDLE)pnsOwner;
pns->pnsParent = pnsParent;
ListInsertTail(&pns->list,
(PPLIST)&pnsParent->pnsFirstChild);
}
}
}
}
if ((rc == ASLERR_NONE) && (ppns != NULL))
*ppns = pns;
EXIT((1, "CreateNameSpaceObj=%d (pns=%p)\n", rc, pns));
return rc;
} //CreateNameSpaceObj
/***LP DumpNameSpacePaths - Dump all the name space object paths
*
* ENTRY
* pnsObj -> name space subtree root
* pfileOut -> output device
*
* EXIT
* None
*/
VOID LOCAL DumpNameSpacePaths(PNSOBJ pnsObj, FILE *pfileOut)
{
PNSOBJ pns, pnsNext;
ENTER((3, "DumpNameSpacePaths(pns=%x,pfileOut=%p)\n", pnsObj, pfileOut));
//
// First, dump myself
//
fprintf(pfileOut, "%13s: [%08x] %s",
GetObjectTypeName(pnsObj->ObjData.dwDataType), pnsObj->dwRefCount,
GetObjectPath(pnsObj));
if (pnsObj->ObjData.dwDataType == OBJTYPE_METHOD)
{
fprintf(pfileOut, " (cArgs=%d)", pnsObj->ObjData.uipDataValue);
}
else if (pnsObj->ObjData.dwDataType == OBJTYPE_RES_FIELD)
{
fprintf(pfileOut, " (BitOffset=0x%x, BitSize=0x%x)",
pnsObj->ObjData.uipDataValue, pnsObj->ObjData.dwDataLen);
}
fprintf(pfileOut, "%s\n", pnsObj->hOwner? "*": "");
//
// 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
//
DumpNameSpacePaths(pns, pfileOut);
}
EXIT((3, "DumpNameSpacePaths!\n"));
} //DumpNameSpacePaths
/***LP GetObjectPath - get object namespace path
*
* ENTRY
* pns -> object
*
* EXIT
* returns name space path
*/
PSZ LOCAL GetObjectPath(PNSOBJ pns)
{
static char szPath[MAX_NSPATH_LEN + 1] = {0};
int i;
ENTER((4, "GetObjectPath(pns=%x)\n", pns));
if (pns != NULL)
{
if (pns->pnsParent == NULL)
strcpy(szPath, "\\");
else
{
GetObjectPath(pns->pnsParent);
if (pns->pnsParent->pnsParent != NULL)
{
strcat(szPath, ".");
}
strncat(szPath, (PSZ)&pns->dwNameSeg, sizeof(NAMESEG));
}
for (i = strlen(szPath) - 1; i >= 0; --i)
{
if (szPath[i] == '_')
szPath[i] = '\0';
else
break;
}
}
else
{
szPath[0] = '\0';
}
EXIT((4, "GetObjectPath=%s\n", szPath));
return szPath;
} //GetObjectPath
/***LP GetObjectTypeName - get object type name
*
* ENTRY
* dwObjType - object type
*
* EXIT
* return object type name
*/
PSZ LOCAL GetObjectTypeName(DWORD dwObjType)
{
PSZ psz = NULL;
int i;
static struct
{
ULONG dwObjType;
PSZ pszObjTypeName;
} ObjTypeTable[] =
{
OBJTYPE_UNKNOWN, "Unknown",
OBJTYPE_INTDATA, "Integer",
OBJTYPE_STRDATA, "String",
OBJTYPE_BUFFDATA, "Buffer",
OBJTYPE_PKGDATA, "Package",
OBJTYPE_FIELDUNIT, "FieldUnit",
OBJTYPE_DEVICE, "Device",
OBJTYPE_EVENT, "Event",
OBJTYPE_METHOD, "Method",
OBJTYPE_MUTEX, "Mutex",
OBJTYPE_OPREGION, "OpRegion",
OBJTYPE_POWERRES, "PowerResource",
OBJTYPE_PROCESSOR, "Processor",
OBJTYPE_THERMALZONE,"ThermalZone",
OBJTYPE_BUFFFIELD, "BuffField",
OBJTYPE_DDBHANDLE, "DDBHandle",
OBJTYPE_DEBUG, "Debug",
OBJTYPE_OBJALIAS, "ObjAlias",
OBJTYPE_DATAALIAS, "DataAlias",
OBJTYPE_BANKFIELD, "BankField",
OBJTYPE_FIELD, "Field",
OBJTYPE_INDEXFIELD, "IndexField",
OBJTYPE_DATA, "Data",
OBJTYPE_DATAFIELD, "DataField",
OBJTYPE_DATAOBJ, "DataObject",
OBJTYPE_PNP_RES, "PNPResource",
OBJTYPE_RES_FIELD, "ResField",
0, NULL
};
ENTER((4, "GetObjectTypeName(Type=%x)\n", dwObjType));
for (i = 0; ObjTypeTable[i].pszObjTypeName != NULL; ++i)
{
if (dwObjType == ObjTypeTable[i].dwObjType)
{
psz = ObjTypeTable[i].pszObjTypeName;
break;
}
}
EXIT((4, "GetObjectTypeName=%s\n", psz? psz: "NULL"));
return psz;
} //GetObjectTypeName