1 #include "MsTypes.h"
2 #include "utopia_private.h"
3 #include <stdlib.h>
4 #include "MsOS.h"
5 #include <stdio.h>
6 #include "utopia.h"
7 #include <string.h>
8 #include "utopia_dapi.h"
9 #include "ULog.h"
10
11 // length should be the same to definition
12 extern char moduleNames[][40];
13 extern char rpoolNames[][40];
14 extern char ResourceNames[][40];
15
16 UTOPIA_SHM_ID* utopiaShmIdArray[50]; // FIXME: enum
17 MS_U32 utopiaShmIdIndex = 0;
18
19 UTOPIA_MODULE_STR_LIST* UTOPIA_MODULE_STR_LIST_HEAD = NULL;
20 UTOPIA_MODULE_STR_LIST* UTOPIA_MODULE_STR_LIST_CURRENT = NULL;
21 UTOPIA_MODULE_STR_LIST* UTOPIA_MODULE_STR_LIST_PREV = NULL;
22
23 // should directly refer to SHM_ARRAY_LENGTH in nuttx/MsOS_nuttx.c
24 // FIXME: for now, we do it with hardcode
25 #define SHM_ARRAY_LENGTH 200
26
27 void* shmid2va_table[SHM_ARRAY_LENGTH] = {NULL};
28
29 extern UTOPIA_PRIVATE* psUtopiaPrivate;
30
31 //struct sembuf op_down[1] = {{0, -1, 0}}; // "0" means 0th semaphore in sem. set
32 // second "0" is flag, but I don't what it means
33 //struct sembuf op_up[1] = {{0, 1, 0}}; // "0" means 0th semaphore in sem. set
34 // second "0" is flag, but I don't what it means
35 //############################
36 //## Static Functions Start ##
37 //############################
obtain_sem(MS_U32 u32SemID)38 static void obtain_sem(MS_U32 u32SemID)
39 {
40 /* Perform down operation */
41 //semop(u32SemID, &op_down[0], 1);
42 MsOS_ObtainSemaphore(u32SemID, MSOS_WAIT_FOREVER);
43 }
44
release_sem(MS_U32 u32SemID)45 static void release_sem(MS_U32 u32SemID)
46 {
47 /* Perform down operation */
48 //semop(u32SemID, &op_up[0], 1);
49 MsOS_ReleaseSemaphore(u32SemID);
50 }
51
52
shmid2va(MS_U32 u32ShmID)53 static inline void* shmid2va(MS_U32 u32ShmID)
54 {
55 if (u32ShmID == 0xFFFFFFFF)
56 return NULL;
57 return shmid2va_table[u32ShmID];
58 }
59
60 // u32ShmID: shmid2va table index
61 // u32ShmAddr: shmid2va table value
fill_shmid2va_table(MS_U32 u32ShmID,void * u32ShmAddr)62 static MS_U32 fill_shmid2va_table(MS_U32 u32ShmID, void* u32ShmAddr)
63 {
64 if (shmid2va_table[u32ShmID] != NULL)
65 {
66 printf("error: register duplicated shared memory ID %d\n", (int)u32ShmID);
67 //while(1);
68 return -1;
69 }
70 else
71 {
72 shmid2va_table[u32ShmID] = u32ShmAddr;
73 return 0;
74 }
75 }
76
77 // u32ShmSize: user specified shared memory size
78 // shmName: user specified shared memory name
79 // p32RetShmID: for returning shared memory id
80 // return: shared memory address in virtual
shm_malloc(MS_U32 u32ShmSize,char * shmName,MS_U32 * pu32RetShmID)81 static void* shm_malloc(MS_U32 u32ShmSize, char* shmName, MS_U32* pu32RetShmID)
82 {
83 MS_U32 u32RetShmID, u32RetAddr, u32RetShmSize;
84 MS_U32 u32Ret;
85
86 // u32Ret: TRUE for success, FALSE for failure
87 u32Ret = MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_QUERY);
88
89 // MsOS_SHM_GetId need to be called for each process to set up per-process shmid2va table
90 // it's ok for duplicated calls with same shmName
91 MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID, &u32RetAddr, &u32RetShmSize, MSOS_SHM_CREATE);
92 fill_shmid2va_table(u32RetShmID, (void*)u32RetAddr);
93
94 // u32Ret: TRUE for success, FALSE for failure
95 // if failure --> first time allocation, memset to 0
96 if (u32Ret != 1)
97 memset((void*)u32RetAddr, 0, u32RetShmSize);
98
99 *pu32RetShmID = u32RetShmID;
100 return (void*)u32RetAddr;
101 }
102
103 enum eObjectType
104 {
105 E_TYPE_INSTANCE,
106 E_TYPE_MODULE,
107 E_TYPE_MODULE_SHM,
108 E_TYPE_RESOURCE_POOL,
109 E_TYPE_RESOURCE,
110 };
111
next_resource(void * pUnkown,enum eObjectType eObjectType)112 static UTOPIA_RESOURCE* next_resource(void* pUnkown, enum eObjectType eObjectType)
113 {
114 switch(eObjectType)
115 {
116 case E_TYPE_RESOURCE_POOL:
117 return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE_POOL*)pUnkown)->shmid_resource_head.ID);
118 case E_TYPE_RESOURCE:
119 return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE*)pUnkown)->shmid_next_resource.ID);
120 default:
121 printf("[utopia error] type is not supported\n");
122 while(1);
123 }
124 }
125
126 /*static MS_U32 isResourceInPool(UTOPIA_RESOURCE_POOL* psResourcePool, UTOPIA_RESOURCE* pResource)
127 {
128 MS_U32 i;
129 UTOPIA_RESOURCE* pResourceFound = NULL;
130
131 pResourceFound = nextResource(psResourcePool, E_TYPE_RESOURCE_POOL);
132 for (i = 0; i < psResourcePool->u32ResourceTotal; i++)
133 {
134 if (pResource == pResourceFound)
135 return 1;
136 pResourceFound = nextResource(pResourceFound, E_TYPE_RESOURCE);
137 }
138 return 0;
139 }*/
140
141 /*static UTOPIA_RESOURCE_POOL* nextResourcePool(void* pUnkown, enum eUtopiaType eUtopiaType)
142 {
143 switch(eUtopiaType)
144 {
145 case E_TYPE_INSTANT:
146 return (UTOPIA_RESOURCE_POOL*)shmid2va(((UTOPIA_INSTANCE*)pUnkown)->psModuleNode->psModuleNodeShm->shmid_UTOPIA_RESOURCE_POOL__Head.ID);
147 case E_TYPE_MODULE_SHM:
148 return (UTOPIA_RESOURCE_POOL*)shmid2va(((UTOPIA_MODULE_NODE_SHM*)pUnkown)->shmid_UTOPIA_RESOURCE_POOL__Head.ID);
149 case E_TYPE_RESOURCE_POOL:
150 return (UTOPIA_RESOURCE_POOL*)shmid2va(((UTOPIA_RESOURCE_POOL*)pUnkown)->shmid_UTOPIA_RESOURCE_POOL__Next.ID);
151 default:
152 printf("\n%s, %d, %s, what the fuck!\n", __FUNCTION__, __LINE__, __FILE__);
153 while(1);
154 }
155 }*/
156
157 /*static UTOPIA_RESOURCE_POOL* locate_pool_by_instant_resource(UTOPIA_INSTANCE* psInstant, UTOPIA_RESOURCE* pResource)
158 {
159 //MS_U32 u32ShmID = psInstant->psModuleNode->psModuleNodeShm->shmid_UTOPIA_RESOURCE_POOL__Head.ID;
160 //UTOPIA_RESOURCE_POOL* psResourcePool = (UTOPIA_RESOURCE_POOL*)shmid2va(u32ShmID);
161 UTOPIA_RESOURCE_POOL* psResourcePool = nextResourcePool(psInstant, E_TYPE_INSTANT);
162 while (psResourcePool != NULL && !isResourceInPool(psResourcePool, pResource))
163 {
164 psResourcePool = nextResourcePool(psResourcePool, E_TYPE_RESOURCE_POOL);
165 }
166
167 return psResourcePool;
168 }*/
169
170 // return located module address or NULL if not found
locate_module(MS_U32 u32ModuleID)171 void* locate_module(MS_U32 u32ModuleID)
172 {
173 UTOPIA_MODULE* pLocatedModule = psUtopiaPrivate->psModuleHead;
174
175 while (pLocatedModule != NULL && pLocatedModule->u32ModuleID != u32ModuleID)
176 pLocatedModule = pLocatedModule->psNext;
177
178 return pLocatedModule;
179 }
180
181 // case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
182 // case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
183 // case 3: at least one resource pool exists, and so is the located one --> *ppRPool != NULL & ppRPoolPrev doesn't matter
locate_resource_pool(UTOPIA_MODULE * pModule,MS_U32 u32LocatedRPoolID,UTOPIA_RESOURCE_POOL ** ppRPool,UTOPIA_RESOURCE_POOL ** ppRPoolPrev)184 static int locate_resource_pool(UTOPIA_MODULE* pModule, MS_U32 u32LocatedRPoolID
185 , UTOPIA_RESOURCE_POOL** ppRPool, UTOPIA_RESOURCE_POOL** ppRPoolPrev)
186 {
187 UTOPIA_RESOURCE_POOL* pRPool = TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
188 UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
189
190 while (pRPool != NULL && pRPool->u32PoolID != u32LocatedRPoolID)
191 {
192 pRPoolPrev = pRPool;
193 pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
194 }
195
196 *ppRPool = pRPool;
197 *ppRPoolPrev = pRPoolPrev;
198 return 0;
199 }
200
201 /*static void UtopiaResourcePoolLocate(MS_U32 u32PoolID, void** ppsResourcePoolTmp, void** ppsResourcePoolPrevTmp)
202 {
203 UTOPIA_RESOURCE_POOL** ppsResourcePool = (UTOPIA_RESOURCE_POOL**)ppsResourcePoolTmp;
204 UTOPIA_RESOURCE_POOL** ppsResourcePoolPrev = (UTOPIA_RESOURCE_POOL**)ppsResourcePoolPrevTmp;
205 UTOPIA_RESOURCE_POOL* psResourcePool = *ppsResourcePool;
206 UTOPIA_RESOURCE_POOL* psResourcePoolPrev = *ppsResourcePoolPrev = NULL;
207
208 while (psResourcePool != NULL && psResourcePool->u32PoolID != u32PoolID)
209 {
210 psResourcePoolPrev = psResourcePool;
211 psResourcePool = (UTOPIA_RESOURCE_POOL*)shmid2va(psResourcePool->shmid_next_rpool.ID);
212 }
213 *ppsResourcePool = psResourcePool;
214 *ppsResourcePoolPrev = psResourcePoolPrev;
215 }*/
216
locate_resource(UTOPIA_RESOURCE_POOL * pRPool,MS_U32 u32LocatedResourceID,UTOPIA_RESOURCE ** ppResource,UTOPIA_RESOURCE ** ppResourcePrev)217 static int locate_resource(UTOPIA_RESOURCE_POOL* pRPool, MS_U32 u32LocatedResourceID
218 , UTOPIA_RESOURCE** ppResource, UTOPIA_RESOURCE** ppResourcePrev)
219 {
220 UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(shmid2va(pRPool->shmid_resource_head.ID));
221 UTOPIA_RESOURCE* pResourcePrev = NULL;
222
223 while (pResource != NULL && (pResource->shmid_self.ID != u32LocatedResourceID))
224 {
225 pResourcePrev = pResource;
226 pResource = TO_RESOURCE_PTR(shmid2va(pResource->shmid_next_resource.ID));
227 }
228
229 *ppResource = pResource;
230 *ppResourcePrev = pResourcePrev;
231 return 0;
232 }
233
234 //##########################
235 //## Static Functions End ##
236 //##########################
237
238 //#############################
239 //## Instance Functions Start ##
240 //#############################
UtopiaInstanceCreate(MS_U32 u32PrivateSize,void ** ppInstance)241 MS_U32 UtopiaInstanceCreate(MS_U32 u32PrivateSize, void** ppInstance)
242 {
243 UTOPIA_INSTANCE* pInstance = NULL;
244
245 // check parameters
246 if (ppInstance == NULL)
247 printf("ppInstance should not be NULL\n");
248
249 pInstance = malloc(sizeof(UTOPIA_INSTANCE));
250 memset((void*)pInstance, 0, sizeof(UTOPIA_INSTANCE));
251 if (u32PrivateSize != 0)
252 {
253 pInstance->pPrivate = malloc(u32PrivateSize);
254 memset(pInstance->pPrivate, 0, u32PrivateSize);
255 }
256 //pInstant->u32DeviceDebugLevel = 0; // FIXME: u32DeviceDebugLevel is in UTOPIA_MODULE_NODE_SHM
257
258 *ppInstance = pInstance;
259 return 0; // FIXME: error code
260 }
261
UtopiaInstanceDelete(void * pInstance)262 MS_U32 UtopiaInstanceDelete(void* pInstance)
263 {
264 free(TO_INSTANCE_PTR(pInstance)->pPrivate);
265 free(pInstance);
266
267 return 0; // FIXME: error code
268 }
269
UtopiaInstanceGetPrivate(void * pInstance,void ** ppPrivate)270 MS_U32 UtopiaInstanceGetPrivate(void* pInstance, void** ppPrivate)
271 {
272 *ppPrivate = TO_INSTANCE_PTR(pInstance)->pPrivate;
273 return 0; // FIXME: error code
274 }
275
UtopiaInstanceGetModule(void * pInstance,void ** ppModule)276 MS_U32 UtopiaInstanceGetModule(void* pInstance, void** ppModule)
277 {
278 *ppModule = TO_INSTANCE_PTR(pInstance)->psModule;
279 return 0; // FIXME: error code
280 }
281
UtopiaInstanceGetModuleID(void * pInstance,MS_U32 * pu32ModuleID)282 MS_U32 UtopiaInstanceGetModuleID(void* pInstance, MS_U32* pu32ModuleID)
283 {
284 *pu32ModuleID = TO_INSTANCE_PTR(pInstance)->psModule->u32ModuleID;
285 return 0;
286 }
287
UtopiaInstanceGetModuleVersion(void * pInstance,MS_U32 * pu32Version)288 MS_U32 UtopiaInstanceGetModuleVersion(void* pInstance, MS_U32* pu32Version)
289 {
290 *pu32Version = TO_INSTANCE_PTR(pInstance)->psModule->u32Version;
291 return 0;
292 }
293
UtopiaInstanceGetAppRequiredModuleVersion(void * pInstance,MS_U32 * pu32ModuleVersion)294 MS_U32 UtopiaInstanceGetAppRequiredModuleVersion(void* pInstance, MS_U32* pu32ModuleVersion)
295 {
296 *pu32ModuleVersion = TO_INSTANCE_PTR(pInstance)->u32AppRequireModuleVersion;
297 return 0;
298 }
299 //###########################
300 //## Instant Functions End ##
301 //###########################
302
303 //############################
304 //## Module Functions Start ##
305 //############################
306 // assume one module for each driver, otherwise they have to pass module name as parameter
UtopiaModuleCreate(MS_U32 u32ModuleID,MS_U32 u32PrivateSize,void ** ppModule)307 MS_U32 UtopiaModuleCreate(MS_U32 u32ModuleID, MS_U32 u32PrivateSize, void** ppModule)
308 {
309 MS_U32 u32ShmID;
310 UTOPIA_MODULE_SHM* pModuleShm = NULL;
311 UTOPIA_MODULE* pModule = NULL;
312 void* pPrivate = NULL;
313 char privateName[50]; // FIXME: potential bug
314
315 // 1. create module@shm
316 pModuleShm = shm_malloc(sizeof(UTOPIA_MODULE_SHM), moduleNames[u32ModuleID], &u32ShmID);
317 pModuleShm->shmid_rpool_head.ID = 0xFFFFFFFF;
318
319 // 2. create module
320 pModule = malloc(sizeof(UTOPIA_MODULE));
321 memset(pModule, 0, sizeof(UTOPIA_MODULE));
322 pModule->u32ModuleID = u32ModuleID;
323 pModule->psModuleShm = pModuleShm;
324
325 // 3. create private of module
326 snprintf(privateName, sizeof(privateName), "%s_PRI", moduleNames[u32ModuleID]);
327 pPrivate = shm_malloc(u32PrivateSize, privateName, &(pModule->shmid_private.ID));
328
329 // 4. initial str private
330 pModule->shmid_str.ID=0xFFFFFFFF;
331
332 *ppModule = pModule;
333 return 0; //FIXME: error code
334 }
335
UtopiaModuleGetPrivate(void * pModule,void ** ppPrivate)336 MS_U32 UtopiaModuleGetPrivate(void* pModule, void** ppPrivate)
337 {
338 *ppPrivate = shmid2va(TO_MODULE_PTR(pModule)->shmid_private.ID);
339 return 0;
340 }
341
UtopiaModuleSetSTRPrivate(void * pModule,MS_U32 u32STRPrivateSize)342 MS_U32 UtopiaModuleSetSTRPrivate(void* pModule, MS_U32 u32STRPrivateSize)
343 {
344 char privateName[50]; // FIXME: potential bug
345 void* pPrivate = NULL;
346
347 /* check str private exist? */
348 if (!pModule)
349 {
350 printf("[utopia param error] module pointer should not be null\n");
351 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
352 }
353 if (0xFFFFFFFF != TO_MODULE_PTR(pModule)->shmid_str.ID)
354 {
355 printf("[utopia module error] set duplicated STR private of module: %s\n"
356 , moduleNames[TO_MODULE_PTR(pModule)->u32ModuleID]);
357 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
358 }
359
360 /* create str private of module */
361 snprintf(privateName, sizeof(privateName)
362 , "%s_STR", moduleNames[TO_MODULE_PTR(pModule)->u32ModuleID]);
363 pPrivate = shm_malloc(u32STRPrivateSize, privateName,
364 &(TO_MODULE_PTR(pModule)->shmid_str.ID));
365
366 if(pPrivate == NULL) //Coverity
367 {
368 printu("[utopia malloc error] Line: %d shm_malloc fail\n",__LINE__);
369 }
370
371 return 0;
372 }
373
UtopiaModuleGetSTRPrivate(void * pModule,void ** ppPrivate)374 MS_U32 UtopiaModuleGetSTRPrivate(void* pModule, void** ppPrivate)
375 {
376 /* check str private exist? */
377 if (!pModule)
378 {
379 printu("[utopia param error] module pointer should not be null\n");
380 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
381 }
382 if (0xFFFFFFFF == TO_MODULE_PTR(pModule)->shmid_str.ID)
383 {
384 printf("[utopia module error] NULL STR private of module: %s\n"
385 , moduleNames[TO_MODULE_PTR(pModule)->u32ModuleID]);
386 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
387 }
388
389 *ppPrivate = shmid2va(TO_MODULE_PTR(pModule)->shmid_str.ID);
390 return 0;
391 }
392
UtopiaModuleRegister(void * pModuleTmp)393 MS_U32 UtopiaModuleRegister(void* pModuleTmp)
394 {
395 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
396 UTOPIA_MODULE* pLocatedModule = NULL;
397
398 // check parameter
399 if (pModule == NULL)
400 {
401 printf("module pointer can't be null\n");
402 return 1; // FIXME: error code
403 }
404
405 pLocatedModule = TO_MODULE_PTR(locate_module(pModule->u32ModuleID));
406 if (pLocatedModule == NULL) // module is not yet registered
407 {
408 // insert module into list head
409 printf("register module: %s\n", moduleNames[pModule->u32ModuleID]);
410 pModule->psNext = psUtopiaPrivate->psModuleHead;
411 psUtopiaPrivate->psModuleHead = pModule;
412 return 0; // FIXME: error code
413 }
414 else // module is already registered
415 {
416 printf("error: register duplicated module: %s\n", moduleNames[pModule->u32ModuleID]);
417 return 1; // FIXME: error code
418 }
419 }
420
UtopiaModuleSetupFunctionPtr(void * pModuleTmp,FUtopiaOpen fpOpen,FUtopiaClose fpClose,FUtopiaIOctl fpIoctl)421 MS_U32 UtopiaModuleSetupFunctionPtr(void* pModuleTmp, FUtopiaOpen fpOpen, FUtopiaClose fpClose, FUtopiaIOctl fpIoctl)
422 {
423 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
424
425 pModule->fpOpen = fpOpen;
426 pModule->fpClose = fpClose;
427 pModule->fpIoctl = fpIoctl;
428
429 return 0; //FIXME: error code
430 }
431
UtopiaModuleSetupSTRFunctionPtr(void * pModuleTmp,FUtopiaSTR fpSTR)432 MS_U32 UtopiaModuleSetupSTRFunctionPtr(void* pModuleTmp, FUtopiaSTR fpSTR)
433 {
434 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
435
436 if (!pModuleTmp)
437 {
438 printf("[utopia param error] module pointer should not be null\n");
439 RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
440 }
441 pModule->fpSTR = fpSTR;
442 /* insert linked list */
443 UTOPIA_MODULE_STR_LIST_CURRENT = (UTOPIA_MODULE_STR_LIST*)malloc( sizeof(UTOPIA_MODULE_STR_LIST) );
444 UTOPIA_MODULE_STR_LIST_CURRENT->fpSTR = fpSTR;
445 UTOPIA_MODULE_STR_LIST_CURRENT->pModule = pModuleTmp;
446 UTOPIA_MODULE_STR_LIST_CURRENT->next = NULL;
447 if(UTOPIA_MODULE_STR_LIST_HEAD == NULL)
448 {
449 UTOPIA_MODULE_STR_LIST_HEAD = UTOPIA_MODULE_STR_LIST_CURRENT;
450 }
451 else
452 {
453 UTOPIA_MODULE_STR_LIST_PREV->next = UTOPIA_MODULE_STR_LIST_CURRENT;
454 }
455 UTOPIA_MODULE_STR_LIST_PREV = UTOPIA_MODULE_STR_LIST_CURRENT;
456 return 0;
457 }
458
UtopiaModuleSuspend(void)459 MS_U32 UtopiaModuleSuspend(void)
460 {
461 UTOPIA_MODULE_STR_LIST_CURRENT = UTOPIA_MODULE_STR_LIST_HEAD;
462 while(1)
463 {
464
465 if(UTOPIA_MODULE_STR_LIST_CURRENT == NULL)
466 break;
467
468 UTOPIA_MODULE_STR_LIST_CURRENT->fpSTR(E_POWER_SUSPEND, UTOPIA_MODULE_STR_LIST_CURRENT->pModule);
469 if(UTOPIA_MODULE_STR_LIST_CURRENT->next == NULL)
470 {
471 break;
472 }
473 UTOPIA_MODULE_STR_LIST_CURRENT = UTOPIA_MODULE_STR_LIST_CURRENT->next;
474 }
475 return 0;
476 }
477
UtopiaModuleResume(void)478 MS_U32 UtopiaModuleResume(void)
479 {
480 FUtopiaSTR fpSealSTR = NULL;
481 UTOPIA_MODULE_STR_LIST_CURRENT = UTOPIA_MODULE_STR_LIST_HEAD;
482 while(1)
483 {
484 if(UTOPIA_MODULE_STR_LIST_CURRENT == NULL)
485 {
486 break;
487 }
488 if(MODULE_SEAL == TO_MODULE_PTR(UTOPIA_MODULE_STR_LIST_CURRENT->pModule)->u32ModuleID)
489 {
490 fpSealSTR = UTOPIA_MODULE_STR_LIST_CURRENT->fpSTR;
491 }
492 else
493 {
494 UTOPIA_MODULE_STR_LIST_CURRENT->fpSTR(E_POWER_RESUME, UTOPIA_MODULE_STR_LIST_CURRENT->pModule);
495 }
496 if(UTOPIA_MODULE_STR_LIST_CURRENT->next == NULL)
497 {
498 break;
499 }
500 UTOPIA_MODULE_STR_LIST_CURRENT = UTOPIA_MODULE_STR_LIST_CURRENT->next;
501 }
502 if(fpSealSTR != NULL)
503 {
504 fpSealSTR(E_POWER_RESUME, UTOPIA_MODULE_STR_LIST_CURRENT->pModule);
505 }
506 return 0;
507 }
508
UtopiaModuleSetVersion(void * pModule,MS_U32 u32Version)509 MS_U32 UtopiaModuleSetVersion(void* pModule, MS_U32 u32Version)
510 {
511 TO_MODULE_PTR(pModule)->u32Version = u32Version;
512
513 return 0;
514 }
515
UtopiaModuleGetDebugLevel(void * pInstance,MS_U32 * pu32DebugLevel)516 MS_U32 UtopiaModuleGetDebugLevel(void* pInstance, MS_U32* pu32DebugLevel)
517 {
518 *pu32DebugLevel = TO_INSTANCE_PTR(pInstance)->psModule->u32DeviceDebugLevel;
519 return 0;
520 }
521
UtopiaModuleGetPtr(MS_U32 u32ModuleID,void ** ppModule)522 MS_U32 UtopiaModuleGetPtr(MS_U32 u32ModuleID, void** ppModule)
523 {
524 *ppModule = locate_module(u32ModuleID);
525
526 return 0;
527 }
528 //##########################
529 //## Module Functions End ##
530 //##########################
531
532 //##############################
533 //## Resource Functions Start ##
534 //##############################
UtopiaResourceCreate(char * resourceName,MS_U32 u32PrivateSize,void ** ppResource)535 MS_U32 UtopiaResourceCreate(char* resourceName, MS_U32 u32PrivateSize, void** ppResource)
536 {
537 MS_U32 u32RetResourceShmID;
538 UTOPIA_RESOURCE* pResource = NULL;
539 char privateName[50]; // FIXME: potential bug
540
541 // 1. create resource
542 pResource = shm_malloc(sizeof(UTOPIA_RESOURCE), resourceName, &(u32RetResourceShmID));
543 pResource->shmid_self.ID = u32RetResourceShmID;
544 pResource->shmid_next_resource.ID = 0xFFFFFFFF;
545 *ppResource = pResource;
546
547 // 2. create resource private
548 snprintf(privateName, sizeof(privateName), "%s_PRI", resourceName);
549 shm_malloc(u32PrivateSize, privateName, &(pResource->shmid_private.ID));
550
551 return 0; // FIXME: error code
552 }
553
UtopiaResourceGetPrivate(void * pResource,void ** ppPrivate)554 MS_U32 UtopiaResourceGetPrivate(void* pResource, void** ppPrivate)
555 {
556 *ppPrivate = shmid2va(TO_RESOURCE_PTR(pResource)->shmid_private.ID);
557 return 0;
558 }
559
560 // case 1: no resource pool -> create resource pool & attach resource to it. combine with case 2
561 // case 2: resource pool exists, but no mathcing resource pool -> create resource pool & attach resource to it. combine with case 1
562 // case 3: resource pool exists, and there's matching resource pool -> attach resource to it
UtopiaResourceRegister(void * pModuleTmp,void * pResourceTmp,MS_U32 u32RPoolID)563 MS_U32 UtopiaResourceRegister(void* pModuleTmp, void* pResourceTmp, MS_U32 u32RPoolID)
564 {
565 //lock(u32ResourcePoolsMutex)
566 //insert psResouce into psModuleNode->psResourcePoolHeads->psResourceHeads->psResource
567
568 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
569 UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(pResourceTmp);
570 char rpoolName[50];
571
572 // 1. deal with resource pool
573 UTOPIA_RESOURCE_POOL* pRPool = NULL;
574 UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
575 locate_resource_pool(pModule, u32RPoolID, &pRPool, &pRPoolPrev);
576 // case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
577 // case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
578 // case 3: at least one resource pool exists, and so is the located one --> *ppRPool != NULL & ppRPoolPrev doesn't matter
579 if (pRPool == NULL) { // case 1 or 2
580 MS_U32 u32RetRPoolShmID;
581 MS_U32 u32ModuleID = pModule->u32ModuleID;
582
583 snprintf(rpoolName, sizeof(rpoolName), "%s_%d", rpoolNames[u32ModuleID], (int)u32RPoolID);
584 pRPool = shm_malloc(sizeof(UTOPIA_RESOURCE_POOL), rpoolName, &u32RetRPoolShmID);
585 pRPool->shmid_self.ID = u32RetRPoolShmID;
586 pRPool->u32PoolID = u32RPoolID;
587 pRPool->shmid_next_rpool.ID = 0xFFFFFFFF;
588 pRPool->shmid_resource_head.ID = 0xFFFFFFFF;
589
590 // set up connection
591 if (pRPoolPrev == NULL) // case 1
592 {
593 pModule->psModuleShm->shmid_rpool_head.ID = u32RetRPoolShmID;
594 }
595 else // case 2
596 {
597 pRPoolPrev->shmid_next_rpool.ID = u32RetRPoolShmID;
598 }
599
600 pModule->psModuleShm->u32ResourcePoolTotal++;
601 }
602
603 // 2. deal with resource
604 pResource->shmid_rpool = pRPool->shmid_self;
605
606 UTOPIA_RESOURCE* pLocatedResource = NULL;
607 UTOPIA_RESOURCE* pLocatedResourcePrev = NULL;
608 locate_resource(pRPool, pResource->shmid_self.ID, &pLocatedResource, &pLocatedResourcePrev);
609 // case 1: there's no resource in pool --> pLocatedResource = NULL, pLocatedResourcePrev = NULL
610 // case 2: at least one resource exists, but not the located one --> pLocatedResource = NULL, pLocatedResourcePrev != NULL
611 // case 3: at least one resource exists, and so is the located one --> pLocatedResource != NULL, pLocatedResourcePrev doesn't matter
612 if (pLocatedResource == NULL) // case 1 or 2
613 {
614 if (pLocatedResourcePrev == NULL) // case 1
615 {
616 pRPool->shmid_resource_head.ID = pResource->shmid_self.ID;
617 }
618 else // case 2
619 {
620 pLocatedResourcePrev->shmid_next_resource.ID = pResource->shmid_self.ID;
621 }
622 pRPool->u32ResourceTotal++;
623
624 return 0;
625 }
626 else // case 3
627 {
628 // duplicated registration: it may be registered by other process
629 return 1;
630 }
631
632 //unlock(u32ResourcePoolsMutex)
633 }
634
635
UtopiaResourceObtain(void * pModule,MS_U32 u32RPoolID,void ** ppResource)636 MS_U32 UtopiaResourceObtain(void* pModule, MS_U32 u32RPoolID, void** ppResource)
637 {
638 //Search and get one resource from psModuleNode->psResourcePoolHeads
639 //set flag bit0 to 1 for using
640
641 //UTOPIA_RESOURCE_POOL* psResourcePool = NULL;
642 //psResourcePool = MODULE_PTR_TO_RPOOL_PTR(TO_MODULE_PTR(pModule));
643 //UTOPIA_RESOURCE_POOL* psResourcePoolPrev = NULL;
644 //UTOPIA_RESOURCE* psResource = NULL;
645 UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
646 UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
647 UTOPIA_RESOURCE* pAvailResource = NULL;
648 locate_resource_pool(TO_MODULE_PTR(pModule), u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
649
650
651 //semephone_lock(u32ResourcesSemaphore)
652 obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
653
654 pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
655 while (pAvailResource != NULL)
656 {
657 if (!(pAvailResource->bInUse))
658 {
659 pAvailResource->bInUse = true;
660 *ppResource = pAvailResource;
661 return 0;
662 }
663 else
664 {
665 pAvailResource = next_resource(pAvailResource, E_TYPE_MODULE);
666 }
667 }
668
669 return 1; // what kind of situation? FIXME: error code
670
671 //lock(u32ResourcesSemaphore)
672 //semephone_unlock(u32ResourcesSemaphore)
673 }
674
UtopiaResourceRelease(void * pResource)675 MS_U32 UtopiaResourceRelease(void* pResource)
676 {
677 UTOPIA_RESOURCE_POOL* pRPool = RESOURCE_PTR_TO_RPOOL_PTR(TO_RESOURCE_PTR(pResource));
678
679 // modify resource before releasing it, to avoid race condition
680 TO_RESOURCE_PTR(pResource)->bInUse = false;
681 release_sem(pRPool->u32ResourcesSemaphore);
682
683 return 0;
684 }
685
UtopiaModuleAddResourceStart(void * psModuleTmp,MS_U32 u32PoolID)686 MS_U32 UtopiaModuleAddResourceStart(void* psModuleTmp, MS_U32 u32PoolID)
687 {
688 return 0;
689 }
690
691 #define PERMS 0666
692 // semaphore num isn't equal to resource count
693 #define SEMAPHORE_NUM 1
694 //MS_U32 u32LastUtopiaSemID = UTOPIA_SEM_START;
UtopiaModuleAddResourceEnd(void * pModuleTmp,MS_U32 u32RPoolID)695 MS_U32 UtopiaModuleAddResourceEnd(void* pModuleTmp, MS_U32 u32RPoolID)
696 {
697 int u32SemaphoreID;
698 UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
699
700 UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
701 UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
702 //psResourcePool = (UTOPIA_RESOURCE_POOL*)shmid2va(pModule->psModuleShm->shmid_rpool_head.ID);
703 locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
704
705 if (pLocatedRPool->u32ResourcesSemaphore != 0 && pLocatedRPool->u32ResourcesSemaphore != 0xFFFFFFFF)
706 {
707 printf("semaphore id %d already exists\n", (int)pLocatedRPool->u32ResourcesSemaphore);
708 return 1; // FIXME: error code
709 }
710
711 //MS_U32* pu32SemKey = (MS_U32*)shmid2va(4); // 4 for semaphore private
712 MS_U32 u32PoolShmID = pModule->psModuleShm->shmid_rpool_head.ID;
713 UTOPIA_RESOURCE_POOL* pResourcePool = shmid2va(u32PoolShmID);
714 // FIXME: misuse? should I use utopia module resource instead?
715 MS_U32* pu32SemKey = (MS_U32*)shmid2va(pResourcePool->shmid_resource_head.ID);
716
717 //u32SemID = semget(*pu32SemKey, 0, IPC_CREAT | PERMS);
718 u32SemaphoreID = MsOS_InfoSemaphore(*pu32SemKey, &(pLocatedRPool->u32ResourceTotal), NULL, NULL);
719
720 //if(u32SemID == 0 || u32SemID == 0xFFFFFFFF)
721 if(u32SemaphoreID == FALSE)
722 {
723
724 //u32SemID = semget(*pu32SemKey, 1, IPC_CREAT | PERMS); // "1" means semaphore num, not its initial value
725 u32SemaphoreID = MsOS_CreateSemaphore(pLocatedRPool->u32ResourceTotal,E_MSOS_FIFO ,"dont care");
726 //if ((u32SemID != 0 && u32SemID != 0xFFFFFFFF)) // create success, increase *pu32SemKey for next sem create
727 //{
728 (*pu32SemKey)++;
729 //}
730
731 //while(u32SemID == 0 || u32SemID == 0xFFFFFFFF)
732 //{
733 //u32SemID = semget(*pu32SemKey, 1, IPC_CREAT | PERMS); // "1" means semaphore num, not its initial value
734 //u32SemID = MsOS_CreateSemaphore(0,E_MSOS_FIFO ,"dont care");
735 //(*pu32SemKey)++;
736 //}
737 if (u32SemaphoreID < 0)
738 {
739 printf("Couldn't create semaphore!\n");
740 //exit(-1);
741 }
742
743 //semctl(u32SemID, 0, SETVAL, psResourcePool->u32ResourceTotal); // "0" is the semaphore id in sem. set which we got by semget
744 //SEVAL, "1" set its initial value
745 //semctl(u32SemID, 0, SETVAL, 3); // "0" is the semaphore id in sem. set which we got by semget
746 }
747 pLocatedRPool->u32ResourcesSemaphore = u32SemaphoreID;
748
749 return 0;
750 }
751