summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9b932e7)
raw | patch | inline | side by side (parent: 9b932e7)
author | Justin Sobota <jsobota@ti.com> | |
Fri, 9 Nov 2012 23:37:52 +0000 (18:37 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Fri, 9 Nov 2012 23:37:52 +0000 (18:37 -0500) |
include/rmloc.h | [moved from include/rm_pvt.h with 61% similarity] | patch | blob | history |
include/rmtransportloc.h | [new file with mode: 0644] | patch | blob |
resource_table_defs.h | [deleted file] | patch | blob | history |
rm.h | patch | blob | history | |
rmservices.h | [moved from rm_services.h with 65% similarity] | patch | blob | history |
rmtransport.h | [moved from rm_transport.h with 58% similarity] | patch | blob | history |
rmtypes.h | [moved from rm_types.h with 95% similarity] | patch | blob | history |
src/rm.c | patch | blob | history | |
src/rmservices.c | [new file with mode: 0644] | patch | blob |
src/rmtransport.c | [new file with mode: 0644] | patch | blob |
diff --git a/include/rm_pvt.h b/include/rmloc.h
similarity index 61%
rename from include/rm_pvt.h
rename to include/rmloc.h
index 3b2ef1fb5778ec97d9ae27d7a7292deb239172c9..3347a36cd7acc051505c3133f31dca9a55902a55 100644 (file)
rename from include/rm_pvt.h
rename to include/rmloc.h
index 3b2ef1fb5778ec97d9ae27d7a7292deb239172c9..3347a36cd7acc051505c3133f31dca9a55902a55 100644 (file)
--- a/include/rm_pvt.h
+++ b/include/rmloc.h
/*
- * file rm_pvt.h
+ * file rmloc.h
*
- * Private data structures of Resource Manager.
+ * General private data structures of Resource Manager.
*
* ============================================================================
* (C) Copyright 2012, Texas Instruments, Inc.
* \par
*/
-#ifndef RM_PVT_H_
-#define RM_PVT_H_
+#ifndef RMLOC_H_
+#define RMLOC_H_
#ifdef __cplusplus
extern "C" {
/* Device Include */
#include <c6x.h>
-/* RM includes */
-#include <ti/drv/rm/rm_services.h>
-#include <ti/drv/rm/rm_policy.h>
-#include <ti/drv/rm/rm_transport.h>
+/* RM external includes */
+#include <ti/drv/rm/rmservices.h>
+#include <ti/drv/rm/rmpolicy.h>
+#include <ti/drv/rm/rmtransport.h>
+
+/* RM internal includes */
+#include <ti/drv/rm/include/rmtransportloc.h>
/* RM permissions structure for CPPI DMA channels and flows */
typedef struct
/** Maximum number of characters allowed for instance names */
#define RM_INSTANCE_NAME_MAX_CHARS 24
-
-/** Assigned to the Start/EndIndex entries in the protocol packet to request
- * the next available resource instead of a specific index */
-#define RM_NEXT_AVAILABLE_RESOURCE (-1)
-
/** Maximum size of a transmittable RM policy in bytes */
#define RM_MAX_POLICY_SIZE_BYTES (64) // Placeholder: This will change
// during development
-/** Pointer to RM instance's transport routing map */
-typedef void *Rm_TransRouteMap;
-
/** Pointer to RM instance's transaction queue */
typedef void *Rm_TransactionQueue;
-/**
- * @brief RM transport routing map linked list node
- */
-typedef struct {
- /** Transport handle associated with this node */
- Rm_TransportHandle transHandle;
- /** The remote RM instance type associated with this node */
- Rm_InstType remoteInstType;
- /** Link to the next route node in the route map list */
- Rm_TransRouteMapNode *nextNode;
-} Rm_TransRouteMapNode;
-
-/**
- * @brief RM protocol commands. The first N commands should be synchronized with
- * the Rm_ServiceType enum in rm_service.h
- */
-typedef enum {
- /** Resource allocation request */
- Rm_command_ALLOCATE = Rm_service_RESOURCE_ALLOCATE,
- /** Block resource allocation request */
- Rm_command_BLOCK_ALLOCATE = Rm_service_RESOURCE_BLOCK_ALLOCATE,
- /** Resource allocate by name */
- Rm_command_ALLOCATE_NAMED = Rm_service_RESOURCE_ALLOCATE_BY_NAME,
- /** Free resource */
- Rm_command_FREE = Rm_service_RESOURCE_FREE,
- /** Free resource block */
- Rm_command_BLOCK_FREE = Rm_service_RESOURCE_BLOCK_FREE,
- /** Free named resource */
- Rm_command_FREE_NAMED = Rm_service_RESOURCE_FREE_BY_NAME,
- /** Map provided name to specified resource index */
- Rm_command_MAP_NAME = Rm_service_RESOURCE_MAP_TO_NAME,
- /** Unmap provided name from tied resource */
- Rm_command_UNMAP_NAME = Rm_service_RESOURCE_UNMAP_NAME,
- /** Get the status of the specified resource */
- Rm_command_RESOURCE_STATUS = Rm_service_RESOURCE_STATUS,
- /** Resource response - Response applies to all above resource commands */
- Rm_command_RESOURCE_RESPONSE,
- /** Policy request */
- Rm_command_POLICY_REQUEST,
- /** Policy response */
- Rm_command_POLICY_RESPONSE
-} Rm_Command;
-
/**
* @brief RM transaction details values. Details values provide more fine-grained
* information regarding a transaction request or response
*/
typedef enum {
- /** No details provided for transaction */
- Rm_transactionDetials_NONE = 0,
+ /** Transaction is being processed */
+ Rm_transactionState_PROCESSING = 0,
+ /** Transaction is waiting for response from higher level agent */
+ Rm_transactionState_AWAITING_RESPONSE = 1,
/** Transaction has been approved */
- Rm_transactionDetails_RESOURCE_APPROVED = 1,
+ Rm_transactionState_RESOURCE_APPROVED = 2,
/** Transaction has been denied */
- Rm_transactionDetails_RESOURCE_DENIED = 2
-} Rm_TransactionDetails;
+ Rm_transactionState_RESOURCE_DENIED = 3
+} Rm_TransactionState;
/**
* @brief RM protocol packet resource information
*/
typedef struct {
/** Resource name of resource affected by command */
- char resName[RM_MAX_RESOURCE_NAME_SIZE_BYTES];
- /** If applicable, start of resource range affected by command */
- int32_t resBase;
- /** If applicable, number of specified resource affected by command */
- int32_t resNum;
+ char name[RM_MAX_RESOURCE_NAME_SIZE_BYTES];
+ /** If applicable, start of resource range affected by command. If
+ * RM_RESOURCE_UNSPECIFIED is assigned the higher level RM agent*/
+ int32_t base;
+ /** If applicable, range of specified resource, starting from base, affected by command */
+ uint32_t range;
/** If applicable, the alignment of the resource affected by the command */
- uint32_t resAlign;
+ int32_t alignment;
/** If applicable, the NameServer name assigned to the specified
* resource. Used for commands centering on RM NameServer actions */
- char resNsName[RM_MAX_RESOURCE_NAME_SIZE_BYTES];
+ char nsName[RM_MAX_RESOURCE_NAME_SIZE_BYTES];
} Rm_ResourceInfo;
/**
* instance's transaction queue.
*/
typedef struct {
- /** Transaction type */
- Rm_Command command;
+ /** Transaction service type */
+ Rm_ServiceType type;
/** ID of transaction. Maps to the RM protocol packet ID when forwarding
* RM requests or received RM responses. */
- uint32_t transactionId;
+ uint32_t id;
+ /** Name of the RM instance the transaction originated from */
+ char sourceInstName[RM_INSTANCE_NAME_MAX_CHARS];
/** Transaction's associated callback function is the transaction originated
* from a registered component */
void *callback;
+ /** Transaction state */
+ Rm_TransactionState state;
/** Transaction details. Provides detailed request/response codes such as
- * resource denial reasons */
- uint32_t details;
- /** Transport the transaction was received on. Stored in order to provide
- * responses to received RM packets */
- Rm_TransportHandle transportReceivedOn;
- /** Transaction details */
- union {
- /** If the command has to do with resources these fields
- * will contain the resource information */
- Rm_ResourceInfo resourceInfo;
- /** Pointer to policy data if the command has to do with policies */
- char *policyData;
- } u;
+ * resource denial reasons. The codes are externally visible and tracked
+ * in rmservices.h */
+ int32_t details;
+ /** Resource information */
+ Rm_ResourceInfo resourceInfo;
/** Link to the next transaction in the queue */
Rm_Transaction *nextTransaction;
} Rm_Transaction;
/**
- * @brief RM transaction contains transaction result information that is to be passed
+ * @brief Transaction receipt contains transaction result information that is passed
* back to the entity that was the source of the transaction. The source can be
* a component that requested a service or a RM instance that sent a command.
*/
typedef struct {
- int32_t transactionResult;
- uint32_t transactionId;
- uint32_t resBase;
- uint32_t resNum;
+ /** Result of the requested service. Service result types are explained in the
+ * Rm_services.h header */
+ int32_t serviceResult;
+ /** If RM cannot provide a result to the service immediately a service ID will
+ * be provided to the service requester. The service ID should be used by the
+ * requester to map RM service responses received via the callback function
+ * provided to RM at the time of requesting the service */
+ uint32_t serviceId;
+ /** Base value of resource affected by the service request if RM immediately handles
+ * the request */
+ uint32_t resourceBase;
+ /** Range of resource starting at resourceBase affected by the service request if RM
+ * immediately handles the request */
+ uint32_t resourceRange;
} Rm_TransactionReceipt;
-/**
- * @brief RM protocol packet used to transmit RM commands and resources
- * between RM instances.
- */
-typedef struct {
- /** Packet ID - Used to synchronize sent command packets with
- * response commands. */
- uint32_t rmPktId;
- /** Command issued from source RM instance */
- uint32_t rmCmd;
- /** RM Instance Name - Name of RM instance that is issuing the command.
- * The instance name will be used to validate the
- * command against the instance name data stored in
- * the RM policy data */
- char rmInstName[RM_INST_NAME_MAX_CHARS];
- /** Details field provides more information about RM request/response transactions
- * such as whether a transaction has been approved or denied */
- uint32_t rmDetails;
- /** Union separating resource information from policy information */
- union {
- /** If the command has to do with one or more resources these fields
- * will contain the resource information */
- Rm_ResourceInfo resInfo;
- /** If the command has to do with a policy this array will hold the
- * policy data */
- char rmPolicyData[RM_MAX_POLICY_SIZE_BYTES];
- } u;
-} Rm_ProtocolPkt;
-
typedef enum {
/** running */
RM_state_IDLE = 0,
void *serviceCallback;
} Rm_Inst;
-Rm_Result Rm_getUsePermissions (Rm_Perms *resourcePermissions);
-
+Rm_Transaction *Rm_transactionQueueAdd(Rm_Inst *rmInst, uint32_t transactionId);
+Rm_Transaction *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId);
+int32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId);
#ifdef __cplusplus
}
#endif
-#endif /* RM_PVT_H_ */
+#endif /* RMLOC_H_ */
diff --git a/include/rmtransportloc.h b/include/rmtransportloc.h
--- /dev/null
+++ b/include/rmtransportloc.h
@@ -0,0 +1,202 @@
+/*
+ * file rmtransportloc.h
+ *
+ * Private data structures of Resource Manager transport layer.
+ *
+ * ============================================================================
+ * (C) Copyright 2012, 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
+*/
+
+#ifndef RMTRANSPORTLOC_H_
+#define RMTRANSPORTLOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Device Include */
+#include <c6x.h>
+
+/* RM external includes */
+#include <ti/drv/rm/rm.h>
+
+/* RM internal includes */
+#include <ti/drv/rm/include/rmloc.h>
+
+/** Pointer to RM instance's transport routing map */
+typedef void *Rm_TransRouteMap;
+
+/**
+ * @brief RM transport routing map linked list node. The created
+ * transport nodes are provided to the application casted
+ * as a Rm_TransportHandle
+ */
+typedef struct {
+ /** The remote RM instance type */
+ Rm_InstType remoteInstType;
+ /** The remote RM instance name */
+ char remoteInstName[RM_INSTANCE_NAME_MAX_CHARS];
+ /** Link to the next route node in the route map list */
+ Rm_TransportNode *nextNode;
+} Rm_TransportNode;
+
+/**********************************************************************
+ ************************* RM Packet Defs *****************************
+ **********************************************************************/
+
+/**
+ * @brief Resource Request Packet Types
+ */
+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_ResourceReqPktType;
+
+/**
+ * @brief Resource Request Packet - Packet sent to higher level RM agents to request
+ * a resource service that cannot be handled on the local RM instance due to
+ * permission restrictions.
+ */
+typedef struct {
+ /** The transaction ID associated with the request packet */
+ uint32_t requestId;
+ /** The resource request type */
+ Rm_ResourceReqPktType resourceReqType;
+ /** Name of RM instance that is issuing the resource request. The instance
+ * name will be used to validate the request against the RM policy defined
+ * for the instance. */
+ char instName[RM_INST_NAME_MAX_CHARS];
+ /** Resource request information */
+ Rm_ResourceInfo resourceInfo;
+} Rm_ResourceRequestPkt;
+
+/**
+ * @brief Resource Response Packet - Packet sent to RM instances that requested
+ * a resource service from a higher level RM agent. The packet will contain
+ * resource response information based on the request
+ */
+typedef struct {
+ /** responseID will equal the requestId received in the resource request
+ * packet. This ID should be associated with a transaction stored in
+ * the RM instance that sent the resource request packet */
+ uint32_t responseId;
+ /** Result of the request. Resource request, denied, or error. The
+ * return values are externally visible so they're tracked in rmservice.h */
+ int32_t requestResult;
+ /* Resource response information */
+ Rm_ResourceInfo resourceInfo;
+} Rm_ResourceResponsePkt;
+
+/**
+ * @brief NameServer Request Packet Types
+ */
+typedef enum {
+ /** Request to map the specified name to the specified resources */
+ Rm_nsReqPktType_MAP_RESOURCE = 0,
+ /** Request to unmap the specified name from the specifed resources */
+ Rm_nsReqPktType_UNMAP_RESOURCE = 1
+} Rm_NsReqPktType;
+
+/**
+ * @brief NameServer Request Packet - Packet sent by RM instances containing
+ * NameServer mapping or unmapping data
+ */
+typedef struct {
+ /** The transaction ID associated with the request packet */
+ uint32_t requestId;
+ /** The resource request type */
+ Rm_NsReqPktType nsRequestType;
+ /** RM instance name making the request. Policies may restrict who
+ * can and cannot map and unmap resources via the RM NameServer */
+ char instName[RM_INST_NAME_MAX_CHARS];
+ /** Resource request information */
+ Rm_ResourceInfo resourceInfo;
+} Rm_NsRequestPkt;
+
+/**
+ * @brief NameServer Response Packet - Provides NameServer transaction response
+ * data to RM instances that request a name map or unmap
+ */
+typedef struct {
+ /** responseID will equal the requestId received in the resource request
+ * packet. This ID should be associated with a transaction stored in
+ * the RM instance that sent the resource request packet */
+ uint32_t responseId;
+ /** Result of the request. Resource request, denied, or error. The
+ * return values are externally visible so they're tracked in rmservice.h */
+ int32_t requestResult;
+} Rm_NsResponsePkt;
+
+/**
+ * @brief Policy Request Packet - Packet used by a RM instance to request an
+ * update to its policy data (supported on Client Delegates and Servers only)
+ */
+typedef struct {
+ /** The transaction ID associated with the request packet */
+ uint32_t requestId;
+ /** Name of RM instance that is issuing the policy request. The instance
+ * name will be used to validate the request against the RM policy defined
+ * for the instance in the global policy.
+ * WARNING: Only Client Delegates and Servers can request policy updates */
+ char instName[RM_INST_NAME_MAX_CHARS];
+} Rm_PolicyRequestPkt;
+
+/**
+ * @brief Policy Change Packet - Provides policy changes to RM instances that
+ * support policy storage (Client Delegates and Servers)
+ */
+typedef struct {
+ /** responseID will equal the requestId received in the resource request
+ * packet. This ID should be associated with a transaction stored in
+ * the RM instance that sent the resource request packet */
+ uint32_t responseId;
+ /** Byte array containing new policy data for receiving RM instance */
+ char policyData[RM_MAX_POLICY_SIZE_BYTES];
+} Rm_PolicyChangePkt;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RMTRANSPORTLOC_H_ */
+
diff --git a/resource_table_defs.h b/resource_table_defs.h
--- a/resource_table_defs.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/**
- * @file resource_table_defs.h
- *
- * @brief
- * This file defines the identifiers used to populate the resource table used
- * by the RM LLD to divy resources.
- *
- * \par
- * NOTE:
- * (C) Copyright 2012 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
-*/
-#ifndef __RESOURCE_TABLE_DEFS_H__
-#define __RESOURCE_TABLE_DEFS_H__
-
-/* c99 include */
-#include <stdint.h>
-
-/**
-@addtogroup RM_LLD_RESOURCE_TABLE
-@{
-*/
-
-/** RM LLD Resource Table Resource Identifiers */
-/** This value should be first entry in the resource table. Used to verify RM can read the resource table. */
-#define RM_RESOURCE_MAGIC_NUMBER (0x76543210)
-/** This value should be last entry in the resource table. Used by RM to find last entry in resource table. */
-#define RM_RESOURCE_FINAL_ENTRY (0xFFFFFFFF)
-
-/** Start of QMSS resource identifiers */
-#define RM_RESOURCE_QMSS_BASE 0
-/** QMSS Firmware PDSP write permissions */
-#define RM_RESOURCE_QMSS_FIRMWARE_PDSP (RM_RESOURCE_QMSS_BASE+1)
-/** QMSS queues. This identifier will be expanded to identify all queue types in the near future */
-#define RM_RESOURCE_QMSS_QUEUE (RM_RESOURCE_QMSS_BASE+2)
-/** QMSS Memory regions */
-#define RM_RESOURCE_QMSS_MEMORY_REGION (RM_RESOURCE_QMSS_BASE+3)
-/** QMSS Linking RAM Control */
-#define RM_RESOURCE_QMSS_LINKING_RAM_CONTROL (RM_RESOURCE_QMSS_BASE+4)
-/** QMSS Linking RAM indices */
-#define RM_RESOURCE_QMSS_LINKING_RAM (RM_RESOURCE_QMSS_BASE+5)
-/** QMSS accumulator channels */
-#define RM_RESOURCE_QMSS_ACCUMULATOR_CH (RM_RESOURCE_QMSS_BASE+6)
-/** QMSS QOS PDSP timer */
-#define RM_RESOURCE_QMSS_QOS_PDSP_TIMER (RM_RESOURCE_QMSS_BASE+7)
-/** QMSS QOS clusters */
-#define RM_RESOURCE_QMSS_QOS_CLUSTER (RM_RESOURCE_QMSS_BASE+8)
-/** QMSS QOS queues */
-#define RM_RESOURCE_QMSS_QOS_QUEUE (RM_RESOURCE_QMSS_BASE+9)
-
-/** Start of CPPI resource identifiers */
-#define RM_RESOURCE_CPPI_BASE 64
-/** CPPI SRIO transmit channel */
-#define RM_RESOURCE_CPPI_SRIO_TX_CH (RM_RESOURCE_CPPI_BASE+1)
-/** CPPI SRIO receive channel */
-#define RM_RESOURCE_CPPI_SRIO_RX_CH (RM_RESOURCE_CPPI_BASE+2)
-/** CPPI SRIO flow */
-#define RM_RESOURCE_CPPI_SRIO_FLOW (RM_RESOURCE_CPPI_BASE+3)
-/** CPPI AIF transmit channel */
-#define RM_RESOURCE_CPPI_AIF_TX_CH (RM_RESOURCE_CPPI_BASE+4)
-/** CPPI AIF receive channel */
-#define RM_RESOURCE_CPPI_AIF_RX_CH (RM_RESOURCE_CPPI_BASE+5)
-/** CPPI AIF flow */
-#define RM_RESOURCE_CPPI_AIF_FLOW (RM_RESOURCE_CPPI_BASE+6)
-/** CPPI FFTC_A transmit channel */
-#define RM_RESOURCE_CPPI_FFTC_A_TX_CH (RM_RESOURCE_CPPI_BASE+7)
-/** CPPI FFTC_A receive channel */
-#define RM_RESOURCE_CPPI_FFTC_A_RX_CH (RM_RESOURCE_CPPI_BASE+8)
-/** CPPI FFTC_A flow */
-#define RM_RESOURCE_CPPI_FFTC_A_FLOW (RM_RESOURCE_CPPI_BASE+9)
-/** CPPI FFTC_B transmit channel */
-#define RM_RESOURCE_CPPI_FFTC_B_TX_CH (RM_RESOURCE_CPPI_BASE+10)
-/** CPPI FFTC_B receive channel */
-#define RM_RESOURCE_CPPI_FFTC_B_RX_CH (RM_RESOURCE_CPPI_BASE+11)
-/** CPPI FFTC_B flow */
-#define RM_RESOURCE_CPPI_FFTC_B_FLOW (RM_RESOURCE_CPPI_BASE+12)
-/** CPPI PASS transmit channel */
-#define RM_RESOURCE_CPPI_PASS_TX_CH (RM_RESOURCE_CPPI_BASE+13)
-/** CPPI PASS receive channel */
-#define RM_RESOURCE_CPPI_PASS_RX_CH (RM_RESOURCE_CPPI_BASE+14)
-/** CPPI PASS flow */
-#define RM_RESOURCE_CPPI_PASS_FLOW (RM_RESOURCE_CPPI_BASE+15)
-/** CPPI QMSS transmit channel */
-#define RM_RESOURCE_CPPI_QMSS_TX_CH (RM_RESOURCE_CPPI_BASE+16)
-/** CPPI QMSS receive channel */
-#define RM_RESOURCE_CPPI_QMSS_RX_CH (RM_RESOURCE_CPPI_BASE+17)
-/** CPPI QMSS flow */
-#define RM_RESOURCE_CPPI_QMSS_FLOW (RM_RESOURCE_CPPI_BASE+18)
-/** CPPI FFTC_C transmit channel */
-#define RM_RESOURCE_CPPI_FFTC_C_TX_CH (RM_RESOURCE_CPPI_BASE+19)
-/** CPPI FFTC_C receive channel */
-#define RM_RESOURCE_CPPI_FFTC_C_RX_CH (RM_RESOURCE_CPPI_BASE+20)
-/** CPPI FFTC_C flow */
-#define RM_RESOURCE_CPPI_FFTC_C_FLOW (RM_RESOURCE_CPPI_BASE+21)
-/** CPPI BCP transmit channel */
-#define RM_RESOURCE_CPPI_BCP_TX_CH (RM_RESOURCE_CPPI_BASE+22)
-/** CPPI BCP receive channel */
-#define RM_RESOURCE_CPPI_BCP_RX_CH (RM_RESOURCE_CPPI_BASE+23)
-/** CPPI BCP flow */
-#define RM_RESOURCE_CPPI_BCP_FLOW (RM_RESOURCE_CPPI_BASE+24)
-
-/** Start of CPPI resource identifiers */
-#define RM_RESOURCE_PA_BASE 128
-/** PA Firmware write permissions */
-#define RM_RESOURCE_PA_FIRMWARE (RM_RESOURCE_PA_BASE+1)
-/** PA look-up table entry */
-#define RM_RESOURCE_PA_LUT_ENTRY (RM_RESOURCE_PA_BASE+2)
-
-/** RM LLD Resource Table Permission Codes */
-/** Init or use permission allowed */
-#define RM_RESOURCE_PERM_DENIED 0x0
-/** Init or use permission denied */
-#define RM_RESOURCE_PERM_ALLOWED 0x1
-
-/** Resource entry flags bitfield DSP shift macro */
-#define RM_RESOURCE_FLAG_DSP_SHIFT(dspNum, perms) \
- (((uint32_t) perms) << dspNum)
-
-/** Full Permissions - All DSPs can use and initialize resource */
-#define RM_RESOURCE_ALL_DSPS_FULL_PERMS \
- ((RM_RESOURCE_FLAG_DSP_SHIFT(0, RM_RESOURCE_PERM_ALLOWED)) | \
- (RM_RESOURCE_FLAG_DSP_SHIFT(1, RM_RESOURCE_PERM_ALLOWED)) | \
- (RM_RESOURCE_FLAG_DSP_SHIFT(2, RM_RESOURCE_PERM_ALLOWED)) | \
- (RM_RESOURCE_FLAG_DSP_SHIFT(3, RM_RESOURCE_PERM_ALLOWED)))
-
-/**
- * @brief Resource Table resource definition structure
- */
-typedef struct
-{
- /** Resouce identifier. */
- uint32_t resourceId;
- /** Start range for identified resource */
- uint32_t resourceStart;
- /** End range for identified resource */
- uint32_t resourceEnd;
- /** Resource initialization permission flags
- * Bits 0 : DSP 0 Permission Bit
- * Bits 1 : DSP 1 Permission Bit
- * Bits 2 : DSP 2 Permission Bit
- * Bits 3 : DSP 3 Permission Bit
- * Bits 31-8 : UNUSED
- */
- uint32_t resourceInitFlags;
- /** Resource usage permission flags
- * Bits 0 : DSP 0 Permission Bit
- * Bits 1 : DSP 1 Permission Bit
- * Bits 2 : DSP 2 Permission Bit
- * Bits 3 : DSP 3 Permission Bit
- * Bits 31-8 : UNUSED
- */
- uint32_t resourceUseFlags;
-} Rm_Resource;
-
-/**
-@}
-*/
-
-#endif /* __RESOURCE_TABLE_DEFS_H__ */
-
-
-
index 4f59095d17ad16d49e458077a66da921c863bece..c7495276d003200f696aba55bfe5cd36c68b2f7a 100644 (file)
--- a/rm.h
+++ b/rm.h
*/
typedef void *Rm_Handle;
-/**
- * @brief RM Service Handle provided to components that want to use RM to
- * for management of their resources.
- */
-typedef void *Rm_ServiceHandle;
-
/**
* @brief RM Instance types
*/
Rm_instType_CLIENT
} Rm_InstType;
-/**
- * @brief RM transport registration configuration structure
- */
-typedef struct {
- /** Defines the remote RM instance's type */
- Rm_InstType rmRemoteInstType;
-} Rm_TransCfg;
-
/**
* @brief RM transport verification return value
*/
*/
Rm_ServiceHandle Rm_getServiceHandle(Rm_Handle rmHandle);
-/**
- * @b Description
- * @n
- * This function is used to register transports with RM for sending and
- * receiving packets between RM instances over application transport
- * data paths.
- *
- * @param[in] rmHandle
- * RM instance to which the transport will be registered. Used internally
- * by RM if there are more than one RM instances per core.
- *
- * @param[in] transCfg
- * Transport registration configuration structure. Provides information
- * regarding the application transports remote entity. For example,
- * if the transCfg structure specifies the remote type is the RM Server
- * RM will know any Server requests must be pushed to the application
- * transport API with the transport handle returned to the application
- *
- * @retval
- * Success - non-NULL RM transport handle. No two transport handles
- * returned by RM should be the same.
- * @retval
- * Failure - NULL
- */
-Rm_TransHandle Rm_registerTransport (Rm_Handle rmHandle,
- Rm_TransCfg *transCfg);
-
-/**
- * @b Description
- * @n
- * This function places the selected RM instance into the transport
- * verification state. When all RM instances in the tree are placed
- * in the transport verification state a transport path verification
- * test will take place to verify the application transport paths between
- * all RM tree nodes are connected correctly.
- *
- * Note: This API should not be called until all transport have been
- * registered with RM
- *
- * @param[in] rmHandle
- * Which RM instance to begin the transport verification process
- *
- * @param[in] timeout
- * Number of ______ (cycles, usec, msec???) to wait before signaling a
- * transport path verification timeout
- *
- * @param[in] failData
- * Pointer to an empty Rm_TransFailData structure. If the transport
- * verification process fails this structure will return with transport
- * failure data
- *
- * @retval
- * Success - 0 - Transport Verification succeeded
- * @retval
- * Failure - non-0 - Transport Verification failed
- */
-Rm_TransVerifyResult Rm_verifyTransport (Rm_Handle, uint32_t timeout,
- Rm_TransFailData *failData);
-
/**
* @b Description
* @n
diff --git a/rm_services.h b/rmservices.h
similarity index 65%
rename from rm_services.h
rename to rmservices.h
index 5b62ad634f5c8d4936dc9e5a609fa94f2d3a9722..1f4facf4b3b92a9e008269be59c66b0d89daec38 100644 (file)
rename from rm_services.h
rename to rmservices.h
index 5b62ad634f5c8d4936dc9e5a609fa94f2d3a9722..1f4facf4b3b92a9e008269be59c66b0d89daec38 100644 (file)
--- a/rm_services.h
+++ b/rmservices.h
/**
- * @file rm_services.h
+ * @file rmservices.h
*
* @brief
- * This is the RM include file for services provided to components that register a RM
- * instance
+ * This is the RM include file for services provided to components that
+ * register a RM instance
*
* \par
* ============================================================================
* \par
*/
-#ifndef RM_SERVICES_H_
-#define RM_SERVICES_H_
+#ifndef RMSERVICES_H_
+#define RMSERVICES_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
-@addtogroup RM_SERVICES_API
+@addtogroup RMSERVICES_API
@{
*/
-/**
- * @brief RM will return the next available resource if the component assigns
- * "not specified" in the resourceIndex field when the resource allocate
- * service is initiated.
- */
-#define RM_SERVICE_INDEX_NOT_SPECIFIED (-1)
-
/** RM Service Request (serviceResult) Action Codes and Errors */
/** RM Service Request Action Code Base */
#define RM_SERVICE_ACTION_BASE (0)
+/** RM internal action okay - This value is for internal use by RM. It should never be
+ * seen as a return value during normal operation */
+#define RM_SERVICE_ACTION_OKAY (RM_SERVICE_ACTION_BASE)
/** RM service was approved. The resource data in the response is valid if
* the service has been approved. */
-#define RM_SERVICE_APPROVED (RM_SERVICE_ACTION_BASE)
-/** RM service was denied. The resource data in the response is not valid */
-#define RM_SERVICE_DENIED (RM_SERVICE_ACTION_BASE+1)
+#define RM_SERVICE_APPROVED (RM_SERVICE_ACTION_BASE+1)
+/** Beginning of resource denied reasons */
+#define RM_SERVICE_DENIED_BEGIN (RM_SERVICE_ACTION_BASE+2)
+/** End of resource denied reasons */
+#define RM_SERVICE_DENIED_END (RM_SERVICE_ACTION_BASE+2)
/** RM service is being processed. Typically this means the service is
* being sent to a higher level RM agent for processing */
-#define RM_SERVICE_PROCESSING (RM_SERVICE_ACTION_BASE+2)
-/** RM response packet sent successfully */
-#define RM_RESPONSE_PACKET_SENT (RM_SERVICE_ACTION_BASE+3)
+#define RM_SERVICE_PROCESSING (RM_SERVICE_ACTION_BASE+3)
/** RM Service Request Error Code Base */
#define RM_SERVICE_ERROR_BASE (-64)
/** RM service request needs to be forwarded but the transport packet alloc API
* has not been provided */
#define RM_SERVICE_ERROR_TRANSPORT_PKT_ALLOC_API_NULL (RM_SERVICE_ERROR_BASE-4)
-/** RM service request needs to be forwarded but the transport packet alloc returned
- * NULL for the packet buffer */
-#define RM_SERVICE_ERROR_TRANSPORT_NULL_PKT_BUF (RM_SERVICE_ERROR_BASE-5)
+/** A failure occurred within a registered transport's packet alloc API */
+#define RM_SERVICE_ERROR_TRANSPORT_ALLOC_PKT_ERROR (RM_SERVICE_ERROR_BASE-5)
/** RM service request needs to be forwarded but the buffer allocated by transport
* is not large enough to fit the RM transport packet */
#define RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL (RM_SERVICE_ERROR_BASE-6)
/** RM service request needs to be forwarded but the transport returned an error
* when trying to send the RM packet to the higher level agent */
#define RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR (RM_SERVICE_ERROR_BASE-7)
-/** RM service request needs to be forwarded but the transport packet send API
- * has not been provided */
-#define RM_SERVICE_ERROR_TRANSPORT_PKT_SEND_API_NULL (RM_SERVICE_ERROR_BASE-8)
/** RM service response from higher level agent did not match any requests made
* by the provided RM instance */
-#define RM_SERVICE_ERROR_TRANSACTION_DOES_NOT_EXST_FOR_THIS_RM_INSTANCE (RM_SERVICE_ERROR_BASE-9)
+#define RM_SERVICE_ERROR_TRANSACTION_DOES_NOT_EXST_FOR_THIS_RM_INSTANCE (RM_SERVICE_ERROR_BASE-8)
+/** RM failed to allocate memory for new service transaction */
+#define RM_SERVICE_ERROR_TRANSACTION_FAILED_TO_ALLOCATE (RM_SERVICE_ERROR_BASE-9)
+/** RM found no service transactions queued when trying to delete a received service
+ * transaction */
+#define RM_SERVICE_ERROR_NO_TRANSACTIONS_IN_QUEUE (RM_SERVICE_ERROR_BASE-10)
+/** RM could not find the service transaction in the RM instance's transaction queue */
+#define RM_SERVICE_ERROR_SERVICE_TRANSACTION_DOES_NOT_EXIST (RM_SERVICE_ERROR_BASE-11)
+/** RM received a response transaction and found a request transaction awaiting a response.
+ * However, the request transaction was not in the "awaiting response" state */
+#define RM_SERVICE_ERROR_INVALID_REQUEST_TRANSACTION_STATE_UPON_RESPONSE (RM_SERVICE_ERROR_BASE-12)
+/** RM Client instance received a service transaction response that did not have a
+ * matching service request that originated on the Client instance */
+#define RM_SERVICE_ERROR_INVALID_TRANSACTION_RECEIVED_ON_CLIENT (RM_SERVICE_ERROR_BASE-13)
+/** A failure occurred within a registered transport's packet free API */
+#define RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR (RM_SERVICE_ERROR_BASE-14)
+
+/** RM Transport Error Code Base */
+#define RM_TRANSPORT_ERROR_BASE (-128)
+/** The transport handle provided to the RM instance was not registered with the RM instance */
+#define RM_TRANSPORT_ERROR_TRANSPORT_HANDLE_NOT_REGISTERED_WITH_INSTANCE (RM_TRANSPORT_ERROR_BASE)
+/** RM received a packet with an unknown RM packet type */
+#define RM_TRANSPORT_ERROR_INVALID_PACKET_TYPE (RM_TRANSPORT_ERROR_BASE-1)
/**
* @brief RM service types
Rm_service_RESOURCE_MAP_TO_NAME = 6,
/** RM resource name unmapping service */
Rm_service_RESOURCE_UNMAP_NAME = 7,
- /** RM resource status service */
- Rm_service_RESOURCE_STATUS = 8,
/** Last service type. Used by RM for bounds checking. Should
* not be used by component. */
- Rm_service_LAST = 8
+ Rm_service_LAST = 7
} Rm_ServiceType;
/**
uint32_t requestId;
/** The base value of the returned resource. In the case of a block resource allocation
* response this field will contain the base value of the block. */
- int32_t resBase;
- /** The number of resources allocated in block requests */
- uint32_t resNum;
+ int32_t resourceBase;
+ /** The range of resources starting from resourceBase allocated in block requests */
+ uint32_t resourceRange;
} Rm_ServiceRespInfo;
/**
*/
typedef struct {
/** The type of RM service requested */
- Rm_ServiceType serviceType;
+ Rm_ServiceType type;
/** Pointer to the name of the resource requested. The
* name provided by the component must match the resource node names
* provided in the global resource table and allocation policies */
- char *resName;
+ char *resourceName;
+/** An allocate service can be requested with an unspecified resource base.
+ * If this occurs the RM Client Delegate or Server will assign the next available
+ * resource or set of resources based on the allocation type. */
+#define RM_RESOURCE_BASE_UNSPECIFIED (-1)
/** The resource base value. */
- int32_t resBase;
- /** The number of the specified resources. Will be greater than one only
- * for block allocate and free service requests. */
- uint32_t resNum;
+ int32_t resourceBase;
+ /** The range of the specified resource to be allocated starting from
+ * resourceBase. Will be greater than one only for block allocate
+ * and free service requests. */
+ uint32_t resourceRange;
+/** An allocate service can be requested with an unspecified resource alignment.
+ * WARNING: Only applicapable if resourceBase is unspecified
+ *
+ * If the alignment is unspecified the RM Client Delegate or Server will allocate
+ * the resources from a default alignment as specified in the global policy. */
+#define RM_RESOURCE_ALIGNMENT_UNSPECIFIED (-1)
/** Resource alignment in block allocation requests */
- uint32_t resAlign;
+ int32_t resourceAlignment;
/** The name server name associated with the resource. Used only for
* allocate and free by name service requests */
- char *resNsName;
+ char *resourceNsName;
/** Component callback function. RM will call this function when the
* resource service request is completed. The callback function supplied
* for this parameter must match this function pointer prototype. */
- void (*serviceCallback) (Rm_ServiceRespInfo *responseInfo);
+ void (*serviceCallback) (Rm_ServiceRespInfo *serviceResponse);
} Rm_ServiceReqInfo;
/**
- * @brief RM Service Handle provided to software components that
- * request RM services for the resources they control
+ * @brief RM Service Port provided to software components and applications that
+ * request RM services for the resources they wish to use
*/
typedef struct {
/** RM instance handle for which the service handle was registered */
* RM instance handle specifying the RM instance that should handle the
* service request
*
- * @param[in] requestInfo
+ * @param[in] serviceRequest
* Service request structure that provides details of the service requested from
* the RM instance tied to this component
*
- * @param[in] responseInfo
+ * @param[in] serviceResponse
* Service response structure that provides details of RM's response to the
* service request
*/
- void (*rmService)(void *rmHandle, Rm_ServiceReqInfo *requestInfo,
- Rm_ServiceRespInfo *responseInfo);
+ void (*rmService)(void *rmHandle, Rm_ServiceReqInfo *serviceRequest,
+ Rm_ServiceRespInfo *serviceResponse);
} Rm_ServicesPort;
/**
}
#endif
-#endif /* RM_SERVICES_H_ */
+#endif /* RMSERVICES_H_ */
diff --git a/rm_transport.h b/rmtransport.h
similarity index 58%
rename from rm_transport.h
rename to rmtransport.h
index ba6553e1ee97f9ef7b70c294680a745dbe071722..cb040089750d04b49f1540d4fb58472d74445123 100644 (file)
rename from rm_transport.h
rename to rmtransport.h
index ba6553e1ee97f9ef7b70c294680a745dbe071722..cb040089750d04b49f1540d4fb58472d74445123 100644 (file)
--- a/rm_transport.h
+++ b/rmtransport.h
/**
- * @file rm_transport.h
+ * @file rmtransport.h
*
* @brief
* This is the RM include file for the generic transport interface used by RM to exchange
* \par
*/
-#ifndef RM_TRANSPORT_H_
-#define RM_TRANSPORT_H_
+#ifndef RMTRANSPORT_H_
+#define RMTRANSPORT_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
-@addtogroup RM_TRANSPORT_API
+@addtogroup RMTRANSPORT_API
@{
*/
+/** RM Transport Result Return Codes */
+/** RM Transport Success Code Base */
+#define RM_TRANSPORT_OK_BASE (0)
+/** RM transport action was successful. */
+#define RM_TRANSPORT_SUCCESSFUL (RM_TRANSPORT_OK_BASE)
+
+/** RM Transport Error Code Base */
+#define RM_TRANSPORT_ERROR_BASE (-64)
+/** RM transport handle has not been registered with the RM instance */
+#define RM_TRANSPORT_ERROR_HANDLE_HAS_NOT_BEEN_REGISTERED (RM_TRANSPORT_ERROR_BASE-1)
+/** No transports have been registered with the RM instance */
+#define RM_TRANSPORT_ERROR_NO_TRANSPORTS_REGISTERED (RM_TRANSPORT_ERROR_BASE-2)
+
+/**
+ * @brief Result of RM transport layer operations
+ */
+typedef int32_t Rm_TransportResult;
+
+
+
/** Maximum size of the RM transport packet */
#define RM_TRANSPORT_PACKET_MAX_SIZE_BYTES (128) // Placeholder: This will
// change during development
typedef void *Rm_TransportHandle;
/**
- * @brief Result of RM transport layer operations
+ * @brief RM transport registration configuration structure
*/
-typedef int32_t Rm_TransportResult;
+typedef struct {
+ /** The transport's remote RM instance type */
+ Rm_InstType remoteInstType;
+ /** Pointer to the transport's remote RM instance name */
+ char *remoteInstName;
+} Rm_TransportCfg;
+
+/**
+ * @brief RM packet types that can be sent between RM instances
+ */
+typedef enum {
+ /** Allocate/Free request packet */
+ Rm_pktType_RESOURCE_REQUEST = 0,
+ /** Allocate/Free response packet */
+ Rm_pktType_RESOURCE_RESPONSE = 1,
+ /** RM NameServer mapping request */
+ Rm_pktType_NAMESERVER_REQUEST = 2,
+ /** RM NameServer mapping response */
+ Rm_pktType_NAMESERVER_RESPONSE = 3,
+ /** Policy request packet */
+ Rm_pktType_POLICY_REQUEST = 4,
+ /** Policy response packet */
+ Rm_pktType_POLICY_CHANGE = 5
+} Rm_pktType;
/**
- * @brief RM transport layer packet packet descriptor structure
+ * @brief RM transport layer packet
*/
typedef struct {
- /** Length of packet. Written by application when allocated */
- uint32_t rmPktLen;
- /** Pointer to RM resource packet */
- char rmData[RM_TRANSPORT_PACKET_MAX_SIZE_BYTES];
+ /** Packet length in bytes. Written by application when allocated */
+ uint32_t pktLenBytes;
+ /** Type of RM packet contained in the byte data array */
+ Rm_pktType pktType;
+ /** Byte array containing RM packet data */
+ char data[RM_TRANSPORT_PACKET_MAX_SIZE_BYTES];
} Rm_Packet;
-
typedef struct {
/**
* @b Description
* buffers for use by the RM transport for sending messages between RM
* instances in the SOC.
*
- * @param[in] transHandle
+ * @param[in] transportHandle
* Which application transport to allocate a packet from.
*
* @param[in] pktSize
* @retval
* Failure - NULL
*/
- Rm_Packet *(*rmAllocPkt)(Rm_TransportHandle transHandle, uint32_t pktSize);
+ Rm_Packet *(*rmAllocPkt)(Rm_TransportHandle transportHandle, uint32_t pktSize);
/**
* @b Description
* buffers used by the RM transport for sending/receiving messages
* between RM instances in the SOC.
*
- * @param[in] transHandle
+ * @param[in] transportHandle
* Which application transport to free the packet to.
*
* @param[in] pkt
* @retval
* Non-zero - Send failed.
*/
- Rm_TransportResult (*rmFreePkt)(Rm_TransportHandle transHandle, Rm_Packet *pkt);
+ int32_t (*rmFreePkt)(Rm_TransportHandle transportHandle, Rm_Packet *pkt);
/**
* @b Description
* function implements the send side of the transport between RM
* instances on different cores in the SOC.
*
- * @param[in] transHandle
+ * @param[in] transportHandle
* Which application transport to send the packet over.
*
* @param[in] pkt
* @retval
* Non-zero - Send failed.
*/
- Rm_TransportResult (*rmSend)(Rm_TransportHandle transHandle, Rm_Packet *pkt);
+ int32_t (*rmSend)(Rm_TransportHandle transportHandle, Rm_Packet *pkt);
/**
* @b Description
* The provided function implements the receive side of the transport
* between RM instances on different cores in the SOC.
*
- * @param[in] transHandle
+ * @param[in] transportHandle
* Which application transport to retrieve a packet from
*
* @param[in] pkt
* @retval
* Non-zero - Packet receive failed.
*/
- Rm_TransportResult (*rmReceive)(Rm_TransportHandle transHandle, Rm_Packet *pkt);
+ int32_t (*rmReceive)(Rm_TransportHandle transportHandle, Rm_Packet *pkt);
/**
* @b Description
* prototype. The provided function implements a query of the number of
* RM packets received on a specified transport.
*
- * @param[in] transHandle
+ * @param[in] transportHandle
* Which application transport to check for received packets.
*
* @retval
* @retval
* Failure - -1
*/
- int32_t (*rmNumPktsReceived)(Rm_TransportHandle transHandle);
+ int32_t (*rmNumPktsReceived)(Rm_TransportHandle transportHandle);
} Rm_TransportCallouts;
/**
* This API can be used if RM polling the application code for received
* packets is not desired.
*
- * @param[in] transHandle
+ * @param[in] transportHandle
* Transport handle. Used to distinguish which RM instance the packet
* was received from and how to internally route the packet if more than
* one RM instance exists on the core.
* @retval
* Failure - Non-zero RM error
*/
-Rm_Result rmTransportCallback(Rm_TransHandle transHandle, Rm_Packet *pkt);
+Rm_Result rmTransportCallback(Rm_TransHandle transportHandle, Rm_Packet *pkt);
+
+
+/**
+ * @b Description
+ * @n
+ * This function is used to register transports with RM for sending and
+ * receiving packets between RM instances over application transport
+ * data paths.
+ *
+ * @param[in] rmHandle
+ * RM instance to which the transport will be registered. Used internally
+ * by RM if there are more than one RM instances per core.
+ *
+ * @param[in] transportCfg
+ * Transport registration configuration structure. Provides information
+ * regarding the application transports remote entity. For example,
+ * if the transCfg structure specifies the remote type is the RM Server
+ * RM will know any Server requests must be pushed to the application
+ * transport API with the transport handle returned to the application
+ *
+ * @retval
+ * Success - non-NULL RM transport handle. No two transport handles
+ * returned by RM should be the same.
+ * @retval
+ * Failure - NULL
+ */
+Rm_TransportHandle Rm_transportRegister (Rm_Handle rmHandle,
+ Rm_TransportCfg *transportCfg);
+
+/**
+ * @b Description
+ * @n
+ * This function places the selected RM instance into the transport
+ * verification state. When all RM instances in the tree are placed
+ * in the transport verification state a transport path verification
+ * test will take place to verify the application transport paths between
+ * all RM tree nodes are connected correctly.
+ *
+ * Note: This API should not be called until all transport have been
+ * registered with RM
+ *
+ * @param[in] rmHandle
+ * Which RM instance to begin the transport verification process
+ *
+ * @param[in] timeout
+ * Number of ______ (cycles, usec, msec???) to wait before signaling a
+ * transport path verification timeout
+ *
+ * @param[in] failData
+ * Pointer to an empty Rm_TransFailData structure. If the transport
+ * verification process fails this structure will return with transport
+ * failure data
+ *
+ * @retval
+ * Success - 0 - Transport Verification succeeded
+ * @retval
+ * Failure - non-0 - Transport Verification failed
+ */
+Rm_TransVerifyResult Rm_transportVerify (Rm_Handle, uint32_t timeout,
+ Rm_TransFailData *failData);
+
/**
}
#endif
-#endif /* RM_TRANSPORT_H_ */
+#endif /* RMTRANSPORT_H_ */
diff --git a/rm_types.h b/rmtypes.h
similarity index 95%
rename from rm_types.h
rename to rmtypes.h
index 643be405768e62f33789e98e44feb705dc12a910..5886f03e2dbf3fb1d84024fa2fadff8c52cde2c9 100644 (file)
rename from rm_types.h
rename to rmtypes.h
index 643be405768e62f33789e98e44feb705dc12a910..5886f03e2dbf3fb1d84024fa2fadff8c52cde2c9 100644 (file)
--- a/rm_types.h
+++ b/rmtypes.h
/**
- * @file rm_types.h
+ * @file rmtypes.h
*
* @brief
* This is a wrapper header file which includes the standard types
*
* \par
*/
-#ifndef __RM_TYPES_H__
-#define __RM_TYPES_H__
+#ifndef __RMTYPES_H__
+#define __RMTYPES_H__
/* c99 include */
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#endif /* __RM_TYPES_H__ */
+#endif /* __RMTYPES_H__ */
diff --git a/src/rm.c b/src/rm.c
index a7137978888f48ca9ba98f8d79b82938557b6d3a..e546fc3f09be869737c996a1d0028a1394c1085e 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
/* RM Types */\r
#include <ti/drv/rm/rm_types.h>\r
\r
-/* RM includes */\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
-#include <ti/drv/rm/include/rm_pvt.h>\r
+#include <ti/drv/rm/rmservices.h>\r
+#include <ti/drv/rm/rmtransport.h>\r
+#include <ti/drv/rm/rmpolicy.h>\r
+\r
+/* RM internal includes */\r
+#include <ti/drv/rm/include/rmloc.h>\r
\r
/* RM OSAL layer */\r
#include <rm_osal.h>\r
********************** Internal Functions ****************************\r
**********************************************************************/\r
\r
-void Rm_transactionQueueAdd(Rm_Inst *rmInst, uint32_t transactionId, \r
- Rm_TransportHandle transportHandle, void *callbackFunc)\r
+/* At the very least the transaction ID needs to be provided to create a transaction */\r
+Rm_Transaction *Rm_transactionQueueAdd(Rm_Inst *rmInst, uint32_t transactionId)\r
{\r
- Rm_TransactionQueueEntry *transactionQueue = (Rm_TransactionQueueEntry *) rmInst->transactionQueue;\r
- Rm_TransactionQueueEntry *newEntry;\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_osalLocalCsEnter();\r
\r
- /* Get memory for a new transaction queue entry from local memory */\r
- newEntry = Rm_osalMalloc (sizeof(Rm_TransactionQueueNode), false);\r
+ /* Get memory for a new transaction from local memory */\r
+ newTransaction = Rm_osalMalloc(sizeof(Rm_Transaction), false);\r
+\r
+ /* Return if the memory allocated for the transaction entry is NULL */\r
+ if (newTransaction == NULL)\r
+ {\r
+ Rm_osalLocalCsExit(key);\r
+ return(newTransaction);\r
+ }\r
+\r
+ /* Clear the transaction */\r
+ memset((void *)newTransaction, 0, sizeof(Rm_Transaction));\r
\r
- /* Populate the new entry. */\r
- newEntry->transactionId = transactionId;\r
- newEntry->transportHandle = transportHandle;\r
- newEntry->transactionCallback = callbackFunc;\r
- newEntry->nextEntry = NULL; /* New entry's nextEntry pointer will always be NULL */\r
+ /* Populate transaction with the provided ID */\r
+ newTransaction->id = transactionId;\r
+ /* New transaction's nextTransaction pointer will always be NULL */\r
+ newTransaction->nextTransaction = NULL; \r
\r
- /* Check if there are any entries in the transaction queue */\r
+ /* Check if there are any transactions in the transaction queue */\r
if (transactionQueue)\r
{\r
- /* At least one entry in the transaction queue. Add the new entry to the end of the\r
- * transaction queue */\r
- while (transactionQueue->nextEntry != NULL)\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 entry */\r
- transactionQueue = transactionQueue->nextEntry;\r
+ /* Traverse the list until arriving at the last transaction */\r
+ transactionQueue = transactionQueue->nextTransaction;\r
}\r
\r
- /* Add the new entry to the end of the queue */\r
- transactionQueue->nextEntry = newEntry;\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 entry is the first entry */\r
- rmInst->routeMap = newEntry;\r
+ /* The transaction queue does not currently exist. The new transaction is the \r
+ * first transaction */\r
+ rmInst->transactionQueue = newTransaction;\r
}\r
\r
Rm_osalLocalCsExit(key);\r
+ return (newTransaction);\r
}\r
\r
-Rm_TransactionQueueEntry *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)\r
+Rm_Transaction *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)\r
{\r
- Rm_TransactionQueueEntry *entry = (Rm_TransactionQueueEntry *) rmInst->transactionQueue;\r
+ Rm_Transaction *transaction = (Rm_Transaction *)rmInst->transactionQueue;\r
void *key;\r
\r
- /* Lock access to the RM instance's transaction queue */\r
- key = Rm_osalLocalCsEnter();\r
-\r
- /* Make sure there is at least one entry in the transaction queue */\r
- if (entry != NULL)\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 entry the \r
- * entry pointer will be NULL */\r
- while (entry != NULL)\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 (entry->transactionId == transactionId)\r
+ if (transaction->transactionId == transactionId)\r
{\r
- /* Match: break out of loop and return the entry */\r
+ /* Match: break out of loop and return the transaction */\r
break; \r
}\r
- entry = entry->nextEntry;\r
+ transaction = transaction->nextTransaction;\r
}\r
}\r
- \r
- Rm_osalLocalCsExit(key);\r
- return (entry);\r
+\r
+ return (transaction);\r
}\r
\r
-uint32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)\r
+int32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)\r
{\r
- Rm_TransactionQueueEntry *currentEntry = (Rm_TransactionQueueEntry *) rmInst->transactionQueue;\r
- Rm_TransactionQueueEntry *prevEntry = NULL;\r
+ Rm_Transaction *transaction = (Rm_Transaction *) rmInst->transactionQueue;\r
+ Rm_Transaction *prevTransaction = NULL;\r
void *key;\r
\r
/* Lock access to the RM instance's transaction queue */\r
key = Rm_osalLocalCsEnter();\r
\r
/* Make sure there is at least one entry in the transaction queue */\r
- if (currentEntry == NULL)\r
+ if (transaction == NULL)\r
{\r
Rm_osalLocalCsExit(key);\r
- return (-1); /* TEMP ERROR RETURN */\r
+ return (RM_SERVICE_ERROR_NO_TRANSACTIONS_IN_QUEUE);\r
}\r
\r
/* Find the transaction ID within the specified RM instance's transaction queue. */\r
- while (currentEntry != NULL)\r
+ while (transaction != NULL)\r
{\r
- if (currentEntry->transactionId == transactionId)\r
+ if (transaction->transactionId == transactionId)\r
{\r
- /* Match: break out of loop and delete the entry */\r
+ /* Match: break out of loop and delete the transaction */\r
break; \r
}\r
\r
- prevEntry = currentEntry;\r
- currentEntry = currentEntry->nextEntry;\r
+ prevTransaction = transaction;\r
+ transaction = transaction->nextEntry;\r
}\r
\r
/* Traversed entire queue but did not find transaction */\r
- if (currentEntry == NULL)\r
+ if (transaction == NULL)\r
{\r
Rm_osalLocalCsExit(key);\r
- return (-2); /* TEMP ERROR RETURN */\r
+ return (RM_SERVICE_ERROR_SERVICE_TRANSACTION_DOES_NOT_EXIST);\r
}\r
else\r
{\r
- /* Delete the transaction queue entry */\r
- if ((prevEntry == NULL) && currentEntry->nextEntry)\r
+ /* Delete the transaction */\r
+ if ((prevTransaction == NULL) && transaction->nextTransaction)\r
{\r
- /* Entry to be deleted exists at start of transaction queue. Map second\r
- * entry to be start of transaction queue as long as there are more than\r
- * one entries */\r
- rmInst->transactionQueue = currentEntry->nextNode;\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
- /* Entry to be deleted is in the middle or at end of the queue. Adjust adjacent\r
- * entry pointers. This covers the case where the entry to be removed is at the\r
- * end of the queue. */\r
- prevEntry->nextNode = currentEntry->nextNode;\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
- /* Delete the node, free the memory associated with the node. */\r
- Rm_osalFree((void *) currentEntry, sizeof(Rm_TransactionQueueEntry), false);\r
+ /* Free the memory associated with the transaction. */\r
+ Rm_osalFree((void *)transaction, sizeof(Rm_Transaction), false);\r
}\r
\r
Rm_osalLocalCsExit(key);\r
- return (0); /* RETURN OKAY - FIX MAGIC NUMBER */\r
-}\r
-\r
-/* Used in Client Delegate case where it forwarded requests from Client to Server\r
- * callback will direct to internal function that forwards response from server back\r
- * to client */\r
-void Rm_internalCallback (Rm_ServiceRespInfo *responseInfo)\r
-{\r
-\r
+ return (RM_SERVICE_ACTION_OKAY);\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
Rm_TransactionReceipt *receipt)\r
{\r
- Rm_TransactionQueueEntry *transactionEntry;\r
+ Rm_TransportNode *dstTransportNode = NULL;\r
Rm_Packet *rmPkt = NULL;\r
- Rm_ProtocolPkt *rmProtPkt = NULL;\r
\r
- /* Find the transaction request that matches the received response */\r
- transactionEntry = Rm_transactionQueueFind(rmInst,transaction->pktId);\r
-\r
- if (transactionEntry == NULL)\r
- {\r
- /* No transaction request matching the transaction ID was forwarded from\r
- * this RM instace */\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSACTION_DOES_NOT_EXST_FOR_THIS_RM_INSTANCE;\r
- return;\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 transaction information */\r
- if (rmInst->transport.rmAllocPkt)\r
- {\r
- rmPkt = rmInst->transport.rmAllocPkt(transactionEntry->transportHandle, sizeof(Rm_Packet));\r
- }\r
- else\r
- {\r
- /* The transport packet alloc API is not plugged */\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_ALLOC_API_NULL;\r
- return;\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, receipt);\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, receipt);\r
+ break;\r
+ default:\r
+ /* Invalid service type. Flag the error and return */\r
+ receipt->serviceResult = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
+ break;\r
}\r
\r
- /* Make sure a buffer for the packet was allocated */\r
- if (rmPkt == NULL)\r
+ if (receipt->serviceResult <= RM_SERVICE_ERROR_BASE)\r
{\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_NULL_PKT_BUF;\r
+ /* Delete the transaction and return immediately because an error occurred \r
+ * allocating the packet */\r
+ Rm_transactionQueueDelete(rmInst, transaction->id);\r
return;\r
}\r
\r
- /* Make sure allocated buffer is large enough to fit the protocol packet plus the \r
- * rmPktLen field */\r
- if (rmPkt->rmPktLen < (sizeof(Rm_ProtocolPkt) + sizeof(uint32_t))\r
- { \r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL;\r
- return;\r
- }\r
-\r
-\r
- /* Initialize the rmPkt. Do not assume the transport code will do it */ \r
- memset((void *)rmPkt, 0, sizeof(Rm_Packet));\r
-\r
- /* Assign the rmData field to be the rmProtPkt */\r
- rmProtPkt = &(rmPkt->rmData[0]);\r
-\r
- /* Populate the response packet with the transaction response details for\r
- * the lower leverl RM instance */\r
- rmProtPkt->rmPktId = transactionEntry->transactionId;\r
- strcpy((void *)rmProtPkt->rmInstName,(void *)rmInst->name);\r
- rmProtPkt->rmCmd = (uint32_t) transaction->command;\r
- rmProtPkt->rmDetails = transaction->details;\r
- if (transaction->command == Rm_command_POLICY_RESPONSE)\r
- {\r
- /* Copy the policy data if the transaction is policy based */\r
- memcpy ((void *)rmProtPkt->u.rmPolicyData, (void *)transaction->u.policyData,\r
- RM_MAX_POLICY_SIZE_BYTES);\r
- }\r
- else\r
- {\r
- /* Otherwise copy the resource data */\r
- memcpy ((void *)&(rmProtPkt->u.resInfo), (void *) &(transaction->u.resourceInfo),\r
- sizeof(Rm_ResourceInfo));\r
- }\r
-\r
/* Send the RM packet to the application transport */\r
- if (rmInst->transport.rmSend)\r
+ if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt))\r
{\r
- if (!(rmInst->transport.rmSend(transactionEntry->transportHandle, rmPkt))\r
+ /* Non-NULL value returned by transport send. An error occurred\r
+ * in the transport while attempting to send the packet.*/\r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
+ /* Clean up the packet */\r
+ if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
{\r
- /* Transport returned an error */\r
-\r
- /* SHOULD TRANSPORT ERROR SOMEHOW BE OR'D WITH THE SERVICE ERROR ??? */\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
- return;\r
+ /* Non-NULL value returned by transport packet free. Flag the\r
+ * error */\r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
}\r
- }\r
- else\r
- {\r
- /* The transport packet send API is not plugged */\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_SEND_API_NULL;\r
return;\r
- } \r
- \r
- receipt->transactionResult = RM_RESPONSE_PACKET_SENT;\r
-\r
- /* Delete the transaction entry from the transaction queue */\r
- Rm_transactionQueueDelete(rmInst,transaction->pktId);\r
+ }\r
\r
- return;\r
+ /* Fill out the receipt information and delete the transaction */\r
+ receipt->serviceResult = transaction->details;\r
+ Rm_transactionQueueDelete(rmInst, transaction->id);\r
}\r
\r
/* Function used to forward RM transactions to higher level agents */\r
void Rm_transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction,\r
Rm_TransactionReceipt *receipt)\r
{\r
- Rm_TransRouteMapNode *routeMap = (Rm_TransRouteMapNode *) rmInst->routeMap;\r
- uint32_t transactionId;\r
+ Rm_TransportNode *dstTransportNode = NULL;\r
Rm_Packet *rmPkt = NULL;\r
- Rm_ProtocolPkt *rmProtPkt = NULL;\r
\r
- /* Make sure at least one transport has been registered */\r
- if (routeMap == NULL)\r
- {\r
- receipt->transactionResult = RM_SERVICE_ERROR_NO_TRANSPORT_REGISTERED;\r
- return;\r
- }\r
- \r
/* Make sure the RM instance has a transport registered with a higher level agent */\r
- if (!rmInst->registeredWithDelegateOrServer)\r
+ if (rmInst->registeredWithDelegateOrServer == false)\r
{\r
- receipt->transactionResult = RM_SERVICE_ERROR_NOT_REGISTERED_WITH_DEL_OR_SERVER;\r
+ receipt->serviceResult = RM_SERVICE_ERROR_NOT_REGISTERED_WITH_DEL_OR_SERVER;\r
return;\r
}\r
\r
- /* Parse the RM instance's routing map to find the higher level agent for forwarding */\r
- while ((routeMap->remoteInstType != Rm_instType_CLIENT_DELEGATE) || \r
- (routeMap->remoteInstType != Rm_instType_SERVER))\r
+ /* Find the transport for the higher level agent. Check for a remote Client Delegate first.\r
+ * If a connection does not exist check for a connection to a Server */\r
+ dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_CLIENT_DELEGATE);\r
+ if (dstTransportNode == NULL)\r
{\r
- /* Traverse the list until arriving at the upper level agent node */\r
- routeMap = routeMap->nextNode;\r
+ dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_SERVER);\r
}\r
\r
/* Create a RM packet using the service information */\r
- if (rmInst->transport.rmAllocPkt)\r
- {\r
- rmPkt = rmInst->transport.rmAllocPkt(routeMap->transHandle, sizeof(Rm_Packet));\r
- }\r
- else\r
- {\r
- /* The transport packet alloc API is not plugged */\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_ALLOC_API_NULL;\r
- return;\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_transportCreateResourceReqPkt(rmInst, dstTransportNode, \r
+ transaction, receipt);\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, receipt);\r
+ break;\r
+ default:\r
+ /* Invalid service type. Flag the error and return */\r
+ receipt->serviceResult = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
+ break;\r
}\r
\r
- /* Make sure a buffer for the packet was allocated */\r
- if (rmPkt == NULL)\r
+ if (receipt->serviceResult <= RM_SERVICE_ERROR_BASE)\r
{\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_NULL_PKT_BUF;\r
+ /* Return immediately because an error occurred allocating the packet */\r
return;\r
}\r
\r
- /* Make sure allocated buffer is large enough to fit the protocol packet plus the \r
- * rmPktLen field */\r
- if (rmPkt->rmPktLen < (sizeof(Rm_ProtocolPkt) + sizeof(uint32_t))\r
- { \r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL;\r
- return;\r
- }\r
-\r
- /* Create an ID for this transaction. The ID will be used for two purposes:\r
- * 1) Matching the response from the higher level RM agent to the request\r
- * 2) Provided to the service requesting component so that it can match the\r
- * service request with the response it receives via its callback function */\r
- transactionId = ...; /* NEED SCHEME FOR CREATING A MUTUALLY EXCLUSIVE PKT ID. CAN'T\r
- * CONFLICT WITH PCKT IDS CREATED ON OTHER RM INSTANCES */\r
- /* Initialize the rmPkt. Do not assume the transport code will do it */ \r
- memset((void *)rmPkt, 0, sizeof(Rm_Packet));\r
- \r
- /* Assign the rmData field to be the rmProtPkt */\r
- rmProtPkt = &(rmPkt->rmData[0]);\r
- /* Populate the RM packet using the service information */\r
- rmProtPkt->rmPktId = transactionId;\r
- strcpy((void *)rmProtPkt->rmInstName,(void *)rmInst->name);\r
- rmProtPkt->rmCmd = (uint32_t) transaction->command;\r
- if ((transaction->command == Rm_command_POLICY_REQUEST) ||\r
- (transaction->command == Rm_command_POLICY_RESPONSE)\r
- {\r
- /* Copy the policy data if the transaction is policy based */\r
- memcpy ((void *)rmProtPkt->u.rmPolicyData, (void *)transaction->u.policyData,\r
- RM_MAX_POLICY_SIZE_BYTES);\r
- }\r
- else\r
- {\r
- /* Otherwise copy the resource data */\r
- memcpy ((void *)&(rmProtPkt->u.resInfo), (void *) &(transaction->u.resourceInfo),\r
- sizeof(Rm_ResourceInfo));\r
- }\r
-\r
- /* Create an entry in the transaction queue */\r
- Rm_transactionQueueAdd(rmInst, transactionId, transaction->callback);\r
+ /* Switch the queued transaction to the awaiting response state */\r
+ transaction->state = Rm_transactionState_AWAITING_RESPONSE;\r
\r
/* Send the RM packet to the application transport */\r
- if (rmInst->transport.rmSend)\r
+ if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt))\r
{\r
- if (!(rmInst->transport.rmSend(routeMap->transHandle, rmPkt))\r
+ /* Non-NULL value returned by transport send. An error occurred\r
+ * in the transport while attempting to send the packet.*/\r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
+ /* Clean up the packet */\r
+ if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
{\r
- /* Transport returned an error */\r
-\r
- /* SHOULD TRANSPORT ERROR SOMEHOW BE OR'D WITH THE SERVICE ERROR ??? */\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
- return;\r
+ /* Non-NULL value returned by transport packet free. Flag the\r
+ * error */\r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
}\r
- }\r
- else\r
- {\r
- /* The transport packet send API is not plugged */\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_SEND_API_NULL;\r
return;\r
- } \r
+ }\r
\r
/* Inform requesting component that the service is being forwarded to a higher lever\r
* RM agent for processing. The result of the service will be provided to the \r
* component via the specified callback function */\r
- receipt->transactionResult = RM_SERVICE_PROCESSING;\r
- receipt->transactionId = transactionId;\r
- return;\r
+ receipt->serviceResult = RM_SERVICE_PROCESSING;\r
+ receipt->serviceId = transaction->id;\r
}\r
\r
void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction, \r
- Rm_TransactionReceipt *receipt)\r
+ Rm_TransactionReceipt *receipt)\r
{\r
+ Rm_Transaction *queuedTransaction = NULL;\r
+ \r
if (rmInst->instType == Rm_instType_CLIENT)\r
{\r
- if (transaction->command == Rm_command_RESOURCE_RESPONSE)\r
+ /* Check if the new transaction's ID matches any transactions waiting for\r
+ * responses. A transaction received as a response will have an ID that \r
+ * matches the transaction that originated the request packet */\r
+ if (queuedTransaction = Rm_transactionQueueFind(rmInst, transaction->id))\r
{\r
- /* Responses received by the Client must be issued back to the requesting\r
- * component */\r
- Rm_serviceResponder (rmInst, transaction, receipt);\r
+ if (queuedTransaction->state == Rm_transactionState_AWAITING_RESPONSE)\r
+ {\r
+ /* Found a transaction awaiting a response. Pass both transactions\r
+ * to the service responder for response processing */\r
+ Rm_serviceResponder(rmInst, transaction, queuedTransaction, receipt);\r
+ }\r
+ else\r
+ {\r
+ /* Request transaction was not in the awaiting response state. Flag the\r
+ * error in the receipt and return */\r
+ receipt->serviceResult = RM_SERVICE_ERROR_INVALID_REQUEST_TRANSACTION_STATE_UPON_RESPONSE;\r
+ }\r
}\r
else\r
{\r
- /* All service requests on Clients are forwarded to the higher level RM agent\r
- * either a Client Delegate or Server, based on the RM system architecture */\r
- Rm_transactionForwarder(rmInst, transaction, receipt);\r
+ /* This is a new transaction. Make sure the transaction is not a \r
+ * response transaction sent to the wrong RM instance */\r
+ if ((transaction->state == Rm_transactionState_RESOURCE_APPROVED) ||\r
+ (transaction->state == Rm_transactionState_RESOURCE_DENIED))\r
+ {\r
+ /* No matching request transaction. This transaction result was sent to the\r
+ * wrong RM instance. Flag the error in the receipt and return */\r
+ receipt->serviceResult = RM_SERVICE_ERROR_INVALID_TRANSACTION_RECEIVED_ON_CLIENT;\r
+ }\r
+ else\r
+ {\r
+ /* All service requests on Clients are forwarded to the higher level RM agent\r
+ * either a Client Delegate or Server, based on the RM system architecture */\r
+ Rm_transactionForwarder(rmInst, transaction, receipt);\r
+ }\r
}\r
}\r
else\r
\r
}\r
\r
-void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *requestInfo,\r
- Rm_ServiceRespInfo *responseInfo)\r
-{\r
- Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
- Rm_Transaction transaction;\r
- Rm_TransactionReceipt receipt;\r
- void *key;\r
-\r
- /* Prevent another component using the same instance from wiping out the current\r
- * service request */\r
- key = Rm_osalLocalCsEnter();\r
-\r
- /* Make sure serviceType is valid and that a callback function has been provided */\r
- if ((requestInfo->serviceType < Rm_service_FIRST) || \r
- (requestInfo->serviceType > Rm_service_LAST))\r
- {\r
- responseInfo->serviceResult = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
- Rm_osalLocalCsExit(key);\r
- return;\r
- }\r
- else if (requestInfo->serviceCallback == NULL)\r
- {\r
- /* RM Client's and Client Delegate's use blocking transports to consult with a \r
- * high-level RM agent prior to providing a response to the component. It is \r
- * assumed the component's cannot block. Therefore, all responses must go\r
- * through the callback function provided by the component. Return an error \r
- * if the component does not provide a callback function. */\r
- responseInfo->serviceResult = RM_SERVICE_ERROR_CALLBACK_NOT_PROVIDED;\r
- Rm_osalLocalCsExit(key);\r
- return;\r
- }\r
-\r
- /* Clear the transaction and receipt prior to using them */\r
- memset((void *) &transaction, 0, sizeof(Rm_Transaction));\r
- memset((void *) &transactionReceipt, 0, sizeof(Rm_TransactionReceipt));\r
-\r
- /* Transfer request information into the internal transaction format */\r
- transaction.command = (Rm_Command) requestInfo->serviceType;\r
- transaction.callback = requestInfo->serviceCallback;\r
- /* Policy modifications will never originate from components */\r
- strcpy ((void *) &(transaction.u.resourceInfo.resName)[0], (void *)requestInfo->resName);\r
- transaction.u.resourceInfo.resBase = requestInfo->resourceBase;\r
- transaction.u.resourceInfo.resNum = requestInfo->resourceNum;\r
- transaction.u.resourceInfo.resAlign = requestInfo->resourceAlign;\r
- strcpy ((void *) &(transaction.u.resourceInfo.resNsName)[0], (void *)requestInfo->resNsName);\r
-\r
- /* Pass the new transaction to the transaction processor */\r
- Rm_transactionProcessor (rmInst, &transaction, &receipt);\r
-\r
- /* Copy transaction receipt information into the response info fields for the \r
- * component based on the result of the transaction. Denied service requests\r
- * will have only a valid serviceResult field */\r
- responseInfo->serviceResult = receipt->transactionResult;\r
- if (responseInfo->serviceResult == RM_SERVICE_APPROVED)\r
- {\r
- /* Service was approved. The resource data should be passed back\r
- * to the component */\r
- responseInfo->resBase = receipt.resBase;\r
- responseInfo->resNum = receipt.resNum;\r
- }\r
- else if (responseInfo->serviceResult == RM_SERVICE_PROCESSING)\r
- {\r
- /* The service is still being processed. Provide the transaction ID\r
- * back to the component so that it can sort service responses received\r
- * via the provided callback function */\r
- responseInfo->requestId = receipt.transactionId;\r
- }\r
-\r
- Rm_osalLocalCsExit(key);\r
- \r
- return;\r
-}\r
-\r
-/* This function is executed when a RM instance receives a response to one of it's requests\r
- * and the information in the request must be provided to the original requesting component */\r
-void Rm_serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction, \r
- Rm_TransactionReceipt *receipt)\r
-{\r
- Rm_TransactionQueueEntry *transactionEntry;\r
- Rm_ServiceRespInfo responseInfo;\r
-\r
- /* Find the transaction request that matches the received response */\r
- transactionEntry = Rm_transactionQueueFind(rmInst,transaction->pktId);\r
-\r
- if (transactionEntry == NULL)\r
- {\r
- /* No transaction request matching the transaction ID was forwarded from\r
- * this RM instace */\r
- receipt->transactionResult = RM_SERVICE_ERROR_TRANSACTION_DOES_NOT_EXST_FOR_THIS_RM_INSTANCE;\r
- return;\r
- }\r
-\r
- /* Populate the service response with the transaction response details for\r
- * the component */\r
- responseInfo.requestId = transaction->pktId;\r
- responseInfo.serviceResult = transaction->details;\r
- responseInfo.resBase = transaction->u.resourceInfo.resBase;\r
- responseInfo.resNum = transaction->u.resourceInfo.resNum;\r
-\r
- /* Issue the callback to the requesting component with the response information */\r
- transactionEntry->transactionCallback(&responseInfo);\r
-\r
- /* Delete the transaction entry from the transaction queue */\r
- Rm_transactionQueueDelete(rmInst,transaction->pktId);\r
-\r
- return;\r
-}\r
-\r
/**********************************************************************\r
- *********************** Application visible APIs ***************************\r
+ ********************** Application visible APIs **********************\r
**********************************************************************/\r
\r
Rm_Handle Rm_init(Rm_InitCfg *initCfg)\r
rmInst->registeredWithDelegateOrServer = false;\r
rmInst->serviceCallback = NULL;\r
\r
+ /* The transport APIs must be provided */\r
+ if ((initCfg->rmAllocPktFuncPtr == NULL) ||\r
+ (initCfg->rmFreePktFuncPtr == NULL) ||\r
+ (initCfg->rmSendFuncPtr == NULL) ||\r
+ (initCfg->rmReceiveFuncPtr == NULL) ||\r
+ (initCfg->rmNumPktsReceivedFuncPtr == NULL))\r
+ {\r
+ return (NULL);\r
+ }\r
+ \r
/* Populate the instance transport callouts */\r
rmInst->transport.rmAllocPkt = initCfg->rmAllocPktFuncPtr;\r
rmInst->transport.rmFreePkt = initCfg->rmFreePktFuncPtr;\r
return ((Rm_Handle) rmInst);\r
}\r
\r
-Rm_Result Rm_preMainAllocResource(Rm_PreMainAllocInfo *preMainAllocInfo)\r
-{\r
-\r
-}\r
-\r
-Rm_ServiceHandle Rm_getServiceHandle(Rm_Handle rmHandle)\r
-{\r
- Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
- Rm_ServicesPort *newServicePort;\r
- \r
- /* Create a new service handle for the specified RM instance */\r
- \r
- /* Get memory for a new service port from local memory */\r
- newServicePort = Rm_osalMalloc (sizeof(Rm_ServicesPort), false);\r
-\r
- newServicePort->rmHandle = rmHandle;\r
- newServicePort->rmService = rmServiceHandler;\r
-\r
- return ((Rm_ServiceHandle) newServicePort);\r
-}\r
-\r
-Rm_TransportHandle Rm_registerTransport (Rm_Handle rmHandle, Rm_TransCfg *transCfg)\r
-{\r
- Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
- Rm_TransRouteMapNode *existingRouteMap = (Rm_TransRouteMapNode *) rmInst->routeMap;\r
- Rm_TransRouteMapNode *newRouteMapNode;\r
-\r
- /* RM Servers cannot connect to other Servers */\r
- if ((rmInst->instType == Rm_instType_SERVER) &&\r
- (transCfg->rmRemoteInstType == Rm_instType_SERVER))\r
- {\r
- return (NULL); /* Error -return null */\r
- }\r
-\r
- /* Verify Clients and Client Delegates are not registering with more than one \r
- * Client Delegate or Server. Assuming a Client Delegate can register with another \r
- * Client Delegate that can "act" as a server */\r
- if (((rmInst->instType == Rm_instType_CLIENT) || \r
- (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) &&\r
- ((transCfg->rmRemoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
- (transCfg->rmRemoteInstType == Rm_instType_SERVER)) &&\r
- rmInst->registeredWithDelegateOrServer)\r
- {\r
- return (NULL); /* Error -return null */\r
- } \r
-\r
- /* Error checks passed - Create a new transport handle for the specified RM instance */\r
- \r
- /* Get memory for a new routing map node from local memory */\r
- newRouteMapNode = Rm_osalMalloc (sizeof(Rm_TransRouteMapNode), false);\r
-\r
- /* Populate the new node. The address of the node itself is stored since this address is returned\r
- * to the application as the Rm_TransportHandle */\r
- newRouteMapNode->transHandle = newRouteMapNode;\r
- newRouteMapNode->remoteInstType = transCfg->rmRemoteInstType;\r
- newRouteMapNode->nextNode = NULL; /* New node will always be NULL */\r
-\r
- /* Check if there are any entries in the routing map */\r
- if (existingRouteMap)\r
- {\r
- /* At least one entry in the routing map. Add the new routing map node to the end of the\r
- * routing map node list */\r
- while (existingRouteMap->nextNode != NULL)\r
- {\r
- /* Traverse the list until arriving at the last node */\r
- existingRouteMap = existingRouteMap->nextNode;\r
- }\r
-\r
- /* Add the new node to the end of the list */\r
- existingRouteMap->nextNode = newRouteMapNode;\r
- }\r
- else\r
- {\r
- /* A routing map does not currently exist. The new node is the first entry */\r
- rmInst->routeMap = newRouteMapNode;\r
- }\r
-\r
- /* Specify RM instance has registered with a higher level agent */\r
- if ((newRouteMapNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
- (newRouteMapNode->remoteInstType == Rm_instType_SERVER))\r
- {\r
- rmInst->registeredWithDelegateOrServer = true;\r
- }\r
-\r
- return ((Rm_TransportHandle) newRouteMapNode);\r
-}\r
-\r
-Rm_Result Rm_unregisterTransport (Rm_Handle rmHandle, Rm_TransportHandle transHandle)\r
-{\r
- Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
- Rm_TransRouteMapNode *routeMapNode = (Rm_TransRouteMapNode *) rmInst->routeMap;\r
- Rm_TransRouteMapNode *prevNode = NULL;\r
-\r
- /* Make sure a routing map exists for the RM instance */\r
- if (routeMapNode == NULL)\r
- {\r
- return (-1); /* TEMP ERROR RETURN */\r
- }\r
-\r
- /* Find the transport handle within the specified RM instance's routing map. */\r
- while (1)\r
- {\r
- if (routeMapNode->transHandle == transHandle)\r
- {\r
- /* Match: break out of loop and delete the node */\r
- break; \r
- }\r
- else if (routeMapNode->nextNode == NULL)\r
- {\r
- return (-1); /* TEMP ERROR: transhandle does not exist for RM instance */\r
- }\r
-\r
- prevNode = routeMapNode;\r
- routeMapNode = routeMapNode->nextNode;\r
- }\r
- \r
- /* Delete the routing map node */\r
- if ((prevNode == NULL) && routeMapNode->nextNode)\r
- {\r
- /* Node to be deleted exists at start of route map. Map second node to be start of\r
- * node list as long as there are more than one routing map nodes */\r
- rmInst->routeMap = routeMapNode->nextNode;\r
- }\r
- else\r
- {\r
- /* Node to be deleted is in the middle or at end of the list. Adjust adjacent\r
- * nodes pointers. This covers the case where the node to be removed is at the\r
- * end of the list. */\r
- prevNode->nextNode = routeMapNode->nextNode;\r
- }\r
-\r
- /* Remove specification in RM instance that it has been connected to an upper level agent\r
- * if the node to be deleted has a remote instance type of Client Delegate or Server */\r
- if ((routeMapNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
- (routeMapNode->remoteInstType == Rm_instType_SERVER))\r
- {\r
- rmInst->registeredWithDelegateOrServer = false;\r
- }\r
-\r
- /* Delete the node, free the memory associated with the node. */\r
- Rm_osalFree((void *) routeMapNode, sizeof(Rm_TransRouteMapNode), false);\r
-\r
- return (RM_OK);\r
-}\r
-\r
-\r
-Rm_TransVerifyResult Rm_verifyTransport (Rm_Handle rmHandle, uint32_t timeout, \r
- Rm_TransFailData *failData)\r
-{\r
-\r
-}\r
-\r
-/* Resource requests that come directly from application go through this API */\r
-void Rm_requestService (void *rmHandle, Rm_ServiceReqInfo *requestInfo,\r
- Rm_ServiceRespInfo *responseInfo)\r
-{\r
- Rm_serviceHandler(rmHandle, requestInfo, responseInfo);\r
-}\r
-\r
-/* Used by the application to pass RM packets received from a transport to RM.\r
- * CODE THE FUNCTION SUCH THAT IT CAN BE CALLED DIRECTLY BY APP OR BE PLUGGED\r
- * AS PART OF AN ISR HANDLER FOR THE TRANSACTION RECEIVE */\r
-Rm_Result Rm_receiveRmPkt(Rm_Handle rmHandle, Rm_TransportHandle transHandle, Rm_Packet *pkt)\r
-{\r\r\r
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;\r
- Rm_ProtocolPkt rmProtPkt = &(pkt->rmData)[0];\r
- Rm_Transaction transaction;\r
- Rm_TransactionReceipt receipt;\r
- void *key;\r
-\r
- /* Lock access to the RM instance's transaction queue */\r
- key = Rm_osalLocalCsEnter(); \r
-\r
- /* Initialize the transaction and receipt */\r
- memset((void *)&transaction, 0, sizeof(Rm_Transaction));\r
- memset((void *)&receipt, 0, sizeof(Rm_TransactionReceipt));\r
-\r
- /* Create a new transaction based on the packet details */\r
- transaction.pktId = rmProtPkt->rmPktId;\r
- transaction.command = (Rm_Command) rmProtPkt->rmCmd;\r
- transaction.details = rmProtPkt->rmDetails;\r
- transaction.receivedTransport = transHandle;\r
- if ((transaction->command == Rm_command_POLICY_REQUEST) ||\r
- (transaction->command == Rm_command_POLICY_RESPONSE)\r
- {\r
- /* Copy the policy data if the transaction is policy based */\r
- memcpy ((void *)transInfo->u.policyData, (void *)rmProtPkt->u.rmPolicyData,\r
- RM_MAX_POLICY_SIZE_BYTES);\r
- }\r
- else\r
- {\r
- /* Otherwise copy the resource data */\r
- memcpy((void *)transaction.u.resourceInfo,(void *)rmProtPkt->u.resInfo, \r
- sizeof(Rm_ResourceInfo));\r
- }\r
-\r
- /* Process the transaction */\r
- Rm_transactionProcessor(rmInst,&transaction,&receipt)\r
-\r
- /* IS RECEIPT DATA NEEDED FOR ANYTHING HERE??*/\r
-\r
- Rm_osalLocalCsExit(key);\r
- return (0); \r
-}\r
-\r
-/* Application can call this API so that RM handles reception of packets based on\r
- * the RM handle and transport handle provided */\r
-Rm_Result Rm_getRmPkt(Rm_Handle rmHandle, Rm_TransportHandle transHandle)\r
-{\r
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;\r
- Rm_TransRouteMapNode *transNode = rmInst->routeMap;\r
- Rm_Packet *rmPkt = NULL;\r
- Rm_Result retVal = 0;\r
- void *key;\r
-\r
- /* Lock access to the RM instance's transaction queue */\r
- key = Rm_osalLocalCsEnter(); \r
-\r
- /* Verify the transport handle is registered with the RM handle */\r
- while (transNode != NULL)\r
- {\r
- if (transNode->transHandle == transHandle)\r
- {\r
- /* Break out of loop if an entry in the route map has been found */\r
- break;\r
- }\r
- transNode = transNode->nextNode;\r
- }\r
-\r
- if (transNode == NULL)\r
- {\r
- Rm_osalLocalCsExit(key);\r
- return (-1) /* ERROR: THE TRANSPORT HANDLE IS NOT REGISTERED WITH THE RM HANDLE */\r
- }\r
-\r
- /* Check to see if any RM packets are available. Process any available packets. */\r
- while (rmInst->transport.rmNumPktsReceived(transHandle))\r
- {\r
- rmInst->transport.rmReceive(transHandle, rmPkt);\r
-\r
- if (rmPkt == NULL)\r
- {\r
- retVal = -1; /* ERROR - PACKET RECEIVED FROM TRANSPORT IS NULL */\r
- }\r
-\r
- /* Pass the packet to RM */\r
- retVal = Rm_receiveRmPkt(rmHandle, transHandle, rmPkt);\r
- /* Delete the packet */\r
- rmInst->transport.rmFreePkt(transHandle, rmPkt);\r
-\r
- if (retVal)\r
- {\r
- /* If retVal is not 0 (Okay) there was an error so break out of loop and return */\r
- break;\r
- }\r
- }\r
- \r
- Rm_osalLocalCsExit(key);\r
- return (retVal); \r
-}\r
-\r
uint32_t Rm_getVersion (void)\r
{\r
return RM_VERSION_ID;\r
diff --git a/src/rmservices.c b/src/rmservices.c
--- /dev/null
+++ b/src/rmservices.c
@@ -0,0 +1,233 @@
+/**
+ * @file rmservices.c
+ *
+ * @brief
+ * This is the Resource Manager services source.
+ *
+ * \par
+ * ============================================================================
+ * @n (C) Copyright 2012, 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
+*/
+
+/* RM Types */
+#include <ti/drv/rm/rmtypes.h>
+
+/* RM external API includes */
+#include <ti/drv/rm/rmservices.h>
+
+/* RM internal API includes */
+#include <ti/drv/rm/include/rmloc.h>
+
+/* RM OSAL layer */
+#include <rm_osal.h>
+
+/**********************************************************************
+ ********************** Internal Functions ****************************
+ **********************************************************************/
+
+void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *serviceRequest,
+ Rm_ServiceRespInfo *serviceResponse)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ uint32_t transactionId = 0;
+ Rm_Transaction *transaction;
+ Rm_TransactionReceipt receipt;
+ void *key;
+
+ /* Prevent another component using the same instance from wiping out the current
+ * service request */
+ key = Rm_osalLocalCsEnter();
+
+ /* Make sure serviceType is valid and that a callback function has been provided */
+ if ((serviceRequest->serviceType < Rm_service_FIRST) ||
+ (serviceRequest->serviceType > Rm_service_LAST))
+ {
+ serviceResponse->serviceResult = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;
+ Rm_osalLocalCsExit(key);
+ return;
+ }
+ else if (serviceRequest->serviceCallback == NULL)
+ {
+ /* The RM Client and Client Delegate use blocking transports to consult with a
+ * high-level RM agent prior to providing a response to the component. It is
+ * assumed the component's cannot block. Therefore, all responses must go
+ * through the callback function provided by the component. Return an error
+ * if the component does not provide a callback function. */
+ serviceResponse->serviceResult = RM_SERVICE_ERROR_CALLBACK_NOT_PROVIDED;
+ Rm_osalLocalCsExit(key);
+ return;
+ }
+
+ /* Create an ID for this transaction. The ID will be used for two purposes:
+ * 1) Matching responses from higher level RM agents to requests
+ * 2) Provided to the entity that requested the service so that it can match its
+ * request with the response it receives via its callback function it provided */
+ transactionId = ...; /* NEED SCHEME FOR CREATING A MUTUALLY EXCLUSIVE PKT ID. CAN'T
+ * CONFLICT WITH PCKT IDS CREATED ON OTHER RM INSTANCES */
+ /* Create a new transaction */
+ transaction = Rm_transactionQueueAdd(rmInst, transactionId);
+
+ if (transaction == NULL)
+ {
+ /* Failed to create a new transaction */
+ serviceResponse->serviceResult = RM_SERVICE_ERROR_TRANSACTION_FAILED_TO_ALLOCATE;
+ }
+ else
+ {
+ /* Clear the receipt */
+ memset((void *) &receipt, 0, sizeof(Rm_TransactionReceipt));
+
+ /* Transfer request information into the transaction */
+ transaction->type = serviceRequest->serviceType;
+ strcpy((transaction->sourceInstName, rmInst->name);
+ transaction->callback = serviceRequest->serviceCallback;
+ transaction->state = Rm_transactionState_PROCESSING;
+ transaction->details = RM_SERVICE_PROCESSING;
+ strcpy(&(transaction->resourceInfo.name)[0], serviceRequest->resourceName);
+ transaction->resourceInfo.base = serviceRequest->resourceBase;
+ transaction->resourceInfo.range = serviceRequest->resourceRange;
+ transaction->resourceInfo.alignment = serviceRequest->resourceAlignment;
+ strcpy(&(transaction->resourceInfo.nsName)[0], serviceRequest->resourceNsName);
+
+ /* Pass the new transaction to the transaction processor */
+ Rm_transactionProcessor (rmInst, transaction, &receipt);
+
+ /* Copy transaction receipt information into the response info fields for the
+ * component based on the result of the transaction. Denied service requests
+ * will have only a valid serviceResult field */
+ serviceResponse->serviceResult = receipt->serviceResult;
+
+ /* Service was approved and service was an allocate request the resource
+ * data is passed back to the component */
+ if ((serviceResponse->serviceResult == RM_SERVICE_APPROVED) &&
+ ((transaction->type == Rm_service_RESOURCE_ALLOCATE) ||
+ (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME)))
+ {
+ serviceResponse->resourceBase = receipt.resourceBase;
+ serviceResponse->resourceRange = receipt.resourceRange;
+
+ /* Delete the transaction since a response was received immediately */
+ Rm_transactionQueueDelete(rmInst, transaction->id);
+ }
+ else if (serviceResponse->serviceResult == RM_SERVICE_PROCESSING)
+ {
+ /* The service is still being processed. Provide the transaction ID
+ * back to the component so that it can sort service responses received
+ * via the provided callback function */
+ serviceResponse->requestId = receipt.serviceId;
+ }
+ else if (serviceResponse->serviceResult <= RM_SERVICE_ERROR_BASE)
+ {
+ /* Delete the transaction since there was an error processing it. */
+ Rm_transactionQueueDelete(rmInst, transaction->id);
+ }
+ }
+
+ Rm_osalLocalCsExit(key);
+ return;
+}
+
+/* This function is executed when a RM instance receives a response to one of its requests
+ * and the information in the request must be provided to the original requesting component */
+void Rm_serviceResponder (Rm_Inst *rmInst, Rm_Transaction *responseTransaction,
+ Rm_Transaction *requestTransaction, Rm_TransactionReceipt *receipt)
+{
+ Rm_ServiceRespInfo serviceResponse;
+
+ /* Populate the service response with the transaction response details
+ * for the component */
+ serviceResponse.serviceResult = responseTransaction->details;
+ /* Pass back the ID that was provided to the component when it requested
+ * the service */
+ serviceResponse.requestId = requestTransaction->id;
+
+ /* Service was approved and service was an allocate request. The resource
+ * data is passed back to the component */
+ if ((serviceResponse->serviceResult == RM_SERVICE_APPROVED) &&
+ ((requestTransaction.type == Rm_service_RESOURCE_ALLOCATE) ||
+ (requestTransaction.type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||
+ (requestTransaction.type == Rm_service_RESOURCE_ALLOCATE_BY_NAME)))
+ {
+ serviceResponse->resourceBase = receipt.resourceBase;
+ serviceResponse->resourceRange = receipt.resourceRange;
+ }
+
+ /* Issue the callback to the requesting component with the response information */
+ requestTransaction->callback(&serviceResponse);
+
+ /* Delete both transactions from the transaction queue */
+ Rm_transactionQueueDelete(rmInst,responseTransaction->id);
+ Rm_transactionQueueDelete(rmInst,requestTransaction->id);
+
+ /* Response to component completed */
+ receipt.serviceResult = RM_SERVICE_ACTION_OKAY;
+ return;
+}
+
+/**********************************************************************
+ ********************** Application visible APIs **********************
+ **********************************************************************/
+
+void Rm_preMainAllocService(Rm_PreMainAllocInfo *preMainAllocInfo,
+ Rm_ServiceRespInfo *serviceResponse)
+{
+
+}
+
+
+Rm_ServicesPort *Rm_getServicePort(Rm_Handle rmHandle)
+{
+ Rm_Inst *rmInst = (Rm_Inst *) rmHandle;
+ Rm_ServicesPort *newServicePort = NULL;
+
+ /* Create a new service handle for the specified RM instance */
+
+ /* Get memory for a new service port from local memory */
+ newServicePort = Rm_osalMalloc (sizeof(Rm_ServicesPort), false);
+
+ /* Return NULL immediately if malloc returned NULL */
+ if (newServicePort == NULL)
+ {
+ return (newServicePort);
+ }
+
+ newServicePort->rmHandle = rmHandle;
+ newServicePort->rmService = Rm_serviceHandler;
+
+ return (newServicePort);
+}
+
+/**
+@}
+*/
diff --git a/src/rmtransport.c b/src/rmtransport.c
--- /dev/null
+++ b/src/rmtransport.c
@@ -0,0 +1,714 @@
+/**\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/rmtransport.h>\r
+\r
+/* RM internal includes */\r
+#include <ti/drv/rm/rmloc.h>\r
+#include <ti/drv/rm/rmtransportloc.h>\r
+\r
+/* RM OSAL layer */\r
+#include <rm_osal.h>\r
+\r
+/**********************************************************************\r
+ ********************** Internal Functions ****************************\r
+ **********************************************************************/\r
+\r
+Rm_TransportNode *Rm_transportNodeAdd(Rm_Inst *rmInst, Rm_TransportCfg *transportCfg)\r
+{\r
+ Rm_TransportNode *routeMap = (Rm_TransportNode *)rmInst->routeMap;\r
+ Rm_TransportNode *newTransportNode = NULL;\r
+ void *key;\r
+\r
+ /* Lock access to the RM instance's route map */\r
+ key = Rm_osalLocalCsEnter();\r
+\r
+ /* Get memory for a new transport node from local memory */\r
+ newTransportNode = Rm_osalMalloc (sizeof(Rm_TransportNode), false);\r
+\r
+ /* Return if the memory allocated for the transport node is NULL */\r
+ if (newTransportNode == NULL)\r
+ {\r
+ return;\r
+ }\r
+\r
+ /* Populate the new entry. */\r
+ newTransportNode->remoteInstType = transportCfg->remoteInstType;\r
+ strcpy(&(newTransportNode->remoteInstName)[0], transportCfg->remoteInstName);\r
+ newTransportNode->nextNode = NULL; /* New node will always be NULL */\r
+\r
+ /* Check if there are any nodes in the transport routing map */\r
+ if (routeMap)\r
+ {\r
+ /* At least one node in the routing map. Add the new node to the end of the\r
+ * routing map */\r
+ while (routeMap->nextNode != NULL)\r
+ {\r
+ /* Traverse the list until arriving at the last node */\r
+ routeMap = routeMap->nextNode;\r
+ }\r
+\r
+ /* Add the new node to the end of the list */\r
+ routeMap->nextNode = newTransportNode;\r
+ }\r
+ else\r
+ {\r
+ /* The transport routing map does not currently exist. The new node is the first node */\r
+ rmInst->routeMap = newTransportNode;\r
+ }\r
+ \r
+ Rm_osalLocalCsExit(key);\r
+\r
+ return (newTransportNode);\r
+}\r
+\r
+Rm_TransportNode *Rm_transportNodeFindTransportHandle(Rm_Inst *rmInst, \r
+ Rm_TransportHandle transportHandle)\r
+{\r
+ Rm_TransportNode *transportNode = (Rm_TransportNode *)rmInst->routeMap;\r
+\r
+ /* Make sure there is at least one node in the route map */\r
+ if (transportNode != NULL)\r
+ {\r
+ /* Find the transport node with the transport handle within the RM instance's\r
+ * route map. If the end of the route map is reached without finding the node the \r
+ * node pointer will be NULL */\r
+ while (transportNode != NULL)\r
+ {\r
+ /* The transport handle is the address of the transport node */\r
+ if (transportNode == ((Rm_TransportNode *)transportHandle)\r
+ {\r
+ /* Match: break out of loop and return the node */\r
+ break; \r
+ }\r
+ transportNode = transportNode->nextNode;\r
+ }\r
+ }\r
+\r
+ return (transportNode);\r
+}\r
+\r
+Rm_TransportNode *Rm_transportNodeFindRemoteName(Rm_Inst *rmInst, char *remoteName)\r
+{\r
+ Rm_TransportNode *transportNode = (Rm_TransportNode *)rmInst->routeMap;\r
+\r
+ /* Make sure there is at least one node in the route map */\r
+ if (transportNode != NULL)\r
+ {\r
+ /* Find the transport node with the provided remote instance name.\r
+ * If the end of the route map is reached without finding the node the \r
+ * node pointer will be NULL */\r
+ while (transportNode != NULL)\r
+ {\r
+ /* The transport handle is the address of the transport node */\r
+ if (strcmp(&(transportNode->remoteInstName)[0], remoteName) == 0)\r
+ {\r
+ /* Match: break out of loop and return the node */\r
+ break; \r
+ }\r
+ transportNode = transportNode->nextNode;\r
+ }\r
+ }\r
+\r
+ return (transportNode);\r
+}\r
+\r
+Rm_TransportNode *Rm_transportNodeFindRemoteInstType(Rm_Inst *rmInst,\r
+ Rm_InstType remoteInstType)\r
+{\r
+ Rm_TransportNode *transportNode = (Rm_TransportNode *)rmInst->routeMap;\r
+\r
+ /* Make sure there is at least one node in the route map */\r
+ if (transportNode != NULL)\r
+ {\r
+ /* Find the transport node with the provided remote instance type.\r
+ * If the end of the route map is reached without finding the node the \r
+ * node pointer will be NULL */\r
+ while (transportNode != NULL)\r
+ {\r
+ if (transportNode->remoteInstType == remoteInstType)\r
+ {\r
+ /* Match: break out of loop and return the node */\r
+ break; \r
+ }\r
+ transportNode = transportNode->nextNode;\r
+ }\r
+ }\r
+\r
+ return (transportNode);\r
+}\r
+\r
+Rm_TransportResult Rm_transportNodeDelete(Rm_Inst *rmInst, Rm_TransportHandle transportHandle)\r
+{\r
+ Rm_TransportNode *transportNode = (Rm_TransportNode *)rmInst->routeMap;\r
+ Rm_TransportNode *prevNode = NULL;\r
+ void *key;\r
+\r
+ /* Lock access to the RM instance's route map */\r
+ key = Rm_osalLocalCsEnter();\r
+\r
+ /* Make sure there is at least one entry in the transaction queue */\r
+ if (transportNode == NULL)\r
+ {\r
+ Rm_osalLocalCsExit(key);\r
+ return (RM_TRANSPORT_ERROR_NO_TRANSPORTS_REGISTERED);\r
+ }\r
+\r
+ /* Find the transport handle within the RM instance's route map. */\r
+ while (transportNode != NULL)\r
+ {\r
+ if (transportNode == (Rm_TransportNode *) transportHandle)\r
+ {\r
+ /* Match: break out of loop and delete the entry */\r
+ break; \r
+ }\r
+\r
+ prevNode = transportNode;\r
+ transportNode = transportNode->nextNode;\r
+ }\r
+\r
+ /* Traversed entire queue but did not find transaction */\r
+ if (transportNode == NULL)\r
+ {\r
+ Rm_osalLocalCsExit(key);\r
+ return (RM_TRANSPORT_ERROR_HANDLE_HAS_NOT_BEEN_REGISTERED);\r
+ }\r
+ else\r
+ {\r
+ /* Delete the transport node */\r
+ if ((prevNode == NULL) && transportNode->nextNode)\r
+ {\r
+ /* Node to be deleted exists at start of route map. Map second\r
+ * node to be start of route map as long as there are more than\r
+ * one nodes */\r
+ rmInst->routeMap = transportNode->nextNode;\r
+ }\r
+ else\r
+ {\r
+ /* Node to be deleted is in the middle or at end of the route map. Adjust adjacent\r
+ * node pointers. This covers the case where the node to be removed is at the\r
+ * end of the route map. */\r
+ prevNode->nextNode = transportNode->nextNode;\r
+ }\r
+\r
+ /* Free the memory associated with the node. */\r
+ Rm_osalFree((void *) transportNode, sizeof(Rm_TransportNode), false);\r
+ }\r
+\r
+ Rm_osalLocalCsExit(key);\r
+ return (RM_TRANSPORT_SUCCESSFUL);\r
+}\r
+\r
+Rm_Packet *Rm_transportCreateResourceReqPkt(Rm_Inst *rmInst, Rm_TransportNode *dstTransportNode,\r
+ Rm_Transaction *transaction, Rm_TransactionReceipt *receipt)\r
+{\r
+ Rm_Packet *rmPkt = NULL;\r
+ Rm_ResourceRequestPkt *resourceReqPkt = NULL;\r
+\r
+ /* Make sure a buffer for the packet was allocated */\r
+ if ((rmPkt = rmInst->transport.rmAllocPkt((Rm_TransportHandle)dstTransportNode, sizeof(Rm_Packet))) ==\r
+ NULL)\r
+ {\r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_ALLOC_PKT_ERROR;\r
+ return;\r
+ }\r
+\r
+ /* Make sure allocated buffer is large enough to fit the request packet plus the \r
+ * rmPktLen and Rm_PktType fields */\r
+ if (rmPkt->rmPktLen < (sizeof(Rm_ResourceRequestPkt) + sizeof(uint32_t) + sizeof(Rm_pktType))\r
+ { \r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL;\r
+ return;\r
+ }\r
+\r
+ /* Set the Rm Packet type */ \r
+ rmPkt->pktType = Rm_pktType_RESOURCE_REQUEST;\r
+ \r
+ /* Assign the packet's data field to be the start of the resource request packet */\r
+ resourceReqPkt = (Rm_ResourceRequestPkt *) rmPkt->data;\r
+ /* Populate the resource request packet using the transaction information */\r
+ resourceReqPkt->requestId = transaction->id;\r
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE)\r
+ {\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 == case Rm_service_RESOURCE_BLOCK_FREE)\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
+ }\r
+ strcpy(&(resourceReqPkt->instName)[0], rmInst->name);\r
+ /* Copy the resource data */\r
+ memcpy ((void *)&(resourceReqPkt->resourceInfo), (void *)&(transaction->resourceInfo),\r
+ sizeof(Rm_ResourceInfo));\r
+\r
+ return (rmPkt);\r
+}\r
+\r
+Rm_Packet *Rm_transportCreateResourceResponsePkt(Rm_Inst *rmInst, Rm_TransportNode *dstTransportNode,\r
+ Rm_Transaction *transaction, Rm_TransactionReceipt *receipt)\r
+{\r
+ Rm_Packet *rmPkt = NULL;\r
+ Rm_ResourceResponsePkt *resourceRespPkt = NULL;\r
+\r
+ /* Make sure a buffer for the packet was allocated */\r
+ if ((rmPkt = rmInst->transport.rmAllocPkt((Rm_TransportHandle)dstTransportNode, sizeof(Rm_Packet))) ==\r
+ NULL)\r
+ {\r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_ALLOC_PKT_ERROR;\r
+ return;\r
+ }\r
+\r
+ /* Make sure allocated buffer is large enough to fit the request packet plus the \r
+ * rmPktLen and Rm_PktType fields */\r
+ if (rmPkt->rmPktLen < (sizeof(Rm_ResourceResponsePkt) + sizeof(uint32_t) + sizeof(Rm_pktType))\r
+ { \r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL;\r
+ return;\r
+ }\r
+\r
+ /* Set the Rm Packet type */ \r
+ rmPkt->pktType = Rm_pktType_RESOURCE_RESPONSE;\r
+ \r
+ /* Assign the packet's data field to be the start of the resource response packet */\r
+ resourceRespPkt = (Rm_ResourceResponsePkt *)rmPkt->data);\r
+ /* Populate the resource response packet using the transaction information */\r
+ resourceRespPkt->responseId = transaction->id;\r
+ resourceRespPkt->requestResult = transaction->details;\r
+ /* Copy the resource data */\r
+ memcpy ((void *)&(resourceRespPkt->resourceInfo), (void *)&(transaction->resourceInfo),\r
+ sizeof(Rm_ResourceInfo));\r
+\r
+ return (rmPkt);\r
+}\r
+\r
+Rm_Packet *Rm_transportCreateNsRequestPkt(Rm_Inst *rmInst, Rm_TransportNode *dstTransportNode,\r
+ Rm_Transaction *transaction, Rm_TransactionReceipt *receipt)\r
+{\r
+ Rm_Packet *rmPkt = NULL;\r
+ Rm_NsRequestPkt *nsReqPkt = NULL;\r
+\r
+ /* Make sure a buffer for the packet was allocated */\r
+ if ((rmPkt = rmInst->transport.rmAllocPkt((Rm_TransportHandle)dstTransportNode, sizeof(Rm_Packet))) ==\r
+ NULL)\r
+ {\r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_ALLOC_PKT_ERROR;\r
+ return;\r
+ }\r
+\r
+ /* Make sure allocated buffer is large enough to fit the request packet plus the \r
+ * rmPktLen and Rm_PktType fields */\r
+ if (rmPkt->rmPktLen < (sizeof(Rm_NsRequestPkt) + sizeof(uint32_t) + sizeof(Rm_pktType))\r
+ { \r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL;\r
+ return;\r
+ }\r
+\r
+ /* Set the Rm Packet type */ \r
+ rmPkt->pktType = Rm_pktType_NAMESERVER_REQUEST;\r
+ \r
+ /* Assign the packet's data field to be the start of the NameServer request packet */\r
+ nsReqPkt = (Rm_NsRequestPkt *)rmPkt->data;\r
+ /* Populate the NameServer request packet using the transaction information */\r
+ nsReqPkt->requestId = transaction->id;\r
+ if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME)\r
+ {\r
+ nsReqPkt->nsRequestType = Rm_nsReqPktType_MAP_RESOURCE;\r
+ }\r
+ else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME)\r
+ {\r
+ nsReqPkt->nsRequestType = Rm_nsReqPktType_UNMAP_RESOURCE;\r
+ }\r
+ strcpy(&(nsReqPkt->instName)[0], rmInst->name);\r
+ /* Copy the NameServer request data */\r
+ memcpy ((void *)&(nsReqPkt->resourceInfo), (void *)&(transaction->resourceInfo),\r
+ sizeof(Rm_ResourceInfo));\r
+\r
+ return (rmPkt);\r
+}\r
+\r
+Rm_Packet *Rm_transportCreateNsResponsePkt(Rm_Inst *rmInst, Rm_TransportNode *dstTransportNode,\r
+ Rm_Transaction *transaction, Rm_TransactionReceipt *receipt)\r
+{\r
+ Rm_Packet *rmPkt = NULL;\r
+ Rm_NsResponsePkt *nsRespPkt = NULL;\r
+\r
+ /* Make sure a buffer for the packet was allocated */\r
+ if ((rmPkt = rmInst->transport.rmAllocPkt((Rm_TransportHandle)dstTransportNode, sizeof(Rm_Packet))) ==\r
+ NULL)\r
+ {\r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_ALLOC_PKT_ERROR;\r
+ return;\r
+ }\r
+\r
+ /* Make sure allocated buffer is large enough to fit the response packet plus the \r
+ * rmPktLen and Rm_PktType fields */\r
+ if (rmPkt->rmPktLen < (sizeof(Rm_NsResponsePkt) + sizeof(uint32_t) + sizeof(Rm_pktType))\r
+ { \r
+ receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL;\r
+ return;\r
+ }\r
+\r
+ /* Set the Rm Packet type */ \r
+ rmPkt->pktType = Rm_pktType_NAMESERVER_RESPONSE;\r
+ \r
+ /* Assign the packet's data field to be the start of the NameServer response packet */\r
+ nsRespPkt = (Rm_NsResponsePkt *)rmPkt->data;\r
+ /* Populate the NameServer response packet using the transaction information */\r
+ nsRespPkt->responseId = transaction->id;\r
+ nsRespPkt->requestResult = transaction->details;\r
+\r
+ return (rmPkt);\r
+}\r
+\r
+/**********************************************************************\r
+ *********************** Application visible APIs ***************************\r
+ **********************************************************************/\r
+\r
+Rm_TransportHandle Rm_transportRegister (Rm_Handle rmHandle, Rm_TransportCfg *transportCfg)\r
+{\r
+ Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
+ Rm_TransportNode *transportNode = NULL;\r
+ void *key;\r
+\r
+ /* Lock access to the RM instance */\r
+ key = Rm_osalLocalCsEnter();\r
+\r
+ /* RM Servers cannot connect to other Servers */\r
+ if ((rmInst->instType == Rm_instType_SERVER) &&\r
+ (transportCfg->rmRemoteInstType == Rm_instType_SERVER))\r
+ {\r
+ Rm_osalLocalCsExit(key);\r
+ return (NULL); /* Error - return null */\r
+ }\r
+\r
+ /* Verify Clients and Client Delegates are not registering with more than one \r
+ * Client Delegate or Server. Assuming a Client Delegate can register with another \r
+ * Client Delegate that can "act" as a server */\r
+ if (((rmInst->instType == Rm_instType_CLIENT) || \r
+ (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) &&\r
+ ((transportCfg->rmRemoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
+ (transportCfg->rmRemoteInstType == Rm_instType_SERVER)) &&\r
+ rmInst->registeredWithDelegateOrServer)\r
+ {\r
+ Rm_osalLocalCsExit(key);\r
+ return (NULL); /* Error - return null */\r
+ } \r
+\r
+ /* Error checks passed - Create a new transport handle for the specified RM instance and\r
+ * create a new node in the RM instance's routing map. */\r
+ transportNode = Rm_transportNodeAdd(rmInst, transportCfg);\r
+\r
+ /* Specify RM instance has registered with a higher level agent */\r
+ if ((transportNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
+ (transportNode->remoteInstType == Rm_instType_SERVER))\r
+ {\r
+ rmInst->registeredWithDelegateOrServer = true;\r
+ }\r
+\r
+ Rm_osalLocalCsExit(key);\r
+\r
+ return ((Rm_TransportHandle) transportNode);\r
+}\r
+\r
+Rm_TransportResult Rm_transportUnregister (Rm_Handle rmHandle, Rm_TransportHandle transportHandle)\r
+{\r
+ Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
+ Rm_TransportNode *transportNode = NULL;\r
+ Rm_TransportResult retVal = RM_TRANSPORT_SUCCESSFUL;\r
+ void *key;\r
+\r
+ /* Lock access to the RM instance */\r
+ key = Rm_osalLocalCsEnter(); \r
+\r
+ /* Check if the transportHandle exists in the RM instance's route map */\r
+ transportNode = Rm_transportNodeFindTransportHandle(rmInst, transportHandle);\r
+\r
+ if (transportNode == NULL)\r
+ {\r
+ /* Error - transport node does not exist in RM instance route map */\r
+ Rm_osalLocalCsExit(key);\r
+ return (RM_TRANSPORT_ERROR_HANDLE_HAS_NOT_BEEN_REGISTERED);\r
+ }\r
+\r
+ /* Remove specification that RM instance has been connected to an upper level agent\r
+ * if the node to be deleted has a remote instance type of Client Delegate or Server */\r
+ if ((transportNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
+ (transportNode->remoteInstType == Rm_instType_SERVER))\r
+ {\r
+ rmInst->registeredWithDelegateOrServer = false;\r
+ }\r
+\r
+ /* Delete the transport node */\r
+ retVal = Rm_transportNodeDelete(rmInst, transportHandle);\r
+\r
+ Rm_osalLocalCsExit(key);\r
+\r
+ return (retVal);\r
+}\r
+\r
+\r
+Rm_TransVerifyResult Rm_transportVerify (Rm_Handle rmHandle, uint32_t timeout, \r
+ Rm_TransFailData *failData)\r
+{\r
+\r
+}\r
+\r
+\r
+/* Used by the application to pass RM packets received from a transport to RM.\r
+ * CODE THE FUNCTION SUCH THAT IT CAN BE CALLED DIRECTLY BY APP OR BE PLUGGED\r
+ * AS PART OF AN ISR HANDLER FOR THE TRANSACTION RECEIVE */\r
+int32_t Rm_receivePktIsr(Rm_Handle rmHandle, Rm_TransportHandle transportHandle, Rm_Packet *pkt)\r
+{\r\r\r
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;\r
+ Rm_TransportNode *transportNode = (Rm_TransportNode *)transportHandle;\r
+ Rm_Transaction *transaction;\r
+ Rm_TransactionReceipt receipt;\r
+ void *key;\r
+\r
+ /* Make sure the transport handle is registered with the provided RM instance */\r
+ if (Rm_transportNodeFindTransportHandle(rmInst, transportHandle) == NULL)\r
+ {\r
+ /* Transport is not registered with the RM instance. Return an error.\r
+ * The packet cannot be freed since the transport handle is not valid. */\r
+ return (RM_TRANSPORT_ERROR_TRANSPORT_HANDLE_NOT_REGISTERED_WITH_INSTANCE);\r
+ }\r
+\r
+ /* Clear the transaction receipt */\r
+ memset((void *)&receipt, 0, sizeof(Rm_TransactionReceipt));\r
+\r
+ /* Based on packet type transfer the data to a transaction or a policy structure */\r
+ switch (pkt->pktType)\r
+ {\r
+ case Rm_pktType_RESOURCE_REQUEST:\r
+ Rm_ResourceRequestPkt *resourceReqPkt = (Rm_ResourceRequestPkt *)pkt->data;\r
+\r
+ /* The transaction ID will be the request ID. The request ID\r
+ * will become the response packet's ID so the requesting RM instance\r
+ * can filter received resource responses */\r
+ transaction = Rm_transactionQueueAdd(rmInst, resourceReqPkt->requestId);\r
+\r
+ /* Transfer the rest of the data into the transaction */\r
+ if (resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE)\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
+ {\r
+ transaction->type = case 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
+\r
+ strcpy(transaction->sourceInstName, resourceReqPkt->instName);\r
+ transaction->state = Rm_transactionState_PROCESSING;\r
+ memcpy ((void *)&(transaction->resourceInfo), (void *)&(resourceReqPkt->resourceInfo),\r
+ sizeof(Rm_ResourceInfo));\r
+\r
+ /* Process the transaction */\r
+ Rm_transactionProcessor(rmInst, transaction, &receipt);\r
+ break;\r
+ case Rm_pktType_RESOURCE_RESPONSE:\r
+ Rm_ResourceResponsePkt *resourceRespPkt = (Rm_ResourceResponsePkt *)pkt->data;\r
+\r
+ /* If the packet is a response packet the transaction ID should match a queued \r
+ * request transaction's ID */\r
+ transaction = Rm_transactionQueueAdd(rmInst, resourceRespPkt->responseId);\r
+\r
+ /* Transfer the rest of the data into the transaction */\r
+ if (resourceRespPkt->resourceReqType = Rm_resReqPktType_ALLOCATE)\r
+ {\r
+ transaction->type = Rm_service_RESOURCE_ALLOCATE;\r
+ }\r
+ else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_BLOCK_ALLOCATE)\r
+ {\r
+ transaction->type = Rm_service_RESOURCE_BLOCK_ALLOCATE;\r
+ }\r
+ else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_NAMED)\r
+ {\r
+ transaction->type = Rm_service_RESOURCE_ALLOCATE_BY_NAME;\r
+ }\r
+ else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_FREE)\r
+ {\r
+ transaction->type = Rm_service_RESOURCE_FREE;\r
+ }\r
+ else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_BLOCK_FREE)\r
+ {\r
+ transaction->type = case Rm_service_RESOURCE_BLOCK_FREE;\r
+ }\r
+ else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_FREE_NAMED)\r
+ {\r
+ transaction->type = Rm_service_RESOURCE_FREE_BY_NAME;\r
+ }\r
+\r
+ strcpy(transaction->sourceInstName, resourceReqPkt->instName);\r
+\r
+ if (resourceRespPkt->requestResult = RM_SERVICE_APPROVED)\r
+ {\r
+ transaction->state = Rm_transactionState_RESOURCE_APPROVED;\r
+ }\r
+ else if ((resourceRespPkt->requestResult >= RM_SERVICE_DENIED_BEGIN) &&\r
+ (resourceRespPkt->requestResult <= RM_SERVICE_DENIED_END)\r
+ {\r
+ transaction->state - Rm_transactionState_RESOURCE_DENIED;\r
+ } \r
+ /* The result of the request should be placed in the details field of the \r
+ * response transaction */\r
+ transaction->details = resourceRespPkt->requestResult;\r
+ memcpy ((void *)&(transaction->resourceInfo), (void *)&(resourceRespPkt->resourceInfo),\r
+ sizeof(Rm_ResourceInfo));\r
+ \r
+ /* Process the transaction */\r
+ Rm_transactionProcessor(rmInst, transaction, &receipt);\r
+ break;\r
+ case Rm_pktType_NAMESERVER_REQUEST:\r
+ break;\r
+ case Rm_pktType_NAMESERVER_RESPONSE:\r
+ break;\r
+ case Rm_pktType_POLICY_CHANGE:\r
+ break;\r
+ case Rm_pktType_POLICY_REQUEST:\r
+ break;\r
+ default:\r
+ /* Invalid packet type. Free the packet and return */\r
+ rmInst->transport.rmFreePkt(transportHandle, pkt);\r
+ return (RM_TRANSPORT_ERROR_INVALID_PACKET_TYPE);\r
+ }\r
+\r
+ /* Return the receipt's service result which contains the result return code\r
+ * for the receive packet */\r
+ return (receipt->serviceResult);\r
+}\r
+\r
+/* Application can call this API so that RM handles reception of packets based on\r
+ * the RM handle and transport handle provided */\r
+Rm_Result Rm_receivePktPolling(Rm_Handle rmHandle, Rm_TransportHandle transHandle)\r
+{\r
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;\r
+ Rm_TransRouteMapNode *transNode = rmInst->routeMap;\r
+ Rm_Packet *rmPkt = NULL;\r
+ Rm_Result retVal = 0;\r
+ void *key;\r
+\r
+ /* Lock access to the RM instance's transaction queue */\r
+ key = Rm_osalLocalCsEnter(); \r
+\r
+ /* Verify the transport handle is registered with the RM handle */\r
+ while (transNode != NULL)\r
+ {\r
+ if (transNode->transHandle == transHandle)\r
+ {\r
+ /* Break out of loop if an entry in the route map has been found */\r
+ break;\r
+ }\r
+ transNode = transNode->nextNode;\r
+ }\r
+\r
+ if (transNode == NULL)\r
+ {\r
+ Rm_osalLocalCsExit(key);\r
+ return (-1) /* ERROR: THE TRANSPORT HANDLE IS NOT REGISTERED WITH THE RM HANDLE */\r
+ }\r
+\r
+ /* Check to see if any RM packets are available. Process any available packets. */\r
+ while (rmInst->transport.rmNumPktsReceived(transHandle))\r
+ {\r
+ rmInst->transport.rmReceive(transHandle, rmPkt);\r
+\r
+ if (rmPkt == NULL)\r
+ {\r
+ retVal = -1; /* ERROR - PACKET RECEIVED FROM TRANSPORT IS NULL */\r
+ }\r
+\r
+ /* Pass the packet to RM */\r
+ retVal = Rm_receiveRmPkt(rmHandle, transHandle, rmPkt);\r
+ /* Delete the packet */\r
+ rmInst->transport.rmFreePkt(transHandle, rmPkt);\r
+\r
+ if (retVal)\r
+ {\r
+ /* If retVal is not 0 (Okay) there was an error so break out of loop and return */\r
+ break;\r
+ }\r
+ }\r
+ \r
+ Rm_osalLocalCsExit(key);\r
+ return (retVal); \r
+}\r
+\r
+\r
+/**\r
+@}\r
+*/\r