/*** 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