summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0501be2)
raw | patch | inline | side by side (parent: 0501be2)
author | Justin Sobota <jsobota@ti.com> | |
Sun, 16 Dec 2012 02:15:42 +0000 (21:15 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Sun, 16 Dec 2012 02:15:42 +0000 (21:15 -0500) |
index f6b5726a8064e0609f418404620487883f7426a8..46a90a8c674b11207b9a44a67b875e6af78e2922 100644 (file)
qmss {
pdsps {
- allocator = "tree";
resource-range = <0 2>;
};
memory-regions {
- allocator = "tree";
resource-range = <0 20>;
linux-dtb-alias = "hwqueue@2a00000", "regions", "region-12", "id", "end", <0>, "end";
};
link-ram {
- allocator = "tree";
resource-range = <0x00000000 0xFFFFFFFF>;
};
accumulator-ch {
- allocator = "tree";
resource-range = <0 48>;
/* Each new line specifies a different path. The last string in the line
* must result in a property tied to a value */
"hwqueue@2a00000", "queues", "accumulator-high", "accumulator", "end", <1>, "end";
};
qos-cluster {
- allocator = "tree";
resource-range = <0 8>;
};
qos-queue {
- allocator = "tree";
resource-range = <0 64>;
};
/* Queue definitions based on csl_qm_queue.h */
low-prio-queue {
- allocator = "tree";
resource-range = <0 512>;
/* Each new line specifies a different path. */
linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-low-0", "values", "end", <0>, <1>, "end",
"hwqueue@2a00000", "queues", "accumulator-low-3", "values", "end", <0>, <1>, "end";
};
aif-queue {
- allocator = "tree";
resource-range = <512 128>;
};
pass-queue {
- allocator = "tree";
resource-range = <640 9>;
+ ns-assignment = "NETFP_Fail_Route_Queue_Num", <650 1>;
};
intc-queue {
- allocator = "tree";
resource-range = <662 10>;
};
srio-queue {
- allocator = "tree";
resource-range = <672 16>;
linux-dtb-alias = "hwqueue@2a00000", "queues", "riotx", "values", "end", <0>, <1>, "end";
};
fftc-a-queue {
- allocator = "tree";
resource-range = <688 4>;
};
fftc-b-queue {
- allocator = "tree";
resource-range = <692 4>;
};
bcp-queue {
- allocator = "tree";
resource-range = <864 8>;
};
high-prio-queue {
- allocator = "tree";
resource-range = <704 32>;
linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-high", "values", "end", <0>, <1>, "end";
};
starvation-queue {
- allocator = "tree";
resource-range = <736 64>;
};
infra-queue {
- allocator = "tree";
resource-range = <800 32>;
linux-dtb-alias = "hwqueue@2a00000", "queues", "infradma", "values", "end", <0>, <1>, "end";
};
traffic-shaping-queue {
- allocator = "tree";
resource-range = <832 32>;
};
gp-queue {
- allocator = "tree";
resource-range = <896 7296>;
linux-dtb-alias = "hwqueue@2a00000", "queues", "general", "values", "end", <0>, <1>, "end";
+ ns-assignment = "QOS_Ingress_Queue_Base", <8000 1>;
};
}; /* qmss */
/* CPPI channel and flow ID ranges based on tci6614 cppi_device.c */
cppi {
srio-rx-ch {
- allocator = "tree";
resource-range = <0 16>;
};
srio-tx-ch {
- allocator = "tree";
resource-range = <0 16>;
};
srio-rx-flow-id {
- allocator = "tree";
resource-range = <0 20>;
};
aif-rx-ch {
- allocator = "tree";
resource-range = <0 129>;
};
aif-tx-ch {
- allocator = "tree";
resource-range = <0 129>;
};
aif-rx-flow-id {
- allocator = "tree";
resource-range = <0 129>;
};
fftc-a-rx-ch {
- allocator = "tree";
resource-range = <0 4>;
};
fftc-a-tx-ch {
- allocator = "tree";
resource-range = <0 4>;
};
fftc-a-rx-flow-id {
- allocator = "tree";
resource-range = <0 8>;
};
fftc-b-rx-ch {
- allocator = "tree";
resource-range = <0 4>;
};
fftc-b-tx-ch {
- allocator = "tree";
resource-range = <0 4>;
};
fftc-b-rx-flow-id {
- allocator = "tree";
resource-range = <0 8>;
};
pass-rx-ch {
- allocator = "tree";
resource-range = <0 23>;
};
pass-tx-ch {
- allocator = "tree";
resource-range = <0 9>;
};
pass-rx-flow-id {
- allocator = "tree";
resource-range = <0 32>;
+ ns-assignment = "NETFP_Fail_Route_Flow_ID", <23 1>;
};
qmss-rx-ch {
- allocator = "tree";
resource-range = <0 32>;
};
qmss-tx-ch {
- allocator = "tree";
resource-range = <0 32>;
};
qmss-rx-flow-id {
- allocator = "tree";
resource-range = <0 64>;
};
bcp-rx-ch {
- allocator = "tree";
resource-range = <0 8>;
};
bcp-tx-ch {
- allocator = "tree";
resource-range = <0 8>;
};
bcp-rx-flow-id {
- allocator = "tree";
resource-range = <0 64>;
};
}; /* cppi */
- pa-lut {
- allocator = "tree";
+ pa-lut {
resource-range = <0 5>;
};
};
index 7405b782458914d56b3f2cfeeede2495ff097b91..b9ced927d5637b4863202303ca046d66b3d76eb4 100644 (file)
--- a/include/rm_dtb_utilloc.h
+++ b/include/rm_dtb_utilloc.h
Rm_resourcePropType_DEVICE_NAME = 1,
/** Resource DTB resource range property type */
Rm_resourcePropType_RESOURCE_RANGE = 2,
- /** Resource DTB resource allocator property type */
- Rm_resourcePropType_RESOURCE_ALLOCATOR = 3,
/** Resource DTB resource alias path in Linux DTB */
- Rm_resourcePropType_RESOURCE_LINUX_ALIAS = 4,
+ Rm_resourcePropType_RESOURCE_LINUX_ALIAS = 3,
/** Resource DTB NameServer assignment property type */
- Rm_resourcePropType_NSASSIGNMENT = 5,
+ Rm_resourcePropType_NSASSIGNMENT = 4,
} Rm_ResourcePropType;
typedef struct {
typedef struct {
char *nsName;
- uint32_t resourceValue;
+ uint32_t resourceBase;
+ uint32_t resourceLength;
void *nextNsAssignment;
} Rm_NsAssignment;
void Rm_resourceFreeDeviceName(char *deviceName);
Rm_ResourceRange *Rm_resourceExtractRange(const void *dtbDataPtr, int32_t dtbDataLen);
void Rm_resourceFreeRange(Rm_ResourceRange *rangeList);
-char *Rm_resourceExtractAllocator(const void *dtbDataPtr, int32_t dtbDataLen);
-void Rm_resourceFreeAllocator(char *resourceAllocatorType);
Rm_LinuxAlias *Rm_resourceExtractLinuxAlias(const void *dtbDataPtr, int32_t dtbDataLen);
void Rm_resourceFreeLinuxAlias(Rm_LinuxAlias *aliasList);
Rm_NsAssignment *Rm_resourceExtractNsAssignment(const void *dtbDataPtr, int32_t dtbDataLen);
diff --git a/include/rm_loc.h b/include/rm_loc.h
index 32077e31b9ce869fe323cc7a0241c6c83372fec9..aa42d44087e3a970da6ebd55ca6c1a4d0d544c68 100644 (file)
--- a/include/rm_loc.h
+++ b/include/rm_loc.h
/** Pointer to the RM instance's allocators */
typedef void *Rm_Allocators;
+/** Pointer to the RM instance's NameServer (Valid only on Server) */
+typedef void *Rm_NameServer;
+
/**
* @brief RM transaction details values. Details values provide more fine-grained
* information regarding a transaction request or response
} Rm_Transaction;
typedef struct {
- const void *allocatorData;
- int32_t allocatorLen;
const void *rangeData;
int32_t rangeLen;
const void *nsAssignData;
int32_t linuxAliasLen;
} Rm_ResourceProperties;
-typedef enum {
- Rm_allocatorType_INTEGER = 0,
- Rm_allocatorType_TREE = 1,
-} Rm_AllocatorType;
-
typedef enum {
Rm_allocatorOp_ALLOCATE = 0,
Rm_allocatorOp_FREE = 1,
Rm_ResourceInfo *resourceInfo;
} Rm_AllocatorOpInfo;
-typedef struct {
- uint32_t value;
- char allocatedTo[RM_INSTANCE_NAME_MAX_CHARS];
-} Rm_IntegerEntry;
-
-typedef struct {
- uint32_t numResourceElements;
- Rm_IntegerEntry *resourceArrayBase;
-} Rm_IntegerAllocatorRootEntry;
-
typedef struct {
char resourceName[RM_RESOURCE_NAME_MAX_CHARS];
- Rm_AllocatorType type;
/** Pointer to the first resource entry in the allocator */
void *allocatorRootEntry;
/** Pointer to next resource allocator */
bool registeredWithDelegateOrServer;
Rm_PolicyHandle policyDtb;
Rm_Allocators allocators;
+ Rm_NameServer nameServer;
/* RM instance transport parameters */
Rm_TransportRouteMap routeMap;
/* RM Transaction sequence number counter */
@@ -211,6 +197,8 @@ Rm_Transaction *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)
int32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId);
uint32_t Rm_transactionGetSequenceNum(Rm_Inst *rmInst);
+void Rm_transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction);
+void Rm_transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction);
void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction);
/**********************************************************************
* malloc'd for each tree that is to be created. */
typedef RB_HEAD(_Rm_ResourceTree, _Rm_ResourceTreeNode) Rm_ResourceTree;
-/* Prototype for function that allocates new tree nodes */
+
Rm_ResourceTreeNode *Rm_newResourceTreeNode(uint32_t resourceBase, uint32_t resourceLength,
char *allocatedTo);
-/* Prototype for function that frees new tree nodes */
void Rm_freeResourceTreeNode(Rm_ResourceTreeNode *treeNode);
/* Prototype for tree node comparison function
* element1 < element2 --> return < 0
index 91b5a3bc99ebbb1adb55e77e00b1ad0348af0c99..8bb33905b0301b71029f79061e47f7d7cffd569c 100644 (file)
/* RM internal includes */
#include <ti/drv/rm/include/rm_loc.h>
+/* AVL BBST includes */
+#include <ti/drv/rm/include/tree.h>
+
#define RM_NS_ACTION_APPROVED 0
+#define RM_NS_OBJECT_FOUND 1
+#define RM_NS_OBJECT_NOT_FOUND 2
+
#define RM_NS_ACTION_DENIED -1
+#define RM_NS_ERROR_NAME_ALREADY_EXISTS -2
+#define RM_NS_ERROR_NAME_DOES_NOT_EXIST -3
+
+int32_t Rm_nsInit(Rm_Inst *rmInst);
+int32_t Rm_nsAddObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo);
+int32_t Rm_nsFindObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo);
+int32_t Rm_nsDeleteObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo);
+
+/**********************************************************************
+ ******************* Red-Black Tree BBST Defines **********************
+ **********************************************************************/
+
+/* Declare the tree structure nodes */
+typedef struct _Rm_NameServerNode {
+ RB_ENTRY(_Rm_NameServerNode) linkage;
+ char name[RM_RESOURCE_NAME_MAX_CHARS];
+ uint32_t base;
+ uint32_t length;
+} Rm_NameServerNode;
+
+/* Declare the tree head structure. */
+typedef RB_HEAD(_Rm_NameServerTree, _Rm_NameServerNode) Rm_NameServerTree;
+
+Rm_NameServerNode *Rm_newNameServerNode(char *name, uint32_t resourceBase,
+ uint32_t resourceLength);
+void Rm_freeNameServerNode(Rm_NameServerNode *node);
+/* Prototype for NameServer node comparison function
+ * element1 < element2 --> return < 0
+ * element1 = element2 --> return 0
+ * element1 > element2 --> return > 0 */
+int Rm_NameServerNodeCompare(Rm_NameServerNode *element1, Rm_NameServerNode *element2);
-int32_t Rm_nsAddObject(Rm_Inst *rmInst, char *objectString, uint32_t objectValue);
-int32_t Rm_nsDeleteObject(Rm_Inst *rmInst, char *objectString);
+/* Generate the tree prototypes */
+RB_PROTOTYPE(_Rm_NameServerTree, _Rm_NameServerNode, linkage, Rm_NameServerNodeCompare);
#ifdef __cplusplus
}
index 6c3899b4aa8f334668b4716a287c25521b30d0dc..163f52495f74cbc0498d9a505a5726e975a6aaaf 100644 (file)
typedef enum {
/** Resource allocation request */
Rm_resReqPktType_ALLOCATE = 0,
- /** Block resource allocation request */
- Rm_resReqPktType_BLOCK_ALLOCATE = 1,
- /** Resource allocate by name */
- Rm_resReqPktType_ALLOCATE_NAMED = 2,
/** Free resource */
- Rm_resReqPktType_FREE = 3,
- /** Free resource block */
- Rm_resReqPktType_BLOCK_FREE = 4,
- /** Free named resource */
- Rm_resReqPktType_FREE_NAMED = 5
+ Rm_resReqPktType_FREE = 1,
+ /** Get name resource */
+ Rm_resReqPktType_GET_NAMED = 2
} Rm_ResourceReqPktType;
/**
diff --git a/rm_services.h b/rm_services.h
index 194969189764e56fe7174697263eb4b678872ff2..5b2a2d9c0f048a28ce8099d048687327de8b6869 100644 (file)
--- a/rm_services.h
+++ b/rm_services.h
#define RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR (RM_SERVICE_ERROR_BASE-11)
/** Invalid NameServer object modification on non-Server instance */
#define RM_SERVICE_ERROR_NAMESERVER_OBJECT_MOD_ON_INVALID_INSTANCE (RM_SERVICE_ERROR_BASE-12)
-
+/** Request failed because both a NameServer name and a resource range were specified */
+#define RM_SERVICE_ERROR_NAMESERVER_NAME_AND_RESOURCE_RANGE_BOTH_DEFINED (RM_SERVICE_ERROR_BASE-13)
/**
* @brief Maximum number of characters in the resource names
* not be used by component. */
Rm_service_FIRST = 0,
/** RM resource allocate service */
- Rm_service_RESOURCE_ALLOCATE = 0,
- /** RM resource block allocate service */
- Rm_service_RESOURCE_BLOCK_ALLOCATE = 1,
- /** RM resource allocate by name service */
- Rm_service_RESOURCE_ALLOCATE_BY_NAME = 2,
+ Rm_service_RESOURCE_ALLOCATE = 0,
/** RM resource free service */
- Rm_service_RESOURCE_FREE = 3,
- /** RM resource block free service */
- Rm_service_RESOURCE_BLOCK_FREE = 4,
- /** RM resource free by name service */
- Rm_service_RESOURCE_FREE_BY_NAME = 5,
+ Rm_service_RESOURCE_FREE = 1,
/** RM resource mapping to name service */
- Rm_service_RESOURCE_MAP_TO_NAME = 6,
+ Rm_service_RESOURCE_MAP_TO_NAME = 2,
+ /** RM resource get by name service */
+ Rm_service_RESOURCE_GET_BY_NAME = 3,
/** RM resource name unmapping service */
- Rm_service_RESOURCE_UNMAP_NAME = 7,
+ Rm_service_RESOURCE_UNMAP_NAME = 4,
/** Last service type. Used by RM for bounds checking. Should
* not be used by component. */
- Rm_service_LAST = 7
+ Rm_service_LAST = 4
} Rm_ServiceType;
/**
diff --git a/src/rm.c b/src/rm.c
index 3947f68b1c8faf2024bf54703fe3026b4eb2a65c..15f3d6dc533f4732ca6ef2a365e0d25f24c19426 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
return (sequenceNum);\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->sourceInstName);\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_BLOCK_ALLOCATE:\r
- case Rm_service_RESOURCE_ALLOCATE_BY_NAME:\r
- case Rm_service_RESOURCE_FREE:\r
- case Rm_service_RESOURCE_BLOCK_FREE:\r
- case Rm_service_RESOURCE_FREE_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
-Rm_Allocator *Rm_allocatorAdd(Rm_Inst *rmInst, const char *resourceName, Rm_AllocatorType type)\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
@@ -377,7 +313,6 @@ Rm_Allocator *Rm_allocatorAdd(Rm_Inst *rmInst, const char *resourceName, Rm_Allo
memset((void *)newAllocator, 0, sizeof(Rm_Allocator));\r
\r
/* Populate the allocator */\r
- newAllocator->type = type;\r
strcpy(newAllocator->resourceName, resourceName);\r
/* allocator's root entry will be created by the invoking function */\r
newAllocator->allocatorRootEntry = NULL;\r
return (retVal);\r
}\r
\r
-int32_t Rm_createIntegerAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)\r
-{\r
- Rm_Allocator *allocator = NULL;\r
- Rm_ResourceRange *rangeBasePtr = range;\r
- Rm_IntegerAllocatorRootEntry *intRootEntry = NULL;\r
- uint16_t i, entryIndex;\r
-\r
- /* Create the new base integer allocator */\r
- allocator = Rm_allocatorAdd(rmInst, resourceName, Rm_allocatorType_INTEGER);\r
-\r
- /* Construct the integer allocator root entry */\r
- intRootEntry = Rm_osalMalloc(sizeof(Rm_IntegerAllocatorRootEntry));\r
- intRootEntry->numResourceElements = 0;\r
-\r
- /* Get the number of entries to allocate based on the lengths in the ranges */\r
- while (range != NULL)\r
- {\r
- intRootEntry->numResourceElements += range->length;\r
- range = range->nextRange;\r
- }\r
-\r
- /* Initialize the entries using the range information */\r
- if (intRootEntry->numResourceElements)\r
- {\r
- intRootEntry->resourceArrayBase = Rm_osalMalloc(sizeof(Rm_IntegerEntry) * intRootEntry->numResourceElements);\r
- memset((void *)intRootEntry->resourceArrayBase, 0, sizeof(Rm_IntegerEntry) * intRootEntry->numResourceElements);\r
-\r
- /* Reset the range pointer */\r
- range = rangeBasePtr;\r
- entryIndex = 0;\r
-\r
- while (range != NULL)\r
- {\r
- /* Initialize each entry */\r
- for (i = range->base; i < (range->base + range->length); i++, entryIndex++)\r
- {\r
- intRootEntry->resourceArrayBase[entryIndex].value = i;\r
- /* Initialize the allocatedTo field to the NOT_ALLOCATED string */\r
- strcpy(intRootEntry->resourceArrayBase[entryIndex].allocatedTo, RM_NOT_ALLOCATED_STRING);\r
- }\r
- \r
- range = range->nextRange;\r
- }\r
- \r
- allocator->allocatorRootEntry = intRootEntry;\r
- }\r
- else\r
- {\r
- /* No resource entries were created. Free the memory associated with the\r
- * allocator and the root entry */\r
- Rm_osalFree((void *)intRootEntry, sizeof(Rm_IntegerAllocatorRootEntry));\r
- Rm_allocatorDelete(rmInst, allocator->resourceName);\r
- }\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_integerPreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
-{\r
- Rm_IntegerAllocatorRootEntry *root = allocator->allocatorRootEntry;\r
- Rm_IntegerEntry *resourceArray = root->resourceArrayBase;\r
- uint16_t index, i;\r
- bool resourcesValidated;\r
- int32_t retVal = RM_SERVICE_PROCESSING;\r
-\r
- /* Find the specified resource base within the allocator */\r
- for (index = 0; index < root->numResourceElements; index++)\r
- {\r
- if (resourceArray[index].value == opInfo->resourceInfo->base)\r
- {\r
- /* Found the resource base in the allocator. Break from the loop */\r
- break;\r
- }\r
- } \r
-\r
- /* Only execute the allocate operation if the resource base was found in the allocator\r
- * and the base+length does not exceed the number of entries in the allocator */\r
- if ((index + opInfo->resourceInfo->length) <= root->numResourceElements)\r
- {\r
- /* Search for a contiguous block of unallocated resources of length "length"\r
- * and with the alignment specified */\r
- while ((index + opInfo->resourceInfo->length) <= root->numResourceElements)\r
- {\r
- resourcesValidated = FALSE; \r
- \r
- /* Does the resource base value satisfy the alignment? */\r
- if ((resourceArray[index].value % opInfo->resourceInfo->alignment) == 0)\r
- {\r
- /* Check to see all the resource values in the requested range are free */\r
- resourcesValidated = TRUE;\r
- for (i = index; i < opInfo->resourceInfo->length; i++)\r
- {\r
- if (strcmp(resourceArray[i].allocatedTo, RM_NOT_ALLOCATED_STRING) != 0)\r
- {\r
- /* A resource within the range was already allocated. Update the\r
- * index to the resource after the allocated resource and continue \r
- * looking. */\r
- index = i + 1;\r
- resourcesValidated = FALSE;\r
- /* Break out of the for loop */\r
- break;\r
- }\r
- }\r
-\r
- if (resourcesValidated)\r
- {\r
- /* Found a set of resources that satisfies the request requirements. Return\r
- * the results to be tested against the policy. If the policy approves the\r
- * resources will be allocated via the Rm_integerAllocate API. */\r
- opInfo->resourceInfo->base = resourceArray[index].value;\r
- /* Break out of the while loop */\r
- break;\r
- }\r
- }\r
- else\r
- {\r
- /* Jump to the next resource value that satisfies the alignment */\r
- for (; index < root->numResourceElements; index++)\r
- {\r
- if ((resourceArray[index].value % opInfo->resourceInfo->alignment) == 0)\r
- {\r
- /* Found the next resource value that satisfies the alignment */\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (!resourcesValidated)\r
- {\r
- retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
- }\r
- }\r
- else\r
- {\r
- retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
- }\r
-\r
- return(retVal); \r
-}\r
-\r
-/* Assumes resource range for allocation has already been approved by the policy */\r
-int32_t Rm_integerAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
-{\r
- Rm_IntegerAllocatorRootEntry *root = allocator->allocatorRootEntry;\r
- uint16_t resourceIndex, i, j;\r
- bool resourcesValidated = TRUE;\r
- int32_t retVal;\r
-\r
- /* Find the specified resource base within the allocator */\r
- for (resourceIndex = 0; resourceIndex < root->numResourceElements; resourceIndex++)\r
- {\r
- if (root->resourceArrayBase[resourceIndex].value == opInfo->resourceInfo->base)\r
- {\r
- /* Found the resource base in the allocator. Break from the loop */\r
- break;\r
- }\r
- }\r
-\r
- /* Only execute the allocate operation if the resource base was found in the allocator\r
- * and the base+length does not exceed the number of entries in the allocator */\r
- if ((resourceIndex + opInfo->resourceInfo->length) <= root->numResourceElements)\r
- {\r
- /* Verify all resource values from base to base+length exist in the allocator and\r
- * are not allocated to another instance. */\r
- for (i = resourceIndex, j = opInfo->resourceInfo->base; \r
- i < (resourceIndex + opInfo->resourceInfo->length);\r
- i++, j++)\r
- {\r
- if (root->resourceArrayBase[i].value != j)\r
- {\r
- /* A value in the range did not match. */\r
- retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
- resourcesValidated = FALSE;\r
- break;\r
- }\r
- else if (strcmp(root->resourceArrayBase[i].allocatedTo, RM_NOT_ALLOCATED_STRING) != 0)\r
- {\r
- /* A value in the range is already allocated. */\r
- retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
- resourcesValidated = FALSE;\r
- break; \r
- }\r
- }\r
-\r
- if (resourcesValidated)\r
- {\r
- /* Allocate all resources from base to base+length */\r
- for (i = resourceIndex; i < (resourceIndex + opInfo->resourceInfo->length); i++)\r
- {\r
- strcpy(root->resourceArrayBase[i].allocatedTo, opInfo->srcInstName);\r
- }\r
- retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
- }\r
- }\r
- else\r
- {\r
- retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
- }\r
-\r
- return(retVal); \r
-}\r
-\r
-/* Assumes resource range for free has already been approved by the policy */\r
-int32_t Rm_integerFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
-{\r
- Rm_IntegerAllocatorRootEntry *root = allocator->allocatorRootEntry;\r
- uint16_t resourceIndex, i, j;\r
- bool resourcesValidated = TRUE;\r
- int32_t retVal;\r
-\r
- /* Find the specified resource base within the allocator */\r
- for (resourceIndex = 0; resourceIndex < root->numResourceElements; resourceIndex++)\r
- {\r
- if (root->resourceArrayBase[resourceIndex].value == opInfo->resourceInfo->base)\r
- {\r
- /* Found the resource base in the allocator. Break from the loop */\r
- break;\r
- }\r
- }\r
-\r
- /* Only execute the free operation if the resource base was found in the allocator\r
- * and the base+length does not exceed the number of entries in the allocator */\r
- if ((resourceIndex + opInfo->resourceInfo->length) <= root->numResourceElements)\r
- {\r
- /* Verify all resource values from base to base+length exist in the allocator,\r
- * were not already free and were allocated to the instance that is the source\r
- * of the free request. */\r
- for (i = resourceIndex, j = opInfo->resourceInfo->base; \r
- i < (resourceIndex + opInfo->resourceInfo->length);\r
- i++, j++)\r
- {\r
- if (root->resourceArrayBase[i].value != j)\r
- {\r
- /* A value in the range did not match. */\r
- retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
- resourcesValidated = FALSE;\r
- break;\r
- }\r
- else if (strcmp(root->resourceArrayBase[i].allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
- {\r
- /* A value in the range is already free. */\r
- retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_FREE;\r
- resourcesValidated = FALSE;\r
- break; \r
- } \r
- else if (strcmp(root->resourceArrayBase[i].allocatedTo, opInfo->srcInstName) != 0)\r
- {\r
- /* A value in the range was not allocated to the source of\r
- * the free request */\r
- retVal = RM_SERVICE_DENIED_RESOURCE_NOT_ALLOCATED_TO_INSTANCE_REQUESTING_THE_SERVICE;\r
- resourcesValidated = FALSE;\r
- break;\r
- }\r
- }\r
-\r
- if (resourcesValidated)\r
- {\r
- /* Free all resources from base to base+length */\r
- for (i = resourceIndex; i < (resourceIndex + opInfo->resourceInfo->length); i++)\r
- {\r
- strcpy(root->resourceArrayBase[i].allocatedTo, RM_NOT_ALLOCATED_STRING);\r
- }\r
- retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
- }\r
- }\r
- else\r
- {\r
- retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
- }\r
-\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
@@ -775,7 +431,7 @@ int32_t Rm_createTreeAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_Res
Rm_ResourceTreeNode *collidingNode = NULL;\r
\r
/* Create the new base integer allocator */\r
- allocator = Rm_allocatorAdd(rmInst, resourceName, Rm_allocatorType_TREE);\r
+ allocator = Rm_allocatorAdd(rmInst, resourceName);\r
\r
/* Create the tree root entry and initialize it */\r
treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));\r
@@ -832,7 +488,16 @@ int32_t Rm_treePreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
int32_t retVal = RM_SERVICE_PROCESSING;\r
\r
/* Find the tree node that contains the first value in the specified policy range. */\r
- findNode.base = opInfo->policyBase;\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
\r
if (allocator)\r
{\r
- /* Call the allocator's type-based allocation function */\r
- if(allocator->type == Rm_allocatorType_INTEGER)\r
+ /* Call the allocator's function */\r
+ if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE)\r
{\r
- if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE)\r
- {\r
- retVal = Rm_integerPreAllocate(allocator, opInfo);\r
- } \r
- else if (opInfo->operation == Rm_allocatorOp_ALLOCATE)\r
- {\r
- retVal = Rm_integerAllocate(allocator, opInfo);\r
- }\r
- else if (opInfo->operation == Rm_allocatorOp_FREE)\r
- {\r
- retVal = Rm_integerFree(allocator, opInfo);\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 (allocator->type == Rm_allocatorType_TREE)\r
+ else if (opInfo->operation == Rm_allocatorOp_FREE)\r
{\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
+ retVal = Rm_treeFree(allocator, opInfo);\r
+ } \r
}\r
else\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
-#if 0 \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
else if (rmInst->instType == Rm_instType_SERVER)\r
{\r
-#if 0 \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.srcInstName = transaction->sourceInstName;\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)\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->sourceInstName, 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
void Rm_freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
{\r
+ Rm_AllocatorOpInfo opInfo;\r
+ int32_t retVal = transaction->state;\r
+ \r
if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
{\r
-#if 0 \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
else if (rmInst->instType == Rm_instType_SERVER)\r
{\r
-#if 0 \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.srcInstName = transaction->sourceInstName;\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)\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->sourceInstName, 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
} \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->sourceInstName);\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
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
switch (transaction->type)\r
{\r
case Rm_service_RESOURCE_ALLOCATE:\r
- case Rm_service_RESOURCE_BLOCK_ALLOCATE:\r
- case Rm_service_RESOURCE_ALLOCATE_BY_NAME:\r
case Rm_service_RESOURCE_FREE:\r
- case Rm_service_RESOURCE_BLOCK_FREE:\r
- case Rm_service_RESOURCE_FREE_BY_NAME:\r
+ case Rm_service_RESOURCE_GET_BY_NAME:\r
rmPkt = Rm_transportCreateResourceReqPkt(rmInst, dstTransportNode, \r
transaction);\r
break;\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
switch (transaction->type)\r
{\r
case Rm_service_RESOURCE_ALLOCATE:\r
- case Rm_service_RESOURCE_BLOCK_ALLOCATE:\r
- case Rm_service_RESOURCE_ALLOCATE_BY_NAME:\r
- case Rm_service_RESOURCE_FREE:\r
- case Rm_service_RESOURCE_BLOCK_FREE:\r
- case Rm_service_RESOURCE_FREE_BY_NAME: \r
+ case Rm_service_RESOURCE_FREE: \r
/* Check if the transaction is fulfilled request */\r
if (transaction->state != RM_SERVICE_PROCESSING)\r
{\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
- (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||\r
- (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME))\r
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE)\r
{\r
Rm_allocationHandler(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
/* 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.nsName,\r
- transaction->resourceInfo.base) == RM_NS_ACTION_APPROVED)\r
+ if (Rm_nsAddObject(rmInst, &transaction->resourceInfo) == RM_NS_ACTION_APPROVED)\r
{\r
transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
}\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.nsName) == \r
+ if (Rm_nsDeleteObject(rmInst, &transaction->resourceInfo) == \r
RM_NS_ACTION_APPROVED)\r
{\r
transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
@@ -1945,38 +1786,22 @@ int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName
int32_t Rm_createAndInitAllocator(Rm_Inst *rmInst, const char *resourceName, \r
Rm_ResourceProperties *resourceProperties, void *linuxDtb)\r
{\r
- char *allocatorType = NULL;\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
/* TODO: NEED CHECKS FOR VALIDITY OF ALL THE resourceProperties FIELDS */\r
\r
/* Extract the resource properties from the DTB */\r
- allocatorType = Rm_resourceExtractAllocator(resourceProperties->allocatorData, \r
- resourceProperties->allocatorLen);\r
range = rangeBasePtr = Rm_resourceExtractRange(resourceProperties->rangeData, \r
resourceProperties->rangeLen);\r
\r
- /* Create an allocator based on the allocator type specified */\r
- if (strcmp(allocatorType, &rmIntegerAllocator[0]) == 0)\r
- {\r
- /* Create an integer allocator using the resource properties */\r
- retVal = Rm_createIntegerAllocator(rmInst, resourceName, range); \r
- }\r
- else if (strcmp(allocatorType, &rmTreeAllocator[0]) == 0)\r
- {\r
- /* Create a tree allocator using the resource properties */\r
- retVal = Rm_createTreeAllocator(rmInst, resourceName, range); \r
- }\r
- else\r
- {\r
- /* Allocator type not recognized. Free the resource properties and return */\r
- retVal = -21; /* TEMP ERROR: Can't conflict with LIBFDT errors */\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
nsAssignmentBasePtr = nsAssignments;\r
while (nsAssignments)\r
{\r
+ memset((void *)&resourceInfo, 0, sizeof(Rm_ResourceInfo));\r
+\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, nsAssignments->nsName, nsAssignments->resourceValue);\r
+ Rm_nsAddObject(rmInst, &resourceInfo);\r
nsAssignments = nsAssignments->nextNsAssignment;\r
}\r
/* Free the memory allocated for the NameServer assignments */\r
}\r
\r
/* Free the memory allocated for the resource properties */\r
- Rm_resourceFreeAllocator(allocatorType);\r
Rm_resourceFreeRange(rangeBasePtr);\r
Rm_resourceFreeLinuxAlias(linuxAlias);\r
\r
@@ -2032,22 +1862,7 @@ int32_t Rm_parseResourceProperty(void *globalResourceDtb, int32_t offset, Rm_Res
if (propertyData)\r
{\r
propertyType = Rm_resourceGetPropertyType(propertyName);\r
- if (propertyType == Rm_resourcePropType_RESOURCE_ALLOCATOR)\r
- {\r
- if (propertyInfo->allocatorData || propertyInfo->allocatorLen)\r
- {\r
- /* The allocator 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 = -17; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
- }\r
- else\r
- {\r
- propertyInfo->allocatorData = propertyData;\r
- propertyInfo->allocatorLen = propertyLen;\r
- }\r
- }\r
- else if (propertyType == Rm_resourcePropType_RESOURCE_RANGE)\r
+ if (propertyType == Rm_resourcePropType_RESOURCE_RANGE)\r
{\r
if (propertyInfo->rangeData || propertyInfo->rangeLen)\r
{\r
@@ -2194,12 +2009,9 @@ int32_t Rm_initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb, void *
void Rm_printResourceStatus(Rm_Inst *rmInst)\r
{\r
Rm_Allocator *allocator = rmInst->allocators;\r
- Rm_IntegerAllocatorRootEntry *integerRoot;\r
- Rm_IntegerEntry *integerEntry;\r
Rm_ResourceTree *treeRoot;\r
Rm_ResourceTreeNode *treeNode;\r
uint32_t numLinuxResources;\r
- uint32_t i;\r
\r
while (allocator != NULL)\r
{\r
\r
Rm_osalLog("Resource: %s\n", allocator->resourceName);\r
\r
- if (allocator->type == Rm_allocatorType_INTEGER)\r
- {\r
- integerRoot = allocator->allocatorRootEntry;\r
- integerEntry = integerRoot->resourceArrayBase;\r
+ treeRoot = allocator->allocatorRootEntry;\r
\r
- for (i = 0; i < integerRoot->numResourceElements; i++)\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
- if (strcmp(integerEntry[i].allocatedTo, RM_ALLOCATED_TO_LINUX) == 0)\r
- {\r
- Rm_osalLog("Value: %5d reserved for %s\n", integerEntry[i].value, \r
- integerEntry[i].allocatedTo);\r
- numLinuxResources++;\r
- }\r
+ Rm_osalLog("NOT ALLOCATED\n");\r
+ }\r
+ else\r
+ {\r
+ Rm_osalLog("allocated to %s\n", treeNode->allocatedTo);\r
}\r
- }\r
- else if (allocator->type == Rm_allocatorType_TREE)\r
- {\r
- treeRoot = allocator->allocatorRootEntry;\r
-\r
- RB_FOREACH(treeNode, _Rm_ResourceTree, treeRoot)\r
- { \r
- Rm_osalLog(" %5d - %5d ", 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
+ if (strcmp(treeNode->allocatedTo, RM_ALLOCATED_TO_LINUX) == 0)\r
+ {\r
+ numLinuxResources += treeNode->length;\r
}\r
}\r
- else\r
- {\r
- Rm_osalLog("Error: Unknown allocator type\n");\r
- }\r
\r
Rm_osalLog("Total allocated to Linux: %d\n", numLinuxResources);\r
\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_printResourceStatus(rmInst);\r
}\r
+\r
+ /* Initialize the NameServer */\r
+ Rm_nsInit(rmInst);\r
}\r
\r
/* Instance startup policies are only used for Servers and Client Delegates */\r
diff --git a/src/rm_dtb_util.c b/src/rm_dtb_util.c
index 1c381dc42d7e4187f391130f9fdeab6f6291e85d..fc10988437d90895ae548f8b253d26e9dee12c52 100644 (file)
--- a/src/rm_dtb_util.c
+++ b/src/rm_dtb_util.c
* listed in the Device Resource List */
char rmResourceDeviceNameProp[] = "device-name";
char rmResourceRangeProp[] = "resource-range";
-char rmResourceAllocatorProp[] = "allocator";
char rmResourceLinuxAliasProp[] = "linux-dtb-alias";
char rmResourceLinuxAliasCompletionString[] = "end";
char rmResourceNsAssignmentProp[] = "ns-assignment";
{
propertyType = Rm_resourcePropType_RESOURCE_RANGE;
}
- else if(strcmp(rmResourceAllocatorProp, propertyName) == 0)
- {
- propertyType = Rm_resourcePropType_RESOURCE_ALLOCATOR;
- }
else if(strcmp(rmResourceLinuxAliasProp, propertyName) == 0)
{
propertyType = Rm_resourcePropType_RESOURCE_LINUX_ALIAS;
Rm_commonFreeRangeList(rangeList);
}
-/* MODIFY TO RETURN AN ALLOCATOR TYPE INSTEAD OF A STRING??? */
-char *Rm_resourceExtractAllocator(const void *dtbDataPtr, int32_t dtbDataLen)
-{
- return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
-}
-
-void Rm_resourceFreeAllocator(char *resourceAllocatorType)
-{
- Rm_commonFreeName(resourceAllocatorType);
-}
-
Rm_LinuxAlias *Rm_resourceExtractLinuxAlias(const void *dtbDataPtr, int32_t dtbDataLen)
{
uint8_t *aliasData = (uint8_t *)dtbDataPtr;
newAssignment->nsName = (char *) Rm_osalMalloc(nameLenBytes);
strcpy(newAssignment->nsName, ((char *) &dtbNsAssignmentData[i]));
- /* Extract the 32-bit value */
+ /* Extract the 32-bit base value */
i += nameLenBytes;
extractedValueBytePtr = (uint8_t *)&extractedValue;
for (j = 0; j < sizeof(uint32_t); j++, i++)
@@ -370,7 +354,15 @@ Rm_NsAssignment *Rm_resourceExtractNsAssignment(const void *dtbDataPtr, int32_t
extractedValueBytePtr[j] = dtbNsAssignmentData[i];
}
/* flip the endianness */
- newAssignment->resourceValue = fdt32_to_cpu(extractedValue);
+ newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
+
+ /* Extract the 32-bit length value */
+ for (j = 0; j < sizeof(uint32_t); j++, i++)
+ {
+ extractedValueBytePtr[j] = dtbNsAssignmentData[i];
+ }
+ /* flip the endianness */
+ newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
newAssignment->nextNsAssignment = NULL;
diff --git a/src/rm_nameserver.c b/src/rm_nameserver.c
index 858a9931974ad65684eca59072ff6eb779f68027..9d1f2b54d9be30e53bbba6a4f939408eed427f1c 100644 (file)
--- a/src/rm_nameserver.c
+++ b/src/rm_nameserver.c
#include <ti/drv/rm/include/rm_loc.h>
#include <ti/drv/rm/include/rm_nameserverloc.h>
+/* AVL BBST includes */
+#include <ti/drv/rm/include/tree.h>
+
/* RM OSAL layer */
#include <rm_osal.h>
+/**********************************************************************
+ ************** Red-Black BBST Tree NameServer Functions **************
+ **********************************************************************/
+
+Rm_NameServerNode *Rm_newNameServerNode(char *name, uint32_t resourceBase,
+ uint32_t resourceLength)
+{
+ Rm_NameServerNode *newNode = NULL;
+
+ newNode = Rm_osalMalloc(sizeof(Rm_NameServerNode));
+
+ /* Populate the node */
+ strcpy(newNode->name, name);
+ newNode->base = resourceBase;
+ newNode->length = resourceLength;
+
+ return(newNode);
+}
+
+void Rm_freeNameServerNode(Rm_NameServerNode *node)
+{
+ /* Free the memory associated with the tree node. */
+ Rm_osalFree((void *)node, sizeof(Rm_NameServerNode));
+}
+
+/* Prototype for tree node comparison function
+ * element1 < element2 --> return < 0
+ * element1 = element2 --> return 0
+ * element1 > element2 --> return > 0 */
+int Rm_NameServerNodeCompare(Rm_NameServerNode *element1, Rm_NameServerNode *element2)
+{
+ return(strcmp(element1->name, element2->name));
+}
+
+/* Generate the red-black tree manipulation functions */
+RB_GENERATE(_Rm_NameServerTree, _Rm_NameServerNode, linkage, Rm_NameServerNodeCompare);
+
/**********************************************************************
********************** Internal Functions ****************************
**********************************************************************/
-int32_t Rm_nsAddObject(Rm_Inst *rmInst, char *objectString, uint32_t objectValue)
+int32_t Rm_nsInit(Rm_Inst *rmInst)
{
- /* STUB APPROVED FOR NOW */
+ Rm_NameServerTree *rootEntry = NULL;
+
+ /* Create the NameServer root entry and initialize it */
+ rootEntry = Rm_osalMalloc(sizeof(Rm_NameServerTree));
+ RB_INIT(rootEntry);
+
+ rmInst->nameServer = (void *)rootEntry;
+
return(RM_NS_ACTION_APPROVED);
+}
+int32_t Rm_nsAddObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo)
+{
+ Rm_NameServerNode *newNode = NULL;
+ Rm_NameServerNode *collidingNode = NULL;
+
+ newNode = Rm_newNameServerNode(resourceInfo->nsName, resourceInfo->base,
+ resourceInfo->length);
+
+ /* Try to insert the new name */
+ collidingNode = RB_INSERT(_Rm_NameServerTree, rmInst->nameServer, newNode);
+
+ if (collidingNode)
+ {
+ Rm_freeNameServerNode(newNode);
+ return(RM_NS_ERROR_NAME_ALREADY_EXISTS);
+ }
+
+ return(RM_NS_ACTION_APPROVED);
}
-int32_t Rm_nsDeleteObject(Rm_Inst *rmInst, char *objectString)
+int32_t Rm_nsFindObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo)
{
+ Rm_NameServerNode findNode;
+ Rm_NameServerNode *matchingNode = NULL;
+
+ /* Copy the name to find into the find node structure */
+ strcpy(findNode.name, resourceInfo->nsName);
+
+ matchingNode = RB_FIND(_Rm_NameServerTree, rmInst->nameServer, &findNode);
+
+ if (matchingNode)
+ {
+ /* Copy the name's resource information */
+ resourceInfo->base = matchingNode->base;
+ resourceInfo->length = matchingNode->length;
+ }
+ else
+ {
+ return(RM_NS_ERROR_NAME_DOES_NOT_EXIST);
+ }
+
+ /* STUB APPROVED FOR NOW */
+ return(RM_NS_ACTION_APPROVED);
+}
+
+int32_t Rm_nsDeleteObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo)
+{
+ Rm_NameServerNode findNode;
+ Rm_NameServerNode *matchingNode = NULL;
+
+ /* Copy the name to find into the find node structure */
+ strcpy(findNode.name, resourceInfo->nsName);
+
+ matchingNode = RB_FIND(_Rm_NameServerTree, rmInst->nameServer, &findNode);
+
+ if (matchingNode)
+ {
+ /* Remove the name from the NameServer */
+ RB_REMOVE(_Rm_NameServerTree, rmInst->nameServer, matchingNode);
+ Rm_freeNameServerNode(matchingNode);
+ }
+ else
+ {
+ return(RM_NS_ERROR_NAME_DOES_NOT_EXIST);
+ }
+
/* STUB APPROVED FOR NOW */
return(RM_NS_ACTION_APPROVED);
}
diff --git a/src/rm_services.c b/src/rm_services.c
index 6d413246b2b2fb29f45f8993439bff3057462cd3..bbecd4dfc0c556087f2c2ad0f9c92e80131ca9cb 100644 (file)
--- a/src/rm_services.c
+++ b/src/rm_services.c
/* Service was approved and service was an allocate request the resource
* data is passed back to the component */
if ((transaction->type == Rm_service_RESOURCE_ALLOCATE) ||
- (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||
- (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME))
+ (transaction->type == Rm_service_RESOURCE_GET_BY_NAME))
{
serviceResponse->resourceBase = transaction->resourceInfo.base;
serviceResponse->resourceLength = transaction->resourceInfo.length;
* data is passed back to the component */
if ((serviceResponse.serviceState == RM_SERVICE_APPROVED_AND_COMPLETED) &&
((transaction->type == Rm_service_RESOURCE_ALLOCATE) ||
- (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||
- (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME)))
+ (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)))
{
serviceResponse.resourceBase = transaction->resourceInfo.base;
serviceResponse.resourceLength = transaction->resourceInfo.length;
diff --git a/src/rm_transport.c b/src/rm_transport.c
index 8c49337b3cdd74575cbe1d3a80045faa4a59bda8..fca00691db4a5e418520b04f7c391ce8bfe6cefc 100644 (file)
--- a/src/rm_transport.c
+++ b/src/rm_transport.c
@@ -261,25 +261,13 @@ Rm_Packet *Rm_transportCreateResourceReqPkt(Rm_Inst *rmInst, Rm_TransportNode *d
{\r
resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE;\r
}\r
- else if (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE)\r
- {\r
- resourceReqPkt->resourceReqType = Rm_resReqPktType_BLOCK_ALLOCATE;\r
- }\r
- else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME)\r
- {\r
- resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_NAMED;\r
- }\r
else if (transaction->type == Rm_service_RESOURCE_FREE)\r
{\r
resourceReqPkt->resourceReqType = Rm_resReqPktType_FREE;\r
}\r
- else if (transaction->type == Rm_service_RESOURCE_BLOCK_FREE)\r
+ else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)\r
{\r
- resourceReqPkt->resourceReqType = Rm_resReqPktType_BLOCK_FREE;\r
- }\r
- else if (transaction->type == Rm_service_RESOURCE_FREE_BY_NAME)\r
- {\r
- resourceReqPkt->resourceReqType = Rm_resReqPktType_FREE_NAMED;\r
+ resourceReqPkt->resourceReqType = Rm_resReqPktType_GET_NAMED;\r
}\r
strcpy(&(resourceReqPkt->instName)[0], rmInst->name);\r
/* Copy the resource data */\r
{\r
transaction->type = Rm_service_RESOURCE_ALLOCATE;\r
}\r
- else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_BLOCK_ALLOCATE)\r
- {\r
- transaction->type = Rm_service_RESOURCE_BLOCK_ALLOCATE;\r
- }\r
- else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE_NAMED)\r
- {\r
- transaction->type = Rm_service_RESOURCE_ALLOCATE_BY_NAME;\r
- }\r
else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_FREE)\r
{\r
transaction->type = Rm_service_RESOURCE_FREE;\r
}\r
- else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_BLOCK_FREE)\r
+ else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_GET_NAMED)\r
{\r
- transaction->type = Rm_service_RESOURCE_BLOCK_FREE;\r
- }\r
- else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_FREE_NAMED)\r
- {\r
- transaction->type = Rm_service_RESOURCE_FREE_BY_NAME;\r
- }\r
+ transaction->type = Rm_service_RESOURCE_GET_BY_NAME;\r
+ } \r
\r
strcpy(transaction->sourceInstName, resourceReqPkt->instName);\r
transaction->state = RM_SERVICE_PROCESSING;\r
\r
if ((transaction->state == RM_SERVICE_APPROVED_AND_COMPLETED) &&\r
((transaction->type == Rm_service_RESOURCE_ALLOCATE) ||\r
- (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||\r
- (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME)))\r
+ (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)))\r
{\r
/* Copy resources from request for allocations since an allocation\r
* can be specified as unknown. If the request resources were unspecified\r