xref: /utopia/UTPA2-700.0.x/modules/sem/drv/sem/mdrvSEM.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 #if !defined(MSOS_TYPE_LINUX_KERNEL)
2 #include "string.h"
3 #include <stdio.h>
4 #else
5 #include <linux/string.h>
6 #include <linux/slab.h>
7 #endif
8 #include "MsTypes.h"
9 #include "utopia_dapi.h"
10 #include "drvSEM.h"
11 #include "drvSEM_priv.h"
12 #include "MsOS.h"
13 #include "utopia.h"
14 
15 
16 enum
17 {
18     SEM_POOL_ID_SEM0 = 0
19 } eSEM_PoolID;
20 
21 //--------------------------------------------------------------------------------------------------
22 // Utopia2.0 will call this function to register module
23 //--------------------------------------------------------------------------------------------------
SEMRegisterToUtopia(void)24 void SEMRegisterToUtopia(void)
25 {
26     // 1. create a module(module_name, SHM_size), and register to utopia2.0
27     void* pUtopiaModule = NULL;
28     UtopiaModuleCreate(MODULE_SEM, 8, &pUtopiaModule);
29     UtopiaModuleRegister(pUtopiaModule);
30 
31     // register func for module, after register here, then ap call UtopiaOpen/UtopiaIoctl/UtopiaClose can call to these registered standard func
32     UtopiaModuleSetupFunctionPtr(pUtopiaModule, (FUtopiaOpen)SEMOpen, (FUtopiaClose)SEMClose, (FUtopiaIOctl)SEMIoctl);
33 
34     // 2. Resource register
35     void* psResource = NULL;
36 
37     // start func to add resources of a certain Resource_Pool
38     UtopiaModuleAddResourceStart(pUtopiaModule, SEM_POOL_ID_SEM0);
39 
40     // create a resouce and regiter it to a certain Resource_Pool, resource can alloc private for internal use
41     UtopiaResourceCreate("sem0", sizeof(SEM_RESOURCE_PRIVATE), &psResource);
42     UtopiaResourceRegister(pUtopiaModule, psResource, SEM_POOL_ID_SEM0);
43 
44     //UtopiaResourceCreate("sem1", sizeof(SEM_RESOURCE_PRIVATE), &psResource);
45     //UtopiaResourceRegister(pUtopiaModule, psResource, SEM_POOL_ID_SEM0);
46 
47     // end func to add resources of a certain Resource_Pool(this will set the ResourceSemaphore of this ResourcePool)
48     UtopiaModuleAddResourceEnd(pUtopiaModule, SEM_POOL_ID_SEM0);
49 
50     // Duplicated Init, check this(FIX LATER)
51     //ULOGD(TAG_SEM, "\033[35mFunction = %s, Line = %d, SEM_Init is opened\033[m\n", __PRETTY_FUNCTION__, __LINE__);
52     MDrv_SEM_Init();
53    // ULOGE(TAG_SEM, "\033[35mFunction = %s, Line = %d, SEM Register finished\033[m\n", __PRETTY_FUNCTION__, __LINE__);
54 }
55 
56 //--------------------------------------------------------------------------------------------------
57 // Utopia2.0 will call this function to get a instance to use SEM
58 // @ \b in: 32ModuleVersion => this is for checking if API version is the same
59 //--------------------------------------------------------------------------------------------------
SEMOpen(void ** ppInstance,MS_U32 u32ModuleVersion,void * pAttribute)60 MS_U32 SEMOpen(void** ppInstance, MS_U32 u32ModuleVersion, void* pAttribute)
61 {
62 #if defined(MSOS_TYPE_LINUX) || defined(MSOS_TYPE_NUTTX)
63     // for multi-process safe, check if already other Instance exist
64     // 1. use moduleID to get module, then try to get resource
65     void *pModule = NULL;
66     void *pResource = NULL;
67     UtopiaModuleGetPtr(MODULE_SEM, &pModule);
68 
69     if(UtopiaResourceObtain(pModule, SEM_POOL_ID_SEM0, &pResource) != 0)
70     {
71         //ULOGE(TAG_SEM, "UtopiaResourceObtainToInstant fail\n");
72         return 1;
73     }
74 
75     // if get a resource, check the module private SHM(default to be 0, only create at the first time) to decide whether this process can open instance
76     void *pSEMResPri = NULL;
77     UtopiaResourceGetPrivate(pResource, &pSEMResPri);
78 
79 //    #if defined (__aarch64__)
80 //        ULOGD(TAG_SEM, "\033[35mFunction = %s, Line = %d, current resource pri_shm content is: %lu\033[m\n", __PRETTY_FUNCTION__, __LINE__, *(MS_VIRT *)pSEMResPri);
81 //    #else
82 //        ULOGD(TAG_SEM, "\033[35mFunction = %s, Line = %d, current resource pri_shm content is: %u\033[m\n", __PRETTY_FUNCTION__, __LINE__, *(MS_VIRT *)pSEMResPri);
83 //    #endif
84 
85     if(*(MS_U32 *)pSEMResPri == 0)
86     {
87         *(MS_U32 *)pSEMResPri = 1;
88         UtopiaResourceRelease(pResource);
89     }
90     else
91     {
92         //ULOGE(TAG_SEM, "\033[35mFunction = %s, Line = %d, [SEM INFO] can not open an INSTANCE\033[m\n", __PRETTY_FUNCTION__, __LINE__);
93         UtopiaResourceRelease(pResource);
94         return 1;
95     }
96 #endif
97     //ULOGE(TAG_SEM, "\033[35mFunction = %s, Line = %d, [SEM INFO] OPEN INSTANCE...\033[m\n", __PRETTY_FUNCTION__, __LINE__);
98     SEM_INSTANT_PRIVATE *pSEMPri = NULL;
99 
100     // instance is allocated here, also can allocate private for internal use
101     UtopiaInstanceCreate(sizeof(SEM_INSTANT_PRIVATE), ppInstance);
102     // set the pSEMPri point to the private of UTOPIA_INSTANCE
103     UtopiaInstanceGetPrivate(*ppInstance, (void**)&pSEMPri);
104 
105     // setup func in private and assign the calling func in func ptr in instance private
106     pSEMPri->fpSEMGetResource = (IOCTL_SEM_GETRESOURCE)MDrv_SEM_Get_Resource_U2K;
107     pSEMPri->fpSEMFreeResource = (IOCTL_SEM_FREERESOURCE)MDrv_SEM_Free_Resource_U2K;
108     pSEMPri->fpSEMResetResource = (IOCTL_SEM_RESETRESOURCE)MDrv_SEM_Reset_Resource_U2K;
109     pSEMPri->fpSEMGetResourceID = (IOCTL_SEM_GETRESOURCEID)MDrv_SEM_Get_ResourceID_U2K;
110     pSEMPri->fpSEMLock = (IOCTL_SEM_LOCK)MDrv_SEM_Lock_U2K;
111     pSEMPri->fpSEMUnlock = (IOCTL_SEM_UNLOCK)MDrv_SEM_Unlock_U2K;
112     pSEMPri->fpSEMDelete = (IOCTL_SEM_DELETE)MDrv_SEM_Delete_U2K;
113 
114     return 0;
115 }
116 
SEMIoctl(void * pInstance,MS_U32 u32Cmd,void * pArgs)117 MS_U32 SEMIoctl(void* pInstance, MS_U32 u32Cmd, void* pArgs)
118 {
119     void* pModule = NULL;
120     UtopiaInstanceGetModule(pInstance, &pModule);
121 
122     SEM_INSTANT_PRIVATE* psSEMInstPri = NULL;
123     UtopiaInstanceGetPrivate(pInstance, (void**)&psSEMInstPri);
124 
125     PSEM_GETRESOURCE_PARAM pGetResource = NULL;
126     PSEM_FREERESOURCE_PARAM pFreeResource = NULL;
127     PSEM_RESETRESOURCE_PARAM pResetResource = NULL;
128     PSEM_GETRESOURCEID_PARAM pGetResourceID = NULL;
129     PSEM_GETLIBVER_PARAM pGetLibVer = NULL;
130     PSEM_LOCK_PARAM pLock = NULL;
131     PSEM_UNLOCK_PARAM pUnlock = NULL;
132     PSEM_DELETE_PARAM pDelete = NULL;
133 
134     MS_U32 u32Ret;
135 
136     switch(u32Cmd)
137     {
138         case MDrv_CMD_SEM_Get_Resource:
139             //ULOGD(TAG_SEM, "SEMIoctl - MDrv_CMD_SEM_Get_Resource\n");
140             pGetResource = (PSEM_GETRESOURCE_PARAM)pArgs;
141             u32Ret = psSEMInstPri->fpSEMGetResource(pGetResource->u8SemID, pGetResource->u16ResId);
142             return u32Ret;
143         case MDrv_CMD_SEM_Free_Resource:
144             //ULOGD(TAG_SEM, "SEMIoctl - MDrv_CMD_SEM_Free_Resource\n");
145             pFreeResource = (PSEM_FREERESOURCE_PARAM)pArgs;
146             u32Ret = psSEMInstPri->fpSEMFreeResource(pFreeResource->u8SemID, pFreeResource->u16ResId);
147             return u32Ret;
148         case MDrv_CMD_SEM_Reset_Resource:
149             //ULOGD(TAG_SEM, "SEMIoctl - MDrv_CMD_SEM_Reset_Resource\n");
150             pResetResource = (PSEM_RESETRESOURCE_PARAM)pArgs;
151             u32Ret = psSEMInstPri->fpSEMResetResource(pResetResource->u8SemID);
152             return u32Ret;
153         case MDrv_CMD_SEM_Get_ResourceID:
154             //ULOGD(TAG_SEM, "SEMIoctl - MDrv_CMD_SEM_Get_ResourceID\n");
155             pGetResourceID = (PSEM_GETRESOURCEID_PARAM)pArgs;
156             u32Ret = psSEMInstPri->fpSEMGetResourceID(pGetResourceID->u8SemID, pGetResourceID->pu16ResId);
157             return u32Ret;
158         case MDrv_CMD_SEM_Get_Num:
159             //ULOGD(TAG_SEM, "SEMIoctl - MDrv_CMD_SEM_Get_Num\n");
160             *((MS_U32 *)(pArgs)) = psSEMInstPri->fpSEMGetNum();
161             return 0;
162         case MDrv_CMD_SEM_GetLibVer:
163             //ULOGD(TAG_SEM, "SEMIoctl - MDrv_CMD_SEM_GetLibVer\n");
164             pGetLibVer = (PSEM_GETLIBVER_PARAM)pArgs;
165             u32Ret = psSEMInstPri->fpSEMGetLibVer(pGetLibVer->ppVersion);
166             return u32Ret;
167         case MDrv_CMD_SEM_Lock:
168             //ULOGD(TAG_SEM, "SEMIoctl - MDrv_CMD_SEM_Lock\n");
169             pLock = (PSEM_LOCK_PARAM)pArgs;
170             u32Ret = psSEMInstPri->fpSEMLock(pLock->u32SemID, pLock->u32WaitMs);
171             return u32Ret;
172         case MDrv_CMD_SEM_Unlock:
173             //ULOGD(TAG_SEM, "SEMIoctl - MDrv_CMD_SEM_Unlock\n");
174             pUnlock = (PSEM_UNLOCK_PARAM)pArgs;
175             u32Ret = psSEMInstPri->fpSEMUnlock(pUnlock->u32SemID);
176             return u32Ret;
177         case MDrv_CMD_SEM_Delete:
178             //ULOGD(TAG_SEM, "SEMIoctl - MDrv_CMD_SEM_Delete\n");
179             pDelete = (PSEM_DELETE_PARAM)pArgs;
180             u32Ret = psSEMInstPri->fpSEMDelete(pDelete->u32SemID);
181             return u32Ret;
182         default:
183             break;
184     };
185 
186     return 1; // FIXME: error code
187 }
188 
SEMClose(void * pInstance)189 MS_U32 SEMClose(void* pInstance)
190 {
191     UtopiaInstanceDelete(pInstance);
192 #if defined(MSOS_TYPE_LINUX) || defined(MSOS_TYPE_NUTTX)
193     // Restore resource pri_shm content
194     // 1. use moduleID to get module, then try to get resource
195     void *pModule = NULL;
196     void *pResource = NULL;
197     UtopiaModuleGetPtr(MODULE_SEM, &pModule);
198 
199     if(UtopiaResourceObtain(pModule, SEM_POOL_ID_SEM0, &pResource) != 0)
200     {
201         //ULOGE(TAG_SEM, "UtopiaResourceObtainToInstant fail\n");
202         return 1;
203     }
204 
205     // if get a resource, check the module private SHM(default to be 0, only create at the first time) to decide whether this process can open instance
206     void *pSEMResPri = NULL;
207     UtopiaResourceGetPrivate(pResource, &pSEMResPri);
208 
209     if(*(MS_U32 *)pSEMResPri == 0)
210     {
211         //ULOGE(TAG_SEM, "\033[35mFunction = %s, Line = %d, [SEMClose] Strange resource pri_shm content!!\033[m\n", __PRETTY_FUNCTION__, __LINE__);
212         UtopiaResourceRelease(pResource);
213         return 1;
214     }
215     else
216     {
217         //ULOGD(TAG_SEM, "\033[35mFunction = %s, Line = %d, [Multi-process Safe] Release an Instance!!\033[m\n", __PRETTY_FUNCTION__, __LINE__);
218         *(MS_U32 *)pSEMResPri = 0;
219         UtopiaResourceRelease(pResource);
220         return 0;
221     }
222 #endif
223     return 0;
224 }
225