]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blobdiff - src/rm.c
Minor updates
[keystone-rtos/rm-lld.git] / src / rm.c
index 57e42c0a379831fb8739e85aad45a8af4aeddd23..d66ae06494669a74a004f62e7b9aea6a431b61e0 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, 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
-/* RM Types */\r
-#include <ti/drv/rm/rm_types.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
-#include <ti/drv/rm/rm_policy.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_servicesloc.h>\r
-#include <ti/drv/rm/include/rm_nameserverloc.h>\r
-#include <ti/drv/rm/include/rm_dtb_utilloc.h>\r
-\r
-/* RM LIBFDT includes */\r
-#include <ti/drv/rm/src/libfdt/libfdt.h>\r
-\r
-/* AVL BBST includes */\r
-#include <ti/drv/rm/include/tree.h>\r
-\r
-/* RM OSAL layer */\r
-#include <rm_osal.h>\r
-\r
-/**********************************************************************\r
- ************************** Globals ***********************************\r
- **********************************************************************/\r
-char rmIntegerAllocator[] = "integer";\r
-char rmTreeAllocator[] = "tree";\r
-\r
-extern char rmDtbStartingNode[];\r
-\r
-/** @brief Global Variable which describes the RM Version Information */\r
-const char   rmVersionStr[] = RM_VERSION_STR ":" __DATE__  ":" __TIME__;\r
-\r
-/**********************************************************************\r
- ************** Red-Black BBST Tree Allocator Functions ***************\r
- **********************************************************************/\r
-\r
-/* Prototype for function that allocates new tree nodes */\r
-Rm_ResourceTreeNode *Rm_newResourceTreeNode(uint32_t resourceBase, uint32_t resourceLength, \r
-                                            char *allocatedTo)\r
-{\r
-    Rm_ResourceTreeNode *newNode = NULL;\r
-\r
-    newNode = Rm_osalMalloc(sizeof(Rm_ResourceTreeNode));\r
-\r
-    /* Populate the RM relevant fields */\r
-    newNode->base = resourceBase;\r
-    newNode->length = resourceLength;\r
-    strcpy(newNode->allocatedTo, allocatedTo);\r
-\r
-    return(newNode);\r
-}\r
-\r
-/* Prototype for function that frees new tree nodes */\r
-void Rm_freeResourceTreeNode(Rm_ResourceTreeNode *treeNode)\r
-{\r
-    /* Free the memory associated with the tree node. */\r
-    Rm_osalFree((void *)treeNode, sizeof(Rm_ResourceTreeNode));\r
-}\r
-\r
-/* Prototype for tree node comparison function\r
- * element1 < element2 --> return < 0\r
- * element1 = element2 --> return 0\r
- * element1 > element2 --> return > 0 */\r
-int Rm_ResourceTreeNodeCompare(Rm_ResourceTreeNode *element1, Rm_ResourceTreeNode *element2)\r
-{\r
-    uint32_t element1End = element1->base + element1->length - 1;\r
-    uint32_t element2End = element2->base + element2->length - 1;\r
-\r
-    if (element1End < element2->base)\r
-    {\r
-        /* End of element1 range is less than the start of element2's range.  Return a negative\r
-         * value */\r
-        return (-1);\r
-    }\r
-    else if (element1->base > element2End)\r
-    {\r
-        /* Start of element1 range is after end of element2's range.  Return a positive value */\r
-        return (1);\r
-    }\r
-    else\r
-    {\r
-        /* If neither of the latter conditions were satisfied there is some overlap between\r
-         * element1 and element2.  Return 0 since the application must handle this overlap. */\r
-        return (0);\r
-    }\r
-}\r
-\r
-/* Generate the red-black tree manipulation functions */\r
-RB_GENERATE(_Rm_ResourceTree, _Rm_ResourceTreeNode, linkage, Rm_ResourceTreeNodeCompare);\r
-\r
-/**********************************************************************\r
- ********************** Internal Functions ****************************\r
- **********************************************************************/\r
-\r
-Rm_Transaction *Rm_transactionQueueAdd(Rm_Inst *rmInst)\r
-{\r
-    Rm_Transaction *transactionQueue = (Rm_Transaction *)rmInst->transactionQueue;\r
-    Rm_Transaction *newTransaction = NULL;\r
-    void *key;\r
-\r
-    /* Lock access to the RM instance's transaction queue */\r
-    key = Rm_osalMtCsEnter();\r
-\r
-    /* Get memory for a new transaction from local memory */\r
-    newTransaction = Rm_osalMalloc(sizeof(Rm_Transaction));\r
-\r
-    /* Return if the memory allocated for the transaction entry is NULL */\r
-    if (newTransaction != NULL)\r
-    {\r
-        /* Clear the transaction */\r
-        memset((void *)newTransaction, 0, sizeof(Rm_Transaction));\r
-\r
-        /* Create an ID for the new transaction.  The ID will be used for two purposes:\r
-         * 1) Matching responses from higher level RM agents to requests\r
-         * 2) Provided to the component that requested the service so that it can match its\r
-         *    request with the response it receives via its callback function it provided */\r
-        newTransaction->localId = Rm_transactionGetSequenceNum(rmInst);\r
-        /* New transaction's nextTransaction pointer will always be NULL */\r
-        newTransaction->nextTransaction = NULL;  \r
-\r
-        /* Check if there are any transactions in the transaction queue */\r
-        if (transactionQueue)\r
-        {\r
-            /* At least one transaction in the transaction queue.  Add the new entry to the \r
-             * end of the transaction queue */\r
-            while (transactionQueue->nextTransaction != NULL)\r
-            {\r
-                /* Traverse the list until arriving at the last transaction */\r
-                transactionQueue = transactionQueue->nextTransaction;\r
-            }\r
-\r
-            /* Add the new transaction to the end of the queue */\r
-            transactionQueue->nextTransaction = newTransaction;\r
-        }\r
-        else\r
-        {\r
-            /* The transaction queue does not currently exist.  The new transaction is the \r
-             * first transaction */\r
-            rmInst->transactionQueue = newTransaction;\r
-        }\r
-    }\r
-\r
-    Rm_osalMtCsExit(key);\r
-    return (newTransaction);\r
-}\r
-\r
-Rm_Transaction *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)\r
-{\r
-    Rm_Transaction *transaction = (Rm_Transaction *)rmInst->transactionQueue;\r
-\r
-    /* Make sure there is at least one transaction in the transaction queue */\r
-    if (transaction != NULL)\r
-    {\r
-        /* Find the transaction ID within the specified RM instance's transaction queue.\r
-         * If the end of the transaction queue is reached without finding the transaction the \r
-         * transaction pointer will be NULL */\r
-        while (transaction != NULL)\r
-        {\r
-            if (transaction->localId == transactionId)\r
-            {\r
-                /* Match: break out of loop and return the transaction */\r
-                break;             \r
-            }\r
-            transaction = transaction->nextTransaction;\r
-        }\r
-    }\r
-\r
-    return (transaction);\r
-}\r
-\r
-int32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)\r
-{\r
-    Rm_Transaction *transaction = (Rm_Transaction *) rmInst->transactionQueue;\r
-    Rm_Transaction *prevTransaction = NULL;\r
-    int32_t retVal = RM_SERVICE_STATE_OKAY;\r
-    void *key;\r
-\r
-    /* Lock access to the RM instance's transaction queue */\r
-    key = Rm_osalMtCsEnter();\r
-\r
-    /* Find the transaction ID within the specified RM instance's transaction queue. */\r
-    while (transaction != NULL)\r
-    {\r
-        if (transaction->localId == transactionId)\r
-        {\r
-            /* Match: break out of loop and delete the transaction */\r
-            break;             \r
-        }\r
-\r
-        prevTransaction = transaction;\r
-        transaction = transaction->nextTransaction;\r
-    }\r
-\r
-    /* Traversed entire queue but did not find transaction */\r
-    if (transaction == NULL)\r
-    {\r
-        retVal = RM_SERVICE_ERROR_SERVICE_TRANSACTION_DOES_NOT_EXIST;\r
-    }\r
-    else\r
-    {\r
-        /* Delete the transaction */\r
-        if (prevTransaction == NULL)\r
-        {\r
-            /* Transaction to be deleted exists at start of transaction queue.  Map second\r
-             * transaction to be start of transaction queue as long as there are more than\r
-             * one transactions. */\r
-            rmInst->transactionQueue = transaction->nextTransaction;\r
-        }\r
-        else\r
-        {\r
-            /* Transaction to be deleted is in the middle or at end of the queue.  Adjust \r
-             * adjacent transaction pointers.  This covers the case where the transaction to be \r
-             * removed is at the end of the queue. */\r
-            prevTransaction->nextTransaction = transaction->nextTransaction;\r
-        }\r
-\r
-        /* Free the memory associated with the transaction. */\r
-        Rm_osalFree((void *)transaction, sizeof(Rm_Transaction));\r
-    }\r
-\r
-    Rm_osalMtCsExit(key);\r
-    return (retVal);\r
-}\r
-\r
-uint32_t Rm_transactionInitSequenceNum(void)\r
-{\r
-    /* Sequence number can never have a value of zero so that there are no conflicts\r
-     * with transactions that have a remoteOriginatingId of zero */\r
-    return (1);\r
-}\r
-\r
-uint32_t Rm_transactionGetSequenceNum(Rm_Inst *rmInst)\r
-{\r
-    uint32_t sequenceNum = 0;\r
-\r
-    /* Get the next sequence number and then increment.  If there's an overflow\r
-     * assign the initial value instead of incrementing. */\r
-    if (rmInst->transactionSeqNum + 1 < rmInst->transactionSeqNum)\r
-    {\r
-        /* Overflow */\r
-        sequenceNum = rmInst->transactionSeqNum;\r
-        rmInst->transactionSeqNum = Rm_transactionInitSequenceNum();\r
-    }\r
-    else\r
-    {\r
-        sequenceNum = rmInst->transactionSeqNum++;\r
-    }    \r
-\r
-    return (sequenceNum);\r
-}\r
-\r
-Rm_Allocator *Rm_allocatorAdd(Rm_Inst *rmInst, const char *resourceName)\r
-{\r
-    Rm_Allocator *allocators = (Rm_Allocator *)rmInst->allocators;\r
-    Rm_Allocator *newAllocator = NULL;\r
-    void *key;\r
-\r
-    /* Lock access to the RM instance's allocator list */\r
-    key = Rm_osalMtCsEnter();\r
-\r
-    /* Get memory for a new allocator from local memory */\r
-    newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));\r
-\r
-    /* Return if the memory allocated for the allocator is NULL */\r
-    if (newAllocator != NULL)\r
-    {\r
-        /* Clear the allocator */\r
-        memset((void *)newAllocator, 0, sizeof(Rm_Allocator));\r
-\r
-        /* Populate the allocator */\r
-        strcpy(newAllocator->resourceName, resourceName);\r
-        /* allocator's root entry will be created by the invoking function */\r
-        newAllocator->allocatorRootEntry = NULL;\r
-        /* New allocator's nextAllocator pointer will always be NULL */\r
-        newAllocator->nextAllocator = NULL;  \r
-\r
-        /* Check if there are any allocators in the allocator list */\r
-        if (allocators)\r
-        {\r
-            /* At least one allocator in the allocator list.  Add the new allocator to the \r
-             * end of the allocator list */\r
-            while (allocators->nextAllocator != NULL)\r
-            {\r
-                /* Traverse the list until arriving at the last allocator */\r
-                allocators = allocators->nextAllocator;\r
-            }\r
-\r
-            /* Add the new allocator to the end of the list */\r
-            allocators->nextAllocator = newAllocator;\r
-        }\r
-        else\r
-        {\r
-            /* The allocator list does not currently exist.  The new allocator is the \r
-             * first allocator */\r
-            rmInst->allocators = newAllocator;\r
-        }\r
-    }\r
-\r
-    Rm_osalMtCsExit(key);\r
-    return (newAllocator);\r
-}\r
-\r
-Rm_Allocator *Rm_allocatorFind(Rm_Inst *rmInst, char *resourceName)\r
-{\r
-    Rm_Allocator *allocator = (Rm_Allocator *)rmInst->allocators;\r
-\r
-    /* Make sure there is at least one allocator in the allocator list */\r
-    if (allocator != NULL)\r
-    {\r
-        /* Find the resource name within the allocator list.  If the end of the\r
-         * allocator list is reached without finding the resource name the \r
-         * allocator pointer will be NULL */\r
-        while (allocator != NULL)\r
-        {\r
-            if (strcmp(allocator->resourceName, resourceName) == 0)\r
-            {\r
-                /* Match: break out of loop and return the allocator */\r
-                break;             \r
-            }\r
-            allocator = allocator->nextAllocator;\r
-        }\r
-    }\r
-\r
-    return (allocator);\r
-}\r
-\r
-int32_t Rm_allocatorDelete(Rm_Inst *rmInst, char *resourceName)\r
-{\r
-    Rm_Allocator *allocator = (Rm_Allocator *) rmInst->allocators;\r
-    Rm_Allocator *prevAllocator = NULL;\r
-    int32_t retVal = RM_SERVICE_STATE_OKAY;\r
-    void *key;\r
-\r
-    /* Lock access to the RM instance's allocator list */\r
-    key = Rm_osalMtCsEnter();\r
-\r
-    /* Find the resource within the specified RM instance's allocator list. */\r
-    while (allocator != NULL)\r
-    {\r
-        if (strcmp(allocator->resourceName, resourceName) == 0)\r
-        {\r
-            /* Match: break out of loop and delete the transaction */\r
-            break;             \r
-        }\r
-\r
-        prevAllocator = allocator;\r
-        allocator = allocator->nextAllocator;\r
-    }\r
-\r
-    /* Traversed entire list but did not find allocator. */\r
-    if (allocator == NULL)\r
-    {\r
-        retVal = -22; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
-    }\r
-    else\r
-    {\r
-        /* Delete the allocator */\r
-        if (prevAllocator == NULL)\r
-        {\r
-            /* Allocator to be deleted exists at start of allocator list.  Map second\r
-             * allocator to be start of allocator list as long as there are more than\r
-             * one allocators. */\r
-            rmInst->allocators = allocator->nextAllocator;\r
-        }\r
-        else\r
-        {\r
-            /* Allocator to be deleted is in the middle or at end of the list.  Adjust \r
-             * adjacent allocator pointers.  This covers the case where the allocator to be \r
-             * removed is at the end of the list. */\r
-            prevAllocator->nextAllocator = allocator->nextAllocator;\r
-        }\r
-\r
-        /* Free the memory associated with the allocator. */\r
-        Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));\r
-    }\r
-\r
-    Rm_osalMtCsExit(key);\r
-    return (retVal);\r
-}\r
-\r
-int32_t Rm_createTreeAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)\r
-{\r
-    Rm_Allocator *allocator = NULL;\r
-    Rm_ResourceTree *treeRootEntry = NULL;\r
-    Rm_ResourceTreeNode *treeNode = NULL;\r
-    Rm_ResourceTreeNode *collidingNode = NULL;\r
-\r
-    /* Create the new base integer allocator */\r
-    allocator = Rm_allocatorAdd(rmInst, resourceName);\r
-\r
-    /* Create the tree root entry and initialize it */\r
-    treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));\r
-    RB_INIT(treeRootEntry);\r
-\r
-    /* Create a node in the tree for resource range and insert them into the tree. */\r
-    while (range != NULL)\r
-    {\r
-        treeNode = Rm_newResourceTreeNode(range->base, range->length, RM_NOT_ALLOCATED_STRING);\r
-\r
-        /* Insert the node into the tree */\r
-        collidingNode = RB_INSERT(_Rm_ResourceTree, treeRootEntry, treeNode);\r
-\r
-        if (collidingNode)\r
-        {\r
-            Rm_ResourceTreeNode *nextNode = NULL;\r
-            \r
-            /* Node that was inserted colliding with an existing node.  Clean up the tree\r
-             * that's been allocated thus far and return an error since there should be no\r
-             * collisions */\r
-            for (treeNode = RB_MIN(_Rm_ResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode)\r
-            {\r
-                       nextNode = RB_NEXT(_Rm_ResourceTree, treeRootEntry, treeNode);\r
-                       RB_REMOVE(_Rm_ResourceTree, treeRootEntry, nextNode);\r
-                Rm_freeResourceTreeNode(treeNode);\r
-               }\r
-            /* Delete the tree root entry and the allocator */\r
-            Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));\r
-            Rm_allocatorDelete(rmInst, allocator->resourceName);\r
-            return (-24); /* TODO FIX RETURN */\r
-        }\r
-\r
-        range = range->nextRange;\r
-    }\r
-\r
-    /* Assign the tree's root to the allocator */\r
-    allocator->allocatorRootEntry = treeRootEntry;\r
-\r
-    return(0);   /* TODO: FIX THIS RETURN */\r
-}\r
-\r
-/* Called when an allocate request is made but the base is unspecified.  RM must preallocate\r
- * resources which then must be checked against the RM policy for the instance.  If the\r
- * policy does not agree another resource(s) must be preallocated and tested against the \r
- * policy.  Policy will provide initialize the preallocate with the base that it allows\r
- * for the rm instance for the specified resource. */\r
-int32_t Rm_treePreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    Rm_ResourceTreeNode findNode;\r
-    Rm_ResourceTreeNode *matchingNode = NULL;\r
-    uint32_t policyRangeEnd = opInfo->policyBase + opInfo->policyLength - 1;\r
-    uint32_t index;\r
-    bool resourceFound = FALSE;\r
-    int32_t retVal = RM_SERVICE_PROCESSING;\r
-\r
-    /* Find the tree node that contains the first value in the specified policy range. */\r
-    if (opInfo->policyBase)\r
-    {\r
-        findNode.base = opInfo->policyBase;\r
-    }\r
-    else\r
-    {\r
-        matchingNode = RB_MIN(_Rm_ResourceTree, allocator->allocatorRootEntry);\r
-        findNode.base = matchingNode->base;\r
-    }\r
-    \r
-    findNode.length = 1;\r
-    matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
-\r
-    if (matchingNode != NULL)\r
-    {\r
-        /* Begin searching for an available range of resources starting from the\r
-         * matching node */\r
-        for (index = matchingNode->base; index <= policyRangeEnd;)\r
-        {\r
-            /* Is the matchingNode free? */\r
-            if (strcmp(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
-            {\r
-                uint32_t matchEnd = matchingNode->base + matchingNode->length - 1;\r
-\r
-                /* Move index to the first resource satisfying the alignment property */\r
-                if ((index % opInfo->policyAlignment) != 0)\r
-                {\r
-                    index += (opInfo->policyAlignment - (index % opInfo->policyAlignment));\r
-                }\r
-                \r
-                /* Move through the node's resource range looking for a contiguous set of resources\r
-                 * that satisfy the request. */\r
-                while ((index <= matchEnd) && (index <= policyRangeEnd))\r
-                {\r
-                    if (((index + opInfo->resourceInfo->length - 1) <= matchEnd) &&\r
-                        ((index + opInfo->resourceInfo->length - 1) <= policyRangeEnd))\r
-                    {\r
-                        /* Found a resource range in the node that satisfies the requirements */\r
-                        opInfo->resourceInfo->base = index;\r
-                        resourceFound = TRUE;\r
-                        break;\r
-                    }\r
-\r
-                    /* Move index to the next resource value that satisfies the alignment property */\r
-                    index += (opInfo->policyAlignment - (index % opInfo->policyAlignment));\r
-                }\r
-            }\r
-            \r
-            if (!resourceFound)\r
-            {\r
-                /* Move to the next tree node */\r
-                matchingNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                if (matchingNode == NULL)\r
-                {\r
-                    /* Reached end of tree.  Resource range does not exist.  Leave the search\r
-                     * loop */\r
-                    break;\r
-                }\r
-                else\r
-                {\r
-                    index = matchingNode->base;\r
-                }\r
-            }\r
-            else\r
-            {\r
-                /* Found a resource range that satisfies the request properties.  Break out of the\r
-                 * search loop */\r
-                break;\r
-            }\r
-        }\r
-\r
-        if (!resourceFound)\r
-        {\r
-            retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
-    }\r
-\r
-    return(retVal); \r
-}\r
-\r
-/* Assume the policy has already approved of the allocation */\r
-int32_t Rm_treeAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    Rm_ResourceTreeNode findNode;\r
-    Rm_ResourceTreeNode *matchingNode = NULL;\r
-    Rm_ResourceTreeNode *leftNode = NULL;\r
-    Rm_ResourceTreeNode *rightNode = NULL;  \r
-    uint32_t findEnd, matchingEnd;\r
-    int32_t retVal;\r
-\r
-    /* Find the tree node that contains the specified resource range */\r
-    findNode.base = opInfo->resourceInfo->base;\r
-    findNode.length = opInfo->resourceInfo->length;\r
-    matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
-\r
-    if (matchingNode != NULL)\r
-    {\r
-        findEnd = findNode.base + findNode.length - 1;\r
-        matchingEnd = matchingNode->base + matchingNode->length - 1;\r
-        \r
-        /* Does the request range fit within the matching nodes entire range? */\r
-        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd))\r
-        {\r
-            /* Handle node create, combine, deletion based on the request range if\r
-             * resources are available. */\r
-            if (strcmp(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
-            {\r
-                /* Handle case where the findNode range matches the matchingNode\r
-                 * range exactly.\r
-                 *\r
-                 * base0                                  base0+length0-1\r
-                 *   |<---------------length0------------------->|  => existing node\r
-                 *   |<---------------length1------------------->|  => requested resources\r
-                 * base1                                  base1+length1-1\r
-                 */    \r
-                if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))\r
-                {\r
-                    /* Can reserve matchingNode's resources in-place */\r
-                    strcpy(matchingNode->allocatedTo, opInfo->serviceSrcInstName);\r
-                }\r
-                /* Handle case where the findNode range is a subset of the matchingNode\r
-                 * range and neither of the boundaries of the two ranges are equivalent.\r
-                 *\r
-                 * base0                                  base0+length0-1\r
-                 *   |<---------------length0------------------->|  => existing node\r
-                 *         |<---------length1---------->|  => requested resources\r
-                 *       base1                   base1+length1-1\r
-                 */    \r
-                else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd))\r
-                {\r
-                    /* Split the matching node into three nodes:\r
-                     * left node - free resources to left of newly allocated resources\r
-                     * middle node - newly allocated resources that satisfy the request\r
-                     * right node - free resources to the right of newly allocated resources */\r
-\r
-                    /* Remove the matching node from the tree for modification. */\r
-                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-\r
-                    /* New left node attributes:\r
-                     * base: base of the matching node\r
-                     * length: base of requested resources - base of matching node */\r
-                    leftNode = Rm_newResourceTreeNode(matchingNode->base, findNode.base - matchingNode->base,\r
-                                                      RM_NOT_ALLOCATED_STRING);\r
-                    /* New right node attributes:\r
-                     * base: base of the requested resources + length of requested resources\r
-                     * length: right bound of matching node - right bound of request resources */\r
-                    rightNode = Rm_newResourceTreeNode(findNode.base + findNode.length,\r
-                                                       matchingEnd - findEnd, RM_NOT_ALLOCATED_STRING);\r
-\r
-                    /* Base and length of matching node become the base and length of the\r
-                     * requested resources */\r
-                    matchingNode->base = findNode.base;                                    \r
-                    matchingNode->length = findNode.length;\r
-                    /* Reserve the resources */\r
-                    strcpy(matchingNode->allocatedTo, opInfo->serviceSrcInstName);\r
-\r
-                    /* Insert all the nodes */\r
-                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                }\r
-                /* Handle cases where one of findNode range boundaries is equivalent to\r
-                 * one of the matchingNode range boundaries.\r
-                 *\r
-                 * base0                                  base0+length0-1\r
-                 *   |<---------------length0------------------->|  => existing node\r
-                 *   |<---------length1---------->|  => requested resources\r
-                 * base1                   base1+length1-1\r
-                 *\r
-                 * OR\r
-                 *\r
-                 * base0                                  base0+length0-1\r
-                 *   |<---------------length0------------------->|  => existing node\r
-                 *                  |<---------length1---------->|  => requested resources\r
-                 *                base1                   base1+length1-1                 \r
-                 */    \r
-                else\r
-                {     \r
-                    /* Remove the matchingNode from the tree since it will be edited */\r
-                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    \r
-                    if (findNode.base == matchingNode->base)\r
-                    {\r
-                        /* There may be a combine possibility to the left. Extract leftNode to check */\r
-                        leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        \r
-                        /* Can the node to the left of the matchingNode be combined with the \r
-                         * findNode's range? */\r
-                        if (leftNode && (strcmp(leftNode->allocatedTo, opInfo->serviceSrcInstName) == 0))\r
-                        {\r
-                            /* Remove the leftNode from the tree for editing */\r
-                            RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-\r
-                            /* Combine the leftNode and the findNode */\r
-                            leftNode->length += findNode.length;\r
-                        }\r
-                        else\r
-                        {\r
-                            /* Allocate a new leftNode that will take the place of the findNode\r
-                             * range in tree. */\r
-                            leftNode = Rm_newResourceTreeNode(findNode.base, findNode.length,\r
-                                                              opInfo->serviceSrcInstName);\r
-                        }\r
-\r
-                        /* Account for the leftNode in the matchingNode */\r
-                        matchingNode->base = findNode.base + findNode.length;\r
-                        matchingNode->length = matchingEnd - findEnd;  \r
-\r
-                        /* Insert the left node */\r
-                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                    }\r
-                    else if (findEnd == matchingEnd)\r
-                    {\r
-                        /* There may be a combine possibility to the right. Extract rightNode to check */\r
-                        rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        \r
-                        /* Can the node to the right of the matchingNode be combined with the \r
-                         * findNode's range? */\r
-                        if (rightNode && (strcmp(rightNode->allocatedTo, opInfo->serviceSrcInstName) == 0))\r
-                        {\r
-                            /* Remove the rightNode from the tree for editing */\r
-                            RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-\r
-                            /* Combine the rightNode and the findNode */\r
-                            rightNode->base = findNode.base;\r
-                            rightNode->length += findNode.length;\r
-                        }\r
-                        else\r
-                        {\r
-                            /* Allocate a new rightNode that will take the place of the findNode\r
-                             * range in tree. */\r
-                            rightNode = Rm_newResourceTreeNode(findNode.base, findNode.length,\r
-                                                               opInfo->serviceSrcInstName);\r
-                        }\r
-\r
-                        /* Account for the rightNode in the matchingNode */\r
-                        matchingNode->length -= findNode.length;  \r
-\r
-                        /* Insert the right node */\r
-                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                    }\r
-\r
-                    /* Reinsert the edited matching node */\r
-                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                }\r
-                \r
-                retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
-            }\r
-            else\r
-            {\r
-                /* A resource superset containing the requested range has\r
-                 * already been allocated. */\r
-                retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            /* Request ranges that span multiple nodes signify resources are\r
-             * not available because nodes are combined into larger contiguous ranges\r
-             * on resource free operations. */\r
-            retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        /* The requested resources could not be found in the allocator */\r
-        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
-    }\r
-\r
-    return(retVal);        \r
-}\r
-\r
-/* Assume policy has already approved of the free */\r
-int32_t Rm_treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    Rm_ResourceTreeNode findNode;\r
-    Rm_ResourceTreeNode *matchingNode = NULL;\r
-    Rm_ResourceTreeNode *leftNode = NULL;\r
-    Rm_ResourceTreeNode *rightNode = NULL;\r
-    bool combineLeft = FALSE;\r
-    bool combineRight = FALSE;\r
-    uint32_t findEnd, matchingEnd;\r
-    int32_t retVal;\r
-\r
-    /* Find the tree node that contains the specified resource range */\r
-    findNode.base = opInfo->resourceInfo->base;\r
-    findNode.length = opInfo->resourceInfo->length;\r
-    matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
-\r
-    if (matchingNode != NULL)\r
-    {\r
-        findEnd = findNode.base + findNode.length - 1;\r
-        matchingEnd = matchingNode->base + matchingNode->length - 1;\r
-        \r
-        /* Does the free range fit within the matching nodes entire range?  It should\r
-         * either be the entire range or a subset set of the found range. (the latter\r
-         * satisfies the case where an entity allocated a contiguous block of resources\r
-         * then attempts to free a contiguous subset of the allocated block. */\r
-        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd))\r
-        {            \r
-            if (strcmp(matchingNode->allocatedTo, opInfo->serviceSrcInstName) == 0)\r
-            {\r
-                /* Resources can be freed */\r
-\r
-                if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))\r
-                {\r
-                    /* Case 1: free range equals allocated matched node exactly. Attempt to combine \r
-                     *         the range to be freed with the resource nodes to the left and\r
-                     *         right of the free range.\r
-                     *\r
-                     * |<--left node-->||<---matched node--->||<--right node-->|\r
-                     *                  |<---free request--->|\r
-                     */ \r
-\r
-                    leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-\r
-                    /* Remove the matching node from the tree and the nodes to the left and\r
-                     * right of the matching node.  Removing from tree will not\r
-                     * wipe any of the base+length data in the node.  Can reuse since they won't\r
-                     * be freed */\r
-                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-\r
-                    /* See if the left or right or both nodes can be combined with the matching\r
-                     * node that will be freed. */\r
-                    if (leftNode && (strcmp(leftNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
-                    {\r
-                        /* Combine the left node and the matching node */\r
-                        RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                        combineLeft = TRUE;\r
-                    }\r
-                    if (rightNode && (strcmp(rightNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
-                    {\r
-                        /* Combine the right node and the matching node */\r
-                        RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                        combineRight = TRUE;\r
-                    }\r
-\r
-                    /* Perform any combines, insert the leftover nodes, and free any memory associated\r
-                     * with any nodes that weren't reinserted into the tree */\r
-                    if (combineLeft && combineRight)\r
-                    {\r
-                        /* Combine all three nodes into the matchingNode.  Insert the freed cumulative\r
-                         * matching node and delete the memory for the old left and right nodes */\r
-                        matchingNode->base = leftNode->base;\r
-                        matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;\r
-\r
-                        Rm_freeResourceTreeNode(leftNode);\r
-                        Rm_freeResourceTreeNode(rightNode);                        \r
-                    }\r
-                    else if (combineLeft)\r
-                    {\r
-                        /* Combine the left and matching nodes.  Reinsert the right. */\r
-                        matchingNode->base = leftNode->base;\r
-                        matchingNode->length += leftNode->length;\r
-                        \r
-                        Rm_freeResourceTreeNode(leftNode);\r
-                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);                        \r
-                    }\r
-                    else if (combineRight)\r
-                    {\r
-                        /* Combine the right and matching nodes.  Reinsert the left. */\r
-                        matchingNode->length += rightNode->length;\r
-                        \r
-                        Rm_freeResourceTreeNode(rightNode);\r
-                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                    }\r
-                    else\r
-                    {\r
-                        /* Combine cannot be performed.  Reinsert the left and right nodes then\r
-                         * free the matching node and reinsert it */\r
-                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                    }\r
-\r
-                    /* No matter the combine route taken the matching node will always be declared\r
-                     * free and reinserted */\r
-                    strcpy(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING);\r
-                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);                    \r
-                }\r
-                else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd))\r
-                {\r
-                    /* Case 2: free range is less than range in matched node. Need to split\r
-                     *         the matched node into three nodes.\r
-                     *\r
-                     * |<----------matched node---------->|\r
-                     *        |<---free request--->|\r
-                     */ \r
-\r
-                    /* Remove matching node for editing. */\r
-                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-\r
-                    /* New left node attributes:\r
-                     * base: base of the matching node\r
-                     * length: base of requested resources - base of matching node */\r
-                    leftNode = Rm_newResourceTreeNode(matchingNode->base, findNode.base - matchingNode->base,\r
-                                                      matchingNode->allocatedTo); \r
-                    /* New right node attributes:\r
-                     * base: base of the requested resources + length of requested resources\r
-                     * length: right bound of matching node - right bound of request resources */\r
-                    rightNode = Rm_newResourceTreeNode(findNode.base + findNode.length,\r
-                                                       matchingEnd - findEnd, matchingNode->allocatedTo);\r
-\r
-                    /* Insert the left and right nodes into the tree. */\r
-                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-\r
-                    /* Base and length of matching node become the base and length of the freed resources */\r
-                    matchingNode->base = findNode.base;                                    \r
-                    matchingNode->length = findNode.length;\r
-                    /* Free the resources and insert them into the tree */\r
-                    strcpy(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING);\r
-                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                }\r
-                else\r
-                {\r
-                    /* Remove the matchingNode from the tree since it will be edited */\r
-                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                    \r
-                    if (findNode.base == matchingNode->base)\r
-                    {\r
-                        /* Case 3: Free range is on left boundary of matched node. Try to \r
-                         *         combine the free range with the left node if free.\r
-                         *\r
-                         * |<---left node (free)--->||<----------matched node---------->|\r
-                         *                           |<---findNode (free req)--->|\r
-                         */ \r
-                   \r
-                        /* There may be a combine possibility to the left. Extract leftNode to check */\r
-                        leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        \r
-                        /* Can the node to the left of the matchingNode be combined with the \r
-                         * findNode's range? */\r
-                        if (leftNode && (strcmp(leftNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
-                        {\r
-                            /* Remove the leftNode from the tree for editing */\r
-                            RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-\r
-                            /* Combine the leftNode and the findNode */\r
-                            leftNode->length += findNode.length;\r
-                        }\r
-                        else\r
-                        {\r
-                            /* Allocate a new leftNode that will take the place of the findNode\r
-                             * range in tree. */\r
-                            leftNode = Rm_newResourceTreeNode(findNode.base, findNode.length,\r
-                                                              RM_NOT_ALLOCATED_STRING);\r
-                        }\r
-\r
-                        /* Account for the leftNode in the matchingNode */\r
-                        matchingNode->base = findNode.base + findNode.length;\r
-                        matchingNode->length = matchingEnd - findEnd;  \r
-\r
-                        /* Insert the left node */\r
-                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-                    }\r
-                    else if (findEnd == matchingEnd)\r
-                    {\r
-                        /* Case 4: Free range is on right boundary of matched node. Try to \r
-                         *         combine the free range with the right node if free.\r
-                         *\r
-                         * |<----------matched node---------->||<---right node (free)--->|\r
-                         *        |<---findNode (free req)--->|\r
-                         */ \r
-                        \r
-                        /* There may be a combine possibility to the right. Extract rightNode to check */\r
-                        rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                        \r
-                        /* Can the node to the right of the matchingNode be combined with the \r
-                         * findNode's range? */\r
-                        if (rightNode && (strcmp(rightNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
-                        {\r
-                            /* Remove the rightNode from the tree for editing */\r
-                            RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-\r
-                            /* Combine the rightNode and the findNode */\r
-                            rightNode->base = findNode.base;\r
-                            rightNode->length += findNode.length;\r
-                        }\r
-                        else\r
-                        {\r
-                            /* Allocate a new rightNode that will take the place of the findNode\r
-                             * range in tree. */\r
-                            rightNode = Rm_newResourceTreeNode(findNode.base, findNode.length,\r
-                                                               RM_NOT_ALLOCATED_STRING);\r
-                        }\r
-\r
-                        /* Account for the rightNode in the matchingNode */\r
-                        matchingNode->length -= findNode.length;  \r
-\r
-                        /* Insert the right node */\r
-                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-                    }\r
-\r
-                    /* Reinsert the edited matching node */\r
-                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-                }\r
-\r
-                retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
-            }\r
-            else\r
-            {\r
-                /* The matching allocated range to be freed was allocated to a different instance. */\r
-                retVal = RM_SERVICE_DENIED_RESOURCE_NOT_ALLOCATED_TO_INSTANCE_REQUESTING_THE_SERVICE;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            /* Free resource range crosses over node boundaries.  This signifies a\r
-             * free of both allocated and unallocated resources since nodes are combined\r
-             * on allocate and free operations if possible. */\r
-            retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_FREE;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        /* The free resources could not be found in the allocator */\r
-        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
-    }\r
-\r
-    return(retVal);  \r
-}\r
-\r
-int32_t Rm_allocatorOperation(Rm_Inst *rmInst, Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    Rm_Allocator *allocator = NULL;\r
-    int32_t retVal;\r
-    void *key;\r
-\r
-    /* Lock access to the RM instance's transaction queue */\r
-    key = Rm_osalMtCsEnter();\r
-\r
-    /* Get the specified resource's allocator */\r
-    allocator = Rm_allocatorFind(rmInst, opInfo->resourceInfo->name);\r
-\r
-    if (allocator)\r
-    {\r
-        /* Call the allocator's function */\r
-        if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE)\r
-        {\r
-            retVal = Rm_treePreAllocate(allocator, opInfo);\r
-        }               \r
-        else if (opInfo->operation == Rm_allocatorOp_ALLOCATE)\r
-        {\r
-            retVal = Rm_treeAllocate(allocator, opInfo);\r
-        }\r
-        else if (opInfo->operation == Rm_allocatorOp_FREE)\r
-        {\r
-            retVal = Rm_treeFree(allocator, opInfo);\r
-        }         \r
-    }\r
-    else\r
-    {\r
-        /* Allocator could not be found for resource */\r
-        retVal = RM_SERVICE_DENIED_RESOURCE_DOES_NOT_EXIST;\r
-    }\r
-\r
-    Rm_osalMtCsExit(key);\r
-    return(retVal);\r
-}\r
-\r
-void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
-{\r
-    Rm_AllocatorOpInfo opInfo;\r
-    int32_t retVal = transaction->state;\r
-\r
-    /* Initialize the opInfo structure */\r
-    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
-    \r
-    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
-    {\r
-        /* TEMP: For now forward all allocations to the RM Server */\r
-        Rm_transactionForwarder(rmInst, transaction);\r
-        \r
-#if 0  /* Policy psuedo-code.  Will be implemented after basic allocate functionality is ready and tested */   \r
-        if (resourceBase is unspecified)\r
-        {\r
-           while (policy does not approve)\r
-           {\r
-               Rm_policy check get allowed base as starting point for prealloc\r
-               preallocate resource based on the range and alignment\r
-               Rm_policy...check\r
-           }\r
-        }\r
-        else\r
-        {\r
-            /* Check local policy to see if the request can be satisfied with the\r
-             * resources stored locally */\r
-            Rm_policy...API()\r
-\r
-            if (policy check approves the resource)\r
-            {\r
-                /* call the allocator to allocate the resource */\r
-                if (allocator returns resource)\r
-                {\r
-                    /* Populate the transaction with the allocated resources and the result */\r
-                    transaction->state = approve reason;\r
-                    return ...\r
-                }\r
-                else\r
-                {\r
-                    /* allocator ran out of resources, need to contact Server for more\r
-                     * resources */\r
-                    Rm_resourcePoolModRequest(...);\r
-                }\r
-            }\r
-            else if (policy check denies resource)\r
-            {\r
-                /* Policy check denied resource. */\r
-                transaction->state= deny reason;\r
-                return ...\r
-            }\r
-            else if (policy check says forward to Server for validation)\r
-            {\r
-                /* Forward the transaction to the Server */\r
-                Rm_transactionForwarder(rmInst, transaction);\r
-            }\r
-        }\r
-#endif         \r
-    }\r
-    else if (rmInst->instType == Rm_instType_SERVER)\r
-    {\r
-        /* TEMP: If resource properties are unspecified allocate the next available.\r
-         *       If resource properties are specified allocate if they are available. */\r
-\r
-        /* Fill out the allocator operation general information */\r
-        opInfo.resourceInfo = &transaction->resourceInfo;\r
-        opInfo.serviceSrcInstName = transaction->serviceSrcInstName;\r
-\r
-        if (strlen(transaction->resourceInfo.nsName) > 0)\r
-        {\r
-            /* See if a NameServer name is being used to allocate a resource */\r
-            if (transaction->resourceInfo.base != 0)\r
-            {\r
-                /* A name and a value cannot be specified for the request.  It's one\r
-                 * or the other. */\r
-                retVal = RM_SERVICE_ERROR_NAMESERVER_NAME_AND_RESOURCE_RANGE_BOTH_DEFINED;\r
-            }\r
-            else\r
-            {\r
-                /* Get the resource information from the NameServer */\r
-                retVal = Rm_nsFindObject(rmInst, opInfo.resourceInfo);\r
-            }\r
-        }\r
-        else if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED)\r
-        {\r
-            /* Execute the allocator pre-allocate operation to get the next available resources.\r
-             * NORMALLY CHECKED AGAINST THE POLICY */\r
-            opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;\r
-                \r
-            if (transaction->resourceInfo.alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED)\r
-            {   \r
-                /* TEMP: Default resource alignment of 1 if the resource alignment is not\r
-                 *       specified */\r
-                opInfo.policyAlignment = 1;\r
-            }\r
-            else\r
-            {\r
-                opInfo.policyAlignment = transaction->resourceInfo.alignment;\r
-            }\r
-\r
-            /* opInfo.policyBase = comes from policy once implemented */\r
-            opInfo.policyLength = transaction->resourceInfo.length;\r
-\r
-            /* If the pre-allocate operation succeeds the resourceInfo field pointed to\r
-             * by opInfo will contain the next available resources taht satisfy the\r
-             * resource properties */\r
-            retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
-        }\r
-\r
-        /* Call allocator as long as an error or denial hasn't occurred */\r
-        if ((retVal == RM_SERVICE_PROCESSING) || (retVal == RM_NS_ACTION_APPROVED))\r
-        {\r
-            opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
-\r
-            retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
-        }\r
-\r
-        transaction->state = retVal;\r
-\r
-        if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
-        {\r
-            /* Source of allocation was not the server instance, provide the transaction\r
-             * to the transaction responder */\r
-            Rm_transactionResponder(rmInst, transaction);\r
-        }\r
-        /* Otherwise let the return stack return the transaction to the serviceHandler */           \r
-\r
-#if 0  /* Policy psuedo-code.  Will be implemented after basic allocate functionality is ready and tested */        \r
-        if (resourceBase is unspecified)\r
-        {\r
-           while (policy does not approve)\r
-           {\r
-               Rm_policy check get allowed base as starting point for prealloc\r
-               preallocate resource based on the range and alignment\r
-               Rm_policy...check\r
-           }\r
-        }\r
-        else\r
-        {\r
-            /* Check global policy to see if resource can be allocated. return result\r
-             * no matter what */\r
-            Rm_policy...API()\r
-\r
-            if (policy approves)\r
-            {\r
-                /* call allocator to allocate resource */\r
-            }\r
-\r
-            transaction->state = approve or deny reason;\r
-            transaction->resourceInfo.base = ...;\r
-            transaction->resourceInfo.length = ...;\r
-\r
-            /* If source instance name does not match the current instance\r
-             * name the allocation request came from a Client.  The result\r
-             * must be sent back to the Client */\r
-            if (strcmp(transaction->sourceInstName, rmInst->name))\r
-            {\r
-                /* Names don't match.  Send the transaction back to the Client */\r
-                Rm_transactionResponder(rmInst, transaction);\r
-            }\r
-            else\r
-            {\r
-                /* Resource allocation request originated locally on the active\r
-                 * instance. Send the response via the service responder. */          \r
-                Rm_serviceResponder(rmInst, transaction);                            \r
-            }\r
-        }\r
-#endif        \r
-    }   \r
-}\r
-\r
-void Rm_freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
-{\r
-    Rm_AllocatorOpInfo opInfo;\r
-    int32_t retVal = transaction->state;\r
-\r
-    /* Initialize the opInfo structure */\r
-    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
-    \r
-    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
-    {\r
-        /* TEMP: Forward all free requests to the Server */\r
-        Rm_transactionForwarder(rmInst, transaction);\r
-        \r
-#if 0  /* Policy psuedo-code.  Will be implemented after basic allocate functionality is ready and tested */      \r
-        /* Check local policy to see if the request can be satisfied with the\r
-         * resources stored locally */\r
-        Rm_policy...API()\r
-\r
-        if (policy check approves the free)\r
-        {\r
-            /* call the allocator to free the resource */\r
-            /* Run a resource pool check to see if the free combined a resource block\r
-             * that can be returned to the server */\r
-            if (resource block has been combined)\r
-            {\r
-                  /* allocator ran out of resources, need to contact Server for more\r
-                 * resources */\r
-                Rm_resourcePoolModRequest(free pool block to server...);\r
-            }\r
-            else\r
-            {\r
-                /* Populate the receipt with the freed resources and the result */\r
-                transaction->state = approve reason;\r
-                return ...\r
-            }\r
-        }\r
-        else if (policy check denies resource free)\r
-        {\r
-            /* Policy check denied resource. */\r
-            transaction->state = deny reason;\r
-            return ...\r
-        }\r
-        else if (policy check says forward to Server for validation)\r
-        {\r
-            /* Forward the transaction to the Server */\r
-            Rm_transactionForwarder(rmInst, transaction);\r
-        }\r
-#endif         \r
-    }\r
-    else if (rmInst->instType == Rm_instType_SERVER)\r
-    {\r
-        /* TEMP: Free the resources if resources are allocated to the source instance. */\r
-\r
-        /* Fill out the allocator operation general information */\r
-        opInfo.resourceInfo = &transaction->resourceInfo;\r
-        opInfo.serviceSrcInstName = transaction->serviceSrcInstName;\r
-\r
-        if (strlen(transaction->resourceInfo.nsName) > 0)\r
-        {\r
-            /* See if a NameServer name is being used to allocate a resource */\r
-            if (transaction->resourceInfo.base != 0)\r
-            {\r
-                /* A name and a value cannot be specified for the request.  It's one\r
-                 * or the other. */\r
-                retVal = RM_SERVICE_ERROR_NAMESERVER_NAME_AND_RESOURCE_RANGE_BOTH_DEFINED;\r
-            }\r
-            else\r
-            {\r
-                /* Get the resource information from the NameServer */\r
-                retVal = Rm_nsFindObject(rmInst, opInfo.resourceInfo);\r
-            }\r
-        }\r
-        \r
-        /* Call allocator as long as an error or denial hasn't occurred */\r
-        if ((retVal == RM_SERVICE_PROCESSING) || (retVal == RM_NS_ACTION_APPROVED))\r
-        {\r
-            opInfo.operation = Rm_allocatorOp_FREE;\r
-\r
-            retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
-        }\r
-\r
-        transaction->state = retVal;\r
-\r
-        if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
-        {\r
-            /* Source of allocation was not the server instance, provide the transaction\r
-             * to the transaction responder */\r
-            Rm_transactionResponder(rmInst, transaction);\r
-        }\r
-        /* Otherwise let the return stack return the transaction to the serviceHandler */  \r
-        \r
-#if 0  /* Policy psuedo-code.  Will be implemented after basic allocate functionality is ready and tested */ \r
-        /* Check global policy to see if resource can be freed. return result\r
-         * no matter what */\r
-        Rm_policy...API()\r
-        if (policy approves)\r
-        {\r
-            /* call allocator to free resources */\r
-        }\r
-            \r
-        transaction->state = approve or deny reason;\r
-        transaction->resourceInfo.base = ...;\r
-        transaction->resourceInfo.length = ...;\r
-\r
-        /* If source instance name does not match the current instance\r
-         * name the allocation request came from a client.  The result\r
-         * must be sent back to the Client */\r
-        if (strcmp(transaction->sourceInstName, rmInst->name))\r
-        {\r
-            /* Names don't match.  Send the transaction back to the Client Delegate or Client */\r
-            Rm_transactionResponder(rmInst, transaction);\r
-        }\r
-        else\r
-        {\r
-            /* Resource allocation request originated locally on the active\r
-             * instance. Send the response via the service responder. */\r
-            Rm_serviceResponder(rmInst, transaction);                            \r
-        }\r
-#endif        \r
-    }   \r
-}\r
-\r
-/* Function used to send RM response transactions to lower level agents */\r
-void Rm_transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
-{\r
-    Rm_TransportNode *dstTransportNode = NULL;\r
-    Rm_Packet *rmPkt = NULL;\r
-\r
-    /* Find the transport for the RM instance that sent the request. */\r
-    dstTransportNode = Rm_transportNodeFindRemoteName(rmInst, transaction->pktSrcInstName);\r
-\r
-    /* Create a RM packet using the service information */\r
-    switch (transaction->type)\r
-    {\r
-        case Rm_service_RESOURCE_ALLOCATE:\r
-        case Rm_service_RESOURCE_FREE:\r
-        case Rm_service_RESOURCE_GET_BY_NAME:\r
-            rmPkt = Rm_transportCreateResourceResponsePkt(rmInst, dstTransportNode, \r
-                                                          transaction);\r
-            break;\r
-        case Rm_service_RESOURCE_MAP_TO_NAME:\r
-        case Rm_service_RESOURCE_UNMAP_NAME:\r
-            rmPkt = Rm_transportCreateNsResponsePkt(rmInst, dstTransportNode,\r
-                                                    transaction);\r
-            break;\r
-        default:\r
-            /* Invalid service type.  Flag the error and return */\r
-            transaction->state = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
-            break;\r
-    }\r
-\r
-    if (transaction->state <= RM_SERVICE_ERROR_BASE)\r
-    {\r
-        /* Delete the transaction and return immediately because an error occurred \r
-         * allocating the packet */\r
-        Rm_transactionQueueDelete(rmInst, transaction->localId);\r
-        return;\r
-    }\r
-\r
-    /* Send the RM packet to the application transport */\r
-    if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt) < RM_TRANSPORT_SUCCESSFUL)\r
-    {\r
-        /* Negative value returned by transport send.  An error occurred\r
-         * in the transport while attempting to send the packet.*/\r
-        transaction->state = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
-        /* Clean up the packet */\r
-        if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
-        {\r
-            /* Non-NULL value returned by transport packet free. Flag the\r
-             * error */\r
-            transaction->state = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
-        }\r
-        return;\r
-    }\r
-\r
-    /* NEED TO DO SOMETHING IF GET AN ERROR IN THE transaction->state FIELD.  CREATE\r
-     * NEW TRANSACTION WITH DATA FROM ORIGINAL?  THEN TRY TO SEND FAILED REQUEST BACK\r
-     * TO REQUESTER???  KEEP RETRYING SEND OF RESPONSE??? */\r
-\r
-    /* Delete the transaction */\r
-    Rm_transactionQueueDelete(rmInst, transaction->localId);\r
-}\r
-\r
-/* Function used to forward RM transactions to higher level agents */\r
-void Rm_transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
-{\r
-    Rm_TransportNode *dstTransportNode = NULL;\r
-    Rm_Packet *rmPkt = NULL;\r
-\r
-    /* Make sure the RM instance has a transport registered with a higher level agent */\r
-    if (rmInst->registeredWithDelegateOrServer == false)\r
-    {\r
-        transaction->state = RM_SERVICE_ERROR_NOT_REGISTERED_WITH_DEL_OR_SERVER;\r
-        return;\r
-    }\r
-\r
-    /* Find the transport for the higher level agent.  Check for a connection to a Client Delegate\r
-     * or a Server.  Clients will be connected to either a Client Delegate or a Server.  Client\r
-     * Delegates will be connected to a Server. */\r
-    if (rmInst->instType == Rm_instType_CLIENT)\r
-    {\r
-        dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_CLIENT_DELEGATE);\r
-\r
-        if (!dstTransportNode)\r
-        {\r
-            /* No Client Delegate connection found.  Check for a Server connection */\r
-            dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_SERVER);\r
-        }\r
-    } \r
-    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
-    {\r
-        dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_SERVER);\r
-    }\r
-\r
-    /* Create a RM packet using the service information */\r
-    switch (transaction->type)\r
-    {\r
-        case Rm_service_RESOURCE_ALLOCATE:\r
-        case Rm_service_RESOURCE_FREE:\r
-        case Rm_service_RESOURCE_GET_BY_NAME:\r
-            rmPkt = Rm_transportCreateResourceReqPkt(rmInst, dstTransportNode, \r
-                                                     transaction);\r
-            break;\r
-        case Rm_service_RESOURCE_MAP_TO_NAME:\r
-        case Rm_service_RESOURCE_UNMAP_NAME:\r
-            rmPkt = Rm_transportCreateNsRequestPkt(rmInst, dstTransportNode,\r
-                                                   transaction);\r
-            break;\r
-        default:\r
-            /* Invalid service type.  Flag the error and return */\r
-            transaction->state = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
-            break;\r
-    }\r
-\r
-    if (transaction->state <= RM_SERVICE_ERROR_BASE)\r
-    {\r
-        /* Return immediately because an error occurred allocating the packet */\r
-        return;\r
-    }\r
-\r
-    /* Send the RM packet to the application transport */\r
-    if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt) < RM_TRANSPORT_SUCCESSFUL)\r
-    {\r
-        /* Negative value returned by transport send.  An error occurred\r
-         * in the transport while attempting to send the packet.*/\r
-        transaction->state = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
-        /* Clean up the packet */\r
-        if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
-        {\r
-            /* Non-NULL value returned by transport packet free. Flag the\r
-             * error */\r
-            transaction->state = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
-        }\r
-        return;\r
-    }\r
-\r
-    /* Transaction is not deleted because it is awaiting a response from the higher level\r
-     * RM instance */\r
-}\r
-\r
-void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
-{\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
-        /* Check if the transaction is a transaction that received a response to its\r
-         * request. */\r
-        if (transaction->state != RM_SERVICE_PROCESSING)\r
-        {\r
-\r
-            /* A transaction has received a response. Send the response to either the \r
-             * transaction or service responder based on the source instance */\r
-            if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
-            {\r
-                /* Transaction originated from another instance.  Use the \r
-                 * transaction responder to send the result to the source instance.  This\r
-                 * is not possible on RM Clients since they can't forward RM services */\r
-                Rm_transactionResponder(rmInst, transaction);\r
-            }\r
-            else\r
-            {\r
-                /* Transaction originated on this instance.  Send to the\r
-                 * service responder */\r
-                Rm_serviceResponder(rmInst, transaction);\r
-            }\r
-        }\r
-        else\r
-        {\r
-            /* This is a new transaction that must be forwarded to a higher level RM instance. */\r
-            Rm_transactionForwarder(rmInst, transaction);\r
-        }\r
-    }\r
-    else\r
-    {\r
-        /* Client Delegate and Server transaction processors. */\r
-        switch (transaction->type)\r
-        {\r
-            case Rm_service_RESOURCE_ALLOCATE:\r
-            case Rm_service_RESOURCE_FREE:               \r
-                /* Check if the transaction is fulfilled request */\r
-                if (transaction->state != RM_SERVICE_PROCESSING)\r
-                {\r
-                    /* If source instance name does not match the current instance\r
-                     * name the allocation request came from a client.  The result\r
-                     * must be sent back to the Client */\r
-                    if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
-                    {\r
-                        Rm_transactionResponder(rmInst, transaction);\r
-                    }\r
-                    else\r
-                    {\r
-                        /* Resource allocation request originated locally.  Send the response\r
-                         * via the service responder. */\r
-                        Rm_serviceResponder(rmInst, transaction);      \r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    /* This is a new transaction request originating from an RM instance with fewer\r
-                     * allocate/free privileges.  Run the allocation or free handler to see if the resource\r
-                     * request can be handled locally or if it needs to be forwarded to a higher level\r
-                     * agent */\r
-                    if (transaction->type == Rm_service_RESOURCE_ALLOCATE)\r
-                    {\r
-                        Rm_allocationHandler(rmInst, transaction);\r
-                    }\r
-                    else\r
-                    {\r
-                        Rm_freeHandler(rmInst, transaction);\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
-                /* Server is the only RM instance capable of adding NameServer objects */\r
-                if (rmInst->instType == Rm_instType_SERVER)\r
-                {\r
-                    if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME)\r
-                    {\r
-                        /* Create a new NameServer object with the request transaction information.\r
-                         * Transaction will contain the state result of the NameServer addition. */\r
-                        if (Rm_nsAddObject(rmInst, &transaction->resourceInfo) == RM_NS_ACTION_APPROVED)\r
-                        {\r
-                            transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
-                        }\r
-                        else\r
-                        {\r
-                            /* TEMP: UPDATE THIS STATE VALUE */\r
-                            transaction->state = RM_SERVICE_DENIED_BEGIN;\r
-                        }\r
-                    }\r
-                    else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)\r
-                    {\r
-                        /* Create a new NameServer object with the request transaction information.\r
-                         * Transaction will contain the state result of the NameServer addition. */\r
-                        if (Rm_nsFindObject(rmInst, &transaction->resourceInfo) == RM_NS_ACTION_APPROVED)\r
-                        {\r
-                            transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
-                        }\r
-                        else\r
-                        {\r
-                            /* TEMP: UPDATE THIS STATE VALUE */\r
-                            transaction->state = RM_SERVICE_DENIED_BEGIN;\r
-                        }                    \r
-                    }\r
-                    else\r
-                    {\r
-                        /* Delete an existing NameServer object with the request transaction information\r
-                         * Transaction will contain the state result of the NameServer addition. */\r
-                        if (Rm_nsDeleteObject(rmInst, &transaction->resourceInfo) == \r
-                            RM_NS_ACTION_APPROVED)\r
-                        {\r
-                            transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
-                        }\r
-                        else\r
-                        {\r
-                            /* TEMP: UPDATE THIS STATE VALUE */\r
-                            transaction->state = RM_SERVICE_DENIED_BEGIN;\r
-                        }\r
-                    }\r
-\r
-                    /* If source instance name does not match the local instance\r
-                     * name the NameServer request came from a Client or Client Delegate.  The \r
-                     * result must be sent back to the Client or Client Delegate.  Just return if it does\r
-                     * match since the NameServer transaction result can be returned immediately by the\r
-                     * Rm_serviceHandler. */\r
-                    if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
-                    {\r
-                        Rm_transactionResponder(rmInst, transaction);\r
-                    }\r
-                }\r
-                else\r
-                {\r
-                    transaction->state = RM_SERVICE_ERROR_NAMESERVER_OBJECT_MOD_ON_INVALID_INSTANCE;\r
-                }\r
-                break;\r
-        }\r
-    }\r
-}\r
-\r
-int32_t Rm_reserveLinuxResource(Rm_Inst *rmInst, Rm_LinuxAlias *linuxAlias, \r
-                                Rm_LinuxValueRange *linuxValues, Rm_AllocatorOpInfo *opInfo)\r
-{\r
-    int32_t retVal = RM_DTB_UTIL_RESULT_OKAY;\r
-    bool baseFound = FALSE;\r
-    bool lengthFound = FALSE;\r
-    uint32_t valueIndex = 0;\r
-\r
-    while ((linuxValues != NULL) && (!baseFound || !lengthFound))\r
-    {\r
-        if (linuxAlias->baseOffset == valueIndex)\r
-        {\r
-            /* Found the resource base.  Store it in the operation info structure */\r
-            opInfo->resourceInfo->base = linuxValues->value;\r
-            baseFound = TRUE;\r
-\r
-            /* length will always be 1 if there is no length specified in the Linux DTB */\r
-            if (linuxAlias->lengthOffset == RM_DTB_LINUX_ALIAS_OFFSET_NOT_SET)\r
-            {\r
-                opInfo->resourceInfo->length = 1;\r
-                lengthFound = TRUE;\r
-            }\r
-        }\r
-        else if (linuxAlias->lengthOffset == valueIndex)\r
-        {\r
-            /* Found the resource length.  Store it in the operation info structure */\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
-    {\r
-        retVal = -33; /* TODO: ERROR BASE OR LENGTH OFFSET IN LINUX DTB WAS INCORRECT */\r
-    }\r
-    else\r
-    {\r
-        /* Allocate the resource to Linux */\r
-        retVal = Rm_allocatorOperation(rmInst, opInfo);\r
-    }\r
-\r
-    return (retVal);\r
-}\r
-\r
-int32_t Rm_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
-    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_DTB_UTIL_RESULT_OKAY; \r
-\r
-    /* Initialize the allocator opInfo and resourceInfo structures that will be used to \r
-     * reserve the resources taken by the Linux kernel */\r
-    memset((void *) &opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
-    memset((void *) &resourceInfo, 0, sizeof(Rm_ResourceInfo));\r
-\r
-    strcpy(resourceInfo.name, resourceName);\r
-\r
-    /* Set the source instance name for allocation to be the Linux Kernel */\r
-    opInfo.serviceSrcInstName = RM_ALLOCATED_TO_LINUX;\r
-    opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
-    opInfo.resourceInfo = &resourceInfo;    \r
-\r
-    /* Find each resource specified in the Linux resource alias list and reserve that \r
-     * resource as used */\r
-    while(linuxAlias != NULL)\r
-    {\r
-        /* Reset the parsing variables */\r
-        pathOffset = 0;\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
-        while(pathOffset < linuxAlias->pathListLenBytes)\r
-        {\r
-            /* Move through the DTB nodes until the next alias path node is found */\r
-            if (strcmp(linuxAlias->pathList + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL)))\r
-            {\r
-                nodeOffset = fdt_next_node(linuxDtb, nodeOffset, &depth);\r
-\r
-                if (depth < prevDepth)\r
-                {\r
-                    /* Returning from subnode that matched part of alias path without finding\r
-                     * the resource values */\r
-                    retVal = (-31); /* TODO: COULD NOT FIND RESOURCE AT ALIAS PATH */\r
-                    break;\r
-                }\r
-            }\r
-            else\r
-            {\r
-                /* Found the next alias path node */\r
-                pathOffset += (strlen(linuxAlias->pathList + pathOffset) + 1);\r
-                prevDepth = fdt_node_depth(linuxDtb, nodeOffset);\r
-\r
-                /* Check the properties of the node to see if they match the next alias\r
-                 * path string */\r
-               propOffset = fdt_first_property_offset(linuxDtb, nodeOffset);\r
-           \r
-                /* Search the properties for the next alias path string */\r
-                while ((propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&\r
-                       (pathOffset < linuxAlias->pathListLenBytes))\r
-                {\r
-                    propertyData = fdt_getprop_by_offset(linuxDtb, propOffset, \r
-                                                         &propertyName, &propertyLen);\r
-\r
-                    if (strcmp(linuxAlias->pathList + pathOffset, propertyName) == 0)\r
-                    {\r
-                        pathOffset += (strlen(linuxAlias->pathList + pathOffset) + 1);\r
-                        /* Found the alias property.  Extract the values that will\r
-                         * contain the resource information that must be reserved. */\r
-                        linuxValueRange = Rm_linuxExtractValues(propertyData, propertyLen);\r
-                        /* Use the values to reserve resources for the Linux kernel */\r
-                        retVal = Rm_reserveLinuxResource(rmInst, linuxAlias, \r
-                                                         linuxValueRange, &opInfo);\r
-                        \r
-                        /* Free the memory used to store the values */\r
-                        Rm_linuxFreeValues(linuxValueRange);\r
-                    }\r
-                    \r
-                    propOffset = fdt_next_property_offset(linuxDtb, propOffset);\r
-                } \r
-\r
-                if (propOffset < -FDT_ERR_NOTFOUND)\r
-                {\r
-                       /* Error was returned by LIBFDT when parsing the properties */\r
-                    retVal = propOffset;\r
-                    break;\r
-                }\r
-            }\r
-        }\r
-\r
-        if (retVal < RM_DTB_UTIL_RESULT_OKAY)\r
-        {\r
-            /* Error occurred during parsing of Linux DTB.  Return the error */\r
-            break;\r
-        }\r
-        linuxAlias = (Rm_LinuxAlias *) linuxAlias->nextLinuxAlias;\r
-    }\r
-\r
-    return (retVal);\r
-}\r
-\r
-int32_t Rm_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_ResourceInfo resourceInfo;\r
-    int32_t retVal = RM_DTB_UTIL_RESULT_OKAY;\r
-\r
-    if (resourceProperties->rangeData && (resourceProperties->rangeLen > 0))\r
-    {\r
-        /* Extract the resource properties from the DTB */\r
-        range = rangeBasePtr = Rm_resourceExtractRange(resourceProperties->rangeData, \r
-                                                       resourceProperties->rangeLen);\r
-\r
-        /* Create a tree allocator using the resource properties */\r
-        retVal = Rm_createTreeAllocator(rmInst, resourceName, range); \r
-\r
-        if (retVal >= RM_DTB_UTIL_RESULT_OKAY)\r
-        {\r
-            if (resourceProperties->linuxAliasData && resourceProperties->linuxAliasLen)\r
-            {\r
-                /* Reserve the resources taken by the Linux kernel specified in the Linux DTB */\r
-                linuxAlias = Rm_resourceExtractLinuxAlias(resourceProperties->linuxAliasData,\r
-                                                          resourceProperties->linuxAliasLen);\r
-\r
-                retVal = Rm_findAndReserveLinuxResource(rmInst, resourceName, linuxDtb, linuxAlias);            \r
-            }\r
-        }\r
-    }\r
-    \r
-    if (retVal >= RM_DTB_UTIL_RESULT_OKAY)\r
-    {\r
-        /* Create entries in the NameServer if any NameServer assignments were specified */\r
-        if (resourceProperties->nsAssignData && resourceProperties->nsAssignLen)\r
-        {\r
-            nsAssignments = Rm_resourceExtractNsAssignment(resourceProperties->nsAssignData, \r
-                                                           resourceProperties->nsAssignLen);\r
-\r
-            /* Cycle through the list of assignments and add them to the NameServer */\r
-            nsAssignmentBasePtr = nsAssignments;\r
-            while (nsAssignments)\r
-            {\r
-                memset((void *)&resourceInfo, 0, sizeof(Rm_ResourceInfo));\r
-\r
-                strcpy(resourceInfo.name, resourceName);\r
-                resourceInfo.base = nsAssignments->resourceBase;\r
-                resourceInfo.length = nsAssignments->resourceLength;\r
-                strcpy(resourceInfo.nsName, nsAssignments->nsName);\r
-                \r
-                /* TODO: RETURN IF ANY OF THE ADDS FAIL??? */\r
-                Rm_nsAddObject(rmInst, &resourceInfo);\r
-                nsAssignments = nsAssignments->nextNsAssignment;\r
-            }\r
-            /* Free the memory allocated for the NameServer assignments */\r
-            Rm_resourceFreeNsAssignmentList(nsAssignmentBasePtr);\r
-        }\r
-    }\r
-\r
-    /* Free the memory allocated for the resource properties */\r
-    Rm_resourceFreeRange(rangeBasePtr);\r
-    Rm_resourceFreeLinuxAlias(linuxAlias);\r
-\r
-    return(retVal);\r
-}\r
-\r
-int32_t Rm_parseResourceProperty(void *globalResourceDtb, int32_t offset, 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_DTB_UTIL_RESULT_OKAY;\r
-\r
-    /* Get the property data and store it in the corresponding propertyInfo field */\r
-       propertyData = fdt_getprop_by_offset(globalResourceDtb, offset, &propertyName, &propertyLen);\r
-    if (propertyData)\r
-    {\r
-        propertyType = Rm_resourceGetPropertyType(propertyName);\r
-        if (propertyType == Rm_resourcePropType_RESOURCE_RANGE)\r
-        {\r
-            if (propertyInfo->rangeData || propertyInfo->rangeLen)\r
-            {\r
-                /* The range fields have already been populated.  Return an error.\r
-                 * The resource list has specified a property field more than once\r
-                 * for a resource node */\r
-                retVal = -18; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
-            }\r
-            else\r
-            {\r
-                propertyInfo->rangeData = propertyData;\r
-                propertyInfo->rangeLen = propertyLen;\r
-            }\r
-        }\r
-        else if (propertyType == Rm_resourcePropType_NSASSIGNMENT)\r
-        {\r
-            if (propertyInfo->nsAssignData || propertyInfo->nsAssignLen)\r
-            {\r
-                /* The nsAssign fields have already been populated.  Return an error.\r
-                 * The resource list has specified a property field more than once\r
-                 * for a resource node */\r
-                retVal = -19; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
-            }\r
-            else\r
-            {\r
-                propertyInfo->nsAssignData = propertyData;\r
-                propertyInfo->nsAssignLen = propertyLen;\r
-            }\r
-        }\r
-        else if (propertyType == Rm_resourcePropType_RESOURCE_LINUX_ALIAS)\r
-        {\r
-            if (propertyInfo->linuxAliasData || propertyInfo->linuxAliasLen)\r
-            {\r
-                /* The linuxAlias fields have already been populated.  Return an error.\r
-                 * The resource list has specified a property field more than once\r
-                 * for a resource node */\r
-                retVal = -28; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
-            }\r
-            else\r
-            {\r
-                propertyInfo->linuxAliasData = propertyData;\r
-                propertyInfo->linuxAliasLen = propertyLen;\r
-            }\r
-        }        \r
-        else\r
-        {\r
-            retVal = -20; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
-        }\r
-    }\r
-    else\r
-    {\r
-        retVal = -16; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
-    }\r
-\r
-    /* Don't get anymore properties if error occurred */\r
-    if (retVal == RM_DTB_UTIL_RESULT_OKAY)\r
-    {\r
-        offset = fdt_next_property_offset(globalResourceDtb, offset);\r
-       if (offset >= 0)\r
-       {\r
-           retVal = Rm_parseResourceProperty(globalResourceDtb, offset, propertyInfo);\r
-       }\r
-        else if (offset != -FDT_ERR_NOTFOUND)\r
-        {\r
-            /* Error was returned by LIBFDT when parsing the properties */\r
-            retVal = offset;\r
-        }\r
-    }\r
-    \r
-    return (retVal);\r
-}\r
-\r
-int32_t Rm_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 error = RM_DTB_UTIL_RESULT_OKAY;\r
-       int32_t offset;\r
-\r
-    /* Initialize the resource properties structure */\r
-    memset((void *)&resourceProperties, 0, sizeof(Rm_ResourceProperties));\r
-\r
-    /* Ignore properties of the base node */\r
-    if (strcmp(resourceName, rmDtbStartingNode))\r
-    {\r
-        /* Get the properties for the resource node if any exist */\r
-       offset = fdt_first_property_offset(globalResourceDtb, nodeOffset);\r
-       if (offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET)\r
-       {\r
-            /* Since at least one property exists attempt to parse the property nodes and \r
-             * use them to create and initialize a resource allocator */\r
-               error =  Rm_parseResourceProperty(globalResourceDtb, offset, &resourceProperties);\r
-            if (error < -FDT_ERR_NOTFOUND)\r
-            {\r
-                return (error);\r
-            }\r
-            \r
-            /* Initialize an allocator with the resource properties if no error was returned */\r
-            Rm_createAndInitAllocator(rmInst, resourceName, &resourceProperties, linuxDtb);\r
-       }\r
-        else if (offset != -FDT_ERR_NOTFOUND)\r
-        {\r
-               /* Error was returned by LIBFDT when parsing the properties */\r
-            return (offset);\r
-        }\r
-    }\r
-    \r
-    /* Get the next resource node */\r
-       offset = fdt_next_node(globalResourceDtb, nodeOffset, &depth);\r
-    /* Check the offset and depth of the next node to make sure the current node\r
-     * wasn't the last node in the Resource List.  A depth less than the depth set\r
-     * at the start of the recursion will signal the end of the resource list */\r
-    if ((offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH))\r
-    {\r
-        error = Rm_parseResourceNode(rmInst, globalResourceDtb, offset, depth, linuxDtb);\r
-        if (error < -FDT_ERR_NOTFOUND)\r
-        {\r
-            return (error);\r
-        }\r
-    }\r
-    else if (offset != -FDT_ERR_NOTFOUND)\r
-    {\r
-        /* Error was returned by LIBFDT when parsing the nodes */\r
-        return (offset);\r
-    }\r
-\r
-    return (RM_DTB_UTIL_RESULT_OKAY);\r
-}\r
-\r
-int32_t Rm_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_DTB_UTIL_RESULT_OKAY;\r
-\r
-    /* Recursively parse the Global Resource List, creating an allocator for\r
-     * each resource as specified in the node */\r
-    result = Rm_parseResourceNode(rmInst, globalResourceDtb, nodeOffset, startDepth, linuxDtb);\r
-\r
-    return(result);\r
-}\r
-     \r
-/**********************************************************************\r
- ********************** Application visible APIs **********************\r
- **********************************************************************/\r
-\r
-/* Server Only */\r
-void Rm_printResourceStatus(Rm_Handle *rmHandle)\r
-{\r
-    Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
-    Rm_Allocator *allocator = rmInst->allocators;\r
-    Rm_ResourceTree *treeRoot;\r
-    Rm_ResourceTreeNode *treeNode;\r
-    uint32_t numLinuxResources;\r
-\r
-    while (allocator != NULL)\r
-    {\r
-        numLinuxResources = 0;\r
-\r
-        Rm_osalLog("Resource: %s\n", allocator->resourceName);\r
-\r
-        treeRoot = allocator->allocatorRootEntry;\r
-\r
-        RB_FOREACH(treeNode, _Rm_ResourceTree, treeRoot)\r
-        {               \r
-            Rm_osalLog("          %10d - %10d ", treeNode->base, \r
-                                                 treeNode->base + treeNode->length -1);\r
-            \r
-            if (strcmp(treeNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
-            {\r
-                Rm_osalLog("NOT ALLOCATED\n");\r
-            }\r
-            else\r
-            {\r
-                Rm_osalLog("allocated to %s\n", treeNode->allocatedTo);\r
-            }\r
-\r
-            if (strcmp(treeNode->allocatedTo, RM_ALLOCATED_TO_LINUX) == 0)\r
-            {\r
-                numLinuxResources += treeNode->length;\r
-            }\r
-        }\r
-        \r
-        Rm_osalLog("Total allocated to Linux: %d\n", numLinuxResources);\r
-        \r
-        allocator = allocator->nextAllocator;\r
-    }\r
-\r
-    Rm_nsPrintObjects(rmInst);\r
-}\r
-\r
-Rm_Handle Rm_init(Rm_InitCfg *initCfg)\r
-{\r
-    Rm_Inst *rmInst;\r
-    void *globalResourceDtb = NULL;\r
-    void *linuxResourceDtb = NULL;\r
-\r
-    /* Instance creation checks.  Add one to strlen calculation for null character */\r
-    if ((strlen(initCfg->instName) + 1) > RM_INSTANCE_NAME_MAX_CHARS)\r
-    {\r
-        /* Failure: Instance name is too big */\r
-        return (NULL);\r
-    }\r
-    \r
-    /* Get memory for RM instance from local memory */\r
-    rmInst = Rm_osalMalloc (sizeof(Rm_Inst));\r
-    /* Populate instance based on input parameters */\r
-    strcpy (&rmInst->name[0], initCfg->instName);\r
-    rmInst->instType = initCfg->instType;\r
-    rmInst->registeredWithDelegateOrServer = false;\r
-    rmInst->policyDtb = NULL;\r
-\r
-    /* Initialize the transport routing map linked list pointer to NULL.  The linked list\r
-     * nodes will be created when the application registers transports */\r
-    rmInst->routeMap = NULL;\r
-\r
-    /* Initialize the allocators linked list pointer to NULL.  The linked list nodes will\r
-     * be created on the Server instance when the application reads in the resource list.\r
-     * Nodes will also be created on Client Delegates when blocks of resources are requested\r
-     * for allocation to clients. */\r
-    rmInst->allocators = NULL;\r
-\r
-    /* Initialize the NameServer pointer to NULL.  The NameServer should only be located\r
-     * on the RM Server */\r
-    rmInst->nameServer = NULL;\r
-\r
-    /* Initialize the transaction queue elements. */\r
-    rmInst->transactionSeqNum = Rm_transactionInitSequenceNum();\r
-    rmInst->transactionQueue= NULL;\r
-\r
-    /* RM Server specific actions */\r
-    if (rmInst->instType == Rm_instType_SERVER)\r
-    {\r
-        /* Initialize the NameServer */\r
-        Rm_nsInit(rmInst);\r
-        \r
-        /* Open the ResourceList file and provide it to the resource initializer.  The Linux\r
-         * DTB will be parsed simultaneously for resource's consumed by the kernel.  The resources\r
-         * used by the kernel will be marked as used in the resource allocators. */\r
-        if (initCfg->globalResourceList)\r
-        {\r
-            globalResourceDtb = initCfg->globalResourceList;\r
-            fdt_open_into(globalResourceDtb, globalResourceDtb, fdt_totalsize(globalResourceDtb));\r
-\r
-            if (initCfg->linuxDtb)\r
-            {\r
-                linuxResourceDtb = initCfg->linuxDtb;\r
-                fdt_open_into(linuxResourceDtb, linuxResourceDtb, fdt_totalsize(linuxResourceDtb));   \r
-            }\r
-            \r
-            Rm_initializeAllocators(rmInst, globalResourceDtb, linuxResourceDtb);\r
-        }\r
-    }\r
-\r
-    /* Instance startup policies are only used for Servers and Client Delegates */\r
-    if (rmInst->instType != Rm_instType_CLIENT)\r
-    {\r
-        /* Open the instance's policy and store it */\r
-        if (initCfg->startupPolicy)\r
-        {\r
-            rmInst->policyDtb = initCfg->startupPolicy;\r
-            fdt_open_into(rmInst->policyDtb, rmInst->policyDtb, fdt_totalsize(rmInst->policyDtb));  \r
-        }\r
-\r
-        /* Store policy via policy APIs ... */\r
-    }\r
-\r
-    /* Return the RM Handle */\r
-    return ((Rm_Handle) rmInst);\r
-}\r
-\r
-uint32_t Rm_getVersion (void)\r
-{\r
-    return RM_VERSION_ID;\r
-}\r
-\r
-\r
-const char* Rm_getVersionStr (void)\r
-{\r
-    return rmVersionStr;\r
-}\r
-\r
-/**\r
-@}\r
-*/\r
+/**
+ *   @file  rm.c
+ *
+ *   @brief   
+ *      This is the Resource Manager source.
+ *
+ *  \par
+ *  ============================================================================
+ *  @n   (C) Copyright 2012-2013, 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>
+#include <string.h>
+#include <stdbool.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_loc.h>
+#include <ti/drv/rm/include/rm_transportloc.h>
+#include <ti/drv/rm/include/rm_nameserverloc.h>
+#include <ti/drv/rm/include/rm_dtb_utilloc.h>
+#include <ti/drv/rm/include/rm_policyloc.h>
+#include <ti/drv/rm/include/rm_treeloc.h>
+
+/* RM LIBFDT includes */
+#include <ti/drv/rm/util/libfdt/libfdt.h>
+
+/* Tree algorithm includes */
+#include <ti/drv/rm/util/tree.h>
+
+/* RM OSAL layer */
+#include <rm_osal.h>
+
+/**********************************************************************
+ ************************** Globals ***********************************
+ **********************************************************************/
+
+/** @brief 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 allocator
+ ***********************************************************************
+ * DESCRIPTION: Returns a newly Created and initialized resource
+ *              The allocator is also stored in the RM instance
+ *              allocator list.            
+ */
+static Rm_Allocator *allocatorAdd(Rm_Inst *rmInst, const char *resourceName)
+{
+    Rm_Allocator *allocators   = rmInst->allocators;
+    Rm_Allocator *newAllocator = NULL;
+
+    newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));
+
+    if (newAllocator) {
+        memset((void *)newAllocator, 0, sizeof(Rm_Allocator));
+        strncpy(newAllocator->resourceName, resourceName, RM_NAME_MAX_CHARS);
+        newAllocator->allocatorRootEntry = NULL;
+        newAllocator->nextAllocator = NULL;  
+
+        /* Add allocator to end of list */
+        if (allocators) {
+            while (allocators->nextAllocator) {
+                allocators = allocators->nextAllocator;
+            }
+            allocators->nextAllocator = newAllocator;
+        }
+        else {
+            rmInst->allocators = newAllocator;
+        }
+    }
+    return (newAllocator);
+}
+
+/* FUNCTION PURPOSE: Deletes a resource allocator
+ ***********************************************************************
+ * DESCRIPTION: Deletes a resource allocator based on the given
+ *              resource name.  The resource allocator will be
+ *              removed from the RM instance allocator list.
+ */
+static int32_t allocatorDelete(Rm_Inst *rmInst, char *resourceName)
+{
+    Rm_Allocator *allocator = rmInst->allocators;
+    Rm_Allocator *prevAllocator = NULL;
+    int32_t       retVal = RM_OK;
+
+    while (allocator) {
+        if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
+            break;             
+        }
+        prevAllocator = allocator;
+        allocator = allocator->nextAllocator;
+    }
+
+    if (allocator) {
+        if (prevAllocator == NULL) {
+            rmInst->allocators = allocator->nextAllocator;
+        }
+        else {
+            prevAllocator->nextAllocator = allocator->nextAllocator;
+        }
+        Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));
+    }
+    else {
+        retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Adds an owner to an allocator resource
+ ***********************************************************************
+ * DESCRIPTION: Adds a RM instance node to a resource node's
+ *              list of owners.
+ */
+static void addOwner(Rm_ResourceNode *node, void *serviceInstNode)
+{
+    Rm_Owner *ownerList = node->ownerList;
+    Rm_Owner *newOwner = NULL;
+
+    newOwner = Rm_osalMalloc(sizeof(Rm_Owner));
+
+    if (newOwner) {
+        newOwner->instNameNode = serviceInstNode;
+        newOwner->nextOwner = NULL;  
+
+        /* Add owner entry to end of list */
+        if (ownerList) {
+            while (ownerList->nextOwner) {
+                ownerList = ownerList->nextOwner;
+            }
+            ownerList->nextOwner = newOwner;
+        }
+        else {
+            node->ownerList = newOwner;
+        }
+
+        node->allocationCount++;
+        newOwner->instNameNode->allocRefCount++;
+    }
+}
+
+/* FUNCTION PURPOSE: Checks a resource node's ownership
+ ***********************************************************************
+ * DESCRIPTION: Returns TRUE if the provided instance node is
+ *              in the list of resource node owners.  Otherwise,
+ *              returns FALSE.
+ */
+static bool isOwnedBy(Rm_ResourceNode *node, void *serviceInstNode)
+{
+    Rm_Owner *owner = node->ownerList;
+
+    while (owner) {
+        if (owner->instNameNode == serviceInstNode) {
+            return(true);           
+        }
+        owner = owner->nextOwner;
+    }
+    return(false);
+}
+
+/* FUNCTION PURPOSE: Compares two resource node's owners
+ ***********************************************************************
+ * DESCRIPTION: Returns TRUE if the owners of two resource nodes 
+ *              are equivalent.  Otherwise, returns FALSE.
+ */
+static bool compareResourceNodeOwners(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
+{
+    Rm_Owner *node1Owners = node1->ownerList;
+    Rm_Owner *node2Owners = node2->ownerList;
+    bool      matchedInst;
+
+    if (node1->allocationCount == node2->allocationCount) {
+        while (node1Owners) {
+            matchedInst = false;
+            while (node2Owners) {
+                if (node1Owners->instNameNode == node2Owners->instNameNode) {
+                    matchedInst = true;
+                    break;
+                }
+                node2Owners = node2Owners->nextOwner;
+            }
+
+            if (matchedInst) {
+                node2Owners = node2->ownerList;
+                node1Owners = node1Owners->nextOwner;
+            }
+            else {
+                return(false);
+            }                
+        }
+    }
+    else {
+        return(false);
+    }  
+    
+    return(true);
+}
+
+/* FUNCTION PURPOSE: Deletes an owner from an allocator resource
+ ***********************************************************************
+ * DESCRIPTION: Removes a RM instance node from a resource node's
+ *              list of owners.
+ */
+static void deleteOwner(Rm_ResourceNode *node, void *serviceInstNode)
+{
+    Rm_Owner *owner = node->ownerList;
+    Rm_Owner *prevOwner = NULL;
+
+    while (owner) {
+        if (owner->instNameNode == serviceInstNode) {
+            break;             
+        }
+        prevOwner = owner;
+        owner = owner->nextOwner;
+    }
+
+    if (prevOwner == NULL) {
+        node->ownerList = owner->nextOwner;
+    }
+    else {
+        prevOwner->nextOwner = owner->nextOwner;
+    }
+    
+    node->allocationCount--;
+    owner->instNameNode->allocRefCount--;
+    Rm_osalFree((void *)owner, sizeof(Rm_Owner));
+}
+
+/* FUNCTION PURPOSE: Copies the owners of a resource node
+ ***********************************************************************
+ * DESCRIPTION: Creates a list of resource owners for the destination
+ *              resource node that is equivalent to the the 
+ *              source resource node's owners
+ */
+static void copyOwners(Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)
+{
+    Rm_Owner *srcOwnerList = srcNode->ownerList;
+    Rm_Owner *dstNewOwner;
+    Rm_Owner *dstPrevOwner;
+
+    dstNode->allocationCount = srcNode->allocationCount;
+
+    while (srcOwnerList) {
+        dstNewOwner = Rm_osalMalloc(sizeof(Rm_Owner));
+        dstNewOwner->instNameNode = srcOwnerList->instNameNode;
+        dstNewOwner->nextOwner = NULL;
+
+        if (dstNode->ownerList == NULL) {
+            dstNode->ownerList = dstNewOwner;
+        }
+        else {
+            dstPrevOwner->nextOwner = dstNewOwner;
+        }
+        dstPrevOwner = dstNewOwner;
+        srcOwnerList = srcOwnerList->nextOwner;
+    }
+}
+
+/* FUNCTION PURPOSE: Clears a resource node's owners
+ ***********************************************************************
+ * DESCRIPTION: Deletes all owners from the owners list of a 
+ *              resource node.
+ */
+static void clearOwners(Rm_ResourceNode *node)
+{
+    Rm_Owner *owner = node->ownerList;
+    Rm_Owner *nextOwner;
+
+    while (owner) {
+        nextOwner = owner->nextOwner;
+        node->allocationCount--;
+        Rm_osalFree((void *)owner, sizeof(Rm_Owner));
+        owner = nextOwner;
+    }
+}
+
+/* FUNCTION PURPOSE: Creates a new resource tree
+ ***********************************************************************
+ * DESCRIPTION: Creates a new resource tree using the provided
+ *              resource name and value range.  The name and value
+ *              typically originate from the GRL.
+ */
+static int32_t createResourceTree(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)
+{
+    Rm_Allocator    *allocator = NULL;
+    Rm_ResourceTree *treeRootEntry = NULL;
+    Rm_ResourceNode *treeNode = NULL;
+    Rm_ResourceNode *collidingNode = NULL;
+
+    allocator = allocatorAdd(rmInst, resourceName);
+    treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));
+    RB_INIT(treeRootEntry);
+
+    while (range != NULL) {
+        treeNode = rmResourceNodeNew(range->base, range->length);
+        collidingNode = RB_INSERT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
+
+        if (collidingNode) {
+            Rm_ResourceNode *nextNode = NULL;
+            
+            /* Node that was inserted collides with existing node.  Destroy tree and return error */
+            for (treeNode = RB_MIN(_Rm_AllocatorResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode) {
+                       nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
+                       RB_REMOVE(_Rm_AllocatorResourceTree, treeRootEntry, nextNode);
+                rmResourceNodeFree(treeNode);
+               }
+            Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));
+            allocatorDelete(rmInst, allocator->resourceName);
+            return (RM_ERROR_GRL_RES_SPECIFIED_MORE_THAN_ONCE);
+        }
+        range = range->nextRange;
+    }
+    
+    allocator->allocatorRootEntry = treeRootEntry;
+    return(RM_OK);
+}
+
+/* FUNCTION PURPOSE: Preallocates a resource
+ ***********************************************************************
+ * DESCRIPTION: Called when an allocate request is made but the base 
+ *              is unspecified.  The preallocation algorithm looks at 
+ *              available resources as well as policy permissions to 
+ *              determine a resource range that satisfies the request.
+ *              If a valid range is found it will be returned for the 
+ *              treeAllocate algorithm to handle.
+ */
+static int32_t treePreAllocate(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t resourcePolicy,
+                               Rm_AllocatorOpInfo *opInfo)
+{
+    Rm_ResourceNode    findNode;
+    Rm_ResourceNode   *matchingNode = NULL;
+    uint32_t           matchingEnd;
+    uint32_t           rangeIndex;
+    bool               resourceFound = false;
+    Rm_PolicyCheckType policyCheckType;
+    Rm_PolicyCheckCfg  policyCheckCfg;
+    bool               nodePassesPolicy;
+    int32_t            retVal = RM_SERVICE_PROCESSING;    
+
+    opInfo->resourceInfo->base = rmPolicyGetResourceBase(rmInst->policy, opInfo->serviceSrcInstNode, 
+                                                          resourcePolicy, opInfo->allocType, 
+                                                          &retVal);
+    if (retVal != RM_SERVICE_PROCESSING) {
+        return (retVal);
+    }
+
+    if (opInfo->resourceInfo->alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) {  
+        /* Get alignment from policy */
+        opInfo->resourceInfo->alignment = rmPolicyGetResourceAlignment(rmInst->policy, resourcePolicy);
+    }
+    
+    if (opInfo->resourceInfo->alignment == 0) {
+        opInfo->resourceInfo->alignment = 1;
+    }    
+
+    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+    findNode.base = opInfo->resourceInfo->base;
+    findNode.length = opInfo->resourceInfo->length;
+
+    /* Configure policy checking structure */
+    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
+    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
+        policyCheckType = Rm_policyCheck_INIT;
+    }
+    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
+        policyCheckType = Rm_policyCheck_USE;
+    }
+    policyCheckCfg.policyDtb = rmInst->policy;
+    policyCheckCfg.resourceOffset = resourcePolicy;
+    
+    do {
+        matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+        
+        if (matchingNode) {
+            nodePassesPolicy = false;
+            policyCheckCfg.type = policyCheckType;
+            policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
+            policyCheckCfg.resourceBase = findNode.base;
+            policyCheckCfg.resourceLength = findNode.length;
+            nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);    
+            
+            if (nodePassesPolicy && (matchingNode->allocationCount > 0)) {
+                /* Check exclusive privileges of instance requesting resource.  Requesting
+                 * instance with exclusive privileges can't reserve resource if already owned*/
+                policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
+                policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
+                nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+            }
+            
+            if (nodePassesPolicy && (matchingNode->allocationCount == 1)) {
+                /* Check exclusive privileges of instance that currently owns resource */
+                policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
+                policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;
+                nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+            }
+
+            if (retVal != RM_SERVICE_PROCESSING) {
+                break;
+            }
+
+            if (nodePassesPolicy) {
+                matchingEnd = matchingNode->base + matchingNode->length - 1;
+                /* Initialize indexer to be first resource value that alignment */
+                rangeIndex = findNode.base;
+                if (rangeIndex % opInfo->resourceInfo->alignment) {
+                    rangeIndex += (opInfo->resourceInfo->alignment -
+                                  (rangeIndex % opInfo->resourceInfo->alignment));
+                }
+                
+                if ((rangeIndex + opInfo->resourceInfo->length - 1) <= matchingEnd) {
+                    /* Block of unallocated resources within matchingNode that satisfies
+                     * allocate requirements */
+                    opInfo->resourceInfo->base = rangeIndex;
+                    resourceFound = true;
+                }     
+            }
+            
+            if (!resourceFound) {
+                /* Check next resource node for available resources */
+                findNode.base = matchingNode->base + matchingNode->length;
+            }
+        }
+        else {
+            retVal = RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET;
+        }
+    } while ((!resourceFound) && 
+             (retVal != RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET));
+
+    return(retVal); 
+}
+
+/* FUNCTION PURPOSE: Allocates a resource
+ ***********************************************************************
+ * DESCRIPTION: Will attempt to allocate the resource with specified
+ *              base and length from the resource's allocator.  The
+ *              allocation algorithm will verify the allocation against
+ *              the policy permissions for the instance requesting the
+ *              allocation.  If the policy allows the allocation the 
+ *              algorithm will allocate the resource then combine any
+ *              resource nodes that may have become equivalent (in terms
+ *              of ownership) after the allocation.
+ */
+static int32_t treeAllocate(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t resourcePolicy,
+                            Rm_AllocatorOpInfo *opInfo)
+{
+    Rm_ResourceNode     findNode;
+    Rm_ResourceNode    *matchingNode = NULL;
+    Rm_ResourceNode    *leftNode = NULL;
+    Rm_ResourceNode    *rightNode = NULL;
+    Rm_PolicyCheckType  policyCheckType;    
+    Rm_PolicyCheckCfg   policyCheckCfg;
+    bool                allocPassesPolicy;
+    bool                combineLeft = false;
+    bool                combineRight = false;    
+    uint32_t            findEnd;
+    uint32_t            matchingEnd;  
+    int32_t             retVal = RM_SERVICE_PROCESSING;
+
+    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+    findNode.base = opInfo->resourceInfo->base;
+    findNode.length = opInfo->resourceInfo->length;
+    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+    /* Prepare privilege checks */
+    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
+    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
+        policyCheckType = Rm_policyCheck_INIT;
+    }
+    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
+        policyCheckType = Rm_policyCheck_USE;
+    }
+
+    if (matchingNode) {
+        findEnd = findNode.base + findNode.length - 1;
+        matchingEnd = matchingNode->base + matchingNode->length - 1;
+        
+        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
+            if (opInfo->serviceSrcInstNode == rmPolicyGetLinuxInstNode(rmInst->validInstances)) {
+                /* Bypass policy checks since Linux Kernel has full privileges */
+                allocPassesPolicy = true;
+            }
+            else {
+                policyCheckCfg.policyDtb = rmInst->policy;
+                policyCheckCfg.resourceOffset = resourcePolicy;    
+                policyCheckCfg.type = policyCheckType;
+                policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
+                policyCheckCfg.resourceBase = findNode.base;
+                policyCheckCfg.resourceLength = findNode.length;
+                allocPassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+                if (!allocPassesPolicy) {
+                    if (policyCheckType == Rm_policyCheck_INIT) {
+                        retVal = RM_SERVICE_DENIED_INIT_PERM_NOT_GIVEN;
+                    }
+                    else {
+                        retVal = RM_SERVICE_DENIED_USE_PERM_NOT_GIVEN;
+                    }
+                }
+
+                if (!isOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+                    /* Perform exclusive checks if requesting instance does not already an
+                     * owner of the resource */
+                    if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {
+                        /* Check exclusive privileges of instance requesting resource.  Requesting
+                         * instance with exclusive privileges can't reserve resource if already owned*/
+                        policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
+                        policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
+                        allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+                        if (!allocPassesPolicy) {
+                            retVal = RM_SERVICE_DENIED_EXCLUSIVE_RES_ALLOCD;
+                        }
+                    }
+                    if (allocPassesPolicy && (matchingNode->allocationCount == 1)) {
+                        /* Check exclusive privileges of instance that currently owns resource */
+                        policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
+                        policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;
+                        allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+                        if (!allocPassesPolicy) {
+                            retVal = RM_SERVICE_DENIED_ALLOCD_TO_EXCLUSIVE_INST;
+                        }                
+                    }  
+                }
+            }
+            
+            if (allocPassesPolicy) {
+                if (!isOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+                    /* Handle any possible node combinations if requesting instance is
+                     * not already in resource's owner list.  Automatic approval if requesting
+                     * instance is already in owner list. */
+                    if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {
+                        /* findNode range matches matchingNode range
+                         *
+                         *   |<--left node-->||<--matched  node-->||<--right node-->| => existing node
+                         *                    |<--alloc request-->|  => requested resources
+                         */                     
+                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        addOwner(matchingNode, opInfo->serviceSrcInstNode);
+
+                        if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            combineLeft = true;
+                        }
+                        if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                            combineRight = true;
+                        }
+
+                        if (combineLeft && combineRight) {
+                            /* Combine all three nodes into matchingNode */
+                            matchingNode->base = leftNode->base;
+                            matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
+
+                            clearOwners(leftNode);
+                            rmResourceNodeFree(leftNode);
+                            clearOwners(rightNode);
+                            rmResourceNodeFree(rightNode);                        
+                        }
+                        else if (combineLeft) {
+                            /* Combine left and matching nodes.  Reinsert right. */
+                            matchingNode->base = leftNode->base;
+                            matchingNode->length += leftNode->length;
+
+                            clearOwners(leftNode);
+                            rmResourceNodeFree(leftNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        
+                        }
+                        else if (combineRight) {
+                            /* Combine right and matching nodes.  Reinsert left. */
+                            matchingNode->length += rightNode->length;
+
+                            clearOwners(rightNode);
+                            rmResourceNodeFree(rightNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                        else {
+                            /* No combine. */
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        }
+
+                        /* Always reinsert matchingNode */                
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);   
+                    }   
+                    else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
+                        /* findNode range is subset of matchingNode range and neither boundary is
+                         * equivalent.
+                         *
+                         * |<----------matched node---------->|
+                         *        |<---alloc request--->|
+                         */ 
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
+                        copyOwners(leftNode, matchingNode);
+                        rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
+                        copyOwners(rightNode, matchingNode);
+
+                        matchingNode->base = findNode.base;                                    
+                        matchingNode->length = findNode.length;
+                        addOwner(matchingNode, opInfo->serviceSrcInstNode);
+
+                        /* Insert all the nodes */
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                    }  
+                    else {    
+                        if (findNode.base == matchingNode->base) {
+                            /* findNode base and matchingNode base are equivalent.  May be combine
+                             * possibilities to the left
+                             *
+                             * |<---left node (alloc'd)--->||<----------matched node---------->|
+                             *                              |<---findNode (alloc req)--->|
+                             */                         
+                            leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            /* Add allocating instance to owner list for compare with leftNode */
+                            addOwner(matchingNode, opInfo->serviceSrcInstNode);
+                            
+                            if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {
+                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                                /* Combine leftNode and findNode */
+                                leftNode->length += findNode.length;
+                            }
+                            else {
+                                leftNode = rmResourceNodeNew(findNode.base, findNode.length);
+                                copyOwners(leftNode, matchingNode);
+                            }
+
+                            /* Account for leftNode in matchingNode */
+                            matchingNode->base = findNode.base + findNode.length;
+                            matchingNode->length = matchingEnd - findEnd;  
+
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                        else if (findEnd == matchingEnd) {
+                            /* findNode end and matchingNode end are equivalent.  May be combine
+                             * possibilities to the right
+                             *
+                             * |<----------matched node---------->||<---right node (alloc'd)--->|
+                             *       |<---findNode (alloc req)--->| 
+                             */                        
+                            rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            /* Add allocating instance to owner list for compare with rightNode */
+                            addOwner(matchingNode, opInfo->serviceSrcInstNode);
+                            
+                            if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {
+                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                                /* Combine rightNode and findNode */
+                                rightNode->base = findNode.base;
+                                rightNode->length += findNode.length;
+                            }
+                            else {
+                                rightNode = rmResourceNodeNew(findNode.base, findNode.length);
+                                copyOwners(rightNode, matchingNode);
+                            }
+
+                            /* Account for rightNode in matchingNode */
+                            matchingNode->length -= findNode.length;  
+
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        }
+                        /* Remove allocating instance from leftover matchingNode */
+                        deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    }
+                }
+                retVal = RM_SERVICE_APPROVED;
+            }
+        }
+        else {
+            retVal = RM_SERVICE_DENIED_PARTIAL_ALLOCATION;
+        }
+    }
+    else {
+        retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
+    }
+
+    return(retVal);        
+}
+
+/* FUNCTION PURPOSE: Frees a resource
+ ***********************************************************************
+ * DESCRIPTION: Will attempt to free the resource with specified
+ *              base and length from the resource's allocator.  The
+ *              free algorithm will verify the free request parameters
+ *              match an allocated range for the resource and that the
+ *              range is owned by the instance requesting the free. If
+ *              the free is validated the algorithm will free the 
+ *              resource then combine any resource nodes that may have
+ *              become equivalent (in terms of ownership) after the
+ *              allocation.
+ */
+static int32_t treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
+{
+    Rm_ResourceNode  findNode;
+    Rm_ResourceNode *matchingNode = NULL;
+    Rm_ResourceNode *leftNode = NULL;
+    Rm_ResourceNode *rightNode = NULL;
+    bool             combineLeft = false;
+    bool             combineRight = false;
+    uint32_t         findEnd;
+    uint32_t         matchingEnd;
+    int32_t          retVal;
+
+    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+    findNode.base = opInfo->resourceInfo->base;
+    findNode.length = opInfo->resourceInfo->length;
+    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+    if (matchingNode) {
+        findEnd = findNode.base + findNode.length - 1;
+        matchingEnd = matchingNode->base + matchingNode->length - 1;
+        
+        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {  
+            if (matchingNode->allocationCount) {
+                if (isOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+                    if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))
+                    {
+                        /* Case 1: Free range equals allocated matched node exactly. Attempt to combine 
+                         *         freed node with nodes to left and right.
+                         *
+                         * |<--left node-->||<---matched node--->||<--right node-->|
+                         *                  |<---free request--->|
+                         */ 
+                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
+
+                        if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            combineLeft = true;
+                        }
+                        if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                            combineRight = true;
+                        }
+
+                        if (combineLeft && combineRight) {
+                            /* Combine all three nodes into matchingNode */
+                            matchingNode->base = leftNode->base;
+                            matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
+
+                            clearOwners(leftNode);
+                            rmResourceNodeFree(leftNode);
+                            clearOwners(rightNode);
+                            rmResourceNodeFree(rightNode);                        
+                        }
+                        else if (combineLeft) {
+                            /* Combine left and matching nodes.  Reinsert right. */
+                            matchingNode->base = leftNode->base;
+                            matchingNode->length += leftNode->length;
+
+                            clearOwners(leftNode);
+                            rmResourceNodeFree(leftNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        
+                        }
+                        else if (combineRight) {
+                            /* Combine right and matching nodes.  Reinsert left. */
+                            matchingNode->length += rightNode->length;
+
+                            clearOwners(rightNode);
+                            rmResourceNodeFree(rightNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                        else {
+                            /* No combine. */
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        }
+
+                        /* Always reinsert matchingNode */
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);                    
+                    }
+                    else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
+                        /* Case 2: Free range is less than range in matched node. Split
+                         *         matched node into three nodes.
+                         *
+                         * |<----------matched node---------->|
+                         *        |<---free request--->|
+                         *
+                         * Remove instance from AllocatedTo list then add it back in for side nodes for
+                         * proper accounting of allocations in validInstance list
+                         */ 
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
+                        
+                        leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
+                        copyOwners(leftNode, matchingNode);
+                        addOwner(leftNode, opInfo->serviceSrcInstNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        
+                        rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
+                        copyOwners(rightNode, matchingNode);
+                        addOwner(rightNode, opInfo->serviceSrcInstNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+
+                        matchingNode->base = findNode.base;                                    
+                        matchingNode->length = findNode.length;
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    }
+                    else {                        
+                        if (findNode.base == matchingNode->base) {
+                            /* Case 3: Free range is on left boundary of matched node. Try to 
+                             *         combine free range with left node.
+                             *
+                             * |<---left node (free)--->||<----------matched node---------->|
+                             *                           |<---findNode (free req)--->|
+                             */ 
+
+                            leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            /* Remove freeing instance from owner list for compare with leftNode */
+                            deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
+                            
+                            if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {
+                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                                /* Combine leftNode and findNode */
+                                leftNode->length += findNode.length;
+                            }
+                            else {
+                                leftNode = rmResourceNodeNew(findNode.base, findNode.length);
+                                copyOwners(leftNode, matchingNode);
+                            }
+
+                            /* Remove leftNode range from matchingNode */
+                            matchingNode->base = findNode.base + findNode.length;
+                            matchingNode->length = matchingEnd - findEnd;  
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                        else if (findEnd == matchingEnd) {
+                            /* Case 4: Free range is on right boundary of matched node. Try to 
+                             *         combine free range with right node.
+                             *
+                             * |<----------matched node---------->||<---right node (free)--->|
+                             *        |<---findNode (free req)--->|
+                             */ 
+                            
+                            rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode); 
+                            /* Remove freeing instance from owner list for compare with rightNode */
+                            deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
+                            
+                            if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {
+                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                                /* Combine rightNode and findNode */
+                                rightNode->base = findNode.base;
+                                rightNode->length += findNode.length;
+                            }
+                            else {
+                                rightNode = rmResourceNodeNew(findNode.base, findNode.length);
+                                copyOwners(rightNode, matchingNode);
+                            }
+
+                            /* Remove rightNode range from matchingNode */
+                            matchingNode->length -= findNode.length;  
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        }
+
+                        /* Add freeing instance back into matchingNode allocations */
+                        addOwner(matchingNode, opInfo->serviceSrcInstNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    }
+
+                    retVal = RM_SERVICE_APPROVED;
+                }
+                else {
+                    retVal = RM_SERVICE_DENIED_RES_NOT_ALLOCD_TO_INST;
+                }
+            }
+            else {
+                retVal = RM_SERVICE_DENIED_RES_ALREADY_FREE;
+            }
+        }
+        else {
+            retVal = RM_SERVICE_DENIED_PARTIAL_FREE;
+        }
+    }
+    else {
+        retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
+    }
+    return(retVal);  
+}
+
+/* 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;
+
+    /* 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;
+
+    /* 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_GET_BY_NAME)))
+    {
+        strncpy(serviceResponse.resourceName, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+        serviceResponse.resourceBase = transaction->resourceInfo.base;
+        serviceResponse.resourceLength = transaction->resourceInfo.length;
+    }
+
+    /* Issue the callback to the requesting component with the response information */
+    transaction->callback.serviceCallback(&serviceResponse);
+
+    /* Delete the transaction from the transaction queue */
+    rmTransactionQueueDelete(rmInst, transaction->localId);
+    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 = NULL;
+    Rm_PacketHandle  pktHandle = NULL;
+
+    dstTransport = rmTransportFindRemoteName((Rm_Transport *) rmInst->transports, transaction->pktSrcInstName);
+
+    switch (transaction->type) {
+        case Rm_service_RESOURCE_ALLOCATE_INIT:
+        case Rm_service_RESOURCE_ALLOCATE_USE:
+        case Rm_service_RESOURCE_FREE:
+        case Rm_service_RESOURCE_GET_BY_NAME:
+            pktHandle = rmTransportCreateResourceResponsePkt(rmInst, dstTransport->appTransportHandle, 
+                                                             transaction);
+            break;
+        case Rm_service_RESOURCE_MAP_TO_NAME:
+        case Rm_service_RESOURCE_UNMAP_NAME:
+            pktHandle = rmTransportCreateNsResponsePkt(rmInst, dstTransport->appTransportHandle,
+                                                       transaction);
+            break;
+    }
+
+    if (pktHandle) {
+        if (rmInst->transportCallouts.rmSendPkt) {
+            if (rmInst->transportCallouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
+                transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
+            }
+        }
+        else {
+            transaction->state = RM_ERROR_TRANSPORT_SEND_NOT_REGD;
+        }
+    }
+    rmTransactionQueueDelete(rmInst, transaction->localId);
+}
+
+/* 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    *dstTransport = NULL;
+    Rm_PacketHandle  pktHandle = NULL;
+
+    if (rmInst->registeredWithDelegateOrServer) {
+        if (rmInst->instType == Rm_instType_CLIENT) {
+            dstTransport = rmTransportFindRemoteInstType((Rm_Transport *) rmInst->transports, Rm_instType_CLIENT_DELEGATE);
+
+            if (!dstTransport) {
+                dstTransport = rmTransportFindRemoteInstType((Rm_Transport *) rmInst->transports, Rm_instType_SERVER);
+            }
+        } 
+        else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+            dstTransport = rmTransportFindRemoteInstType((Rm_Transport *) rmInst->transports, Rm_instType_SERVER);
+        }
+
+        switch (transaction->type) {
+            case Rm_service_RESOURCE_ALLOCATE_INIT:
+            case Rm_service_RESOURCE_ALLOCATE_USE:
+            case Rm_service_RESOURCE_FREE:
+            case Rm_service_RESOURCE_GET_BY_NAME:
+                pktHandle = rmTransportCreateResourceReqPkt(rmInst, dstTransport->appTransportHandle, transaction);
+                break;
+            case Rm_service_RESOURCE_MAP_TO_NAME:
+            case Rm_service_RESOURCE_UNMAP_NAME:
+                pktHandle = rmTransportCreateNsRequestPkt(rmInst, dstTransport->appTransportHandle, transaction);
+                break;
+        }
+
+        if (pktHandle) {
+            if (rmInst->transportCallouts.rmSendPkt) {            
+                if (rmInst->transportCallouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
+                    transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
+                }
+            }
+            else {
+                transaction->state = RM_ERROR_TRANSPORT_SEND_NOT_REGD;
+            }                
+        }
+
+        transaction->hasBeenForwarded = true;
+        /* Transaction not deleted.  Waiting for response from RM CD or Server */
+    }
+}
+
+/* FUNCTION PURPOSE: Issues an allocator operation
+ ***********************************************************************
+ * DESCRIPTION: Issues an allocator preallocate, allocate, or free
+ *              for an RM resource.
+ */
+static int32_t allocatorOperation(Rm_Inst *rmInst, Rm_AllocatorOpInfo *opInfo)
+{
+    Rm_Allocator *allocator = NULL;
+    int32_t       resourceOffsetInPolicy;
+    int32_t       retVal;
+    
+    resourceOffsetInPolicy = rmPolicyGetResourceOffset(rmInst->policy, opInfo->resourceInfo->name);
+    allocator = rmAllocatorFind(rmInst->allocators, opInfo->resourceInfo->name);
+    
+    if ((resourceOffsetInPolicy > 0) && allocator) {
+        if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE) {
+            retVal = treePreAllocate(rmInst, allocator, resourceOffsetInPolicy, opInfo);
+        }               
+        else if (opInfo->operation == Rm_allocatorOp_ALLOCATE) {
+            retVal = treeAllocate(rmInst, allocator, resourceOffsetInPolicy, opInfo);
+        }
+        else if (opInfo->operation == Rm_allocatorOp_FREE) {
+            retVal = treeFree(allocator, opInfo);
+        }         
+    }
+    else {
+        /* Resource could not be found in policy and/or allocator */
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+    }
+    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, void *validInstNode,
+                               uint32_t allocType)
+{
+    Rm_AllocatorOpInfo  opInfo;
+    Rm_NameServerObjCfg nameServerObjCfg;
+    int32_t             retVal = transaction->state;
+
+    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        /* Forward all allocation requests to Server if transport is up.  Otherwise, just queue. */
+        if (rmInst->registeredWithDelegateOrServer) {
+            transactionForwarder(rmInst, transaction);   
+        }  
+    }
+    else if (rmInst->instType == Rm_instType_SERVER) {
+        opInfo.resourceInfo = &transaction->resourceInfo;
+        opInfo.serviceSrcInstNode = validInstNode;
+        opInfo.allocType = allocType;
+
+        /* Populated NameServer name has precedence over base */
+        if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+            if ((transaction->resourceInfo.base == 0) &&
+                (transaction->resourceInfo.length == 0) &&
+                (transaction->resourceInfo.alignment == 0)) {
+                memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+                nameServerObjCfg.nameServerTree = rmInst->nameServer;
+                nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+                if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+                    strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+                    transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                    transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+                }                
+            }
+            else {
+                retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;
+            }
+        }
+
+        if (retVal == RM_SERVICE_PROCESSING) {      
+            if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
+                opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;
+                retVal = allocatorOperation(rmInst, &opInfo);
+            }
+        
+            if (retVal == RM_SERVICE_PROCESSING) {
+                opInfo.operation = Rm_allocatorOp_ALLOCATE;
+                retVal = allocatorOperation(rmInst, &opInfo);
+            }      
+        }
+        
+        transaction->state = retVal;
+
+        if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+            /* Source of allocation was not the server instance, provide the transaction
+             * to the transaction responder */
+            transactionResponder(rmInst, transaction);
+        }
+        /* Otherwise let the return stack return the transaction to the serviceHandler */                   
+    }   
+}
+
+/* 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, void *validInstNode)
+{
+    Rm_AllocatorOpInfo  opInfo; 
+    Rm_NameServerObjCfg nameServerObjCfg;    
+    int32_t             retVal = transaction->state;
+
+    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        /* Forward all free requests to Server if transport is up.  Otherwise, just queue. */
+        if (rmInst->registeredWithDelegateOrServer) {
+            transactionForwarder(rmInst, transaction);   
+        }
+    }
+    else if (rmInst->instType == Rm_instType_SERVER) {
+        opInfo.resourceInfo = &transaction->resourceInfo;
+        opInfo.serviceSrcInstNode = validInstNode;
+
+        /* Populated NameServer name has precedence over base */
+        if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+            if ((transaction->resourceInfo.base == 0) &&
+                (transaction->resourceInfo.length == 0) &&
+                (transaction->resourceInfo.alignment == 0)) {
+                memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+                nameServerObjCfg.nameServerTree = rmInst->nameServer;
+                nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+                if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+                    strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+                    transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                    transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+                } 
+            }
+            else {
+                retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;
+            }                
+        }
+        
+        if(retVal == RM_SERVICE_PROCESSING) {        
+            opInfo.operation = Rm_allocatorOp_FREE;
+            retVal = allocatorOperation(rmInst, &opInfo);
+        }       
+
+        transaction->state = retVal;
+
+        if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+            /* Source of allocation was not the server instance, provide the transaction
+             * to the transaction responder */
+            transactionResponder(rmInst, transaction);
+        }
+        /* Otherwise let the return stack return the transaction to the serviceHandler */        
+    }   
+}
+
+/* FUNCTION PURPOSE: Reserves a Linux resource
+ ***********************************************************************
+ * DESCRIPTION: Reserves resources for Linux using the base and length
+ *              values retrieved from the Linux DTB via the
+ *              "linux-dtb-alias" properties within the GRL.
+ */
+static int32_t reserveLinuxResource(Rm_Inst *rmInst, Rm_LinuxAlias *linuxAlias, 
+                                    Rm_LinuxValueRange *linuxValues, Rm_AllocatorOpInfo *opInfo)
+{
+    int32_t  retVal = RM_OK;
+    bool     baseFound = false;
+    bool     lengthFound = false;
+    uint32_t valueIndex = 0;
+
+    while ((linuxValues) && (!baseFound || !lengthFound)) {
+        if (linuxAlias->baseOffset == valueIndex) {
+            opInfo->resourceInfo->base = linuxValues->value;
+            baseFound = true;
+
+            if (linuxAlias->lengthOffset == RM_DTB_UTIL_LINUX_ALIAS_OFFSET_NOT_SET) {
+                opInfo->resourceInfo->length = 1;
+                lengthFound = true;
+            }
+        }
+        else if (linuxAlias->lengthOffset == valueIndex) {
+            opInfo->resourceInfo->length = linuxValues->value;
+            lengthFound = true;
+        }
+
+        linuxValues = (Rm_LinuxValueRange *)linuxValues->nextValue;
+        valueIndex++;
+    }
+
+    if (!baseFound || !lengthFound) {
+        retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;
+    }
+    else {
+        /* Allocate resource to Linux */
+        retVal = allocatorOperation(rmInst, opInfo);
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Finds and reserves Linux resources
+ ***********************************************************************
+ * DESCRIPTION: Parses the Linux DTB for resources consumed by the
+ *              Linux kernel.  If the resource is found via the
+ *              "linux-dtb-alias" property defined in the GRL it is 
+ *              reserved.
+ */
+static int32_t findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName, void *linuxDtb, 
+                                           Rm_LinuxAlias *linuxAlias)
+{
+    Rm_AllocatorOpInfo  opInfo;
+    Rm_ResourceInfo     resourceInfo;
+    uint32_t            pathOffset;
+    uint32_t            pathSize;
+    char               *spacePtr;
+    int32_t             propOffset;
+    int32_t             nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+    int32_t             prevDepth = RM_DTB_UTIL_STARTING_DEPTH;
+    int32_t             depth;
+    int32_t             propertyLen;
+    const char         *propertyName;
+    const void         *propertyData; 
+    Rm_LinuxValueRange *linuxValueRange;
+    int32_t             retVal = RM_OK; 
+
+    memset((void *) &opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    memset((void *) &resourceInfo, 0, sizeof(Rm_ResourceInfo));
+
+    strncpy(resourceInfo.name, resourceName, RM_NAME_MAX_CHARS);
+    opInfo.serviceSrcInstNode = rmPolicyGetLinuxInstNode(rmInst->validInstances);
+    opInfo.operation = Rm_allocatorOp_ALLOCATE;
+    opInfo.resourceInfo = &resourceInfo;    
+
+    while(linuxAlias) {
+        /* Reset parsing variables */
+        pathOffset = 0;
+        pathSize = strlen(linuxAlias->path) + 1;
+        nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+        prevDepth = RM_DTB_UTIL_STARTING_DEPTH;   
+        resourceInfo.base = 0;
+        resourceInfo.length = 0;
+
+        spacePtr = strpbrk(linuxAlias->path, " ");
+        if (spacePtr) {
+            *spacePtr = '\0';
+        }       
+        
+        while(pathOffset < pathSize) {
+            /* Move through DTB nodes until next alias path node found */
+            if (strcmp(linuxAlias->path + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL))) {
+                nodeOffset = fdt_next_node(linuxDtb, nodeOffset, &depth);
+
+                if ((depth < prevDepth) || (nodeOffset == -FDT_ERR_NOTFOUND)) {
+                    /* Returning from subnode that matched part of alias path without finding
+                     * resource values */
+                    retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;
+                    break;
+                }
+            }
+            else {
+                /* Found next alias path node.  Move to next node name in path string. */
+                pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);
+                spacePtr = strpbrk(linuxAlias->path + pathOffset, " ");
+                if (spacePtr) {
+                    *spacePtr = '\0';
+                }       
+                
+                prevDepth = fdt_node_depth(linuxDtb, nodeOffset);
+               propOffset = fdt_first_property_offset(linuxDtb, nodeOffset);
+                while ((propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&
+                       (pathOffset < pathSize)) {
+                    propertyData = fdt_getprop_by_offset(linuxDtb, propOffset, 
+                                                         &propertyName, &propertyLen);
+
+                    if (strcmp(linuxAlias->path + pathOffset, propertyName) == 0) {
+                        /* Found resource at end of alias path */
+                        pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);
+                        linuxValueRange = rmDtbUtilLinuxExtractValues(propertyData, propertyLen);
+                        retVal = reserveLinuxResource(rmInst, linuxAlias, 
+                                                      linuxValueRange, &opInfo);
+                        rmDtbUtilLinuxFreeValues(linuxValueRange);
+                    }
+                    propOffset = fdt_next_property_offset(linuxDtb, propOffset);
+                } 
+
+                if (propOffset < -FDT_ERR_NOTFOUND) {
+                    retVal = propOffset;
+                    break;
+                }
+            }
+        }
+
+        if (retVal < RM_OK) {
+            break;
+        }
+        linuxAlias = linuxAlias->nextLinuxAlias;
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Creates and initializes a resource allocator
+ ***********************************************************************
+ * DESCRIPTION: Creates a resource allocator for the provided
+ *              resource name and resource properties retrieved
+ *              from the GRL.  Resources will be reserved for 
+ *              the Linux kernel if the Linux DTB is provided
+ *              and there are "linux-dtb-alias" properties
+ *              specified in the GRL.
+ */
+static int32_t createAndInitAllocator(Rm_Inst *rmInst, const char *resourceName, 
+                                      Rm_ResourceProperties *resourceProperties, void *linuxDtb)
+{
+    Rm_ResourceRange    *range = NULL;
+    Rm_ResourceRange    *rangeBasePtr = NULL;
+    Rm_NsAssignment     *nsAssignments = NULL;
+    Rm_NsAssignment     *nsAssignmentBasePtr = NULL;
+    Rm_LinuxAlias       *linuxAlias = NULL;
+    Rm_NameServerObjCfg  nameServerObjCfg;      
+    int32_t              retVal = RM_OK;
+
+    if (resourceProperties->rangeData && (resourceProperties->rangeLen > 0)) {
+        range = rangeBasePtr = rmDtbUtilResExtractRange(resourceProperties->rangeData, 
+                                                        resourceProperties->rangeLen);
+        
+        if ((retVal = createResourceTree(rmInst, resourceName, range)) >= RM_OK) {
+            if (resourceProperties->linuxAliasData && resourceProperties->linuxAliasLen) {
+                if (linuxDtb) {
+                    linuxAlias = rmDtbUtilResExtractLinuxAlias(resourceProperties->linuxAliasData,
+                                                               resourceProperties->linuxAliasLen, &retVal);
+                    if (linuxAlias) {
+                        retVal = findAndReserveLinuxResource(rmInst, resourceName, linuxDtb, linuxAlias);            
+                    }
+                }
+                else {
+                    retVal = RM_ERROR_GRL_LINUX_ALIAS_BUT_NO_DTB;
+                }
+            }
+        }
+    }
+    
+    if (retVal >= RM_OK) {
+        if (resourceProperties->nsAssignData && resourceProperties->nsAssignLen) {
+            nsAssignments = rmDtbUtilResExtractNsAssignment(resourceProperties->nsAssignData, 
+                                                            resourceProperties->nsAssignLen, &retVal);
+            if (nsAssignments) {
+                nsAssignmentBasePtr = nsAssignments;
+                while (nsAssignments) {
+                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+                    nameServerObjCfg.nameServerTree = rmInst->nameServer;
+                    nameServerObjCfg.nodeCfg.objName = nsAssignments->nsName;
+                    nameServerObjCfg.nodeCfg.resourceName = (char *)resourceName;
+                    nameServerObjCfg.nodeCfg.resourceBase= nsAssignments->resourceBase;
+                    nameServerObjCfg.nodeCfg.resourceLength = nsAssignments->resourceLength;                
+                    rmNameServerAddObject(&nameServerObjCfg);
+                    nsAssignments = nsAssignments->nextNsAssignment;
+                }
+                rmDtbUtilResFreeNsAssignmentList(nsAssignmentBasePtr);
+            }
+        }
+    }
+
+    rmDtbUtilResFreeRange(rangeBasePtr);
+    if (linuxAlias) {
+        rmDtbUtilResFreeLinuxAlias(linuxAlias);
+    }
+    return(retVal);
+}
+
+/* FUNCTION PURPOSE: Recursively parses GRL resource properties
+ ***********************************************************************
+ * DESCRIPTION: Recursively parses and stores GRL resource node 
+ *              properties using the LIBFDT APIs
+ */
+static int32_t parseResourceProperty(void *globalResourceDtb, int32_t offset, 
+                                     Rm_ResourceProperties *propertyInfo)
+{
+       int32_t              propertyLen;
+       const char          *propertyName;
+       const void          *propertyData;
+    Rm_ResourcePropType  propertyType;
+    int32_t              retVal = RM_OK;
+
+       propertyData = fdt_getprop_by_offset(globalResourceDtb, offset, &propertyName, &propertyLen);
+    propertyType = rmDtbUtilResGetPropertyType(propertyName);
+    if (propertyType == Rm_resourcePropType_RESOURCE_RANGE) {
+        propertyInfo->rangeData = propertyData;
+        propertyInfo->rangeLen = propertyLen;
+    }
+    else if (propertyType == Rm_resourcePropType_NSASSIGNMENT) {
+        propertyInfo->nsAssignData = propertyData;
+        propertyInfo->nsAssignLen = propertyLen;
+    }
+    else if (propertyType == Rm_resourcePropType_RESOURCE_LINUX_ALIAS) {
+        propertyInfo->linuxAliasData = propertyData;
+        propertyInfo->linuxAliasLen = propertyLen;
+    }        
+    else {
+        retVal = RM_ERROR_GRL_UNKNOWN_RESOURCE_PROPERTY;
+    }
+
+    if (retVal == RM_OK) {
+        offset = fdt_next_property_offset(globalResourceDtb, offset);
+       if (offset >= 0) {
+           retVal = parseResourceProperty(globalResourceDtb, offset, propertyInfo);
+       }
+        else if (offset != -FDT_ERR_NOTFOUND) {
+            /* Error returned by LIBFDT */
+            retVal = offset;
+        }
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Recursively parses GRL resource nodes
+ ***********************************************************************
+ * DESCRIPTION: Recursively parses GRL resource nodes looking for
+ *              resource properties to create the resource allocators.
+ *              The LIBFDT APIs are used to parse the GRL.
+ */
+static int32_t parseResourceNode(Rm_Inst *rmInst, void *globalResourceDtb, int32_t nodeOffset, int32_t depth,
+                                 void *linuxDtb)
+{
+       const char            *resourceName = fdt_get_name(globalResourceDtb, nodeOffset, NULL);
+    Rm_ResourceProperties  resourceProperties;
+       int32_t                retVal = RM_OK;
+       int32_t                offset;
+
+    memset((void *)&resourceProperties, 0, sizeof(Rm_ResourceProperties));
+    /* Get properties of resource node */
+       offset = fdt_first_property_offset(globalResourceDtb, nodeOffset);
+       if (offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+               retVal =  parseResourceProperty(globalResourceDtb, offset, &resourceProperties);
+        if (retVal < -FDT_ERR_NOTFOUND) {
+            return (retVal);
+        }
+        if (retVal = createAndInitAllocator(rmInst, resourceName, &resourceProperties, linuxDtb) < RM_OK) {
+            return (retVal);
+        }
+       }
+    else if (offset != -FDT_ERR_NOTFOUND) {
+               /* Error returned by LIBFDT */
+        return (offset);
+    }
+    
+       offset = fdt_next_node(globalResourceDtb, nodeOffset, &depth);
+    if ((offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH)) {
+        retVal = parseResourceNode(rmInst, globalResourceDtb, offset, depth, linuxDtb);
+        if (retVal < -FDT_ERR_NOTFOUND) {
+            return (retVal);
+        }
+    }
+    else if (offset != -FDT_ERR_NOTFOUND) {
+        /* Error returned by LIBFDT */
+        return (offset);
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Initializes server allocators
+ ***********************************************************************
+ * DESCRIPTION: Creates and initializes a server instance's
+ *              resource allocators using the GRL and, if
+ *              provided, Linux DTB.
+ */
+static int32_t initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb, void *linuxDtb)
+{
+    int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+    int32_t startDepth = RM_DTB_UTIL_STARTING_DEPTH;
+    int32_t result = RM_OK;
+
+    /* Recursively parse the Global Resource List, creating an allocator for
+     * each resource as specified in the node */
+    result = parseResourceNode(rmInst, globalResourceDtb, nodeOffset, startDepth, linuxDtb);
+
+    return(result);
+}
+
+/**********************************************************************
+ ********************** 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: Finds an allocator
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to an allocator that matches the 
+ *              provided resource name.
+ */
+Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName)
+{
+    while (allocatorList) {
+        if (strncmp(allocatorList->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
+            break;             
+        }
+        allocatorList = allocatorList->nextAllocator;
+    }
+
+    return (allocatorList);
+}
+
+/* FUNCTION PURPOSE: Processes a transaction
+ ***********************************************************************
+ * DESCRIPTION: Processes transactions created from services
+ *              received via the service handle or the transport.
+ *              Transactions will be routed within the RM system
+ *              based on the RM instance type and the type of
+ *              the transaction.
+ */
+void rmTransactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    void                *validInstNode;
+    Rm_PolicyCheckCfg    privCheckCfg;
+    Rm_NameServerObjCfg  nameServerObjCfg;      
+    uint32_t             allocType = 0;    
+
+    /* Handle static transactions originating on this instance.  Any other static transactions will be
+     * stored in transaction queue until all transports are up. */
+    if (((rmInst->instType == Rm_instType_CLIENT) || (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) &&
+        (!rmInst->registeredWithDelegateOrServer) && 
+        (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS) == 0)) {
+        if (rmInst->staticInfo.staticPolicy) {
+            if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+                (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+                /* Check request against startup 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.policyDtb = rmInst->staticInfo.staticPolicy;
+                privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmInst->staticInfo.staticValidInstTree, 
+                                                                      rmInst->instName);
+                privCheckCfg.resourceOffset = rmPolicyGetResourceOffset(rmInst->staticInfo.staticPolicy,
+                                                                        transaction->resourceInfo.name);
+                privCheckCfg.resourceBase = transaction->resourceInfo.base;
+                privCheckCfg.resourceLength = transaction->resourceInfo.length;
+
+                if (rmPolicyCheckPrivilege(&privCheckCfg, &transaction->state)) {
+                    transaction->state = RM_SERVICE_APPROVED_STATIC;
+                }
+                else if (transaction->state == RM_SERVICE_PROCESSING) {
+                    /* Privilege check returned false without error */
+                    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;
+        }        
+    }
+    else {
+        /* Handle auto-forwarded transactions.  These transactions include:
+         * - All request transactions received on Clients are forwarded to the Client Delegate
+         * - NameServer requests received on the Client Delegate are forwarded to the Server */
+        if ((rmInst->instType == Rm_instType_CLIENT) ||
+            ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&
+             ((transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) ||
+              (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) ||
+              (transaction->type == Rm_service_RESOURCE_UNMAP_NAME)))) {
+              
+            if ((transaction->state != RM_SERVICE_PROCESSING) &&
+                (transaction->state != RM_SERVICE_APPROVED_STATIC)) {
+                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);
+                }
+            }
+            else {
+                /* Forward request if transport is up.  Otherwise, just queue. */
+                if (rmInst->registeredWithDelegateOrServer) {
+                    transactionForwarder(rmInst, transaction);   
+                } 
+            }
+        }
+        else {
+            /* Validate service's originating instance name */
+            if (rmInst->instType == Rm_instType_SERVER) {
+                validInstNode = rmPolicyGetValidInstNode(rmInst->validInstances, transaction->serviceSrcInstName);
+                if (validInstNode == NULL) {
+                    transaction->state = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+
+                    /* Send result via responder if transaction did not originate from this instance */
+                    if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+                        transactionResponder(rmInst, transaction);
+                    }
+                }
+            }
+
+            switch (transaction->type) {
+                case Rm_service_RESOURCE_ALLOCATE_INIT:
+                case Rm_service_RESOURCE_ALLOCATE_USE:
+                case Rm_service_RESOURCE_FREE:               
+                    if ((transaction->state != RM_SERVICE_PROCESSING) &&
+                        (transaction->state != RM_SERVICE_APPROVED_STATIC)) {
+                        /* Transaction complete */
+                        if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+                            /* Transaction result not destined for this instance */
+                            transactionResponder(rmInst, transaction);
+                        }
+                        else {
+                            /* Transaction result destined for this instance */
+                            serviceResponder(rmInst, transaction);      
+                        }
+                    }
+                    else {
+                        /* Complete allocation/free request */
+                        if (transaction->type == Rm_service_RESOURCE_FREE) {
+                            freeHandler(rmInst, transaction, validInstNode);
+                        }
+                        else {
+                            switch (transaction->type) {
+                                case Rm_service_RESOURCE_ALLOCATE_INIT:
+                                    RM_policy_SET_PERM(allocType, RM_POLICY_PERM_INIT_SHIFT, 1);
+                                    break;
+                                case Rm_service_RESOURCE_ALLOCATE_USE:
+                                    RM_policy_SET_PERM(allocType, RM_POLICY_PERM_USE_SHIFT, 1);    
+                                    break;
+                            }
+                            allocationHandler(rmInst, transaction, validInstNode, allocType);
+                        }
+                    }
+                    break;
+                case Rm_service_RESOURCE_MAP_TO_NAME:
+                case Rm_service_RESOURCE_GET_BY_NAME:
+                case Rm_service_RESOURCE_UNMAP_NAME:                
+                    /* NameServer resides on server */
+                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+                    if (rmInst->nameServer) {
+                        nameServerObjCfg.nameServerTree = rmInst->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) {
+                                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_NAMESERVER_DOES_NOT_EXIST;
+                    }
+
+                    /* Send result via responder if transaction did not originate from this instance */
+                    if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+                        transactionResponder(rmInst, transaction);
+                    }
+                    break;
+            }
+        }
+    }
+
+    /* Forward any queued requests that weren't forwarded yet */
+    if (rmInst->registeredWithDelegateOrServer) {
+        transaction = rmInst->transactionQueue;
+        while(transaction) {
+            if (((transaction->state == RM_SERVICE_PROCESSING) ||
+                 (transaction->state == RM_SERVICE_APPROVED_STATIC)) &&
+                !transaction->hasBeenForwarded) {
+                transactionForwarder(rmInst, transaction);
+            }
+            transaction = transaction->nextTransaction;
+        }
+    }
+}
+     
+/**********************************************************************
+ ********************** 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.  This function is only available on server
+ *              instances.
+ */
+void Rm_printResourceStatus(Rm_Handle rmServerHandle)
+{
+    Rm_Inst         *rmInst = (Rm_Inst *)rmServerHandle;
+    Rm_Allocator    *allocator = rmInst->allocators;
+    Rm_Owner        *owners;
+    Rm_ResourceTree *treeRoot;
+    Rm_ResourceNode *treeNode;
+
+    if (rmInst->instType == Rm_instType_SERVER) {
+        while (allocator != NULL) {
+            Rm_osalLog("Resource: %s\n", allocator->resourceName);
+
+            treeRoot = allocator->allocatorRootEntry;
+
+            RB_FOREACH(treeNode, _Rm_AllocatorResourceTree, treeRoot) {               
+                Rm_osalLog("          %10d - %10d ", treeNode->base, 
+                                                     treeNode->base + treeNode->length -1);
+                
+                if (treeNode->allocationCount == 0) {
+                    Rm_osalLog("NOT ALLOCATED\n");
+                }
+                else {
+                    owners = treeNode->ownerList;
+                    Rm_osalLog("allocated to");
+                    while (owners) {
+                        Rm_osalLog(" %s", owners->instNameNode->name);
+                        owners = owners->nextOwner;
+                    }
+                    Rm_osalLog("\n");
+                }
+            }        
+            allocator = allocator->nextAllocator;
+        }
+        rmNameServerPrintObjects(rmInst->nameServer);
+    }
+}
+
+/* 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_printInstanceStatus(Rm_Handle rmHandle)
+{
+    Rm_Inst        *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Transport   *transportList = (Rm_Transport *)rmInst->transports;
+    Rm_Transaction *transactionQ = rmInst->transactionQueue;
+
+    Rm_osalLog("Instance name: %s\n", rmInst->instName);
+    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 {
+        Rm_osalLog("Type: Client\n");
+    }
+
+    if (transportList) {
+        Rm_osalLog("\nRegistered Transports:\n");
+        while (transportList) {
+            Rm_osalLog("    Remote instName:    %s\n", transportList->remoteInstName);
+            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;
+        }
+    }
+
+    if (transactionQ) {
+        Rm_osalLog("\nQueued Service Transactions:\n");
+        while (transactionQ) {
+            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;
+        }    
+    }
+}
+
+/* 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;
+    void    *globalResourceDtb = NULL;
+    void    *linuxResourceDtb = NULL;
+    bool     addLinux = false;
+
+    *result = RM_OK;
+    
+    if ((initCfg->instName == NULL) ||
+        ((strlen(initCfg->instName) + 1) > RM_NAME_MAX_CHARS)) {
+        *result = RM_ERROR_INVALID_INST_NAME;
+        return (NULL);
+    }
+
+    if (initCfg->instType >= Rm_instType_LAST) {
+        *result = RM_ERROR_INVALID_INST_TYPE;
+    }
+
+    /* Create and initialize instance */
+    rmInst = Rm_osalMalloc (sizeof(Rm_Inst));
+    memset ((void *) rmInst, 0, sizeof(Rm_Inst));
+    rmInst->isLocked = false;
+    rmInst->registeredWithDelegateOrServer = false;
+    rmInst->transactionSeqNum = transactionInitSequenceNum();
+
+    rmInst->instType = initCfg->instType;    
+    strncpy (rmInst->instName, initCfg->instName, RM_NAME_MAX_CHARS);
+
+    if (rmInst->instType == Rm_instType_SERVER) {
+        if (!initCfg->instCfg.serverCfg.globalResourceList ||
+            !initCfg->instCfg.serverCfg.globalPolicy) {
+            *result = RM_ERROR_INVALID_SERVER_CONFIGURATION;
+            Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+            return(NULL);
+        }
+
+        rmInst->policy = initCfg->instCfg.serverCfg.globalPolicy;
+        fdt_open_into(rmInst->policy, rmInst->policy, fdt_totalsize(rmInst->policy)); 
+
+        if (initCfg->instCfg.serverCfg.linuxDtb) {
+            linuxResourceDtb = initCfg->instCfg.serverCfg.linuxDtb;
+            fdt_open_into(linuxResourceDtb, linuxResourceDtb, fdt_totalsize(linuxResourceDtb));
+            addLinux = true;
+        }
+
+        /* Create valid instance list from policy.  Must be done prior to parsing
+         * GRL so that Linux resources can be reserved correctly */
+        rmInst->validInstances = rmPolicyCreateValidInstTree(rmInst->policy, addLinux, result);
+        /* Validate policy assignment strings */
+        *result = rmPolicyValidatePolicy(rmInst->policy, rmInst->validInstances);  
+
+        rmInst->nameServer = rmNameServerInit();
+
+        globalResourceDtb = initCfg->instCfg.serverCfg.globalResourceList;
+        fdt_open_into(globalResourceDtb, globalResourceDtb, fdt_totalsize(globalResourceDtb));
+
+        if ((*result = initializeAllocators(rmInst, globalResourceDtb, linuxResourceDtb)) == RM_OK) {  
+            *result = rmPolicyValidatePolicyResourceNames(rmInst->policy, (void *)rmInst->allocators);
+        }
+        if (*result < RM_OK) {
+            Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+            return(NULL);
+        }
+    }
+
+    if ((rmInst->instType == Rm_instType_CLIENT) && 
+        (initCfg->instCfg.clientCfg.staticPolicy)) {
+        rmInst->staticInfo.staticPolicy = initCfg->instCfg.clientCfg.staticPolicy; 
+    }
+    else if ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&
+             (initCfg->instCfg.cdCfg.staticPolicy)) { 
+        rmInst->staticInfo.staticPolicy = initCfg->instCfg.cdCfg.staticPolicy; 
+    }
+    if (rmInst->staticInfo.staticPolicy) {
+        fdt_open_into(rmInst->staticInfo.staticPolicy, rmInst->staticInfo.staticPolicy, 
+                      fdt_totalsize(rmInst->staticInfo.staticPolicy));       
+        rmInst->staticInfo.staticValidInstTree = rmPolicyCreateValidInstTree(rmInst->staticInfo.staticPolicy, 
+                                                                             addLinux, result);        
+        if (*result == RM_OK) {
+            /* Validate policy assignment strings */
+            *result = rmPolicyValidatePolicy(rmInst->staticInfo.staticPolicy, rmInst->staticInfo.staticValidInstTree);
+        }
+        if (*result != RM_OK) {
+            if (rmInst->staticInfo.staticValidInstTree) {
+                rmPolicyFreeValidInstTree(rmInst->staticInfo.staticValidInstTree);
+            }
+            Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+            rmInst = NULL;
+        }
+    }
+    return ((Rm_Handle) rmInst);
+}
+
+/* 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;
+}
+