1 /**
2 * @file rm_services.c
3 *
4 * @brief
5 * This is the Resource Manager services source.
6 *
7 * \par
8 * ============================================================================
9 * @n (C) Copyright 2012-2013, Texas Instruments, Inc.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the
21 * distribution.
22 *
23 * Neither the name of Texas Instruments Incorporated nor the names of
24 * its contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 * \par
40 */
42 /* Standard includes */
43 #include <string.h>
45 /* RM external API includes */
46 #include <ti/drv/rm/rm.h>
47 #include <ti/drv/rm/rm_services.h>
49 /* RM internal API includes */
50 #include <ti/drv/rm/include/rm_loc.h>
52 /* RM OSAL layer */
53 #include <rm_osal.h>
55 /**********************************************************************
56 ********************** Internal Functions ****************************
57 **********************************************************************/
59 void rmServiceInternalCallback(Rm_Handle rmHandle)
60 {
61 Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
63 /* Unblock so the serviceHandler can provide the response to the application */
64 Rm_osalLocalGateLeave(rmInst->localGateKey);
65 }
67 /**********************************************************************
68 ********************** Application visible APIs **********************
69 **********************************************************************/
71 /* FUNCTION PURPOSE: Handles application component service requests
72 ***********************************************************************
73 * DESCRIPTION: Receives service requests from application components
74 * and routes them to the transaction processor. If
75 * the service can be handled immediately the response
76 * will be provided in the service response. If the
77 * service requires a blocking operation the handler
78 * will provide a service ID back to the application.
79 * The response will be sent at a later time via the
80 * application supplied callback function.
81 */
82 void Rm_serviceHandler (void *rmHandle, const Rm_ServiceReqInfo *serviceRequest,
83 Rm_ServiceRespInfo *serviceResponse)
84 {
85 Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
86 Rm_Transaction *transaction;
88 if (rmInst->isLocked) {
89 serviceResponse->serviceState = RM_SERVICE_DENIED_RM_INSTANCE_LOCKED;
90 return;
91 }
93 if (serviceRequest->type >= Rm_service_LAST) {
94 serviceResponse->serviceState = RM_ERROR_INVALID_SERVICE_TYPE;
95 return;
96 }
98 transaction = rmTransactionQueueAdd(rmInst);
99 if (transaction) {
100 transaction->type = serviceRequest->type;
101 strncpy(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
102 transaction->callback.serviceCallback = serviceRequest->callback.serviceCallback;
103 transaction->state = RM_SERVICE_PROCESSING;
104 if (serviceRequest->resourceName) {
105 strncpy(transaction->resourceInfo.name, serviceRequest->resourceName, RM_NAME_MAX_CHARS);
106 }
107 transaction->resourceInfo.base = serviceRequest->resourceBase;
108 transaction->resourceInfo.length = serviceRequest->resourceLength;
109 transaction->resourceInfo.alignment = serviceRequest->resourceAlignment;
110 if (serviceRequest->resourceNsName) {
111 strncpy(transaction->resourceInfo.nameServerName, serviceRequest->resourceNsName, RM_NAME_MAX_CHARS);
112 }
114 /* Process received transaction */
115 rmProcessRouter(rmInst, transaction);
117 memset((void *)serviceResponse, 0, sizeof(Rm_ServiceRespInfo));
119 if ((transaction->state == RM_SERVICE_PROCESSING) && (transaction->callback.serviceCallback == NULL)) {
120 /* Block until response is received. Response will be received in transaction. */
121 rmInst->localGateKey = Rm_osalLocalGateEnter();
122 }
124 serviceResponse->rmHandle = rmHandle;
125 serviceResponse->serviceState = transaction->state;
126 if ((serviceResponse->serviceState == RM_SERVICE_PROCESSING) ||
127 (serviceResponse->serviceState == RM_SERVICE_APPROVED_STATIC)) {
128 /* Service still being processed. Static requests will have their validation responses sent once
129 * all transports have been established. Provide transaction ID back to component so it can sort
130 * service responses received via callback function */
131 serviceResponse->serviceId = transaction->localId;
132 }
134 if ((serviceResponse->serviceState == RM_SERVICE_APPROVED) ||
135 (serviceResponse->serviceState == RM_SERVICE_APPROVED_STATIC)) {
136 strncpy(serviceResponse->resourceName, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
137 serviceResponse->resourceBase = transaction->resourceInfo.base;
138 serviceResponse->resourceLength = transaction->resourceInfo.length;
139 }
141 /* Transactions still processing not deleted from queue. Includes static transactions which will be
142 * verified once all transports are up */
143 if ((serviceResponse->serviceState != RM_SERVICE_PROCESSING) &&
144 (serviceResponse->serviceState != RM_SERVICE_APPROVED_STATIC)) {
145 rmTransactionQueueDelete(rmInst, transaction->localId);
146 }
147 }
148 else {
149 serviceResponse->serviceState = RM_ERROR_SERVICE_TRANS_NOT_CREATED;
150 }
151 return;
152 }
154 /* FUNCTION PURPOSE: Opens the RM instance service handle
155 ***********************************************************************
156 * DESCRIPTION: Returns the service handle for an RM instance. Only
157 * one service handle can be opened per instance.
158 */
159 Rm_ServiceHandle *Rm_serviceOpenHandle(Rm_Handle rmHandle, int32_t *result)
160 {
161 Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
162 Rm_ServiceHandle *newServiceHandle = NULL;
164 *result = RM_OK;
166 if (rmInst->serviceHandle == NULL) {
167 newServiceHandle = Rm_osalMalloc(sizeof(Rm_ServiceHandle));
168 if (newServiceHandle) {
169 newServiceHandle->rmHandle = rmHandle;
170 newServiceHandle->Rm_serviceHandler = Rm_serviceHandler;
171 rmInst->serviceHandle = newServiceHandle;
172 }
173 else {
174 *result = RM_ERROR_SERVICE_HANDLE_MEM_ALLOC_FAILED;
175 }
176 }
177 else {
178 *result = RM_ERROR_SERVICE_HANDLE_ALREADY_OPENED;
179 }
180 return (newServiceHandle);
181 }
183 /* FUNCTION PURPOSE: Closes the RM instance service handle
184 ***********************************************************************
185 * DESCRIPTION: Closes the service handle for an RM instance.
186 */
187 int32_t Rm_serviceCloseHandle(Rm_ServiceHandle *rmServiceHandle)
188 {
189 Rm_Inst *rmInst = (Rm_Inst *)rmServiceHandle->rmHandle;
190 int32_t retVal = RM_OK;
192 if (rmInst->serviceHandle) {
193 Rm_osalFree((void *)rmServiceHandle, sizeof(Rm_ServiceHandle));
194 rmInst->serviceHandle = NULL;
195 }
196 else {
197 retVal = RM_ERROR_SERVICE_HANDLE_ALREADY_CLOSED;
198 }
199 return(retVal);
200 }