]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blob - src/rm_services.c
Cleaned up test code to show clear PASS/FAIL
[keystone-rtos/rm-lld.git] / src / rm_services.c
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     }
97     
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);
116             
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;
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)
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);
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)
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);