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