]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blobdiff - src/rm.c
tree.h cache-instrumented macros were invalidating NULL pointers in some cases
[keystone-rtos/rm-lld.git] / src / rm.c
index 9900a28817d0f8b74636bb103d2b0494ba588ae7..d95d87eca17d4eeb22025b3032c2f57351cbafa5 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
-/**\r
- *   @file  rm.c\r
- *\r
- *   @brief   \r
- *      This is the Resource Manager source.\r
- *\r
- *  \par\r
- *  ============================================================================\r
- *  @n   (C) Copyright 2012-2013, Texas Instruments, Inc.\r
- * \r
- *  Redistribution and use in source and binary forms, with or without \r
- *  modification, are permitted provided that the following conditions \r
- *  are met:\r
- *\r
- *    Redistributions of source code must retain the above copyright \r
- *    notice, this list of conditions and the following disclaimer.\r
- *\r
- *    Redistributions in binary form must reproduce the above copyright\r
- *    notice, this list of conditions and the following disclaimer in the \r
- *    documentation and/or other materials provided with the   \r
- *    distribution.\r
- *\r
- *    Neither the name of Texas Instruments Incorporated nor the names of\r
- *    its contributors may be used to endorse or promote products derived\r
- *    from this software without specific prior written permission.\r
- *\r
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- *\r
- *  \par\r
-*/\r
-\r
-/* Standard includes */\r
-#include <stdint.h>\r
-#include <string.h>\r
-#include <stdbool.h>\r
-\r
-/* RM external includes */\r
-#include <ti/drv/rm/rm.h>\r
-#include <ti/drv/rm/rm_services.h>\r
-#include <ti/drv/rm/rm_transport.h>\r
-\r
-/* RM internal includes */\r
-#include <ti/drv/rm/include/rm_loc.h>\r
-#include <ti/drv/rm/include/rm_transportloc.h>\r
-#include <ti/drv/rm/include/rm_nameserverloc.h>\r
-#include <ti/drv/rm/include/rm_dtb_utilloc.h>\r
-#include <ti/drv/rm/include/rm_policyloc.h>\r
-#include <ti/drv/rm/include/rm_treeloc.h>\r
-\r
-/* RM LIBFDT includes */\r
-#include <ti/drv/rm/util/libfdt/libfdt.h>\r
-\r
-/* Tree algorithm includes */\r
-#include <ti/drv/rm/util/tree.h>\r
-\r
-/* RM OSAL layer */\r
-#include <rm_osal.h>\r
-\r
-/**********************************************************************\r
- ************************** Globals ***********************************\r
- **********************************************************************/\r
-\r
-/** @brief Global Variable which describes the RM Version Information */\r
-const char  rmVersionStr[] = RM_VERSION_STR ":" __DATE__  ":" __TIME__;\r
-\r
-/**********************************************************************\r
- ************************ Local Functions *****************************\r
- **********************************************************************/\r
-\r
-/* FUNCTION PURPOSE: Initializes a RM inst's transaction sequence number\r
- ***********************************************************************\r
- * DESCRIPTION: The RM instance transaction sequence number can never\r
- *              have a value of 0 to avoid conflicts with transactions\r
- *              that have a remoteOriginatingId of 0 (transaction ID\r
- *              will be used as the remoteOriginatingId for\r
- *              transactions that are responses to requests).\r
- */\r
-static uint32_t transactionInitSequenceNum(void)\r
-{\r
-    return (1);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Provides a sequence number for new transactions\r
- ***********************************************************************\r
- * DESCRIPTION: Returns a sequence number for a new transaction\r
- *              specific to a RM instance.  Handles rollover of\r
- *              sequence number.\r
- */\r
-static uint32_t transactionGetSequenceNum(Rm_Inst *rmInst)\r
-{\r
-    uint32_t sequenceNum = 0;\r
-\r
-    if (rmInst->transactionSeqNum + 1 < rmInst->transactionSeqNum) {\r
-        /* Rollover */\r
-        sequenceNum = rmInst->transactionSeqNum;\r
-        rmInst->transactionSeqNum = transactionInitSequenceNum();\r
-    }\r
-    else {\r
-        sequenceNum = rmInst->transactionSeqNum++;\r
-    }    \r
-    return (sequenceNum);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Creates a resource allocator\r
- ***********************************************************************\r
- * DESCRIPTION: Returns a newly Created and initialized resource\r
- *              The allocator is also stored in the RM instance\r
- *              allocator list.            \r
- */\r
-static Rm_Allocator *allocatorAdd(Rm_Inst *rmInst, const char *resourceName)\r
-{\r
-    Rm_Allocator *allocators   = rmInst->allocators;\r
-    Rm_Allocator *newAllocator = NULL;\r
-\r
-    newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));\r
-\r
-    if (newAllocator) {\r
-        memset((void *)newAllocator, 0, sizeof(Rm_Allocator));\r
-        strncpy(newAllocator->resourceName, resourceName, RM_NAME_MAX_CHARS);\r
-        newAllocator->allocatorRootEntry = NULL;\r
-        newAllocator->nextAllocator = NULL;  \r
-\r
-        /* Add allocator to end of list */\r
-        if (allocators) {\r
-            while (allocators->nextAllocator) {\r
-                allocators = allocators->nextAllocator;\r
-            }\r
-            allocators->nextAllocator = newAllocator;\r
-        }\r
-        else {\r
-            rmInst->allocators = newAllocator;\r
-        }\r
-    }\r
-    return (newAllocator);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Deletes a resource allocator\r
- ***********************************************************************\r
- * DESCRIPTION: Deletes a resource allocator based on the given\r
- *              resource name.  The resource allocator will be\r
- *              removed from the RM instance allocator list.\r
- */\r
-static int32_t allocatorDelete(Rm_Inst *rmInst, char *resourceName)\r
-{\r
-    Rm_Allocator *allocator = rmInst->allocators;\r
-    Rm_Allocator *prevAllocator = NULL;\r
-    int32_t       retVal = RM_OK;\r
-\r
-    while (allocator) {\r
-        if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {\r
-            break;             \r
-        }\r
-        prevAllocator = allocator;\r
-        allocator = allocator->nextAllocator;\r
-    }\r
-\r
-    if (allocator) {\r
-        if (prevAllocator == NULL) {\r
-            rmInst->allocators = allocator->nextAllocator;\r
-        }\r
-        else {\r
-            prevAllocator->nextAllocator = allocator->nextAllocator;\r
-        }\r
-        Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));\r
-    }\r
-    else {\r
-        retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;\r
-    }\r
-    return (retVal);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Adds an owner to an allocator resource\r
- ***********************************************************************\r
- * DESCRIPTION: Adds a RM instance node to a resource node's\r
- *              list of owners.\r
- */\r
-static void addOwner(Rm_ResourceNode *node, void *serviceInstNode)\r
-{\r
-    Rm_Owner *ownerList = node->ownerList;\r
-    Rm_Owner *newOwner = NULL;\r
-\r
-    newOwner = Rm_osalMalloc(sizeof(Rm_Owner));\r
-\r
-    if (newOwner) {\r
-        newOwner->instNameNode = serviceInstNode;\r
-        newOwner->nextOwner = NULL;  \r
-\r
-        /* Add owner entry to end of list */\r
-        if (ownerList) {\r
-            while (ownerList->nextOwner) {\r
-                ownerList = ownerList->nextOwner;\r
-            }\r
-            ownerList->nextOwner = newOwner;\r
-        }\r
-        else {\r
-            node->ownerList = newOwner;\r
-        }\r
-\r
-        node->allocationCount++;\r
-        newOwner->instNameNode->allocRefCount++;\r
-    }\r
-}\r
-\r
-/* FUNCTION PURPOSE: Checks a resource node's ownership\r
- ***********************************************************************\r
- * DESCRIPTION: Returns TRUE if the provided instance node is\r
- *              in the list of resource node owners.  Otherwise,\r
- *              returns FALSE.\r
- */\r
-static bool isOwnedBy(Rm_ResourceNode *node, void *serviceInstNode)\r
-{\r
-    Rm_Owner *owner = node->ownerList;\r
-\r
-    while (owner) {\r
-        if (owner->instNameNode == serviceInstNode) {\r
-            return(true);           \r
-        }\r
-        owner = owner->nextOwner;\r
-    }\r
-    return(false);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Compares two resource node's owners\r
- ***********************************************************************\r
- * DESCRIPTION: Returns TRUE if the owners of two resource nodes \r
- *              are equivalent.  Otherwise, returns FALSE.\r
- */\r
-static bool compareResourceNodeOwners(Rm_ResourceNode *node1, Rm_ResourceNode *node2)\r
-{\r
-    Rm_Owner *node1Owners = node1->ownerList;\r
-    Rm_Owner *node2Owners = node2->ownerList;\r
-    bool      matchedInst;\r
-\r
-    if (node1->allocationCount == node2->allocationCount) {\r
-        while (node1Owners) {\r
-            matchedInst = false;\r
-            while (node2Owners) {\r
-                if (node1Owners->instNameNode == node2Owners->instNameNode) {\r
-                    matchedInst = true;\r
-                    break;\r
-                }\r
-                node2Owners = node2Owners->nextOwner;\r
-            }\r
-\r
-            if (matchedInst) {\r
-                node2Owners = node2->ownerList;\r
-                node1Owners = node1Owners->nextOwner;\r
-            }\r
-            else {\r
-                return(false);\r
-            }                \r
-        }\r
-    }\r
-    else {\r
-        return(false);\r
-    }  \r
-    \r
-    return(true);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Deletes an owner from an allocator resource\r
- ***********************************************************************\r
- * DESCRIPTION: Removes a RM instance node from a resource node's\r
- *              list of owners.\r
- */\r
-static void deleteOwner(Rm_ResourceNode *node, void *serviceInstNode)\r
-{\r
-    Rm_Owner *owner = node->ownerList;\r
-    Rm_Owner *prevOwner = NULL;\r
-\r
-    while (owner) {\r
-        if (owner->instNameNode == serviceInstNode) {\r
-            break;             \r
-        }\r
-        prevOwner = owner;\r
-        owner = owner->nextOwner;\r
-    }\r
-\r
-    if (prevOwner == NULL) {\r
-        node->ownerList = owner->nextOwner;\r
-    }\r
-    else {\r
-        prevOwner->nextOwner = owner->nextOwner;\r
-    }\r
-    \r
-    node->allocationCount--;\r
-    owner->instNameNode->allocRefCount--;\r
-    Rm_osalFree((void *)owner, sizeof(Rm_Owner));\r
-}\r
-\r
-/* FUNCTION PURPOSE: Copies the owners of a resource node\r
- ***********************************************************************\r
- * DESCRIPTION: Creates a list of resource owners for the destination\r
- *              resource node that is equivalent to the the \r
- *              source resource node's owners\r
- */\r
-static void copyOwners(Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)\r
-{\r
-    Rm_Owner *srcOwnerList = srcNode->ownerList;\r
-    Rm_Owner *dstNewOwner;\r
-    Rm_Owner *dstPrevOwner;\r
-\r
-    dstNode->allocationCount = srcNode->allocationCount;\r
-\r
-    while (srcOwnerList) {\r
-        dstNewOwner = Rm_osalMalloc(sizeof(Rm_Owner));\r
-        dstNewOwner->instNameNode = srcOwnerList->instNameNode;\r
-        dstNewOwner->nextOwner = NULL;\r
-\r
-        if (dstNode->ownerList == NULL) {\r
-            dstNode->ownerList = dstNewOwner;\r
-        }\r
-        else {\r
-            dstPrevOwner->nextOwner = dstNewOwner;\r
-        }\r
-        dstPrevOwner = dstNewOwner;\r
-        srcOwnerList = srcOwnerList->nextOwner;\r
-    }\r
-}\r
-\r
-/* FUNCTION PURPOSE: Clears a resource node's owners\r
- ***********************************************************************\r
- * DESCRIPTION: Deletes all owners from the owners list of a \r
- *              resource node.\r
- */\r
-static void clearOwners(Rm_ResourceNode *node)\r
-{\r
-    Rm_Owner *owner = node->ownerList;\r
-    Rm_Owner *nextOwner;\r
-\r
-    while (owner) {\r
-        nextOwner = owner->nextOwner;\r
-        node->allocationCount--;\r
-        Rm_osalFree((void *)owner, sizeof(Rm_Owner));\r
-        owner = nextOwner;\r
-    }\r
-}\r
-\r
-/* FUNCTION PURPOSE: Creates a new resource tree\r
- ***********************************************************************\r
- * DESCRIPTION: Creates a new resource tree using the provided\r
- *              resource name and value range.  The name and value\r
- *              typically originate from the GRL.\r
- */\r
-static int32_t createResourceTree(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)\r
-{\r
-    Rm_Allocator    *allocator = NULL;\r
-    Rm_ResourceTree *treeRootEntry = NULL;\r
-    Rm_ResourceNode *treeNode = NULL;\r
-    Rm_ResourceNode *collidingNode = NULL;\r
-\r
-    allocator = allocatorAdd(rmInst, resourceName);\r
-    treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));\r
-    RB_INIT(treeRootEntry);\r
-\r
-    while (range != NULL) {\r
-        treeNode = rmResourceNodeNew(range->base, range->length);\r
-        collidingNode = RB_INSERT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);\r
-\r
-        if (collidingNode) {\r
-            Rm_ResourceNode *nextNode = NULL;\r
-            \r
-            /* Node that was inserted collides with existing node.  Destroy tree and return error */\r
-            for (treeNode = RB_MIN(_Rm_AllocatorResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode) {\r
-                       nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);\r
-                       RB_REMOVE(_Rm_AllocatorResourceTree, treeRootEntry, nextNode);\r
-                rmResourceNodeFree(treeNode);\r
-               }\r
-            Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));\r
-            allocatorDelete(rmInst, allocator->resourceName);\r
-            return (RM_ERROR_GRL_RES_SPECIFIED_MORE_THAN_ONCE);\r
-        }\r
-        range = range->nextRange;\r
-    }\r
-    \r
-    allocator->allocatorRootEntry = treeRootEntry;\r
-    return(RM_OK);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Preallocates a resource\r
- ***********************************************************************\r
- * DESCRIPTION: Called when an allocate request is made but the base \r
- *              is unspecified.  The preallocation algorithm looks at \r
- *              available resources as well as policy permissions to \r
- *              determine a resource range that satisfies the request.\r
- *              If a valid range is found it will be returned for the \r
- *              treeAllocate algorithm to handle.\r
- */\r
-static int32_t treePreAllocate(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t resourcePolicy,\r
-                               Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    Rm_ResourceNode    findNode;\r
-    Rm_ResourceNode   *matchingNode = NULL;\r
-    uint32_t           matchingEnd;\r
-    uint32_t           rangeIndex;\r
-    bool               resourceFound = false;\r
-    Rm_PolicyCheckType policyCheckType;\r
-    Rm_PolicyCheckCfg  policyCheckCfg;\r
-    bool               nodePassesPolicy;\r
-    int32_t            retVal = RM_SERVICE_PROCESSING;    \r
-\r
-    opInfo->resourceInfo->base = rmPolicyGetResourceBase(rmInst->policy, opInfo->serviceSrcInstNode, \r
-                                                          resourcePolicy, opInfo->allocType, \r
-                                                          &retVal);\r
-    if (retVal != RM_SERVICE_PROCESSING) {\r
-        return (retVal);\r
-    }\r
-\r
-    if (opInfo->resourceInfo->alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) {  \r
-        /* Get alignment from policy */\r
-        opInfo->resourceInfo->alignment = rmPolicyGetResourceAlignment(rmInst->policy, resourcePolicy);\r
-    }\r
-    \r
-    if (opInfo->resourceInfo->alignment == 0) {\r
-        opInfo->resourceInfo->alignment = 1;\r
-    }    \r
-\r
-    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));\r
-    findNode.base = opInfo->resourceInfo->base;\r
-    findNode.length = opInfo->resourceInfo->length;\r
-\r
-    /* Configure policy checking structure */\r
-    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));\r
-    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {\r
-        policyCheckType = Rm_policyCheck_INIT;\r
-    }\r
-    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {\r
-        policyCheckType = Rm_policyCheck_USE;\r
-    }\r
-    policyCheckCfg.policyDtb = rmInst->policy;\r
-    policyCheckCfg.resourceOffset = resourcePolicy;\r
-    \r
-    do {\r
-        matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);\r
-        \r
-        if (matchingNode) {\r
-            nodePassesPolicy = false;\r
-            policyCheckCfg.type = policyCheckType;\r
-            policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
-            policyCheckCfg.resourceBase = findNode.base;\r
-            policyCheckCfg.resourceLength = findNode.length;\r
-            nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);    \r
-            \r
-            if (nodePassesPolicy && (matchingNode->allocationCount > 0)) {\r
-                /* Check exclusive privileges of instance requesting resource.  Requesting\r
-                 * instance with exclusive privileges can't reserve resource if already owned*/\r
-                policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
-                policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
-                nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);\r
-            }\r
-            \r
-            if (nodePassesPolicy && (matchingNode->allocationCount == 1)) {\r
-                /* Check exclusive privileges of instance that currently owns resource */\r
-                policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
-                policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;\r
-                nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);\r
-            }\r
-\r
-            if (retVal != RM_SERVICE_PROCESSING) {\r
-                break;\r
-            }\r
-\r
-            if (nodePassesPolicy) {\r
-                matchingEnd = matchingNode->base + matchingNode->length - 1;\r
-                /* Initialize indexer to be first resource value that alignment */\r
-                rangeIndex = findNode.base;\r
-                if (rangeIndex % opInfo->resourceInfo->alignment) {\r
-                    rangeIndex += (opInfo->resourceInfo->alignment -\r
-                                  (rangeIndex % opInfo->resourceInfo->alignment));\r
-                }\r
-                \r
-                if ((rangeIndex + opInfo->resourceInfo->length - 1) <= matchingEnd) {\r
-                    /* Block of unallocated resources within matchingNode that satisfies\r
-                     * allocate requirements */\r
-                    opInfo->resourceInfo->base = rangeIndex;\r
-                    resourceFound = true;\r
-                }     \r
-            }\r
-            \r
-            if (!resourceFound) {\r
-                /* Check next resource node for available resources */\r
-                findNode.base = matchingNode->base + matchingNode->length;\r
-            }\r
-        }\r
-        else {\r
-            retVal = RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET;\r
-        }\r
-    } while ((!resourceFound) && \r
-             (retVal != RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET));\r
-\r
-    return(retVal); \r
-}\r
-\r
-/* FUNCTION PURPOSE: Allocates a resource\r
- ***********************************************************************\r
- * DESCRIPTION: Will attempt to allocate the resource with specified\r
- *              base and length from the resource's allocator.  The\r
- *              allocation algorithm will verify the allocation against\r
- *              the policy permissions for the instance requesting the\r
- *              allocation.  If the policy allows the allocation the \r
- *              algorithm will allocate the resource then combine any\r
- *              resource nodes that may have become equivalent (in terms\r
- *              of ownership) after the allocation.\r
- */\r
-static int32_t treeAllocate(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t resourcePolicy,\r
-                            Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    Rm_ResourceNode     findNode;\r
-    Rm_ResourceNode    *matchingNode = NULL;\r
-    Rm_ResourceNode    *leftNode = NULL;\r
-    Rm_ResourceNode    *rightNode = NULL;\r
-    Rm_PolicyCheckType  policyCheckType;    \r
-    Rm_PolicyCheckCfg   policyCheckCfg;\r
-    bool                allocPassesPolicy;\r
-    bool                combineLeft = false;\r
-    bool                combineRight = false;    \r
-    uint32_t            findEnd;\r
-    uint32_t            matchingEnd;  \r
-    int32_t             retVal = RM_SERVICE_PROCESSING;\r
-\r
-    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));\r
-    findNode.base = opInfo->resourceInfo->base;\r
-    findNode.length = opInfo->resourceInfo->length;\r
-    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);\r
-\r
-    /* Prepare privilege checks */\r
-    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));\r
-    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {\r
-        policyCheckType = Rm_policyCheck_INIT;\r
-    }\r
-    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {\r
-        policyCheckType = Rm_policyCheck_USE;\r
-    }\r
-\r
-    if (matchingNode) {\r
-        findEnd = findNode.base + findNode.length - 1;\r
-        matchingEnd = matchingNode->base + matchingNode->length - 1;\r
-        \r
-        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {\r
-            if (opInfo->serviceSrcInstNode == rmPolicyGetLinuxInstNode(rmInst->validInstances)) {\r
-                /* Bypass policy checks since Linux Kernel has full privileges */\r
-                allocPassesPolicy = true;\r
-            }\r
-            else {\r
-                policyCheckCfg.policyDtb = rmInst->policy;\r
-                policyCheckCfg.resourceOffset = resourcePolicy;    \r
-                policyCheckCfg.type = policyCheckType;\r
-                policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
-                policyCheckCfg.resourceBase = findNode.base;\r
-                policyCheckCfg.resourceLength = findNode.length;\r
-                allocPassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);\r
-                if (!allocPassesPolicy) {\r
-                    if (policyCheckType == Rm_policyCheck_INIT) {\r
-                        retVal = RM_SERVICE_DENIED_INIT_PERM_NOT_GIVEN;\r
-                    }\r
-                    else {\r
-                        retVal = RM_SERVICE_DENIED_USE_PERM_NOT_GIVEN;\r
-                    }\r
-                }\r
-                \r
-                if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {\r
-                    /* Check exclusive privileges of instance requesting resource.  Requesting\r
-                     * instance with exclusive privileges can't reserve resource if already owned*/\r
-                    policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
-                    policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
-                    allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);\r
-                    if (!allocPassesPolicy) {\r
-                        retVal = RM_SERVICE_DENIED_EXCLUSIVE_RES_ALLOCD;\r
-                    }\r
-                }\r
-                if (allocPassesPolicy && (matchingNode->allocationCount == 1)) {\r
-                    /* Check exclusive privileges of instance that currently owns resource */\r
-                    policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
-                    policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;\r
-                    allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);\r
-                    if (!allocPassesPolicy) {\r
-                        retVal = RM_SERVICE_DENIED_ALLOCD_TO_EXCLUSIVE_INST;\r
-                    }                \r
-                }  \r
-            }\r
-            \r
-            if (allocPassesPolicy) {   \r
-                if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {\r
-                    /* findNode range matches matchingNode range\r
-                     *\r
-                     *   |<--left node-->||<--matched  node-->||<--right node-->| => existing node\r
-                     *                    |<--alloc request-->|  => requested resources\r
-                     */                     \r
-                    leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-\r
-                    if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {\r
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                        combineLeft = true;\r
-                    }\r
-                    if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {\r
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                        combineRight = true;\r
-                    }\r
-\r
-                    if (combineLeft && combineRight) {\r
-                        /* Combine all three nodes into matchingNode */\r
-                        matchingNode->base = leftNode->base;\r
-                        matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;\r
-\r
-                        clearOwners(leftNode);\r
-                        rmResourceNodeFree(leftNode);\r
-                        clearOwners(rightNode);\r
-                        rmResourceNodeFree(rightNode);                        \r
-                    }\r
-                    else if (combineLeft) {\r
-                        /* Combine left and matching nodes.  Reinsert right. */\r
-                        matchingNode->base = leftNode->base;\r
-                        matchingNode->length += leftNode->length;\r
-\r
-                        clearOwners(leftNode);\r
-                        rmResourceNodeFree(leftNode);\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        \r
-                    }\r
-                    else if (combineRight) {\r
-                        /* Combine right and matching nodes.  Reinsert left. */\r
-                        matchingNode->length += rightNode->length;\r
-\r
-                        clearOwners(rightNode);\r
-                        rmResourceNodeFree(rightNode);\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                    }\r
-                    else {\r
-                        /* No combine. */\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                    }\r
-\r
-                    /* Always reinsert matchingNode */                \r
-                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);   \r
-                }   \r
-                else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {\r
-                    /* findNode range is subset of matchingNode range and neither boundary is\r
-                     * equivalent.\r
-                     *\r
-                     * |<----------matched node---------->|\r
-                     *        |<---alloc request--->|\r
-                     */ \r
-                    RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);\r
-                    copyOwners(leftNode, matchingNode);\r
-                    rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);\r
-                    copyOwners(rightNode, matchingNode);\r
-\r
-                    matchingNode->base = findNode.base;                                    \r
-                    matchingNode->length = findNode.length;\r
-                    addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-\r
-                    /* Insert all the nodes */\r
-                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                }  \r
-                else {    \r
-                    if (findNode.base == matchingNode->base) {\r
-                        /* findNode base and matchingNode base are equivalent.  May be combine\r
-                         * possibilities to the left\r
-                         *\r
-                         * |<---left node (alloc'd)--->||<----------matched node---------->|\r
-                         *                              |<---findNode (alloc req)--->|\r
-                         */                         \r
-                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        /* Add allocating instance to owner list for compare with leftNode */\r
-                        addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-                        \r
-                        if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {\r
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                            /* Combine leftNode and findNode */\r
-                            leftNode->length += findNode.length;\r
-                        }\r
-                        else {\r
-                            leftNode = rmResourceNodeNew(findNode.base, findNode.length);\r
-                            copyOwners(leftNode, matchingNode);\r
-                        }\r
-\r
-                        /* Account for leftNode in matchingNode */\r
-                        matchingNode->base = findNode.base + findNode.length;\r
-                        matchingNode->length = matchingEnd - findEnd;  \r
-\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                    }\r
-                    else if (findEnd == matchingEnd) {\r
-                        /* findNode end and matchingNode end are equivalent.  May be combine\r
-                         * possibilities to the right\r
-                         *\r
-                         * |<----------matched node---------->||<---right node (alloc'd)--->|\r
-                         *       |<---findNode (alloc req)--->| \r
-                         */                        \r
-                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        /* Add allocating instance to owner list for compare with rightNode */\r
-                        addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-                        \r
-                        if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {\r
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                            /* Combine rightNode and findNode */\r
-                            rightNode->base = findNode.base;\r
-                            rightNode->length += findNode.length;\r
-                        }\r
-                        else {\r
-                            rightNode = rmResourceNodeNew(findNode.base, findNode.length);\r
-                            copyOwners(rightNode, matchingNode);\r
-                        }\r
-\r
-                        /* Account for rightNode in matchingNode */\r
-                        matchingNode->length -= findNode.length;  \r
-\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                    }\r
-                    /* Remove allocating instance from leftover matchingNode */\r
-                    deleteOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                }\r
-                retVal = RM_SERVICE_APPROVED;\r
-            }\r
-        }\r
-        else {\r
-            retVal = RM_SERVICE_DENIED_PARTIAL_ALLOCATION;\r
-        }\r
-    }\r
-    else {\r
-        retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;\r
-    }\r
-\r
-    return(retVal);        \r
-}\r
-\r
-/* FUNCTION PURPOSE: Frees a resource\r
- ***********************************************************************\r
- * DESCRIPTION: Will attempt to free the resource with specified\r
- *              base and length from the resource's allocator.  The\r
- *              free algorithm will verify the free request parameters\r
- *              match an allocated range for the resource and that the\r
- *              range is owned by the instance requesting the free. If\r
- *              the free is validated the algorithm will free the \r
- *              resource then combine any resource nodes that may have\r
- *              become equivalent (in terms of ownership) after the\r
- *              allocation.\r
- */\r
-static int32_t treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    Rm_ResourceNode  findNode;\r
-    Rm_ResourceNode *matchingNode = NULL;\r
-    Rm_ResourceNode *leftNode = NULL;\r
-    Rm_ResourceNode *rightNode = NULL;\r
-    bool             combineLeft = false;\r
-    bool             combineRight = false;\r
-    uint32_t         findEnd;\r
-    uint32_t         matchingEnd;\r
-    int32_t          retVal;\r
-\r
-    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));\r
-    findNode.base = opInfo->resourceInfo->base;\r
-    findNode.length = opInfo->resourceInfo->length;\r
-    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);\r
-\r
-    if (matchingNode) {\r
-        findEnd = findNode.base + findNode.length - 1;\r
-        matchingEnd = matchingNode->base + matchingNode->length - 1;\r
-        \r
-        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {  \r
-            if (matchingNode->allocationCount) {\r
-                if (isOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {\r
-                    if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))\r
-                    {\r
-                        /* Case 1: Free range equals allocated matched node exactly. Attempt to combine \r
-                         *         freed node with nodes to left and right.\r
-                         *\r
-                         * |<--left node-->||<---matched node--->||<--right node-->|\r
-                         *                  |<---free request--->|\r
-                         */ \r
-                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        deleteOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-\r
-                        if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {\r
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                            combineLeft = true;\r
-                        }\r
-                        if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {\r
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                            combineRight = true;\r
-                        }\r
-\r
-                        if (combineLeft && combineRight) {\r
-                            /* Combine all three nodes into matchingNode */\r
-                            matchingNode->base = leftNode->base;\r
-                            matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;\r
-\r
-                            clearOwners(leftNode);\r
-                            rmResourceNodeFree(leftNode);\r
-                            clearOwners(rightNode);\r
-                            rmResourceNodeFree(rightNode);                        \r
-                        }\r
-                        else if (combineLeft) {\r
-                            /* Combine left and matching nodes.  Reinsert right. */\r
-                            matchingNode->base = leftNode->base;\r
-                            matchingNode->length += leftNode->length;\r
-\r
-                            clearOwners(leftNode);\r
-                            rmResourceNodeFree(leftNode);\r
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        \r
-                        }\r
-                        else if (combineRight) {\r
-                            /* Combine right and matching nodes.  Reinsert left. */\r
-                            matchingNode->length += rightNode->length;\r
-\r
-                            clearOwners(rightNode);\r
-                            rmResourceNodeFree(rightNode);\r
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                        }\r
-                        else {\r
-                            /* No combine. */\r
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                        }\r
-\r
-                        /* Always reinsert matchingNode */\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);                    \r
-                    }\r
-                    else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {\r
-                        /* Case 2: Free range is less than range in matched node. Split\r
-                         *         matched node into three nodes.\r
-                         *\r
-                         * |<----------matched node---------->|\r
-                         *        |<---free request--->|\r
-                         *\r
-                         * Remove instance from AllocatedTo list then add it back in for side nodes for\r
-                         * proper accounting of allocations in validInstance list\r
-                         */ \r
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        deleteOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-                        \r
-                        leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);\r
-                        copyOwners(leftNode, matchingNode);\r
-                        addOwner(leftNode, opInfo->serviceSrcInstNode);\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                        \r
-                        rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);\r
-                        copyOwners(rightNode, matchingNode);\r
-                        addOwner(rightNode, opInfo->serviceSrcInstNode);\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-\r
-                        matchingNode->base = findNode.base;                                    \r
-                        matchingNode->length = findNode.length;\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    }\r
-                    else {                        \r
-                        if (findNode.base == matchingNode->base) {\r
-                            /* Case 3: Free range is on left boundary of matched node. Try to \r
-                             *         combine free range with left node.\r
-                             *\r
-                             * |<---left node (free)--->||<----------matched node---------->|\r
-                             *                           |<---findNode (free req)--->|\r
-                             */ \r
-\r
-                            leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                            /* Remove freeing instance from owner list for compare with leftNode */\r
-                            deleteOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-                            \r
-                            if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {\r
-                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                                /* Combine leftNode and findNode */\r
-                                leftNode->length += findNode.length;\r
-                            }\r
-                            else {\r
-                                leftNode = rmResourceNodeNew(findNode.base, findNode.length);\r
-                                copyOwners(leftNode, matchingNode);\r
-                            }\r
-\r
-                            /* Remove leftNode range from matchingNode */\r
-                            matchingNode->base = findNode.base + findNode.length;\r
-                            matchingNode->length = matchingEnd - findEnd;  \r
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                        }\r
-                        else if (findEnd == matchingEnd) {\r
-                            /* Case 4: Free range is on right boundary of matched node. Try to \r
-                             *         combine free range with right node.\r
-                             *\r
-                             * |<----------matched node---------->||<---right node (free)--->|\r
-                             *        |<---findNode (free req)--->|\r
-                             */ \r
-                            \r
-                            rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode); \r
-                            /* Remove freeing instance from owner list for compare with rightNode */\r
-                            deleteOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-                            \r
-                            if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {\r
-                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                                /* Combine rightNode and findNode */\r
-                                rightNode->base = findNode.base;\r
-                                rightNode->length += findNode.length;\r
-                            }\r
-                            else {\r
-                                rightNode = rmResourceNodeNew(findNode.base, findNode.length);\r
-                                copyOwners(rightNode, matchingNode);\r
-                            }\r
-\r
-                            /* Remove rightNode range from matchingNode */\r
-                            matchingNode->length -= findNode.length;  \r
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                        }\r
-\r
-                        /* Add freeing instance back into matchingNode allocations */\r
-                        addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    }\r
-\r
-                    retVal = RM_SERVICE_APPROVED;\r
-                }\r
-                else {\r
-                    retVal = RM_SERVICE_DENIED_RES_NOT_ALLOCD_TO_INST;\r
-                }\r
-            }\r
-            else {\r
-                retVal = RM_SERVICE_DENIED_RES_ALREADY_FREE;\r
-            }\r
-        }\r
-        else {\r
-            retVal = RM_SERVICE_DENIED_PARTIAL_FREE;\r
-        }\r
-    }\r
-    else {\r
-        retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;\r
-    }\r
-    return(retVal);  \r
-}\r
-\r
-/* FUNCTION PURPOSE: Issues a service response to application\r
- ***********************************************************************\r
- * DESCRIPTION: Provides a service response back to the application\r
- *              using the service callback function provided to\r
- *              the RM instance at the time of the service request.\r
- */\r
-static void serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
-{\r
-    Rm_ServiceRespInfo serviceResponse;\r
-\r
-    /* The responseTransaction will contain the resultant state details of\r
-     * the requestTransaction's service request */\r
-    serviceResponse.serviceState = transaction->state;\r
-    /* Pass back the ID that was provided to the component when it requested\r
-     * the service */\r
-    serviceResponse.serviceId = transaction->localId;\r
-\r
-    /* Service was approved and service was an allocate request.  The resource\r
-     * data is passed back to the component */\r
-    if ((serviceResponse.serviceState == RM_SERVICE_APPROVED) &&\r
-        ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||\r
-         (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||\r
-         (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)))\r
-    {\r
-        strncpy(serviceResponse.resourceName, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);\r
-        serviceResponse.resourceBase = transaction->resourceInfo.base;\r
-        serviceResponse.resourceLength = transaction->resourceInfo.length;\r
-    }\r
-\r
-    /* Issue the callback to the requesting component with the response information */\r
-    transaction->callback.serviceCallback(&serviceResponse);\r
-\r
-    /* Delete the transaction from the transaction queue */\r
-    rmTransactionQueueDelete(rmInst, transaction->localId);\r
-    return;\r
-}\r
-\r
-/* FUNCTION PURPOSE: Sends RM response packets\r
- ***********************************************************************\r
- * DESCRIPTION: Sends RM response packets to RM instance's that sent\r
- *              RM request packets to the RM instance.  The response\r
- *              is sent via the RM transport API which is plugged\r
- *              with an application created transport path.\r
- */\r
-static void transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
-{\r
-    Rm_Transport    *dstTransport = NULL;\r
-    Rm_PacketHandle  pktHandle = NULL;\r
-\r
-    dstTransport = rmTransportFindRemoteName((Rm_Transport *) rmInst->transports, transaction->pktSrcInstName);\r
-\r
-    switch (transaction->type) {\r
-        case Rm_service_RESOURCE_ALLOCATE_INIT:\r
-        case Rm_service_RESOURCE_ALLOCATE_USE:\r
-        case Rm_service_RESOURCE_FREE:\r
-        case Rm_service_RESOURCE_GET_BY_NAME:\r
-            pktHandle = rmTransportCreateResourceResponsePkt(rmInst, dstTransport->appTransportHandle, \r
-                                                             transaction);\r
-            break;\r
-        case Rm_service_RESOURCE_MAP_TO_NAME:\r
-        case Rm_service_RESOURCE_UNMAP_NAME:\r
-            pktHandle = rmTransportCreateNsResponsePkt(rmInst, dstTransport->appTransportHandle,\r
-                                                       transaction);\r
-            break;\r
-    }\r
-\r
-    if (pktHandle) {\r
-        if (rmInst->transportCallouts.rmSendPkt) {\r
-            if (rmInst->transportCallouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {\r
-                transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;\r
-            }\r
-        }\r
-        else {\r
-            transaction->state = RM_ERROR_TRANSPORT_SEND_NOT_REGD;\r
-        }\r
-    }\r
-    rmTransactionQueueDelete(rmInst, transaction->localId);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Sends RM request packets\r
- ***********************************************************************\r
- * DESCRIPTION: Sends RM request packets to RM instance's that are\r
- *              capable of forwarding or validating service requests.\r
- *              The request is sent via the RM transport API which is\r
- *              plugged with an application created transport path.\r
- */\r
-static void transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
-{\r
-    Rm_Transport    *dstTransport = NULL;\r
-    Rm_PacketHandle  pktHandle = NULL;\r
-\r
-    if (rmInst->registeredWithDelegateOrServer) {\r
-        if (rmInst->instType == Rm_instType_CLIENT) {\r
-            dstTransport = rmTransportFindRemoteInstType((Rm_Transport *) rmInst->transports, Rm_instType_CLIENT_DELEGATE);\r
-\r
-            if (!dstTransport) {\r
-                dstTransport = rmTransportFindRemoteInstType((Rm_Transport *) rmInst->transports, Rm_instType_SERVER);\r
-            }\r
-        } \r
-        else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {\r
-            dstTransport = rmTransportFindRemoteInstType((Rm_Transport *) rmInst->transports, Rm_instType_SERVER);\r
-        }\r
-\r
-        switch (transaction->type) {\r
-            case Rm_service_RESOURCE_ALLOCATE_INIT:\r
-            case Rm_service_RESOURCE_ALLOCATE_USE:\r
-            case Rm_service_RESOURCE_FREE:\r
-            case Rm_service_RESOURCE_GET_BY_NAME:\r
-                pktHandle = rmTransportCreateResourceReqPkt(rmInst, dstTransport->appTransportHandle, transaction);\r
-                break;\r
-            case Rm_service_RESOURCE_MAP_TO_NAME:\r
-            case Rm_service_RESOURCE_UNMAP_NAME:\r
-                pktHandle = rmTransportCreateNsRequestPkt(rmInst, dstTransport->appTransportHandle, transaction);\r
-                break;\r
-        }\r
-\r
-        if (pktHandle) {\r
-            if (rmInst->transportCallouts.rmSendPkt) {            \r
-                if (rmInst->transportCallouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {\r
-                    transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;\r
-                }\r
-            }\r
-            else {\r
-                transaction->state = RM_ERROR_TRANSPORT_SEND_NOT_REGD;\r
-            }                \r
-        }\r
-\r
-        transaction->hasBeenForwarded = true;\r
-        /* Transaction not deleted.  Waiting for response from RM CD or Server */\r
-    }\r
-}\r
-\r
-/* FUNCTION PURPOSE: Issues an allocator operation\r
- ***********************************************************************\r
- * DESCRIPTION: Issues an allocator preallocate, allocate, or free\r
- *              for an RM resource.\r
- */\r
-static int32_t allocatorOperation(Rm_Inst *rmInst, Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    Rm_Allocator *allocator = NULL;\r
-    int32_t       resourceOffsetInPolicy;\r
-    int32_t       retVal;\r
-    \r
-    resourceOffsetInPolicy = rmPolicyGetResourceOffset(rmInst->policy, opInfo->resourceInfo->name);\r
-    allocator = rmAllocatorFind(rmInst->allocators, opInfo->resourceInfo->name);\r
-    \r
-    if ((resourceOffsetInPolicy > 0) && allocator) {\r
-        if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE) {\r
-            retVal = treePreAllocate(rmInst, allocator, resourceOffsetInPolicy, opInfo);\r
-        }               \r
-        else if (opInfo->operation == Rm_allocatorOp_ALLOCATE) {\r
-            retVal = treeAllocate(rmInst, allocator, resourceOffsetInPolicy, opInfo);\r
-        }\r
-        else if (opInfo->operation == Rm_allocatorOp_FREE) {\r
-            retVal = treeFree(allocator, opInfo);\r
-        }         \r
-    }\r
-    else {\r
-        /* Resource could not be found in policy and/or allocator */\r
-        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;\r
-    }\r
-    return(retVal);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Arbitrates allocation service requests\r
- ***********************************************************************\r
- * DESCRIPTION: Issues a set of allocator operations in order to\r
- *              handle a received allocation request.  Allocation\r
- *              requests are always forwarded to the Server on Client\r
- *              CD instances.  If a request is made with a NameServer\r
- *              name the resource base and length parameters are\r
- *              retrieved from the NameServer prior to the allocation\r
- *              attempt.\r
- */\r
-static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode,\r
-                               uint32_t allocType)\r
-{\r
-    Rm_AllocatorOpInfo  opInfo;\r
-    Rm_NameServerObjCfg nameServerObjCfg;\r
-    int32_t             retVal = transaction->state;\r
-\r
-    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
-    \r
-    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {\r
-        /* Forward all allocation requests to Server if transport is up.  Otherwise, just queue. */\r
-        if (rmInst->registeredWithDelegateOrServer) {\r
-            transactionForwarder(rmInst, transaction);   \r
-        }  \r
-    }\r
-    else if (rmInst->instType == Rm_instType_SERVER) {\r
-        opInfo.resourceInfo = &transaction->resourceInfo;\r
-        opInfo.serviceSrcInstNode = validInstNode;\r
-        opInfo.allocType = allocType;\r
-\r
-        /* Populated NameServer name has precedence over base */\r
-        if (strlen(transaction->resourceInfo.nameServerName) > 0) {\r
-            if ((transaction->resourceInfo.base == 0) &&\r
-                (transaction->resourceInfo.length == 0) &&\r
-                (transaction->resourceInfo.alignment == 0)) {\r
-                memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));\r
-                nameServerObjCfg.nameServerTree = rmInst->nameServer;\r
-                nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;\r
-                if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {\r
-                    strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);\r
-                    transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;\r
-                    transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;\r
-                }                \r
-            }\r
-            else {\r
-                retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;\r
-            }\r
-        }\r
-\r
-        if (retVal == RM_SERVICE_PROCESSING) {      \r
-            if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {\r
-                opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;\r
-                retVal = allocatorOperation(rmInst, &opInfo);\r
-            }\r
-        \r
-            if (retVal == RM_SERVICE_PROCESSING) {\r
-                opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
-                retVal = allocatorOperation(rmInst, &opInfo);\r
-            }      \r
-        }\r
-        \r
-        transaction->state = retVal;\r
-\r
-        if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {\r
-            /* Source of allocation was not the server instance, provide the transaction\r
-             * to the transaction responder */\r
-            transactionResponder(rmInst, transaction);\r
-        }\r
-        /* Otherwise let the return stack return the transaction to the serviceHandler */                   \r
-    }   \r
-}\r
-\r
-/* FUNCTION PURPOSE: Arbitrates free service requests\r
- ***********************************************************************\r
- * DESCRIPTION: Issues a set of allocator operations in order to\r
- *              handle a received free request.  Free\r
- *              requests are always forwarded to the Server on Client\r
- *              CD instances.  If a request is made with a NameServer\r
- *              name the resource base and length parameters are\r
- *              retrieved from the NameServer prior to the free\r
- *              attempt.\r
- */\r
-static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode)\r
-{\r
-    Rm_AllocatorOpInfo  opInfo; \r
-    Rm_NameServerObjCfg nameServerObjCfg;    \r
-    int32_t             retVal = transaction->state;\r
-\r
-    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
-    \r
-    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {\r
-        /* Forward all free requests to Server if transport is up.  Otherwise, just queue. */\r
-        if (rmInst->registeredWithDelegateOrServer) {\r
-            transactionForwarder(rmInst, transaction);   \r
-        }\r
-    }\r
-    else if (rmInst->instType == Rm_instType_SERVER) {\r
-        opInfo.resourceInfo = &transaction->resourceInfo;\r
-        opInfo.serviceSrcInstNode = validInstNode;\r
-\r
-        /* Populated NameServer name has precedence over base */\r
-        if (strlen(transaction->resourceInfo.nameServerName) > 0) {\r
-            if ((transaction->resourceInfo.base == 0) &&\r
-                (transaction->resourceInfo.length == 0) &&\r
-                (transaction->resourceInfo.alignment == 0)) {\r
-                memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));\r
-                nameServerObjCfg.nameServerTree = rmInst->nameServer;\r
-                nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;\r
-                if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {\r
-                    strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);\r
-                    transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;\r
-                    transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;\r
-                } \r
-            }\r
-            else {\r
-                retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;\r
-            }                \r
-        }\r
-        \r
-        if(retVal == RM_SERVICE_PROCESSING) {        \r
-            opInfo.operation = Rm_allocatorOp_FREE;\r
-            retVal = allocatorOperation(rmInst, &opInfo);\r
-        }       \r
-\r
-        transaction->state = retVal;\r
-\r
-        if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {\r
-            /* Source of allocation was not the server instance, provide the transaction\r
-             * to the transaction responder */\r
-            transactionResponder(rmInst, transaction);\r
-        }\r
-        /* Otherwise let the return stack return the transaction to the serviceHandler */        \r
-    }   \r
-}\r
-\r
-/* FUNCTION PURPOSE: Reserves a Linux resource\r
- ***********************************************************************\r
- * DESCRIPTION: Reserves resources for Linux using the base and length\r
- *              values retrieved from the Linux DTB via the\r
- *              "linux-dtb-alias" properties within the GRL.\r
- */\r
-static int32_t reserveLinuxResource(Rm_Inst *rmInst, Rm_LinuxAlias *linuxAlias, \r
-                                    Rm_LinuxValueRange *linuxValues, Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    int32_t  retVal = RM_OK;\r
-    bool     baseFound = false;\r
-    bool     lengthFound = false;\r
-    uint32_t valueIndex = 0;\r
-\r
-    while ((linuxValues) && (!baseFound || !lengthFound)) {\r
-        if (linuxAlias->baseOffset == valueIndex) {\r
-            opInfo->resourceInfo->base = linuxValues->value;\r
-            baseFound = true;\r
-\r
-            if (linuxAlias->lengthOffset == RM_DTB_UTIL_LINUX_ALIAS_OFFSET_NOT_SET) {\r
-                opInfo->resourceInfo->length = 1;\r
-                lengthFound = true;\r
-            }\r
-        }\r
-        else if (linuxAlias->lengthOffset == valueIndex) {\r
-            opInfo->resourceInfo->length = linuxValues->value;\r
-            lengthFound = true;\r
-        }\r
-\r
-        linuxValues = (Rm_LinuxValueRange *)linuxValues->nextValue;\r
-        valueIndex++;\r
-    }\r
-\r
-    if (!baseFound || !lengthFound) {\r
-        retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;\r
-    }\r
-    else {\r
-        /* Allocate resource to Linux */\r
-        retVal = allocatorOperation(rmInst, opInfo);\r
-    }\r
-    return (retVal);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Finds and reserves Linux resources\r
- ***********************************************************************\r
- * DESCRIPTION: Parses the Linux DTB for resources consumed by the\r
- *              Linux kernel.  If the resource is found via the\r
- *              "linux-dtb-alias" property defined in the GRL it is \r
- *              reserved.\r
- */\r
-static int32_t findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName, void *linuxDtb, \r
-                                           Rm_LinuxAlias *linuxAlias)\r
-{\r
-    Rm_AllocatorOpInfo  opInfo;\r
-    Rm_ResourceInfo     resourceInfo;\r
-    uint32_t            pathOffset;\r
-    uint32_t            pathSize;\r
-    char               *spacePtr;\r
-    int32_t             propOffset;\r
-    int32_t             nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
-    int32_t             prevDepth = RM_DTB_UTIL_STARTING_DEPTH;\r
-    int32_t             depth;\r
-    int32_t             propertyLen;\r
-    const char         *propertyName;\r
-    const void         *propertyData; \r
-    Rm_LinuxValueRange *linuxValueRange;\r
-    int32_t             retVal = RM_OK; \r
-\r
-    memset((void *) &opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
-    memset((void *) &resourceInfo, 0, sizeof(Rm_ResourceInfo));\r
-\r
-    strncpy(resourceInfo.name, resourceName, RM_NAME_MAX_CHARS);\r
-    opInfo.serviceSrcInstNode = rmPolicyGetLinuxInstNode(rmInst->validInstances);\r
-    opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
-    opInfo.resourceInfo = &resourceInfo;    \r
-\r
-    while(linuxAlias) {\r
-        /* Reset parsing variables */\r
-        pathOffset = 0;\r
-        pathSize = strlen(linuxAlias->path) + 1;\r
-        nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
-        prevDepth = RM_DTB_UTIL_STARTING_DEPTH;   \r
-        resourceInfo.base = 0;\r
-        resourceInfo.length = 0;\r
-\r
-        spacePtr = strpbrk(linuxAlias->path, " ");\r
-        if (spacePtr) {\r
-            *spacePtr = '\0';\r
-        }       \r
-        \r
-        while(pathOffset < pathSize) {\r
-            /* Move through DTB nodes until next alias path node found */\r
-            if (strcmp(linuxAlias->path + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL))) {\r
-                nodeOffset = fdt_next_node(linuxDtb, nodeOffset, &depth);\r
-\r
-                if ((depth < prevDepth) || (nodeOffset == -FDT_ERR_NOTFOUND)) {\r
-                    /* Returning from subnode that matched part of alias path without finding\r
-                     * resource values */\r
-                    retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;\r
-                    break;\r
-                }\r
-            }\r
-            else {\r
-                /* Found next alias path node.  Move to next node name in path string. */\r
-                pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);\r
-                spacePtr = strpbrk(linuxAlias->path + pathOffset, " ");\r
-                if (spacePtr) {\r
-                    *spacePtr = '\0';\r
-                }       \r
-                \r
-                prevDepth = fdt_node_depth(linuxDtb, nodeOffset);\r
-               propOffset = fdt_first_property_offset(linuxDtb, nodeOffset);\r
-                while ((propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&\r
-                       (pathOffset < pathSize)) {\r
-                    propertyData = fdt_getprop_by_offset(linuxDtb, propOffset, \r
-                                                         &propertyName, &propertyLen);\r
-\r
-                    if (strcmp(linuxAlias->path + pathOffset, propertyName) == 0) {\r
-                        /* Found resource at end of alias path */\r
-                        pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);\r
-                        linuxValueRange = rmDtbUtilLinuxExtractValues(propertyData, propertyLen);\r
-                        retVal = reserveLinuxResource(rmInst, linuxAlias, \r
-                                                      linuxValueRange, &opInfo);\r
-                        rmDtbUtilLinuxFreeValues(linuxValueRange);\r
-                    }\r
-                    propOffset = fdt_next_property_offset(linuxDtb, propOffset);\r
-                } \r
-\r
-                if (propOffset < -FDT_ERR_NOTFOUND) {\r
-                    retVal = propOffset;\r
-                    break;\r
-                }\r
-            }\r
-        }\r
-\r
-        if (retVal < RM_OK) {\r
-            break;\r
-        }\r
-        linuxAlias = linuxAlias->nextLinuxAlias;\r
-    }\r
-    return (retVal);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Creates and initializes a resource allocator\r
- ***********************************************************************\r
- * DESCRIPTION: Creates a resource allocator for the provided\r
- *              resource name and resource properties retrieved\r
- *              from the GRL.  Resources will be reserved for \r
- *              the Linux kernel if the Linux DTB is provided\r
- *              and there are "linux-dtb-alias" properties\r
- *              specified in the GRL.\r
- */\r
-static int32_t createAndInitAllocator(Rm_Inst *rmInst, const char *resourceName, \r
-                                      Rm_ResourceProperties *resourceProperties, void *linuxDtb)\r
-{\r
-    Rm_ResourceRange    *range = NULL;\r
-    Rm_ResourceRange    *rangeBasePtr = NULL;\r
-    Rm_NsAssignment     *nsAssignments = NULL;\r
-    Rm_NsAssignment     *nsAssignmentBasePtr = NULL;\r
-    Rm_LinuxAlias       *linuxAlias = NULL;\r
-    Rm_NameServerObjCfg  nameServerObjCfg;      \r
-    int32_t              retVal = RM_OK;\r
-\r
-    if (resourceProperties->rangeData && (resourceProperties->rangeLen > 0)) {\r
-        range = rangeBasePtr = rmDtbUtilResExtractRange(resourceProperties->rangeData, \r
-                                                        resourceProperties->rangeLen);\r
-        \r
-        if ((retVal = createResourceTree(rmInst, resourceName, range)) >= RM_OK) {\r
-            if (resourceProperties->linuxAliasData && resourceProperties->linuxAliasLen) {\r
-                if (linuxDtb) {\r
-                    linuxAlias = rmDtbUtilResExtractLinuxAlias(resourceProperties->linuxAliasData,\r
-                                                               resourceProperties->linuxAliasLen, &retVal);\r
-                    if (linuxAlias) {\r
-                        retVal = findAndReserveLinuxResource(rmInst, resourceName, linuxDtb, linuxAlias);            \r
-                    }\r
-                }\r
-                else {\r
-                    retVal = RM_ERROR_GRL_LINUX_ALIAS_BUT_NO_DTB;\r
-                }\r
-            }\r
-        }\r
-    }\r
-    \r
-    if (retVal >= RM_OK) {\r
-        if (resourceProperties->nsAssignData && resourceProperties->nsAssignLen) {\r
-            nsAssignments = rmDtbUtilResExtractNsAssignment(resourceProperties->nsAssignData, \r
-                                                            resourceProperties->nsAssignLen, &retVal);\r
-            if (nsAssignments) {\r
-                nsAssignmentBasePtr = nsAssignments;\r
-                while (nsAssignments) {\r
-                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));\r
-                    nameServerObjCfg.nameServerTree = rmInst->nameServer;\r
-                    nameServerObjCfg.nodeCfg.objName = nsAssignments->nsName;\r
-                    nameServerObjCfg.nodeCfg.resourceName = (char *)resourceName;\r
-                    nameServerObjCfg.nodeCfg.resourceBase= nsAssignments->resourceBase;\r
-                    nameServerObjCfg.nodeCfg.resourceLength = nsAssignments->resourceLength;                \r
-                    rmNameServerAddObject(&nameServerObjCfg);\r
-                    nsAssignments = nsAssignments->nextNsAssignment;\r
-                }\r
-                rmDtbUtilResFreeNsAssignmentList(nsAssignmentBasePtr);\r
-            }\r
-        }\r
-    }\r
-\r
-    rmDtbUtilResFreeRange(rangeBasePtr);\r
-    if (linuxAlias) {\r
-        rmDtbUtilResFreeLinuxAlias(linuxAlias);\r
-    }\r
-    return(retVal);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Recursively parses GRL resource properties\r
- ***********************************************************************\r
- * DESCRIPTION: Recursively parses and stores GRL resource node \r
- *              properties using the LIBFDT APIs\r
- */\r
-static int32_t parseResourceProperty(void *globalResourceDtb, int32_t offset, \r
-                                     Rm_ResourceProperties *propertyInfo)\r
-{\r
-       int32_t              propertyLen;\r
-       const char          *propertyName;\r
-       const void          *propertyData;\r
-    Rm_ResourcePropType  propertyType;\r
-    int32_t              retVal = RM_OK;\r
-\r
-       propertyData = fdt_getprop_by_offset(globalResourceDtb, offset, &propertyName, &propertyLen);\r
-    propertyType = rmDtbUtilResGetPropertyType(propertyName);\r
-    if (propertyType == Rm_resourcePropType_RESOURCE_RANGE) {\r
-        propertyInfo->rangeData = propertyData;\r
-        propertyInfo->rangeLen = propertyLen;\r
-    }\r
-    else if (propertyType == Rm_resourcePropType_NSASSIGNMENT) {\r
-        propertyInfo->nsAssignData = propertyData;\r
-        propertyInfo->nsAssignLen = propertyLen;\r
-    }\r
-    else if (propertyType == Rm_resourcePropType_RESOURCE_LINUX_ALIAS) {\r
-        propertyInfo->linuxAliasData = propertyData;\r
-        propertyInfo->linuxAliasLen = propertyLen;\r
-    }        \r
-    else {\r
-        retVal = RM_ERROR_GRL_UNKNOWN_RESOURCE_PROPERTY;\r
-    }\r
-\r
-    if (retVal == RM_OK) {\r
-        offset = fdt_next_property_offset(globalResourceDtb, offset);\r
-       if (offset >= 0) {\r
-           retVal = parseResourceProperty(globalResourceDtb, offset, propertyInfo);\r
-       }\r
-        else if (offset != -FDT_ERR_NOTFOUND) {\r
-            /* Error returned by LIBFDT */\r
-            retVal = offset;\r
-        }\r
-    }\r
-    return (retVal);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Recursively parses GRL resource nodes\r
- ***********************************************************************\r
- * DESCRIPTION: Recursively parses GRL resource nodes looking for\r
- *              resource properties to create the resource allocators.\r
- *              The LIBFDT APIs are used to parse the GRL.\r
- */\r
-static int32_t parseResourceNode(Rm_Inst *rmInst, void *globalResourceDtb, int32_t nodeOffset, int32_t depth,\r
-                                 void *linuxDtb)\r
-{\r
-       const char            *resourceName = fdt_get_name(globalResourceDtb, nodeOffset, NULL);\r
-    Rm_ResourceProperties  resourceProperties;\r
-       int32_t                retVal = RM_OK;\r
-       int32_t                offset;\r
-\r
-    memset((void *)&resourceProperties, 0, sizeof(Rm_ResourceProperties));\r
-    /* Get properties of resource node */\r
-       offset = fdt_first_property_offset(globalResourceDtb, nodeOffset);\r
-       if (offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {\r
-               retVal =  parseResourceProperty(globalResourceDtb, offset, &resourceProperties);\r
-        if (retVal < -FDT_ERR_NOTFOUND) {\r
-            return (retVal);\r
-        }\r
-        if (retVal = createAndInitAllocator(rmInst, resourceName, &resourceProperties, linuxDtb) < RM_OK) {\r
-            return (retVal);\r
-        }\r
-       }\r
-    else if (offset != -FDT_ERR_NOTFOUND) {\r
-               /* Error returned by LIBFDT */\r
-        return (offset);\r
-    }\r
-    \r
-       offset = fdt_next_node(globalResourceDtb, nodeOffset, &depth);\r
-    if ((offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH)) {\r
-        retVal = parseResourceNode(rmInst, globalResourceDtb, offset, depth, linuxDtb);\r
-        if (retVal < -FDT_ERR_NOTFOUND) {\r
-            return (retVal);\r
-        }\r
-    }\r
-    else if (offset != -FDT_ERR_NOTFOUND) {\r
-        /* Error returned by LIBFDT */\r
-        return (offset);\r
-    }\r
-    return (retVal);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Initializes server allocators\r
- ***********************************************************************\r
- * DESCRIPTION: Creates and initializes a server instance's\r
- *              resource allocators using the GRL and, if\r
- *              provided, Linux DTB.\r
- */\r
-static int32_t initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb, void *linuxDtb)\r
-{\r
-    int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
-    int32_t startDepth = RM_DTB_UTIL_STARTING_DEPTH;\r
-    int32_t result = RM_OK;\r
-\r
-    /* Recursively parse the Global Resource List, creating an allocator for\r
-     * each resource as specified in the node */\r
-    result = parseResourceNode(rmInst, globalResourceDtb, nodeOffset, startDepth, linuxDtb);\r
-\r
-    return(result);\r
-}\r
-\r
-/**********************************************************************\r
- ********************** Internal Functions ****************************\r
- **********************************************************************/\r
-\r
-/* FUNCTION PURPOSE: Adds a transaction\r
- ***********************************************************************\r
- * DESCRIPTION: Returns a pointer to a newly created transaction.\r
- *              The transaction is created based on a new service\r
- *              request received via the service API or the\r
- *              transport API (service forwarded from another instance)\r
- */\r
-Rm_Transaction *rmTransactionQueueAdd(Rm_Inst *rmInst)\r
-{\r
-    Rm_Transaction *transactionQueue = rmInst->transactionQueue;\r
-    Rm_Transaction *newTransaction   = NULL;\r
-\r
-    newTransaction = Rm_osalMalloc(sizeof(Rm_Transaction));\r
-    if (newTransaction) {\r
-        memset((void *)newTransaction, 0, sizeof(Rm_Transaction));\r
-\r
-        newTransaction->localId = transactionGetSequenceNum(rmInst);\r
-        newTransaction->nextTransaction = NULL;  \r
-        if (transactionQueue) {\r
-            while (transactionQueue->nextTransaction) {\r
-                transactionQueue = transactionQueue->nextTransaction;\r
-            }\r
-            transactionQueue->nextTransaction = newTransaction;\r
-        }\r
-        else {\r
-            rmInst->transactionQueue = newTransaction;\r
-        }\r
-    }\r
-    return (newTransaction);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Finds a transaction\r
- ***********************************************************************\r
- * DESCRIPTION: Returns a pointer to a transaction resident\r
- *              in the transaction queue that matches the provided\r
- *              transaction ID.\r
- */\r
-Rm_Transaction *rmTransactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)\r
-{\r
-    Rm_Transaction *transaction = rmInst->transactionQueue;\r
-\r
-    while (transaction) {\r
-        if (transaction->localId == transactionId) {\r
-            break;             \r
-        }\r
-        transaction = transaction->nextTransaction;\r
-    }\r
-\r
-    return (transaction);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Deletes a transaction\r
- ***********************************************************************\r
- * DESCRIPTION: Deletes the transaction with the provided transaction\r
- *              ID from the instance's transaction queue.\r
- */\r
-int32_t rmTransactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)\r
-{\r
-    Rm_Transaction *transaction     = rmInst->transactionQueue;\r
-    Rm_Transaction *prevTransaction = NULL;\r
-    int32_t         retVal          = RM_OK;\r
-\r
-    while (transaction) {\r
-        if (transaction->localId == transactionId) {\r
-            break;             \r
-        }\r
-\r
-        prevTransaction = transaction;\r
-        transaction = transaction->nextTransaction;\r
-    }\r
-\r
-    if (transaction) {\r
-        if (prevTransaction == NULL) {\r
-            /* Transaction at start of queue. Map second transaction to start of queue \r
-             * as long as more than one transactions. */\r
-            rmInst->transactionQueue = transaction->nextTransaction;\r
-        }\r
-        else {\r
-            /* Transaction in middle or end of queue. */\r
-            prevTransaction->nextTransaction = transaction->nextTransaction;\r
-        }\r
-        Rm_osalFree((void *)transaction, sizeof(Rm_Transaction));\r
-    }\r
-    else {\r
-        retVal = RM_ERROR_SERVICE_TRANS_DOES_NOT_EXIST;\r
-    }    \r
-    return (retVal);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Finds an allocator\r
- ***********************************************************************\r
- * DESCRIPTION: Returns a pointer to an allocator that matches the \r
- *              provided resource name.\r
- */\r
-Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName)\r
-{\r
-    while (allocatorList) {\r
-        if (strncmp(allocatorList->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {\r
-            break;             \r
-        }\r
-        allocatorList = allocatorList->nextAllocator;\r
-    }\r
-\r
-    return (allocatorList);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Processes a transaction\r
- ***********************************************************************\r
- * DESCRIPTION: Processes transactions created from services\r
- *              received via the service handle or the transport.\r
- *              Transactions will be routed within the RM system\r
- *              based on the RM instance type and the type of\r
- *              the transaction.\r
- */\r
-void rmTransactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
-{\r
-    void                *validInstNode;\r
-    Rm_PolicyCheckCfg    privCheckCfg;\r
-    Rm_NameServerObjCfg  nameServerObjCfg;      \r
-    uint32_t             allocType = 0;    \r
-\r
-    /* Handle static transactions originating on this instance.  Any other static transactions will be\r
-     * stored in transaction queue until all transports are up. */\r
-    if (((rmInst->instType == Rm_instType_CLIENT) || (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) &&\r
-        (!rmInst->registeredWithDelegateOrServer) && \r
-        (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS) == 0)) {\r
-        if (rmInst->staticInfo.staticPolicy) {\r
-            if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||\r
-                (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {\r
-                /* Check request against startup policy */\r
-                memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));\r
-\r
-                if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {\r
-                    privCheckCfg.type = Rm_policyCheck_INIT;\r
-                }\r
-                else {\r
-                    privCheckCfg.type = Rm_policyCheck_USE;\r
-                }\r
-                privCheckCfg.policyDtb = rmInst->staticInfo.staticPolicy;\r
-                privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmInst->staticInfo.staticValidInstTree, \r
-                                                                      rmInst->instName);\r
-                privCheckCfg.resourceOffset = rmPolicyGetResourceOffset(rmInst->staticInfo.staticPolicy,\r
-                                                                        transaction->resourceInfo.name);\r
-                privCheckCfg.resourceBase = transaction->resourceInfo.base;\r
-                privCheckCfg.resourceLength = transaction->resourceInfo.length;\r
-\r
-                if (rmPolicyCheckPrivilege(&privCheckCfg, &transaction->state)) {\r
-                    transaction->state = RM_SERVICE_APPROVED_STATIC;\r
-                }\r
-                else if (transaction->state == RM_SERVICE_PROCESSING) {\r
-                    /* Privilege check returned false without error */\r
-                    transaction->state = RM_SERVICE_DENIED_BY_STATIC_POLICY;\r
-                }\r
-            }\r
-            else {\r
-                transaction->state = RM_SERVICE_DENIED_INVALID_STATIC_REQUEST;\r
-            }\r
-        }\r
-        else {\r
-            transaction->state = RM_ERROR_REQ_FAILED_NO_STATIC_POLICY;\r
-        }        \r
-    }\r
-    else {\r
-        /* Handle auto-forwarded transactions.  These transactions include:\r
-         * - All request transactions received on Clients are forwarded to the Client Delegate\r
-         * - NameServer requests received on the Client Delegate are forwarded to the Server */\r
-        if ((rmInst->instType == Rm_instType_CLIENT) ||\r
-            ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
-             ((transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) ||\r
-              (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) ||\r
-              (transaction->type == Rm_service_RESOURCE_UNMAP_NAME)))) {\r
-              \r
-            if ((transaction->state != RM_SERVICE_PROCESSING) &&\r
-                (transaction->state != RM_SERVICE_APPROVED_STATIC)) {\r
-                if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {\r
-                    /* Transaction did not originate on this instance */\r
-                    transactionResponder(rmInst, transaction);\r
-                }\r
-                else {\r
-                    /* Transaction originated on this instance */\r
-                    serviceResponder(rmInst, transaction);\r
-                }\r
-            }\r
-            else {\r
-                /* Forward request if transport is up.  Otherwise, just queue. */\r
-                if (rmInst->registeredWithDelegateOrServer) {\r
-                    transactionForwarder(rmInst, transaction);   \r
-                } \r
-            }\r
-        }\r
-        else {\r
-            /* Validate service's originating instance name */\r
-            if (rmInst->instType == Rm_instType_SERVER) {\r
-                validInstNode = rmPolicyGetValidInstNode(rmInst->validInstances, transaction->serviceSrcInstName);\r
-                if (validInstNode == NULL) {\r
-                    transaction->state = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;\r
-\r
-                    /* Send result via responder if transaction did not originate from this instance */\r
-                    if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {\r
-                        transactionResponder(rmInst, transaction);\r
-                    }\r
-                }\r
-            }\r
-\r
-            switch (transaction->type) {\r
-                case Rm_service_RESOURCE_ALLOCATE_INIT:\r
-                case Rm_service_RESOURCE_ALLOCATE_USE:\r
-                case Rm_service_RESOURCE_FREE:               \r
-                    if ((transaction->state != RM_SERVICE_PROCESSING) &&\r
-                        (transaction->state != RM_SERVICE_APPROVED_STATIC)) {\r
-                        /* Transaction complete */\r
-                        if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {\r
-                            /* Transaction result not destined for this instance */\r
-                            transactionResponder(rmInst, transaction);\r
-                        }\r
-                        else {\r
-                            /* Transaction result destined for this instance */\r
-                            serviceResponder(rmInst, transaction);      \r
-                        }\r
-                    }\r
-                    else {\r
-                        /* Complete allocation/free request */\r
-                        if (transaction->type == Rm_service_RESOURCE_FREE) {\r
-                            freeHandler(rmInst, transaction, validInstNode);\r
-                        }\r
-                        else {\r
-                            switch (transaction->type) {\r
-                                case Rm_service_RESOURCE_ALLOCATE_INIT:\r
-                                    RM_policy_SET_PERM(allocType, RM_POLICY_PERM_INIT_SHIFT, 1);\r
-                                    break;\r
-                                case Rm_service_RESOURCE_ALLOCATE_USE:\r
-                                    RM_policy_SET_PERM(allocType, RM_POLICY_PERM_USE_SHIFT, 1);    \r
-                                    break;\r
-                            }\r
-                            allocationHandler(rmInst, transaction, validInstNode, allocType);\r
-                        }\r
-                    }\r
-                    break;\r
-                case Rm_service_RESOURCE_MAP_TO_NAME:\r
-                case Rm_service_RESOURCE_GET_BY_NAME:\r
-                case Rm_service_RESOURCE_UNMAP_NAME:                \r
-                    /* NameServer resides on server */\r
-                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));\r
-                    if (rmInst->nameServer) {\r
-                        nameServerObjCfg.nameServerTree = rmInst->nameServer;\r
-                        nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;\r
-                        if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {\r
-                            nameServerObjCfg.nodeCfg.resourceName = transaction->resourceInfo.name;\r
-                            nameServerObjCfg.nodeCfg.resourceBase= transaction->resourceInfo.base;\r
-                            nameServerObjCfg.nodeCfg.resourceLength = transaction->resourceInfo.length;\r
-                            transaction->state = rmNameServerAddObject(&nameServerObjCfg);\r
-                        }\r
-                        else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {\r
-                            if ((transaction->state = rmNameServerFindObject(&nameServerObjCfg)) ==\r
-                                RM_SERVICE_PROCESSING) {\r
-                                strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);\r
-                                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;\r
-                                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;\r
-                                transaction->state = RM_SERVICE_APPROVED;\r
-                            } \r
-                        }\r
-                        else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) {\r
-                            transaction->state = rmNameServerDeleteObject(&nameServerObjCfg);\r
-                        }\r
-                    }\r
-                    else {\r
-                        transaction->state = RM_ERROR_NAMESERVER_DOES_NOT_EXIST;\r
-                    }\r
-\r
-                    /* Send result via responder if transaction did not originate from this instance */\r
-                    if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {\r
-                        transactionResponder(rmInst, transaction);\r
-                    }\r
-                    break;\r
-            }\r
-        }\r
-    }\r
-\r
-    /* Forward any queued requests that weren't forwarded yet */\r
-    if (rmInst->registeredWithDelegateOrServer) {\r
-        transaction = rmInst->transactionQueue;\r
-        while(transaction) {\r
-            if (((transaction->state == RM_SERVICE_PROCESSING) ||\r
-                 (transaction->state == RM_SERVICE_APPROVED_STATIC)) &&\r
-                !transaction->hasBeenForwarded) {\r
-                transactionForwarder(rmInst, transaction);\r
-            }\r
-            transaction = transaction->nextTransaction;\r
-        }\r
-    }\r
-}\r
-     \r
-/**********************************************************************\r
- ********************** Application visible APIs **********************\r
- **********************************************************************/\r
-\r
-/* FUNCTION PURPOSE: Display status of managed resources\r
- ***********************************************************************\r
- * DESCRIPTION: Prints the status (allocate/free status, as well as\r
- *              owners) for all resources managed by the RM \r
- *              instance network.  Also, prints the NameServer name\r
- *              entries.  This function is only available on server\r
- *              instances.\r
- */\r
-void Rm_printResourceStatus(Rm_Handle rmServerHandle)\r
-{\r
-    Rm_Inst         *rmInst = (Rm_Inst *)rmServerHandle;\r
-    Rm_Allocator    *allocator = rmInst->allocators;\r
-    Rm_Owner        *owners;\r
-    Rm_ResourceTree *treeRoot;\r
-    Rm_ResourceNode *treeNode;\r
-\r
-    if (rmInst->instType == Rm_instType_SERVER) {\r
-        while (allocator != NULL) {\r
-            Rm_osalLog("Resource: %s\n", allocator->resourceName);\r
-\r
-            treeRoot = allocator->allocatorRootEntry;\r
-\r
-            RB_FOREACH(treeNode, _Rm_AllocatorResourceTree, treeRoot) {               \r
-                Rm_osalLog("          %10d - %10d ", treeNode->base, \r
-                                                     treeNode->base + treeNode->length -1);\r
-                \r
-                if (treeNode->allocationCount == 0) {\r
-                    Rm_osalLog("NOT ALLOCATED\n");\r
-                }\r
-                else {\r
-                    owners = treeNode->ownerList;\r
-                    Rm_osalLog("allocated to");\r
-                    while (owners) {\r
-                        Rm_osalLog(" %s", owners->instNameNode->name);\r
-                        owners = owners->nextOwner;\r
-                    }\r
-                    Rm_osalLog("\n");\r
-                }\r
-            }        \r
-            allocator = allocator->nextAllocator;\r
-        }\r
-        rmNameServerPrintObjects(rmInst->nameServer);\r
-    }\r
-}\r
-\r
-/* FUNCTION PURPOSE: Display status of a RM instance\r
- ***********************************************************************\r
- * DESCRIPTION: Prints the current status of various RM instance\r
- *              properties such as the state of all transactions\r
- *              in the transaction queue and registered transports\r
- */\r
-void Rm_printInstanceStatus(Rm_Handle rmHandle)\r
-{\r
-    Rm_Inst        *rmInst = (Rm_Inst *)rmHandle;\r
-    Rm_Transport   *transportList = (Rm_Transport *)rmInst->transports;\r
-    Rm_Transaction *transactionQ = rmInst->transactionQueue;\r
-\r
-    Rm_osalLog("Instance name: %s\n", rmInst->instName);\r
-    if (rmInst->instType == Rm_instType_SERVER) {\r
-        Rm_osalLog("Type: Server\n");\r
-    }\r
-    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {\r
-        Rm_osalLog("Type: Client Delegate\n");\r
-    }\r
-    else {\r
-        Rm_osalLog("Type: Client\n");\r
-    }\r
-\r
-    if (transportList) {\r
-        Rm_osalLog("\nRegistered Transports:\n");\r
-        while (transportList) {\r
-            Rm_osalLog("    Remote instName:    %s\n", transportList->remoteInstName);\r
-            if (transportList->remoteInstType == Rm_instType_SERVER) {\r
-                Rm_osalLog("    Remote instType:    Server\n");\r
-            }\r
-            else if (transportList->remoteInstType == Rm_instType_CLIENT_DELEGATE) {\r
-                Rm_osalLog("    Remote instType:    Client Delegate\n");\r
-            }\r
-            else {\r
-                Rm_osalLog("    Remote instType:    Client\n");\r
-            }\r
-            Rm_osalLog("    appTransportHandle: 0x%08x\n", transportList->appTransportHandle);\r
-            Rm_osalLog("\n");\r
-            transportList = transportList->nextTransport;\r
-        }\r
-    }\r
-\r
-    if (transactionQ) {\r
-        Rm_osalLog("\nQueued Service Transactions:\n");\r
-        while (transactionQ) {\r
-            Rm_osalLog("    Service type:       %d\n", transactionQ->type);\r
-            Rm_osalLog("    Service ID:         %d\n", transactionQ->localId);\r
-            Rm_osalLog("    Service srcInstName %s\n", transactionQ->serviceSrcInstName);\r
-            Rm_osalLog("    Service state:      %d\n", transactionQ->state);\r
-            Rm_osalLog("    Resource name:      %s\n", transactionQ->resourceInfo.name);\r
-            Rm_osalLog("    Resource base:      %d\n", transactionQ->resourceInfo.base);\r
-            Rm_osalLog("    Resource length:    %d\n", transactionQ->resourceInfo.length);\r
-            Rm_osalLog("    Resource alignment: %d\n", transactionQ->resourceInfo.alignment);\r
-            Rm_osalLog("    Resource NS name:   %s\n", transactionQ->resourceInfo.nameServerName);\r
-            Rm_osalLog("\n");\r
-            transactionQ = transactionQ->nextTransaction;\r
-        }    \r
-    }\r
-}\r
-\r
-/* FUNCTION PURPOSE: RM instance creation and initialization\r
- ***********************************************************************\r
- * DESCRIPTION: Returns a new RM instance created and initialized\r
- *              using the parameters provided via the initCfg\r
- *              structure.\r
- */\r
-Rm_Handle Rm_init(Rm_InitCfg *initCfg, int32_t *result)\r
-{\r
-    Rm_Inst *rmInst;\r
-    void    *globalResourceDtb = NULL;\r
-    void    *linuxResourceDtb = NULL;\r
-    bool     addLinux = false;\r
-\r
-    *result = RM_OK;\r
-    \r
-    if ((initCfg->instName == NULL) ||\r
-        ((strlen(initCfg->instName) + 1) > RM_NAME_MAX_CHARS)) {\r
-        *result = RM_ERROR_INVALID_INST_NAME;\r
-        return (NULL);\r
-    }\r
-\r
-    if (initCfg->instType >= Rm_instType_LAST) {\r
-        *result = RM_ERROR_INVALID_INST_TYPE;\r
-    }\r
-\r
-    /* Create and initialize instance */\r
-    rmInst = Rm_osalMalloc (sizeof(Rm_Inst));\r
-    memset ((void *) rmInst, 0, sizeof(Rm_Inst));\r
-    rmInst->isLocked = false;\r
-    rmInst->registeredWithDelegateOrServer = false;\r
-    rmInst->transactionSeqNum = transactionInitSequenceNum();\r
-\r
-    rmInst->instType = initCfg->instType;    \r
-    strncpy (rmInst->instName, initCfg->instName, RM_NAME_MAX_CHARS);\r
-\r
-    if (rmInst->instType == Rm_instType_SERVER) {\r
-        if (!initCfg->instCfg.serverCfg.globalResourceList ||\r
-            !initCfg->instCfg.serverCfg.globalPolicy) {\r
-            *result = RM_ERROR_INVALID_SERVER_CONFIGURATION;\r
-            Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));\r
-            return(NULL);\r
-        }\r
-\r
-        rmInst->policy = initCfg->instCfg.serverCfg.globalPolicy;\r
-        fdt_open_into(rmInst->policy, rmInst->policy, fdt_totalsize(rmInst->policy)); \r
-\r
-        if (initCfg->instCfg.serverCfg.linuxDtb) {\r
-            linuxResourceDtb = initCfg->instCfg.serverCfg.linuxDtb;\r
-            fdt_open_into(linuxResourceDtb, linuxResourceDtb, fdt_totalsize(linuxResourceDtb));\r
-            addLinux = true;\r
-        }\r
-\r
-        /* Create valid instance list from policy.  Must be done prior to parsing\r
-         * GRL so that Linux resources can be reserved correctly */\r
-        rmInst->validInstances = rmPolicyCreateValidInstTree(rmInst->policy, addLinux, result);\r
-        /* Validate policy assignment strings */\r
-        *result = rmPolicyValidatePolicy(rmInst->policy, rmInst->validInstances);  \r
-\r
-        rmInst->nameServer = rmNameServerInit();\r
-\r
-        globalResourceDtb = initCfg->instCfg.serverCfg.globalResourceList;\r
-        fdt_open_into(globalResourceDtb, globalResourceDtb, fdt_totalsize(globalResourceDtb));\r
-\r
-        if ((*result = initializeAllocators(rmInst, globalResourceDtb, linuxResourceDtb)) == RM_OK) {  \r
-            *result = rmPolicyValidatePolicyResourceNames(rmInst->policy, (void *)rmInst->allocators);\r
-        }\r
-        if (*result < RM_OK) {\r
-            Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));\r
-            return(NULL);\r
-        }\r
-    }\r
-\r
-    if ((rmInst->instType == Rm_instType_CLIENT) && \r
-        (initCfg->instCfg.clientCfg.staticPolicy)) {\r
-        rmInst->staticInfo.staticPolicy = initCfg->instCfg.clientCfg.staticPolicy; \r
-    }\r
-    else if ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
-             (initCfg->instCfg.cdCfg.staticPolicy)) { \r
-        rmInst->staticInfo.staticPolicy = initCfg->instCfg.cdCfg.staticPolicy; \r
-    }\r
-    if (rmInst->staticInfo.staticPolicy) {\r
-        fdt_open_into(rmInst->staticInfo.staticPolicy, rmInst->staticInfo.staticPolicy, \r
-                      fdt_totalsize(rmInst->staticInfo.staticPolicy));       \r
-        rmInst->staticInfo.staticValidInstTree = rmPolicyCreateValidInstTree(rmInst->staticInfo.staticPolicy, \r
-                                                                             addLinux, result);        \r
-        if (*result == RM_OK) {\r
-            /* Validate policy assignment strings */\r
-            *result = rmPolicyValidatePolicy(rmInst->staticInfo.staticPolicy, rmInst->staticInfo.staticValidInstTree);\r
-        }\r
-        if (*result != RM_OK) {\r
-            if (rmInst->staticInfo.staticValidInstTree) {\r
-                rmPolicyFreeValidInstTree(rmInst->staticInfo.staticValidInstTree);\r
-            }\r
-            Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));\r
-            rmInst = NULL;\r
-        }\r
-    }\r
-    return ((Rm_Handle) rmInst);\r
-}\r
-\r
-/* FUNCTION PURPOSE: Returns RM version information\r
- ***********************************************************************\r
- */\r
-uint32_t Rm_getVersion (void)\r
-{\r
-    return RM_VERSION_ID;\r
-}\r
-\r
-/* FUNCTION PURPOSE: Returns RM version string\r
- ***********************************************************************\r
- */\r
-const char* Rm_getVersionStr (void)\r
-{\r
-    return rmVersionStr;\r
-}\r
-\r
+/**
+ *   @file  rm.c
+ *
+ *   @brief   
+ *      This is the Resource Manager source.
+ *
+ *  \par
+ *  ============================================================================
+ *  @n   (C) Copyright 2012-2015, Texas Instruments, Inc.
+ * 
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the   
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  \par
+*/
+
+/* Standard includes */
+#include <stdint.h>
+
+/* RM external includes */
+#include <ti/drv/rm/rm.h>
+#include <ti/drv/rm/rmver.h>
+#include <ti/drv/rm/rm_services.h>
+#include <ti/drv/rm/rm_transport.h>
+
+/* RM internal includes */
+#include <ti/drv/rm/include/rm_internal.h>
+#include <ti/drv/rm/include/rm_loc.h>
+#include <ti/drv/rm/include/rm_allocatorloc.h>
+#include <ti/drv/rm/include/rm_transportloc.h>
+#include <ti/drv/rm/include/rm_nameserverloc.h>
+#include <ti/drv/rm/include/rm_servicesloc.h>
+
+/* RM LIBFDT includes */
+#include <ti/drv/rm/util/libfdt/libfdt.h>
+
+/* RM OSAL layer */
+#include <rm_osal.h>
+
+/**********************************************************************
+ ************************** Globals ***********************************
+ **********************************************************************/
+
+/* Global Variable which describes the RM Version Information */
+const char  rmVersionStr[] = RM_VERSION_STR ":" __DATE__  ":" __TIME__;
+
+/**********************************************************************
+ ************************ Local Functions *****************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Initializes a RM inst's transaction sequence number
+ ***********************************************************************
+ * DESCRIPTION: The RM instance transaction sequence number can never
+ *              have a value of 0 to avoid conflicts with transactions
+ *              that have a remoteOriginatingId of 0 (transaction ID
+ *              will be used as the remoteOriginatingId for
+ *              transactions that are responses to requests).
+ */
+static uint32_t transactionInitSequenceNum(void)
+{
+    return (1);
+}
+
+/* FUNCTION PURPOSE: Provides a sequence number for new transactions
+ ***********************************************************************
+ * DESCRIPTION: Returns a sequence number for a new transaction
+ *              specific to a RM instance.  Handles rollover of
+ *              sequence number.
+ */
+static uint32_t transactionGetSequenceNum(Rm_Inst *rmInst)
+{
+    rmInst->transactionSeqNum++;
+    if (!rmInst->transactionSeqNum) {
+        rmInst->transactionSeqNum++;
+    }
+    return(rmInst->transactionSeqNum);
+}
+
+/* FUNCTION PURPOSE: Creates a resource request packet
+ ***********************************************************************
+ * DESCRIPTION: Returns a RM packet handle that points to a RM
+ *              resource request packet that has been prepared
+ *              for sending to another RM instance.  The packet
+ *              is allocated via the rmAllocPkt API using the
+ *              appTransport handle provided by the application
+ */
+static Rm_Packet *createResourceReqPkt(Rm_ResourceReqPktType resReqType,
+                                       Rm_Transport *dstTrans,
+                                       const char *locInstName,
+                                       Rm_Transaction *transaction,
+                                       Rm_PacketHandle *pktHandle)
+{
+    Rm_Packet             *rmPkt = NULL;
+    Rm_ResourceRequestPkt *resourceReqPkt = NULL;
+
+    rmPkt = dstTrans->callouts.rmAllocPkt(dstTrans->appTransportHandle,
+                                          sizeof(Rm_Packet), pktHandle);
+    if ((rmPkt == NULL) || (pktHandle == NULL)) {
+        transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
+        goto errorExit;
+    }
+
+    rmPkt->pktType = Rm_pktType_RESOURCE_REQUEST;
+    resourceReqPkt = (Rm_ResourceRequestPkt *) rmPkt->data;
+    resourceReqPkt->requestId       = transaction->localId;
+    resourceReqPkt->resourceReqType = resReqType;
+    rm_strncpy(resourceReqPkt->pktSrcInstName, locInstName,
+               RM_NAME_MAX_CHARS);
+    rm_strncpy(resourceReqPkt->serviceSrcInstName,
+               transaction->serviceSrcInstName, RM_NAME_MAX_CHARS);
+    memcpy((void *)&(resourceReqPkt->resourceInfo),
+           (void *)&(transaction->resourceInfo),
+           sizeof(Rm_ResourceInfo));
+
+errorExit:
+    return(rmPkt);
+}
+
+/* FUNCTION PURPOSE: Creates a resource response packet
+ ***********************************************************************
+ * DESCRIPTION: Returns a RM packet handle that points to a RM
+ *              resource response packet that has been prepared
+ *              for sending to another RM instance.  The packet
+ *              is allocated via the rmAllocPkt API using the
+ *              appTransport handle provided by the application
+ */
+static void createResourceResponsePkt(Rm_Packet *rmPkt,
+                                      Rm_Transaction *transaction)
+{
+    Rm_ResourceResponsePkt *resourceRespPkt = NULL;
+
+    rmPkt->pktType = Rm_pktType_RESOURCE_RESPONSE;
+    resourceRespPkt = (Rm_ResourceResponsePkt *)rmPkt->data;
+    resourceRespPkt->responseId = transaction->remoteOriginatingId;
+    resourceRespPkt->requestState = transaction->state;
+    memcpy((void *)&(resourceRespPkt->resourceInfo),
+           (void *)&(transaction->resourceInfo),
+           sizeof(Rm_ResourceInfo));
+}
+
+/* FUNCTION PURPOSE: Creates a NameServer request packet
+ ***********************************************************************
+ * DESCRIPTION: Returns a RM packet handle that points to a RM
+ *              NameServer request packet that has been prepared
+ *              for sending to another RM instance.  The packet
+ *              is allocated via the rmAllocPkt API using the
+ *              appTransport handle provided by the application
+ */
+static Rm_Packet *createNsRequestPkt(Rm_NsReqPktType nsReqType,
+                                     Rm_Transport *dstTrans,
+                                     const char *locInstName,
+                                     Rm_Transaction *transaction,
+                                     Rm_PacketHandle *pktHandle)
+{
+    Rm_Packet       *rmPkt = NULL;
+    Rm_NsRequestPkt *nsReqPkt = NULL;
+
+
+    rmPkt = dstTrans->callouts.rmAllocPkt(dstTrans->appTransportHandle,
+                                          sizeof(Rm_Packet), pktHandle);
+    if ((rmPkt == NULL) || (pktHandle == NULL)) {
+        transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
+        goto errorExit;
+    }
+
+    rmPkt->pktType = Rm_pktType_NAMESERVER_REQUEST;
+    nsReqPkt = (Rm_NsRequestPkt *)rmPkt->data;
+    nsReqPkt->requestId     = transaction->localId;
+    nsReqPkt->nsRequestType = nsReqType;
+    rm_strncpy(nsReqPkt->pktSrcInstName, locInstName, RM_NAME_MAX_CHARS);
+    rm_strncpy(nsReqPkt->serviceSrcInstName, transaction->serviceSrcInstName,
+               RM_NAME_MAX_CHARS);
+    memcpy((void *)&(nsReqPkt->resourceInfo),
+           (void *)&(transaction->resourceInfo),
+           sizeof(Rm_ResourceInfo));
+
+errorExit:
+    return(rmPkt);
+}
+
+/* FUNCTION PURPOSE: Creates a NameServer response packet
+ ***********************************************************************
+ * DESCRIPTION: Returns a RM packet handle that points to a RM
+ *              NameServer response packet that has been prepared
+ *              for sending to another RM instance.  The packet
+ *              is allocated via the rmAllocPkt API using the
+ *              appTransport handle provided by the application
+ */
+static void createNsResponsePkt(Rm_Packet *rmPkt, Rm_Transaction *transaction)
+{
+    Rm_NsResponsePkt *nsRespPkt = NULL;
+
+    rmPkt->pktType = Rm_pktType_NAMESERVER_RESPONSE;
+    nsRespPkt = (Rm_NsResponsePkt *)rmPkt->data;
+    nsRespPkt->responseId = transaction->remoteOriginatingId;
+    nsRespPkt->requestState = transaction->state;
+}
+
+/* FUNCTION PURPOSE: Creates a request packet
+ ***********************************************************************
+ * DESCRIPTION: Returns a RM packet handle that points to a request packet.
+ *              The request packet type is based on the transaction type.
+ */
+static Rm_Packet *createRequestPkt(Rm_Transport *dstTrans,
+                                   const char *locInstName,
+                                   Rm_Transaction *transaction,
+                                   Rm_PacketHandle *pktHandle)
+{
+    Rm_Packet *rmPkt = NULL;
+
+    switch (transaction->type) {
+        case Rm_service_RESOURCE_ALLOCATE_INIT:
+            rmPkt = createResourceReqPkt(Rm_resReqPktType_ALLOCATE_INIT,
+                                         dstTrans, locInstName, transaction,
+                                         pktHandle);
+            break;
+        case Rm_service_RESOURCE_ALLOCATE_USE:
+            rmPkt = createResourceReqPkt(Rm_resReqPktType_ALLOCATE_USE,
+                                         dstTrans, locInstName, transaction,
+                                         pktHandle);
+            break;
+        case Rm_service_RESOURCE_STATUS:
+            rmPkt = createResourceReqPkt(Rm_resReqPktType_GET_STATUS,
+                                         dstTrans, locInstName, transaction,
+                                         pktHandle);
+            break;
+        case Rm_service_RESOURCE_FREE:
+            rmPkt = createResourceReqPkt(Rm_resReqPktType_FREE,
+                                         dstTrans, locInstName, transaction,
+                                         pktHandle);
+            break;
+        case Rm_service_RESOURCE_GET_BY_NAME:
+            rmPkt = createResourceReqPkt(Rm_resReqPktType_GET_NAMED,
+                                         dstTrans, locInstName, transaction,
+                                         pktHandle);
+            break;
+        case Rm_service_RESOURCE_MAP_TO_NAME:
+            rmPkt = createNsRequestPkt(Rm_nsReqPktType_MAP_RESOURCE,
+                                       dstTrans, locInstName, transaction,
+                                       pktHandle);
+            break;
+        case Rm_service_RESOURCE_UNMAP_NAME:
+            rmPkt = createNsRequestPkt(Rm_nsReqPktType_UNMAP_RESOURCE,
+                                       dstTrans, locInstName, transaction,
+                                       pktHandle);
+            break;
+        default:
+            transaction->state = RM_ERROR_INVALID_SERVICE_TYPE;
+            break;
+    }
+
+    return(rmPkt);
+}
+
+/* FUNCTION PURPOSE: Issues a service response to application
+ ***********************************************************************
+ * DESCRIPTION: Provides a service response back to the application
+ *              using the service callback function provided to
+ *              the RM instance at the time of the service request.
+ */
+static void serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_ServiceRespInfo serviceResponse;
+
+    serviceResponse.rmHandle = (Rm_Handle)rmInst;
+    /* The responseTransaction will contain the resultant state details of
+     * the requestTransaction's service request */
+    serviceResponse.serviceState = transaction->state;
+    /* Pass back the ID that was provided to the component when it requested
+     * the service */
+    serviceResponse.serviceId = transaction->localId;
+    /* Owner and instance allocation count will only be set within RM under
+     * certain circumstances. */
+    serviceResponse.resourceNumOwners = transaction->resourceInfo.ownerCount;
+    serviceResponse.instAllocCount = transaction->resourceInfo.instAllocCount;
+
+    /* Service was approved and service was an allocate request.  The resource
+     * data is passed back to the component */
+    if ((serviceResponse.serviceState == RM_SERVICE_APPROVED) &&
+        ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+         (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+         (transaction->type == Rm_service_RESOURCE_FREE) ||
+         (transaction->type == Rm_service_RESOURCE_STATUS) ||
+         (transaction->type == Rm_service_RESOURCE_GET_BY_NAME))) {
+        rm_strncpy(serviceResponse.resourceName, transaction->resourceInfo.name,
+                   RM_NAME_MAX_CHARS);
+        serviceResponse.resourceBase = transaction->resourceInfo.base;
+        serviceResponse.resourceLength = transaction->resourceInfo.length;
+    }
+
+    if (transaction->u.callback.serviceCallback) {
+        /* Issue the callback to the requesting component with the response
+         * information */
+        transaction->u.callback.serviceCallback(&serviceResponse);
+        /* Delete the transaction from the transaction queue */
+        rmTransactionQueueDelete(rmInst, transaction->localId);
+    } else {
+        rmServiceInternalCallback((Rm_Handle)rmInst);
+    }
+
+    return;
+}
+
+/* FUNCTION PURPOSE: Sends RM response packets
+ ***********************************************************************
+ * DESCRIPTION: Sends RM response packets to RM instance's that sent
+ *              RM request packets to the RM instance.  The response
+ *              is sent via the RM transport API which is plugged
+ *              with an application created transport path.
+ */
+static void transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_Transport    *dstTransport = transaction->u.respTrans;
+    Rm_Packet       *rmPkt = NULL;
+    Rm_PacketHandle  pktHandle = NULL;
+
+    rmPkt = dstTransport->callouts.rmAllocPkt(dstTransport->appTransportHandle,
+                                              sizeof(Rm_Packet), &pktHandle);
+    if (!rmPkt || !pktHandle) {
+        transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
+        goto errorExit;
+    }
+
+    switch (transaction->type) {
+        case Rm_service_RESOURCE_ALLOCATE_INIT:
+        case Rm_service_RESOURCE_ALLOCATE_USE:
+        case Rm_service_RESOURCE_STATUS:
+        case Rm_service_RESOURCE_FREE:
+        case Rm_service_RESOURCE_GET_BY_NAME:
+            createResourceResponsePkt(rmPkt, transaction);
+            break;
+        case Rm_service_RESOURCE_MAP_TO_NAME:
+        case Rm_service_RESOURCE_UNMAP_NAME:
+            createNsResponsePkt(rmPkt, transaction);
+            break;
+        default:
+            transaction->state = RM_ERROR_INVALID_SERVICE_TYPE;
+            goto errorExit;
+    }
+    if (dstTransport->callouts.rmSendPkt(dstTransport->appTransportHandle,
+                                         pktHandle) < RM_OK) {
+        transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
+        goto errorExit;
+    }
+
+    /* Response packet sent: Delete transaction from queue */
+    rmTransactionQueueDelete(rmInst, transaction->localId);
+
+errorExit:
+    /* Do not delete transaction on transport error.  Transport error
+     * transactions should be visible from Rm_printInstanceStatus() */
+    return;
+}
+
+/* FUNCTION PURPOSE: Sends RM request packets
+ ***********************************************************************
+ * DESCRIPTION: Sends RM request packets to RM instance's that are
+ *              capable of forwarding or validating service requests.
+ *              The request is sent via the RM transport API which is
+ *              plugged with an application created transport path.
+ */
+static void transactionForwarder(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_Transport *dstTrans;
+
+    if (rmInst->instType == Rm_instType_CLIENT) {
+        dstTrans = rmTransportFindRemoteInstType(rmInst->transports,
+                                                 Rm_instType_CLIENT_DELEGATE);
+        if (dstTrans == NULL) {
+            dstTrans = rmTransportFindRemoteInstType(rmInst->transports,
+                                                     Rm_instType_SERVER);
+        }
+    } else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        dstTrans = rmTransportFindRemoteInstType(rmInst->transports,
+                                                 Rm_instType_SERVER);
+    } else {
+        dstTrans = NULL;
+    }
+
+    /* Just queue transaction if transport hasn't been registered.  Do not
+     * return error */
+    if (dstTrans) {
+        Rm_Packet       *rmPkt = NULL;
+        Rm_PacketHandle  pktHandle = NULL;
+
+        rmPkt = createRequestPkt(dstTrans, rmInst->instName, transaction,
+                                 &pktHandle);
+        if ((rmPkt == NULL) || (pktHandle == NULL)) {
+            /* Error returned via transaction->state */
+            goto errorExit;
+        }
+
+        if (dstTrans->callouts.rmSendPkt(dstTrans->appTransportHandle,
+                                         pktHandle) < RM_OK) {
+            transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
+            goto errorExit;
+        }
+        transaction->hasBeenForwarded = RM_TRUE;
+        /* Transaction not deleted.  Waiting for response from RM CD or
+         * Server */
+    } else {
+        transaction->state = RM_ERROR_TRANSPORT_HANDLE_DOES_NOT_EXIST;
+    }
+errorExit:
+    /* Do not delete transaction on transport error.  Transport error
+     * transactions should be visible from Rm_printInstanceStatus() */
+    return;
+}
+
+/* FUNCTION PURPOSE: Handles static allocation requests
+ ***********************************************************************
+ * DESCRIPTION: Validates allocation requests received on CDs and
+ *              Clients prior to the instance's registering
+ *              with a Server.  The allocation request is validated
+ *              against a static policy.
+ */
+static void staticAllocationHandler(Rm_Handle rmHandle,
+                                    Rm_Transaction *transaction)
+{
+    Rm_Inst           *rmInst = (Rm_Inst *)rmHandle;
+    Rm_AllocatorNode  *allocNode = NULL;
+    Rm_PolicyCheckCfg  privCheckCfg;
+
+    if (rmInst->allocatorTree) {
+        allocNode = rmAllocatorFind(rmHandle, transaction->resourceInfo.name);
+
+        if (allocNode &&
+            ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+             (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE))) {
+            /* Check request against static policy */
+            memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
+
+            if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                privCheckCfg.type = Rm_policyCheck_INIT;
+            } else {
+                privCheckCfg.type = Rm_policyCheck_USE;
+            }
+            privCheckCfg.negCheck       = RM_FALSE;
+            privCheckCfg.validInstNode  = rmPolicyGetValidInstNode(rmHandle,
+                                                              rmInst->instName);
+            privCheckCfg.polTree        = allocNode->policyRoot;
+            privCheckCfg.resourceBase   = transaction->resourceInfo.base;
+            privCheckCfg.resourceLength = transaction->resourceInfo.length;
+
+            if (rmPolicyCheckPrivilege(&privCheckCfg)) {
+                transaction->state = RM_SERVICE_APPROVED_STATIC;
+            } else {
+                transaction->state = RM_SERVICE_DENIED_BY_STATIC_POLICY;
+            }
+        } else {
+            transaction->state = RM_SERVICE_DENIED_INVALID_STATIC_REQUEST;
+        }
+    } else {
+        transaction->state = RM_ERROR_REQ_FAILED_NO_STATIC_POLICY;
+    }
+}
+
+/* FUNCTION PURPOSE: Requests resources from Server for CD
+ ***********************************************************************
+ * DESCRIPTION: Function creates a service request to allocate resources
+ *              from the Server for local management by the CD.  The
+ *              transaction which causes this request is put in the
+ *              pending state in order to wait for the response from the 
+ *              Server
+ */
+static int32_t cdRequestServerResources(Rm_Inst *rmInst,
+                                        Rm_Transaction *transaction)
+{
+    Rm_AllocatorNode *allocNode = NULL;
+    Rm_Transaction   *newTrans = NULL;
+    uint32_t          allocSize = 0;
+    int32_t           retVal;
+
+    allocNode = rmAllocatorFind((Rm_Handle)rmInst,
+                                transaction->resourceInfo.name);
+
+    if (allocNode) {
+        if ((allocSize = rmPolicyGetCdAllocSize(allocNode->policyRoot))) {
+            if ((newTrans = rmTransactionQueueAdd(rmInst))) {
+                newTrans->type = transaction->type;
+                rm_strncpy(newTrans->serviceSrcInstName, rmInst->instName,
+                           RM_NAME_MAX_CHARS);
+                newTrans->state = RM_SERVICE_PROCESSING;
+                rm_strncpy(newTrans->resourceInfo.name,
+                           transaction->resourceInfo.name,
+                           RM_NAME_MAX_CHARS);
+                newTrans->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+                /* Make sure request length will satisfy transaction length */
+                newTrans->resourceInfo.length = allocSize;
+                while (newTrans->resourceInfo.length <
+                       transaction->resourceInfo.length) {
+                    newTrans->resourceInfo.length += allocSize;
+                }
+                newTrans->resourceInfo.alignment = transaction->resourceInfo.alignment;
+                newTrans->pendingTransactionId = transaction->localId;
+                transactionForwarder(rmInst, newTrans);
+
+                retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
+            } else {
+                retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
+            }
+        } else {
+            /* Forward request to Server for completion if policy has 
+             * no allocation size for resource */
+            retVal = RM_SERVICE_PROCESSING;
+        }
+    } else {
+        /* Resource could not be found in policy */
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+    }
+    return(retVal);
+}
+
+/* FUNCTION PURPOSE: Frees local resources to Server from CD
+ ***********************************************************************
+ * DESCRIPTION: Function creates a service request to free locally
+ *              managed resources that are now localized back to
+ *              the Server.
+ */
+static int32_t cdFreeResourcesToServer(Rm_Inst *rmInst,
+                                       Rm_Transaction *transaction)
+{
+    int32_t         baseToFree = transaction->resourceInfo.base;
+    uint32_t        lenToFree = transaction->resourceInfo.length;
+    Rm_Transaction *newTrans = NULL; 
+    /* This function should only be called after a free was approved */
+    int32_t         retVal = RM_SERVICE_APPROVED;    
+
+    /* Did free result in a localized free node that can be given back to
+     * Server?  If so create transaction to Server to free localized
+     * resource node */
+    if (rmAllocatorGetNodeLocalization((Rm_Handle)rmInst,
+                                       transaction->resourceInfo.name,
+                                       &baseToFree, &lenToFree)) {
+        if ((newTrans = rmTransactionQueueAdd(rmInst))) {
+            newTrans->type = transaction->type;
+            rm_strncpy(newTrans->serviceSrcInstName, rmInst->instName,
+                       RM_NAME_MAX_CHARS);
+            newTrans->state = RM_SERVICE_PROCESSING;
+            rm_strncpy(newTrans->resourceInfo.name,
+                       transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+            newTrans->resourceInfo.base = baseToFree;
+            newTrans->resourceInfo.length = lenToFree;
+            newTrans->pendingTransactionId = transaction->localId;
+            transactionForwarder(rmInst, newTrans);
+
+            retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
+        } else {
+            /* Error: Need to re-allocate what was freed */
+            retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
+        }
+    }
+    return(retVal);
+}
+
+/* FUNCTION PURPOSE: Arbitrates allocation service requests
+ ***********************************************************************
+ * DESCRIPTION: Issues a set of allocator operations in order to
+ *              handle a received allocation request.  Allocation
+ *              requests are always forwarded to the Server on Client
+ *              CD instances.  If a request is made with a NameServer
+ *              name the resource base and length parameters are
+ *              retrieved from the NameServer prior to the allocation
+ *              attempt.
+ */
+static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_AllocatorOpInfo   opInfo;
+    Rm_NameServerObjCfg  nameServerObjCfg;
+    int32_t              retVal = transaction->state;
+
+    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    opInfo.resourceInfo = &transaction->resourceInfo;
+    opInfo.serviceInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst,
+                                              transaction->serviceSrcInstName);
+    if (opInfo.serviceInstNode == NULL) {
+        retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+        goto errorExit;
+    }
+
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        if (transaction->resourceInfo.base != RM_RESOURCE_BASE_UNSPECIFIED) {
+            if (rmAllocatorFind((Rm_Handle)rmInst,
+                                transaction->resourceInfo.name)) {
+                /* Attempt to allocate from local resources that were provided
+                 * by Server */
+                if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+                } else if (transaction->type ==
+                           Rm_service_RESOURCE_ALLOCATE_USE) {
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+                } else {
+                    retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                    goto errorExit;
+                }
+                retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+                if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                    /* Request resource range was not found within local
+                     * resources provided by Server.  Set back to PROCESSING so
+                     * request is forwarded to Server */
+                    retVal = RM_SERVICE_PROCESSING;
+                }
+            }
+        } else {
+            if (rmAllocatorFind((Rm_Handle)rmInst,
+                                transaction->resourceInfo.name)) {
+                int32_t oldAlign = transaction->resourceInfo.alignment;
+
+                /* Attempt to allocate from local resources that were provided
+                 * by Server */
+                if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
+                } else if (transaction->type ==
+                         Rm_service_RESOURCE_ALLOCATE_USE) {
+                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
+                } else {
+                    retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                    goto errorExit;
+                }
+                retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+                if (retVal == RM_SERVICE_PROCESSING) {
+                    if (transaction->type ==
+                        Rm_service_RESOURCE_ALLOCATE_INIT) {
+                        opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+                    } else if (transaction->type ==
+                               Rm_service_RESOURCE_ALLOCATE_USE) {
+                        opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+                    } else {
+                        retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                        goto errorExit;
+                    }
+                    retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+                    if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                        /* Request resource range was not found within local
+                         * resources provided by Server.  Set back to
+                         * PROCESSING so request is forwarded to Server */
+                        retVal = RM_SERVICE_PROCESSING;
+                    }
+                } else if (retVal == RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET) {
+                    if (transaction->pendingTransactionId) {
+                        /* Request to Server for resources to complete
+                         * transaction locally performed once already.  Forward
+                         * transaction to Server for completion */
+                        retVal = RM_SERVICE_PROCESSING;
+                    } else {
+                        /* Restore base and alignment since they were replaced
+                         * in pre-allocate routine */
+                        transaction->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+                        transaction->resourceInfo.alignment = oldAlign;
+
+                        retVal = cdRequestServerResources(rmInst, transaction);
+                    }
+                }
+                /* else: fall through to return */
+            } else {
+                retVal = cdRequestServerResources(rmInst, transaction);
+            }
+        }
+    } else if ((rmInst->instType == Rm_instType_SERVER)||
+               (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        /* Populated NameServer name has precedence over base */
+        if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmNameServerTreeInv(rmInst->u.server.nameServer);
+            }
+            memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+            nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+            nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+            if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) ==
+                RM_SERVICE_PROCESSING) {
+                rm_strncpy(transaction->resourceInfo.name,
+                           nameServerObjCfg.nodeCfg.resourceName,
+                           RM_NAME_MAX_CHARS);
+                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+            } else {
+                goto errorExit;
+            }
+        }
+
+        if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
+            if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
+            } else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+                opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
+            } else {
+                retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                goto errorExit;
+            }
+            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+        }
+
+        if (retVal == RM_SERVICE_PROCESSING) {
+            if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+            } else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+                opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+            } else {
+                retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                goto errorExit;
+            }
+            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+        }
+    } else {
+        retVal = RM_ERROR_INVALID_INST_TYPE;
+    }
+errorExit:
+    transaction->state = retVal;
+}
+
+/* FUNCTION PURPOSE: Handles resource status service requests
+ ***********************************************************************
+ * DESCRIPTION: Issues a set of allocator operations to retrieve the
+ *              current status (currently just owner reference count)
+ *              for the resource specified in the transaction
+ */
+static void statusHandler(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_AllocatorOpInfo  opInfo;
+    Rm_NameServerObjCfg nameServerObjCfg;
+    int32_t             retVal = transaction->state;
+
+    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    opInfo.operation = Rm_allocatorOp_GET_STATUS;
+    opInfo.resourceInfo = &transaction->resourceInfo;
+    opInfo.serviceInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst,
+                                            transaction->serviceSrcInstName);
+    if (opInfo.serviceInstNode == NULL) {
+        retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+        goto errorExit;
+    }
+
+    if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+        ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+         (transaction->resourceInfo.length == 0))) {
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+        goto errorExit;
+    }
+
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        if (rmAllocatorFind((Rm_Handle)rmInst,
+                            transaction->resourceInfo.name)) {
+            /* Attempt to get status from local resources that were provided by
+             * Server */
+            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+            if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                /* Request resource range was not found within local allocator
+                 * resources provided by Server.  Set back to PROCESSING so
+                 * request is forwarded to Server */
+                retVal = RM_SERVICE_PROCESSING;
+            }
+        }
+    } else if ((rmInst->instType == Rm_instType_SERVER)||
+               (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        /* Populated NameServer name has precedence over base and length
+         * values */
+        if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmNameServerTreeInv(rmInst->u.server.nameServer);
+            }
+            memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+            nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+            nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+            if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) ==
+                RM_SERVICE_PROCESSING) {
+                rm_strncpy(transaction->resourceInfo.name,
+                           nameServerObjCfg.nodeCfg.resourceName,
+                           RM_NAME_MAX_CHARS);
+                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+            } else {
+                goto errorExit;
+            }
+        }
+        retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+    } else {
+        retVal = RM_ERROR_INVALID_INST_TYPE;
+    }
+errorExit:
+    transaction->state = retVal;
+}
+
+/* FUNCTION PURPOSE: Arbitrates free service requests
+ ***********************************************************************
+ * DESCRIPTION: Issues a set of allocator operations in order to
+ *              handle a received free request.  Free
+ *              requests are always forwarded to the Server on Client
+ *              CD instances.  If a request is made with a NameServer
+ *              name the resource base and length parameters are
+ *              retrieved from the NameServer prior to the free
+ *              attempt.
+ */
+static void freeHandler(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_AllocatorOpInfo  opInfo; 
+    Rm_NameServerObjCfg nameServerObjCfg;
+    int32_t             retVal = transaction->state;
+
+    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    opInfo.operation = Rm_allocatorOp_FREE;
+    opInfo.resourceInfo = &transaction->resourceInfo;
+    opInfo.serviceInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst,
+                                            transaction->serviceSrcInstName);
+    if (opInfo.serviceInstNode == NULL) {
+        retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+        goto errorExit;
+    }
+
+    if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+        ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+         (transaction->resourceInfo.length == 0))) {
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+        goto errorExit;
+    }
+
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        /* Attempt to free from local resources that were provided by Server */
+        retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+        if (retVal == RM_SERVICE_APPROVED) {
+            /* Check if free allows local resources to be freed back to
+             * Server */
+            retVal = cdFreeResourcesToServer(rmInst, transaction);
+        } else if ((retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) ||
+                 (retVal == RM_SERVICE_DENIED_RES_DOES_NOT_EXIST)) {
+            /* Requested resource or its range were not found within local
+             * allocator resources provided by Server.  Set back to PROCESSING
+             * so request is forwarded to Server */
+            retVal = RM_SERVICE_PROCESSING;
+        }
+        /* else: fall through to exit */
+    } else if ((rmInst->instType == Rm_instType_SERVER) ||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        /* Populated NameServer name has precedence over base */
+        if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmNameServerTreeInv(rmInst->u.server.nameServer);
+            }                    
+            memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+            nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+            nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+            if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) ==
+                RM_SERVICE_PROCESSING) {
+                rm_strncpy(transaction->resourceInfo.name,
+                           nameServerObjCfg.nodeCfg.resourceName,
+                           RM_NAME_MAX_CHARS);
+                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+            } else {
+                goto errorExit;
+            }
+        }
+        retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+    } else {
+        retVal = RM_ERROR_INVALID_INST_TYPE;
+    }
+errorExit:
+    transaction->state = retVal;
+}
+
+/* FUNCTION PURPOSE: Client transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Client process for handling transactions created
+ *              from services received via the service handle or the
+ *              transport.  The Client process:
+ *                  - Performs static allocations if no transport
+ *                    to CD or Server has been registered
+ *                  - Forwards all service requests to CD or Server
+ *                    once transport has been registered
+ */
+static void clientProcess(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_Transaction *transQ;
+
+    if (!rmInst->registeredWithDelegateOrServer) {
+        staticAllocationHandler((Rm_Handle)rmInst, transaction);
+    } else {
+        if (transaction->state == RM_SERVICE_PROCESSING) {
+            /* Forward all new transactions to CD or Server */
+            transactionForwarder(rmInst, transaction);
+        } else {
+            /* Transaction validated.  Return result. */
+            serviceResponder(rmInst, transaction);
+        }
+
+        /* Forward any queued static requests that weren't forwarded */
+        transQ = rmInst->transactionQueue;
+        while(transQ) {
+            if ((transQ->state == RM_SERVICE_APPROVED_STATIC) &&
+                (!transQ->hasBeenForwarded)) {
+                transactionForwarder(rmInst, transQ);
+            }
+            transQ = transQ->nextTransaction;
+        }
+    }
+    /* Let call stack return transaction result app via Rm_serviceHandler */
+}
+
+/* FUNCTION PURPOSE: Client Delegate transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Client Delegate process for handling transactions created
+ *              from services received via the service handle or the
+ *              transport.  The Client Delegate process:
+ *                  - Performs static allocations if no transport
+ *                    to Server has been registered
+ *                  - Forwards all NameServer related service requests 
+ *                    to Server once transport has been registered
+ *                  - Attempts to complete resource service requests
+ *                    received from registered Clients
+ */
+static void cdProcess(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{      
+    Rm_Transaction   *newTrans = NULL;
+    Rm_AllocatorNode *allocator = NULL;
+    Rm_Transaction   *transQ;
+
+    if (!rmInst->registeredWithDelegateOrServer) {
+        if ((transaction->state == RM_SERVICE_PROCESSING) &&
+            (strncmp(transaction->serviceSrcInstName, rmInst->instName,
+             RM_NAME_MAX_CHARS) == 0)) {
+            /* Attempt static allocation of requests originating from CD inst */
+            staticAllocationHandler((Rm_Handle)rmInst, transaction);
+        }
+        /* Everything else left in transaction queue for forwarding once
+         * transport to Server is registered */
+    } else {
+        if (transaction->pendingTransactionId) {
+            Rm_Transaction *pendingTrans = rmTransactionQueueFind(rmInst,
+                                             transaction->pendingTransactionId);
+
+            /* Transaction is response from Server for transaction sent to get
+             * information in order to complete pending transaction */
+            if (transaction->state == RM_SERVICE_APPROVED) {
+                if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
+                    /* Transfer resource data tied to name to pending
+                     * transaction */
+                    rm_strncpy(pendingTrans->resourceInfo.name,
+                               transaction->resourceInfo.name,
+                               RM_NAME_MAX_CHARS);
+                    pendingTrans->resourceInfo.base   = transaction->resourceInfo.base;
+                    pendingTrans->resourceInfo.length = transaction->resourceInfo.length;
+                    /* Delete NS name from pending transaction so Server isn't
+                     * queried again */
+                    memset(pendingTrans->resourceInfo.nameServerName, 0,
+                           RM_NAME_MAX_CHARS);
+                    /* Now that resource values have been retrieved clear
+                     * pending transaction ID so CD doesn't think a resource
+                     * request was sent to Server already for more local
+                     * resources */
+                    pendingTrans->pendingTransactionId = 0;
+
+                    /* Return original transaction to processing state to
+                     * attempt completion. */
+                    pendingTrans->state = RM_SERVICE_PROCESSING;
+                } else if ((transaction->type ==
+                            Rm_service_RESOURCE_ALLOCATE_INIT) ||
+                           (transaction->type ==
+                            Rm_service_RESOURCE_ALLOCATE_USE)) {
+                    /* Add resources provided by Server to those managed by
+                     * CD */
+                    if ((allocator = rmAllocatorFind((Rm_Handle)rmInst,
+                                             transaction->resourceInfo.name))) {
+                        rmAllocatorAddResNode((Rm_Handle)rmInst,
+                                              allocator,
+                                              transaction->resourceInfo.base,
+                                              transaction->resourceInfo.length);
+                    }
+
+                    /* Return original transaction to processing state to
+                     * attempt completion */
+                    pendingTrans->state = RM_SERVICE_PROCESSING;
+                } else if (transaction->type == Rm_service_RESOURCE_FREE) {
+                    allocator = rmAllocatorFind((Rm_Handle)rmInst,
+                                                transaction->resourceInfo.name);
+
+                    /* Local resource freed on Server.  Remove node in
+                     * local allocator's resource tree as well */
+                    rmAllocatorDeleteResNode((Rm_Handle)rmInst,
+                                             allocator,
+                                             transaction->resourceInfo.base,
+                                             transaction->resourceInfo.length);
+
+                    /* Allow original free to complete */
+                    pendingTrans->state = RM_SERVICE_APPROVED;
+                } else {
+                    pendingTrans->state = RM_ERROR_SERVER_RESP_INVALID_SERVICE_TYPE;
+                }
+            } else {
+                if (transaction->type == Rm_service_RESOURCE_FREE) {
+                    /* Error occurred when trying to free local resource on
+                     * Server.  Reinsert local resources freed by original
+                     * request */
+                    Rm_AllocatorOpInfo   opInfo;
+
+                    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+                    opInfo.resourceInfo = &pendingTrans->resourceInfo;
+                    opInfo.serviceInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst,
+                                              pendingTrans->serviceSrcInstName);
+                    /* Can't regain the original type of allocate.  Default to
+                     * init */
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+                    if (rmAllocatorOperation((Rm_Handle)rmInst, &opInfo) !=
+                        RM_SERVICE_APPROVED) {
+                        transaction->state = RM_ERROR_LOST_RESOURCES_ON_CD;
+                    }
+                }
+                /* Transfer error or denial to pending transaction */
+                pendingTrans->state = transaction->state;
+            }
+            rmTransactionQueueDelete(rmInst, transaction->localId);
+            /* Switch to pending transaction */
+            transaction = pendingTrans;
+        }
+
+        if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+            (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+            (transaction->type == Rm_service_RESOURCE_STATUS) ||
+            (transaction->type == Rm_service_RESOURCE_FREE)) {
+            if ((transaction->state == RM_SERVICE_PROCESSING) &&
+                (strlen(transaction->resourceInfo.nameServerName) > 0)) {
+                /* Create and forward new transaction to Server to
+                 * retrieve resource data mapped to name */
+                if ((newTrans = rmTransactionQueueAdd(rmInst))) {
+                    newTrans->type = Rm_service_RESOURCE_GET_BY_NAME;
+                    rm_strncpy(newTrans->serviceSrcInstName, rmInst->instName,
+                               RM_NAME_MAX_CHARS);
+                    newTrans->state = RM_SERVICE_PROCESSING;
+                    rm_strncpy(newTrans->resourceInfo.nameServerName,
+                               transaction->resourceInfo.nameServerName,
+                               RM_NAME_MAX_CHARS);
+                    newTrans->pendingTransactionId = transaction->localId;
+                    transactionForwarder(rmInst, newTrans);
+
+                    transaction->state = RM_SERVICE_PENDING_SERVER_RESPONSE;
+                } else {
+                    transaction->state = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
+                }
+            }
+        }
+
+        if (transaction->state == RM_SERVICE_PROCESSING) {
+            switch(transaction->type) {
+                case Rm_service_RESOURCE_ALLOCATE_INIT:
+                case Rm_service_RESOURCE_ALLOCATE_USE:
+                    allocationHandler(rmInst, transaction);
+                    break;
+                case Rm_service_RESOURCE_FREE:
+                    freeHandler(rmInst, transaction);
+                    break;
+                case Rm_service_RESOURCE_STATUS:
+                    statusHandler(rmInst, transaction);
+                    break;
+                case Rm_service_RESOURCE_MAP_TO_NAME:
+                case Rm_service_RESOURCE_GET_BY_NAME:
+                case Rm_service_RESOURCE_UNMAP_NAME:
+                    /* Forward all NameServer-based transactions */
+                    break;
+                default:
+                    transaction->state = RM_ERROR_INVALID_SERVICE_TYPE;
+                    break;
+            }
+        }
+
+        if (transaction->state == RM_SERVICE_PROCESSING) {
+            uint32_t transId = transaction->localId;
+
+            /* NameServer transaction or CD could not complete alloc/free
+             * transaction.  Forward to Server */
+            transactionForwarder(rmInst, transaction);
+
+            /* Refresh transaction for reentrancy of cases where mix of Client
+             * CD and Server are running on the same core and connected via
+             * transport implemented over direct function calls instead of
+             * traditional transport that returns after sending the data */
+            transaction = rmTransactionQueueFind(rmInst, transId);
+        }
+
+        if (transaction) {
+            if ((transaction->state != RM_SERVICE_PROCESSING) &&
+                (transaction->state != RM_SERVICE_PENDING_SERVER_RESPONSE)) {
+                /* Transaction completed by CD or completed response received
+                 * from Server.  Return result */
+                if (strncmp(transaction->serviceSrcInstName, rmInst->instName,
+                    RM_NAME_MAX_CHARS)) {
+                    /* Transaction did not originate on this instance */
+                    transactionResponder(rmInst, transaction);
+                } else {
+                    /* Transaction originated on this instance */
+                    serviceResponder(rmInst, transaction);
+                }
+            }
+        }
+
+        /* Attempt allocation of any queued static requests:
+         * RM_SERVICE_APPROVED_STATIC - Originated locally
+         * RM_SERVICE_PROCESSING - Received from any registered Clients */
+        transQ = rmInst->transactionQueue;
+        while(transQ) {
+            if (((transQ->state == RM_SERVICE_PROCESSING) ||
+                 (transQ->state == RM_SERVICE_APPROVED_STATIC)) &&
+                (!transQ->hasBeenForwarded)) {
+                transactionForwarder(rmInst, transQ);
+            }
+            transQ = transQ->nextTransaction;
+        }
+    }
+}
+
+/* FUNCTION PURPOSE: Server transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Server process for handling transactions created
+ *              from services received via the service handle or the
+ *              transport.  The Server process:
+ *                  - Validates all service requests received from
+ *                    the service handle and registered CDs and
+ *                    Clients
+ */
+static void serverProcess(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_NameServerObjCfg  nameServerObjCfg;
+
+    switch (transaction->type) {
+        case Rm_service_RESOURCE_STATUS:
+            statusHandler(rmInst, transaction);
+            break;
+        case Rm_service_RESOURCE_ALLOCATE_INIT:
+        case Rm_service_RESOURCE_ALLOCATE_USE:
+            allocationHandler(rmInst, transaction);
+            break;
+        case Rm_service_RESOURCE_FREE:
+            freeHandler(rmInst, transaction);
+            break;
+        case Rm_service_RESOURCE_MAP_TO_NAME:
+        case Rm_service_RESOURCE_GET_BY_NAME:
+        case Rm_service_RESOURCE_UNMAP_NAME:
+            if (rmInst->u.server.nameServer) {
+                if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                    rmNameServerTreeInv(rmInst->u.server.nameServer);
+                }                
+                memset((void *)&nameServerObjCfg, 0,
+                       sizeof(Rm_NameServerObjCfg));
+                nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+                nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+                if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {
+                    nameServerObjCfg.nodeCfg.resourceName = transaction->resourceInfo.name;
+                    nameServerObjCfg.nodeCfg.resourceBase= transaction->resourceInfo.base;
+                    nameServerObjCfg.nodeCfg.resourceLength = transaction->resourceInfo.length;
+                    transaction->state = rmNameServerAddObject(&nameServerObjCfg);
+                } else if (transaction->type ==
+                           Rm_service_RESOURCE_GET_BY_NAME) {
+                    if ((transaction->state = rmNameServerFindObject(&nameServerObjCfg)) ==
+                        RM_SERVICE_PROCESSING) {
+                        rm_strncpy(transaction->resourceInfo.name,
+                                   nameServerObjCfg.nodeCfg.resourceName,
+                                   RM_NAME_MAX_CHARS);
+                        transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                        transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+                        transaction->state = RM_SERVICE_APPROVED;
+                    }
+                } else if (transaction->type ==
+                           Rm_service_RESOURCE_UNMAP_NAME) {
+                    transaction->state = rmNameServerDeleteObject(&nameServerObjCfg);
+                } else {
+                    transaction->state = RM_ERROR_INVALID_SERVICE_TYPE;
+                }
+
+                if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                    rmNameServerTreeWb(rmInst->u.server.nameServer);
+                }
+            } else {
+                transaction->state = RM_ERROR_NAMESERVER_DOES_NOT_EXIST;
+            }
+            break;
+        default:
+            transaction->state = RM_ERROR_INVALID_SERVICE_TYPE;
+            break;
+    }
+
+    /* Source of shared server transaction will always be local. */
+    if (rmInst->instType != Rm_instType_SHARED_SERVER) {
+        if (strncmp(transaction->serviceSrcInstName, rmInst->instName,
+                    RM_NAME_MAX_CHARS)) {
+            /* Source of transaction was not Server, return transaction via
+             * responder */
+            transactionResponder(rmInst, transaction);
+        }
+    }
+    /* Otherwise let call stack return transaction result app via
+     * Rm_serviceHandler */ 
+}
+
+/**********************************************************************
+ ********************** Internal Functions ****************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Adds a transaction
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to a newly created transaction.
+ *              The transaction is created based on a new service
+ *              request received via the service API or the
+ *              transport API (service forwarded from another instance)
+ */
+Rm_Transaction *rmTransactionQueueAdd(Rm_Inst *rmInst)
+{
+    Rm_Transaction *transactionQueue = rmInst->transactionQueue;
+    Rm_Transaction *newTransaction   = NULL;
+
+    newTransaction = Rm_osalMalloc(sizeof(Rm_Transaction));
+    if (newTransaction) {
+        memset((void *)newTransaction, 0, sizeof(Rm_Transaction));
+
+        newTransaction->localId = transactionGetSequenceNum(rmInst);
+        newTransaction->nextTransaction = NULL;  
+        if (transactionQueue) {
+            while (transactionQueue->nextTransaction) {
+                transactionQueue = transactionQueue->nextTransaction;
+            }
+            transactionQueue->nextTransaction = newTransaction;
+        } else {
+            rmInst->transactionQueue = newTransaction;
+        }
+    }
+    return(newTransaction);
+}
+
+/* FUNCTION PURPOSE: Finds a transaction
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to a transaction resident
+ *              in the transaction queue that matches the provided
+ *              transaction ID.
+ */
+Rm_Transaction *rmTransactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)
+{
+    Rm_Transaction *transaction = rmInst->transactionQueue;
+
+    while (transaction) {
+        if (transaction->localId == transactionId) {
+            break;
+        }
+        transaction = transaction->nextTransaction;
+    }
+
+    return(transaction);
+}
+
+/* FUNCTION PURPOSE: Deletes a transaction
+ ***********************************************************************
+ * DESCRIPTION: Deletes the transaction with the provided transaction
+ *              ID from the instance's transaction queue.
+ */
+int32_t rmTransactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)
+{
+    Rm_Transaction *transaction = rmInst->transactionQueue;
+    Rm_Transaction *prevTransaction = NULL;
+    int32_t         retVal = RM_OK;
+
+    while (transaction) {
+        if (transaction->localId == transactionId) {
+            break;
+        }
+
+        prevTransaction = transaction;
+        transaction = transaction->nextTransaction;
+    }
+
+    if (transaction) {
+        if (prevTransaction == NULL) {
+            /* Transaction at start of queue. Map second transaction to start
+             * of queue as long as more than one transactions. */
+            rmInst->transactionQueue = transaction->nextTransaction;
+        } else {
+            /* Transaction in middle or end of queue. */
+            prevTransaction->nextTransaction = transaction->nextTransaction;
+        }
+        Rm_osalFree((void *)transaction, sizeof(Rm_Transaction));
+    } else {
+        retVal = RM_ERROR_SERVICE_TRANS_DOES_NOT_EXIST;
+    }
+    return(retVal);
+}
+
+/* FUNCTION PURPOSE: Routes a transaction for processing
+ ***********************************************************************
+ * DESCRIPTION: Routes a received transaction to the appropriate
+ *              instance processing routine
+ */
+void rmProcessRouter(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    if (rmInst->instType == Rm_instType_CLIENT) {
+        clientProcess(rmInst, transaction);
+    } else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        cdProcess(rmInst, transaction);
+    } else if ((rmInst->instType == Rm_instType_SERVER) ||
+               (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        serverProcess(rmInst, transaction);
+    } else {
+        transaction->state = RM_ERROR_INVALID_INST_TYPE;
+    }
+}
+
+/**********************************************************************
+ ********************** Application visible APIs **********************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Display status of managed resources
+ ***********************************************************************
+ * DESCRIPTION: Prints the status (allocate/free status, as well as
+ *              owners) for all resources managed by the RM 
+ *              instance network.  Also, prints the NameServer name
+ *              entries.  The number of resource range owners is
+ *              returned as well.  This function is only available on
+ *              Server and CD instances.
+ */
+int32_t Rm_resourceStatus(Rm_Handle rmHandle, int printResources)
+{
+    Rm_Inst          *rmInst = (Rm_Inst *)rmHandle;
+    Rm_AllocatorTree *allocTree = NULL;
+    Rm_AllocatorNode *allocator;
+    Rm_Owner         *owners;
+    Rm_ResourceTree  *treeRoot;
+    Rm_ResourceNode  *treeNode;
+    int32_t           totalResOwners = 0;
+    void             *key;
+    void             *mtKey;
+
+    RM_SS_INST_INV_ENTER_CS(rmInst, key);
+    RM_SC_INST_INV_ENTER_CS(rmInst, key);
+    if (rmInst->mtSemObj) {
+        mtKey = Rm_osalMtCsEnter(rmInst->mtSemObj);
+    }
+
+    if (rmInst->instType != Rm_instType_CLIENT) {
+        Rm_osalLog("Instance name: %s\n", rmInst->instName);
+        Rm_osalLog("Handle: 0x%08x\n", rmHandle);
+        if (rmInst->instType == Rm_instType_SERVER) {
+            Rm_osalLog("Type:   Server\n");
+        } else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+            Rm_osalLog("Type:   Client Delegate\n");
+        } else if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+            Rm_osalLog("Type:   Shared Server\n");
+        } else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+            Rm_osalLog("Type:   Shared Client\n");
+        } else {
+            Rm_osalLog("Type:   UNKNOWN\n");
+            goto errorExit;
+        }
+
+        Rm_osalLog("\nResource Status:\n\n");
+    }
+
+    if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+        /* Transfer control to shared server instance */
+        rmInst = rmInst->u.sharedClient.sharedServerHandle;
+    }
+
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER) ||
+        (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) {
+
+        allocTree = rmInst->allocatorTree;
+        if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+            rmAllocatorTreeInv(allocTree);
+        }
+
+        RB_FOREACH(allocator, _Rm_AllocatorTree, allocTree) {
+            RM_SS_OBJ_INV(rmInst, allocator, Rm_AllocatorNode);
+            if (printResources) {
+                Rm_osalLog("Resource: %s\n", allocator->resourceName);
+            }
+
+            treeRoot = allocator->resourceRoot;
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmResourceTreeInv(treeRoot);
+            }
+            RB_FOREACH(treeNode, _Rm_AllocatorResourceTree, treeRoot) {
+                if (printResources) {
+                    if ((treeNode->base >= 65536) ||
+                        ((treeNode->base + treeNode->length - 1) >= 65536)) {
+                        /* Print in hex if number is very large */
+                        Rm_osalLog("          0x%08x - 0x%08x ",
+                                   treeNode->base,
+                                   treeNode->base + treeNode->length - 1);
+                    } else {
+                        Rm_osalLog("          %10d - %10d ",
+                                   treeNode->base,
+                                   treeNode->base + treeNode->length - 1);
+                    }
+                }
+
+                if (treeNode->allocationCount == 0) {
+                    if (printResources) {
+                        Rm_osalLog("FREE\n");
+                    }
+                } else {
+                    owners = treeNode->ownerList;
+                    while (owners) {
+                        RM_SS_OBJ_INV(rmInst, owners, Rm_Owner);
+                        if (printResources) {
+                            Rm_osalLog("%s (%d) ", owners->instNameNode->name,
+                                       owners->refCnt);
+                        }
+                        totalResOwners++;
+                        owners = owners->nextOwner;
+                    }
+                    if (printResources) {
+                        Rm_osalLog("\n");
+                    }
+                }
+            }
+        }
+
+        if ((rmInst->instType == Rm_instType_SERVER) ||
+            (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+            if (printResources) {
+                rmNameServerPrintObjects((Rm_Handle)rmInst);
+            }
+        }
+    } else {
+        totalResOwners = RM_ERROR_INVALID_RES_STATUS_INSTANCE;
+    }
+
+errorExit:
+    /* Free sem object using originating instance in case the Shared Client to Shared
+     * Server instance switch took place */
+    if (((Rm_Inst *)rmHandle)->mtSemObj) {
+        Rm_osalMtCsExit(((Rm_Inst *)rmHandle)->mtSemObj, mtKey);
+    }
+    RM_SS_INST_WB_EXIT_CS(rmInst, key);
+    return(totalResOwners);
+}
+
+/* FUNCTION PURPOSE: Display status of a RM instance
+ ***********************************************************************
+ * DESCRIPTION: Prints the current status of various RM instance
+ *              properties such as the state of all transactions
+ *              in the transaction queue and registered transports
+ */
+void Rm_instanceStatus(Rm_Handle rmHandle)
+{
+    Rm_Inst        *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Transport   *transportList = NULL;
+    Rm_Transaction *transactionQ = NULL;
+    void           *key;
+    void           *mtKey;
+
+    RM_SS_INST_INV_ENTER_CS(rmInst, key);
+    RM_SC_INST_INV_ENTER_CS(rmInst, key);
+    if (rmInst->mtSemObj) {
+        mtKey = Rm_osalMtCsEnter(rmInst->mtSemObj);
+    }
+
+    Rm_osalLog("Instance name: %s\n", rmInst->instName);
+    Rm_osalLog("Handle: 0x%08x\n", rmHandle);    
+    if (rmInst->instType == Rm_instType_SERVER) {
+        Rm_osalLog("Type:   Server\n");
+    } else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        Rm_osalLog("Type:   Client Delegate\n");
+    } else if (rmInst->instType == Rm_instType_CLIENT) {
+        Rm_osalLog("Type:   Client\n");
+    } else if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        Rm_osalLog("Type:   Shared Server\n");
+    } else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+        Rm_osalLog("Type:   Shared Client\n");
+
+        Rm_osalLog("\nShared Server Properties:\n");
+        /* Transfer to Shared Server instance to print out transport and
+         * transaction status */
+        rmInst = rmInst->u.sharedClient.sharedServerHandle;
+        Rm_osalLog("Instance name: %s\n", rmInst->instName);
+        Rm_osalLog("Handle: 0x%08x\n", rmHandle);
+    } else {
+        Rm_osalLog("Type:   UNKNOWN\n");
+        goto errorExit;
+    }
+
+    transportList = rmInst->transports;
+    if (transportList) {
+        Rm_osalLog("\nRegistered Transports:\n");
+        while (transportList) {
+            RM_SS_OBJ_INV(rmInst, transportList, Rm_Transport);
+            if (transportList->remoteInstType == Rm_instType_SERVER) {
+                Rm_osalLog("    Remote instType:    Server\n");
+            } else if (transportList->remoteInstType ==
+                       Rm_instType_CLIENT_DELEGATE) {
+                Rm_osalLog("    Remote instType:    Client Delegate\n");
+            } else {
+                Rm_osalLog("    Remote instType:    Client\n");
+            }
+            Rm_osalLog("    appTransportHandle: 0x%08x\n",
+                       transportList->appTransportHandle);
+            Rm_osalLog("\n");
+            transportList = transportList->nextTransport;
+        }
+    }
+
+    transactionQ = rmInst->transactionQueue;
+    if (transactionQ) {
+        Rm_osalLog("\nQueued Service Transactions:\n");
+        while (transactionQ) {
+            RM_SS_OBJ_INV(rmInst, transactionQ, Rm_Transaction);
+            Rm_osalLog("    Service type:       %d\n",
+                       transactionQ->type);
+            Rm_osalLog("    Service ID:         %d\n", transactionQ->localId);
+            Rm_osalLog("    Service srcInstName %s\n",
+                       transactionQ->serviceSrcInstName);
+            Rm_osalLog("    Service state:      %d\n", transactionQ->state);
+            Rm_osalLog("    Resource name:      %s\n",
+                       transactionQ->resourceInfo.name);
+            Rm_osalLog("    Resource base:      %d\n",
+                       transactionQ->resourceInfo.base);
+            Rm_osalLog("    Resource length:    %d\n",
+                       transactionQ->resourceInfo.length);
+            Rm_osalLog("    Resource alignment: %d\n",
+                       transactionQ->resourceInfo.alignment);
+            Rm_osalLog("    Resource NS name:   %s\n",
+                       transactionQ->resourceInfo.nameServerName);
+            Rm_osalLog("\n");
+            transactionQ = transactionQ->nextTransaction;
+        }
+    }
+
+errorExit:
+    /* Free sem object using originating instance in case the Shared Client
+     * to Shared Server instance switch took place */
+    if (((Rm_Inst *)rmHandle)->mtSemObj) {
+        Rm_osalMtCsExit(((Rm_Inst *)rmHandle)->mtSemObj, mtKey);
+    }
+    RM_SS_INST_WB_EXIT_CS(rmInst, key);
+}
+
+/* FUNCTION PURPOSE: RM instance creation and initialization
+ ***********************************************************************
+ * DESCRIPTION: Returns a new RM instance created and initialized
+ *              using the parameters provided via the initCfg
+ *              structure.
+ */
+Rm_Handle Rm_init(const Rm_InitCfg *initCfg, int32_t *result)
+{
+    Rm_Inst  *rmInst = NULL;
+    void     *grlDtb = NULL;
+    void     *policyDtb = NULL;
+    void     *linuxDtb = NULL;
+    int       addLinux = RM_FALSE;
+    void     *key;
+
+    *result = RM_OK;
+
+    if ((initCfg->instName == NULL) ||
+        ((strlen(initCfg->instName) + 1) > RM_NAME_MAX_CHARS)) {
+        *result = RM_ERROR_INVALID_INST_NAME;
+        goto errorExit;
+    }
+
+    if (initCfg->instType >= Rm_instType_LAST) {
+        *result = RM_ERROR_INVALID_INST_TYPE;
+        goto errorExit;
+    }
+
+    /* Create and initialize instance */
+    rmInst = Rm_osalMalloc(sizeof(*rmInst));
+    memset((void *)rmInst, 0, sizeof(*rmInst));
+    rmInst->isLocked = RM_FALSE;
+    rmInst->registeredWithDelegateOrServer = RM_FALSE;
+    rmInst->transactionSeqNum = transactionInitSequenceNum();
+
+    rmInst->instType = initCfg->instType;
+    rm_strncpy(rmInst->instName, initCfg->instName, RM_NAME_MAX_CHARS);
+    rmInst->mtSemObj = initCfg->mtSemObj;
+
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        if (!initCfg->instCfg.serverCfg.globalResourceList ||
+            !initCfg->instCfg.serverCfg.globalPolicy) {
+            *result = RM_ERROR_INVALID_SERVER_CONFIGURATION;
+            goto errorExit;
+        }
+
+        if (initCfg->instCfg.serverCfg.linuxDtb) {
+            linuxDtb = initCfg->instCfg.serverCfg.linuxDtb;
+            addLinux = RM_TRUE;
+        }
+
+        /* Create valid instance list from policy.  Must be done prior to
+         * parsing GRL so that Linux resources can be reserved correctly */
+        policyDtb = initCfg->instCfg.serverCfg.globalPolicy;
+        rmInst->validInstTree = rmPolicyVInstTreeInit(rmInst, policyDtb,
+                                                      addLinux, result);
+        if (*result != RM_OK) {
+            goto errorExit;
+        }
+
+        rmNameServerInit((Rm_Handle)rmInst);
+        grlDtb = initCfg->instCfg.serverCfg.globalResourceList;
+        if ((*result = rmAllocatorTreeInit(rmInst, grlDtb,
+                                           policyDtb, linuxDtb)) != RM_OK) {
+            goto errorExit;
+        }
+    } else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        if (!initCfg->instCfg.cdCfg.cdPolicy) {
+            *result = RM_ERROR_INVALID_CD_CONFIGURATION;
+            goto errorExit;
+        }
+
+        policyDtb = initCfg->instCfg.cdCfg.cdPolicy;
+        rmInst->validInstTree = rmPolicyVInstTreeInit(rmInst, policyDtb,
+                                                      addLinux, result);
+        if (*result != RM_OK) {
+            goto errorExit;
+        }
+
+        if ((*result = rmAllocatorTreeInit(rmInst, NULL,
+                                           policyDtb, NULL)) != RM_OK) {
+            goto errorExit;
+        }
+
+        /* Remove once CD instance is stable - tracked by SDOCM00100797 */
+        *result = RM_WARNING_CD_INSTANCE_NOT_STABLE;
+
+    } else if (rmInst->instType == Rm_instType_CLIENT) {
+        if (initCfg->instCfg.clientCfg.staticPolicy) {
+            policyDtb = initCfg->instCfg.clientCfg.staticPolicy;
+            rmInst->validInstTree = rmPolicyVInstTreeInit(rmInst, policyDtb,
+                                                          addLinux, result);
+            if (*result != RM_OK) {
+                goto errorExit;
+            }
+
+            if ((*result = rmAllocatorTreeInit(rmInst, NULL,
+                                               policyDtb, NULL)) != RM_OK) {
+                goto errorExit;
+            }
+        }
+        
+    } else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+        Rm_Handle  sHdl = initCfg->instCfg.sharedClientCfg.sharedServerHandle;
+        Rm_Inst   *ssInst = NULL;
+
+        if (sHdl) {
+            rmInst->u.sharedClient.sharedServerHandle = sHdl;
+            /* Invalidate the Shared server instance structure on this core to
+             * get the latest instance data. */
+            key = Rm_osalCsEnter();
+            Rm_osalBeginMemAccess((void *)sHdl, sizeof(Rm_Inst));
+            ssInst = rmInst->u.sharedClient.sharedServerHandle;
+            if (ssInst->instType != Rm_instType_SHARED_SERVER) {
+                *result = RM_ERROR_INVALID_SHARED_SERVER_HANDLE;
+                Rm_osalCsExit(key);
+                goto errorExit;
+            } else {
+                /* Invalidate all the trees */
+                rmPolicyValidInstTreeInv(ssInst->validInstTree);
+                rmAllocatorTreeInv(ssInst->allocatorTree);
+                rmNameServerTreeInv(ssInst->u.server.nameServer);
+            }
+            Rm_osalCsExit(key);
+        } else {
+            *result = RM_ERROR_INVALID_SHARED_SERVER_HANDLE;
+            goto errorExit;
+        }
+    } else {
+        *result = RM_ERROR_INVALID_INST_TYPE;
+        goto errorExit;
+    }
+
+    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        /* Writeback instance and trees for other cores */
+        rmPolicyValidInstTreeWb(rmInst->validInstTree);
+        rmAllocatorTreeWb(rmInst->allocatorTree);
+        rmNameServerTreeWb(rmInst->u.server.nameServer);
+        Rm_osalEndMemAccess((void *)rmInst, sizeof(*rmInst));
+    } else if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
+        /* Create the instance's task blocking mechanism */
+        rmInst->blockHandle = Rm_osalTaskBlockCreate();
+    }
+    /* else: just return handle */
+
+    return((Rm_Handle)rmInst);
+
+errorExit:
+    if (rmInst) {
+        rmAllocatorTreeDelete((Rm_Handle)rmInst);
+        rmNameServerDelete((Rm_Handle)rmInst);
+        rmPolicyVInstTreeDelete((Rm_Handle)rmInst);
+        Rm_osalFree((void *)rmInst, sizeof(*rmInst));
+    }
+    return(NULL);
+}
+
+/* FUNCTION PURPOSE: Deletes an RM instance
+ ***********************************************************************
+ * DESCRIPTION: Frees all memory associated with an RM instance
+ *              as long as all transports have been unregistered
+ *              and the service handle has been closed
+ */
+int32_t Rm_delete(Rm_Handle rmHandle, int ignorePendingServices)
+{
+    Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+    void    *key;
+
+    key = Rm_osalCsEnter();
+    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        Rm_osalBeginMemAccess((void *)rmInst, sizeof(*rmInst));
+    }
+
+    if (rmInst->serviceHandle) {
+        return(RM_ERROR_CANT_DELETE_WITH_OPEN_SERV_HNDL);
+    } else if (rmInst->transports) {
+        return(RM_ERROR_CANT_DELETE_WITH_REGD_TRANSPORT);
+    } else if (rmInst->transactionQueue && !ignorePendingServices) {
+        return(RM_ERROR_CANT_DELETE_PENDING_TRANSACTIONS);
+    }
+    /* else: delete instance since no more deletion failure cases */
+
+    if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
+        rmNameServerDelete(rmHandle);
+        rmAllocatorTreeDelete(rmHandle);
+        rmPolicyVInstTreeDelete(rmHandle);
+
+        /* Delete any transactions */
+        while(rmInst->transactionQueue) {
+            rmTransactionQueueDelete(rmInst, rmInst->transactionQueue->localId);
+        }
+
+        if (rmInst->instType != Rm_instType_SHARED_SERVER) {
+            /* Delete the instance's task blocking mechanism */
+            Rm_osalTaskBlockDelete(rmInst->blockHandle);
+        } else {
+            rmInst->allocatorTree       = NULL;
+            rmInst->validInstTree       = NULL;
+            rmInst->u.server.nameServer = NULL;
+            Rm_osalEndMemAccess((void *)rmInst, sizeof(*rmInst));
+        }
+    }
+
+    Rm_osalFree((void *)rmInst, sizeof(*rmInst));
+    Rm_osalCsExit(key);
+    return(RM_OK);
+}
+
+/* FUNCTION PURPOSE: Returns RM version information
+ ***********************************************************************
+ */
+uint32_t Rm_getVersion(void)
+{
+    return(RM_VERSION_ID);
+}
+
+/* FUNCTION PURPOSE: Returns RM version string
+ ***********************************************************************
+ */
+const char* Rm_getVersionStr(void)
+{
+    return(rmVersionStr);
+}
+