xref: /utopia/UTPA2-700.0.x/modules/msos/utopia_core/linux_kernel/utopia_dapi.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 
2 #ifdef MSOS_TYPE_LINUX_KERNEL
3 #include <linux/kernel.h>
4 #include <linux/string.h>
5 #include <linux/slab.h>
6 #include <linux/mutex.h>
7 #include <linux/syscalls.h> // for syscall
8 #include <linux/uaccess.h>
9 #else
10 #include <stdio.h>
11 #include <unistd.h> /* for usleep */
12 #include <string.h>
13 #include <stdlib.h>
14 #endif
15 #include "drvIPAUTH.h"
16 
17 #include "MsTypes.h"
18 #include "utopia_private.h"
19 #include "MsOS.h"
20 #include "utopia.h"
21 #include "utopia_dapi.h"
22 
23 
24 #define DEADLOCK_DEBUG 0
25 
26 #if DEADLOCK_DEBUG == 1
27 #include <execinfo.h>
28 #endif
29 
30 MS_U32 bt_threshold = 30000; /* 30 sec */
31 MS_U32 bt_period = 3000; /* 3 sec */
32 
33 // length should be the same to definition
34 extern char moduleNames[][40];
35 extern char rpoolNames[][40];
36 extern char ResourceNames[][40];
37 
38 extern UTOPIA_PID_LIST *g_Utopia_PID_root;
39 DEFINE_MUTEX(_Utopia_Instance_Mutex);
40 
41 
42 UTOPIA_SHM_ID* utopiaShmIdArray[50]; // FIXME: enum
43 MS_U32 utopiaShmIdIndex = 0;
44 
45 struct shm_info {
46 	void* va;
47 	char name[40]; // FIXME: array length should be unify
48 };
49 
50 /*
51  * could be equal to MAX_SHM_CLIENT_NUM=320 defined in MsOS_linux.c
52  * cause we ues shm id as table index, there may be holes in the table
53  */
54 #define SHM_INFO_TABLE_LENGTH 300
55 struct shm_info shm_info_table[SHM_INFO_TABLE_LENGTH] = {{NULL, ""}};
56 
57 extern UTOPIA_PRIVATE* psUtopiaPrivate;
58 
59 enum eObjectType
60 {
61 	E_TYPE_INSTANCE,
62 	E_TYPE_MODULE,
63 	E_TYPE_MODULE_SHM,
64 	E_TYPE_RESOURCE_POOL,
65 	E_TYPE_RESOURCE,
66 };
67 
68 /* 1st field: the n-th semaphore in set */
69 /* 2nd field: up/down operation */
70 /* 3rd field: ??? */
obtain_sem(MS_U32 u32SemID)71 static int obtain_sem(MS_U32 u32SemID)
72 {
73 	return MsOS_ObtainSemaphore(u32SemID, MSOS_WAIT_FOREVER);
74 }
75 
release_sem(MS_U32 u32SemID)76 static int release_sem(MS_U32 u32SemID)
77 {
78 	return MsOS_ReleaseSemaphore(u32SemID);
79 }
80 
shmid2va(MS_U32 u32ShmID)81 static inline void* shmid2va(MS_U32 u32ShmID)
82 {
83 	if (u32ShmID == 0xFFFFFFFF)
84 		return NULL;
85 	return shm_info_table[u32ShmID].va;
86 }
87 
isFirstCreation(void * pUnknown,enum eObjectType eObjectType)88 static inline int isFirstCreation(void* pUnknown, enum eObjectType eObjectType)
89 {
90 	switch(eObjectType)
91 	{
92 		case E_TYPE_MODULE_SHM:
93 			return TO_MODULE_SHM_PTR(pUnknown)->shmid_self.ID == 0;
94 		case E_TYPE_RESOURCE:
95 			return TO_RESOURCE_PTR(pUnknown)->shmid_self.ID == 0;
96 		case E_TYPE_RESOURCE_POOL:
97 			return TO_RPOOL_PTR(pUnknown)->shmid_self.ID == 0;
98 		default:
99 			printu("[utopia param error] type is not supported in %s\n",
100 					__FUNCTION__);
101 			RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
102 	}
103 }
104 
105 /*
106  * u32ShmSize: user specified shared memory size
107  * shmName: user specified shared memory name
108  * p32RetShmID: for returning shared memory id
109  * return: shared memory address in virtual
110  */
shm_malloc(MS_U32 u32ShmSize,char * shmName,void ** ppRetAddr,MS_U32 * pu32RetShmID)111 static MS_U32 shm_malloc(MS_U32 u32ShmSize, char* shmName,
112 		void** ppRetAddr, MS_U32* pu32RetShmID)
113 {
114 	MS_U32 u32RetShmID = 0, u32RetShmSize= 0;
115 	MS_U32 u32QueryRet, u32CreateRet, u32StatusRet;
116 	MS_VIRT vaRetAddr = 0;
117 
118 	/* FIXME: if shm exist, maybe query is enough to fill shm_info_table */
119 	/* 		--> no need to create again? */
120 
121 	/* check param. */
122 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(strcmp(shmName, "") == 0)) {
123 		printu("[utopia param error] shm name string should not be empty\n");
124 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
125 	}
126 
127 	/*
128 	 * u32QueryRet: 0 for not found
129 	 *         1 for existence
130 	 * u32RetShmID: 0 for not found
131 	 *              n for created share mem id, start from 1
132 	 */
133 	u32QueryRet = MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID
134 			, &vaRetAddr, &u32RetShmSize, MSOS_SHM_QUERY);
135 
136 	/*
137 	 * MsOS_SHM_GetId need to be called for each process
138 	 * to set up per-process shmid2va table
139 	 * it's ok for duplicated calls with same shmName
140 	 */
141 
142 	/*
143 	 * u32CreateRet: 0 for failed creation
144 	 *            1 for successful creation
145 	 * u32RetShmID: 0 for not found
146 	 *              n for created share mem id, start from 1
147 	 */
148 	u32CreateRet = MsOS_SHM_GetId((MS_U8*)shmName, u32ShmSize, &u32RetShmID
149 			, &vaRetAddr, &u32RetShmSize, MSOS_SHM_CREATE);
150 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(u32CreateRet == 0)) {
151 		printu("[utopia shm error] something wrong in MsOS_SHM_GetId\n");
152 		printu("is SHM_SIZE reached?\n");
153 		printu("is MAX_SHM_CLIENT_NUM reached?\n");
154 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
155 	}
156 
157 	/* check whether table limit is reached? */
158 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(u32RetShmID >= SHM_INFO_TABLE_LENGTH)) {
159 		printu("[utopia shm error] shm id %d exceeds shm-info table length %d\n"
160 				, (int)u32RetShmID, SHM_INFO_TABLE_LENGTH);
161 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
162 	}
163 
164 	/* it has already been registered */
165 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(shm_info_table[u32RetShmID].va != NULL)) {
166 		printu("[utopia shm error] register duplicated shared memory ID %d: %s@%p\n"
167 				, (int)u32RetShmID, shm_info_table[u32RetShmID].name
168 				, shm_info_table[u32RetShmID].va);
169 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
170 	} else { /* fill the table */
171 		shm_info_table[u32RetShmID].va = (void*)vaRetAddr;
172 		strncpy(shm_info_table[u32RetShmID].name
173 				, shmName, sizeof(shm_info_table[0].name));
174 	}
175 
176 	/*
177 	 * u32QueryRet: TRUE for success, FALSE for failure
178 	 * if failure --> first time allocation, memset to 0
179 	 */
180 	if (u32QueryRet != 1) {
181 		memset((void*)vaRetAddr, 0, u32RetShmSize);
182 		u32StatusRet = UTOPIA_STATUS_SUCCESS;
183 	} else
184 		u32StatusRet = UTOPIA_STATUS_SHM_EXIST;
185 
186 	*pu32RetShmID = u32RetShmID;
187 	*ppRetAddr = (void*)vaRetAddr;
188 	return u32StatusRet;
189 }
190 
next_resource(void * pUnkown,enum eObjectType eObjectType)191 static UTOPIA_RESOURCE* next_resource(void* pUnkown
192 		, enum eObjectType eObjectType)
193 {
194 	switch(eObjectType)
195 	{
196 		case E_TYPE_RESOURCE_POOL:
197 			return (UTOPIA_RESOURCE*)shmid2va(
198 					((UTOPIA_RESOURCE_POOL*)pUnkown)->shmid_resource_head.ID);
199 		case E_TYPE_RESOURCE:
200 			return (UTOPIA_RESOURCE*)shmid2va(
201 					((UTOPIA_RESOURCE*)pUnkown)->shmid_next_resource.ID);
202 		default:
203 			printu("[utopia error] type is not supported in %s\n", __FUNCTION__);
204 			RET_OR_BLOCK(NULL);
205 	}
206 }
207 
208 #if DEADLOCK_DEBUG == 1
print_trace(void)209 void print_trace(void)
210 {
211 	void *array[10];
212 	size_t size;
213 	char **strings;
214 	size_t i;
215 
216 	size = backtrace (array, 10);
217 	strings = backtrace_symbols (array, size);
218 
219 	printu ("Obtained %zd stack frames.\n", size);
220 
221 	for (i = 0; i < size; i++)
222 		printu ("%s\n", strings[i]);
223 
224 	free (strings);
225 }
226 #endif
227 
228 /* return located module address or NULL if not found */
locate_module(MS_U32 u32ModuleID)229 static void* locate_module(MS_U32 u32ModuleID)
230 {
231 	UTOPIA_MODULE* pLocatedModule = psUtopiaPrivate->psModuleHead;
232 
233 	while (pLocatedModule != NULL && pLocatedModule->u32ModuleID != u32ModuleID)
234 		pLocatedModule = pLocatedModule->psNext;
235 
236 	return pLocatedModule;
237 }
238 
239 /*
240  * case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
241  * case 2: at least one resource pool exists, but not the located one
242  * 		--> *ppRPool = NULL & *ppRPoolPrev != NULL
243  * case 3: at least one resource pool exists, and so is the located one
244  * 		--> *ppRPool != NULL & ppRPoolPrev doesn't matter
245  */
locate_resource_pool(UTOPIA_MODULE * pModule,MS_U32 u32LocatedRPoolID,UTOPIA_RESOURCE_POOL ** ppRPool,UTOPIA_RESOURCE_POOL ** ppRPoolPrev)246 static int locate_resource_pool(UTOPIA_MODULE* pModule, MS_U32 u32LocatedRPoolID
247 		, UTOPIA_RESOURCE_POOL** ppRPool, UTOPIA_RESOURCE_POOL** ppRPoolPrev)
248 {
249 	UTOPIA_RESOURCE_POOL* pRPool
250 		= TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
251 	UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
252 
253 	while (pRPool != NULL && pRPool->u32PoolID != u32LocatedRPoolID)
254 	{
255 		pRPoolPrev = pRPool;
256 		pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
257 	}
258 
259 	*ppRPool = pRPool;
260 	*ppRPoolPrev = pRPoolPrev;
261 	return 0;
262 }
263 
locate_resource(UTOPIA_RESOURCE_POOL * pRPool,MS_U32 u32LocatedResourceID,UTOPIA_RESOURCE ** ppRes,UTOPIA_RESOURCE ** ppResPrev)264 static int locate_resource(UTOPIA_RESOURCE_POOL* pRPool
265 		, MS_U32 u32LocatedResourceID, UTOPIA_RESOURCE** ppRes
266 		, UTOPIA_RESOURCE** ppResPrev)
267 {
268 	UTOPIA_RESOURCE* pRes
269 		= TO_RESOURCE_PTR(shmid2va(pRPool->shmid_resource_head.ID));
270 	UTOPIA_RESOURCE* pResPrev = NULL;
271 
272 	while (pRes != NULL
273 			&& (pRes->shmid_self.ID != u32LocatedResourceID))
274 	{
275 		pResPrev = pRes;
276 		pRes = TO_RESOURCE_PTR(shmid2va(pRes->shmid_next_resource.ID));
277 	}
278 
279 	*ppRes = pRes;
280 	*ppResPrev = pResPrev;
281 	return 0;
282 }
283 
utopia_create_instance_table(pid_t pid,void * pInstance)284 static int utopia_create_instance_table(pid_t pid, void* pInstance)
285 {
286     // 1. Check Pid Exist?
287     MS_BOOL bExist = FALSE;
288     UTOPIA_PID_LIST *CurrNode, *PreNode;
289     int count;
290 
291     mutex_lock(&_Utopia_Instance_Mutex);
292 
293     if (g_Utopia_PID_root)
294     {
295         CurrNode = g_Utopia_PID_root;
296         while(CurrNode)
297         {
298             if (pid == CurrNode->pid)
299             {
300                 bExist = TRUE;
301                 break;
302             }
303             PreNode = CurrNode;
304             CurrNode = CurrNode->pNext;
305         }
306 
307         if (!bExist)
308         {
309             CurrNode = malloc(sizeof(UTOPIA_PID_LIST));
310             memset((void*)CurrNode, 0, sizeof(UTOPIA_PID_LIST));
311             CurrNode->pid = pid;
312             PreNode->pNext = CurrNode;
313         }
314     }
315     else
316     {
317         CurrNode = malloc(sizeof(UTOPIA_PID_LIST));
318         memset((void*)CurrNode, 0, sizeof(UTOPIA_PID_LIST));
319         CurrNode->pid = pid;
320         g_Utopia_PID_root = CurrNode;
321     }
322 
323     mutex_unlock(&_Utopia_Instance_Mutex);
324 
325     // 2. Add Instance.
326     if (CurrNode->instance_count >= INSTANCE_MAX)
327     {
328         printk("[Utopia2K] Instance Table Error: Array is too small.\n");
329         return 0;
330     }
331 
332     mutex_lock(&_Utopia_Instance_Mutex);
333     for (count = 0; count < INSTANCE_MAX; count++)
334     {
335         if (NULL == CurrNode->instance_list[count])
336         {
337             CurrNode->instance_list[count] = pInstance;
338             CurrNode->instance_count++;
339             break;
340         }
341     }
342     mutex_unlock(&_Utopia_Instance_Mutex);
343 
344     return 0;
345 }
346 
utopia_delete_instance_table(pid_t pid,void * pInstance)347 static int utopia_delete_instance_table(pid_t pid, void* pInstance)
348 {
349     int count, zero_count=0;
350     MS_BOOL bFind = FALSE;
351     UTOPIA_PID_LIST *CurrNode, *PreNode, *NextNode;
352     CurrNode = g_Utopia_PID_root;
353     PreNode = CurrNode;
354 
355     mutex_lock(&_Utopia_Instance_Mutex);
356     while(CurrNode)
357     {
358         if (pid == CurrNode->pid)
359         {
360             bFind = TRUE;
361             break;
362         }
363         PreNode = CurrNode;
364         CurrNode = CurrNode->pNext;
365     }
366 
367     if (MSOS_BRANCH_PREDICTION_UNLIKELY(!bFind))
368     {
369         printu("[Utopia2K] Can't fin pid in table:%d\n", pid);
370         mutex_unlock(&_Utopia_Instance_Mutex);
371         RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
372     }
373 
374     for(count = 0; count < INSTANCE_MAX; count++)
375     {
376         if (pInstance == CurrNode->instance_list[count])
377         {
378             CurrNode->instance_list[count] = NULL;
379             CurrNode->instance_count--;
380             zero_count++;
381             //break;
382             continue;
383         }
384 
385         if (NULL == CurrNode->instance_list[count])
386             zero_count++;
387     }
388 
389     if (INSTANCE_MAX == zero_count)
390     {
391         //Cut link.
392         if (CurrNode == g_Utopia_PID_root)
393         {
394             NextNode = CurrNode->pNext;
395             free(CurrNode);
396             g_Utopia_PID_root = NextNode;
397         }
398         else
399         {
400             NextNode = CurrNode->pNext;
401             free(CurrNode);
402             PreNode->pNext = NextNode;
403         }
404     }
405 
406     mutex_unlock(&_Utopia_Instance_Mutex);
407 
408     return 0;
409 }
410 
UtopiaInstanceCreate(MS_U32 u32PrivateSize,void ** ppInstance)411 MS_U32 UtopiaInstanceCreate(MS_U32 u32PrivateSize, void** ppInstance)
412 {
413     UTOPIA_INSTANCE* pInstance = NULL;
414 
415 	/* check param. */
416 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(ppInstance == NULL))
417 	{
418 		printu("[utopia param error] instance ppointer should not be null\n");
419 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
420 	}
421 
422     pInstance = malloc(sizeof(UTOPIA_INSTANCE));
423     memset(pInstance, 0, sizeof(UTOPIA_INSTANCE));
424     pInstance->pPrivate = malloc(u32PrivateSize);
425     memset(pInstance->pPrivate, 0, u32PrivateSize);
426 
427     pInstance->u32Pid = current->tgid;
428 
429 	*ppInstance = pInstance;
430 #if defined(CONFIG_UTOPIA_GARBAGE_COLLECTION) || defined(CONFIG_UTOPIA_PROC_DBG_SUPPORT)
431     utopia_create_instance_table(current->tgid, pInstance);
432 #endif
433     return UTOPIA_STATUS_SUCCESS;
434 }
435 
UtopiaInstanceDelete(void * pInstance)436 MS_U32 UtopiaInstanceDelete(void* pInstance)
437 {
438 #if defined(CONFIG_UTOPIA_GARBAGE_COLLECTION) || defined(CONFIG_UTOPIA_PROC_DBG_SUPPORT)
439     utopia_delete_instance_table(current->tgid, pInstance);
440 #endif
441 
442 	free(TO_INSTANCE_PTR(pInstance)->pPrivate);
443 	free(pInstance);
444 
445 	return UTOPIA_STATUS_SUCCESS;
446 }
447 
UtopiaInstanceGetPrivate(void * pInstance,void ** ppPrivate)448 MS_U32 UtopiaInstanceGetPrivate(void* pInstance, void** ppPrivate)
449 {
450 	/* check param. */
451 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(pInstance == NULL))
452 	{
453 		printu("[utopia param error] instance pointer should not be null\n");
454 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
455 	}
456 	else if (MSOS_BRANCH_PREDICTION_UNLIKELY(ppPrivate == NULL))
457 	{
458 		printu("[utopia param error] private ppointer should not be null\n");
459 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
460 	}
461     else
462     {
463 	*ppPrivate = TO_INSTANCE_PTR(pInstance)->pPrivate;
464     }
465 	return UTOPIA_STATUS_SUCCESS;
466 }
467 
UtopiaInstanceGetModule(void * pInstance,void ** ppModule)468 MS_U32 UtopiaInstanceGetModule(void* pInstance, void** ppModule)
469 {
470 	/* check param. */
471 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(pInstance == NULL))
472 	{
473 		printu("[uopia param error] instance pointer should not be null\n");
474 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
475 	}
476 	else if (MSOS_BRANCH_PREDICTION_UNLIKELY(ppModule == NULL))
477 	{
478 		printu("[utopia param error] module ppointer should not be null\n");
479 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
480 	}
481     else
482     {
483 	*ppModule = TO_INSTANCE_PTR(pInstance)->psModule;
484     }
485 
486 	/* check module pointer */
487 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(*ppModule == NULL))
488 	{
489 		printu("[utopia param error] module pointer should not be null\n");
490 		printu("forgot to call UtopiaOpen first?\n");
491 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
492 	}
493 
494 	return UTOPIA_STATUS_SUCCESS;
495 }
496 
UtopiaInstanceGetModuleID(void * pInstance,MS_U32 * pu32ModuleID)497 MS_U32 UtopiaInstanceGetModuleID(void* pInstance, MS_U32* pu32ModuleID)
498 {
499 	*pu32ModuleID = TO_INSTANCE_PTR(pInstance)->psModule->u32ModuleID;
500 	return UTOPIA_STATUS_SUCCESS;
501 }
502 
UtopiaInstanceGetModuleVersion(void * pInstance,MS_U32 * pu32Version)503 MS_U32 UtopiaInstanceGetModuleVersion(void* pInstance, MS_U32* pu32Version)
504 {
505 	*pu32Version = TO_INSTANCE_PTR(pInstance)->psModule->u32Version;
506 	return UTOPIA_STATUS_SUCCESS;
507 }
508 
UtopiaInstanceGetAppRequiredModuleVersion(void * pInstance,MS_U32 * pu32ModuleVersion)509 MS_U32 UtopiaInstanceGetAppRequiredModuleVersion(void* pInstance
510 		, MS_U32* pu32ModuleVersion)
511 {
512 	*pu32ModuleVersion = TO_INSTANCE_PTR(pInstance)->u32AppRequireModuleVersion;
513 	return UTOPIA_STATUS_SUCCESS;
514 }
515 
UtopiaInstanceGetPid(void * pInstance)516 MS_U32 UtopiaInstanceGetPid(void* pInstance)
517 {
518     return TO_INSTANCE_PTR(pInstance)->u32Pid;
519 }
520 
521 /*
522  * assume one module for each driver
523  * otherwise they have to pass module name as parameter
524  */
UtopiaModuleCreate(MS_U32 u32ModuleID,MS_U32 u32PrivateSize,void ** ppModule)525 MS_U32 UtopiaModuleCreate(MS_U32 u32ModuleID
526 		, MS_U32 u32PrivateSize, void** ppModule)
527 {
528 	MS_U32 u32ShmID, u32Status;
529 	UTOPIA_MODULE_SHM* pModuleShm = NULL;
530 	UTOPIA_MODULE* pModule = NULL;
531 	void* pPrivate = NULL;
532 	char privateName[50]; // FIXME: potential bug
533 
534 	/* 1. create module@shm */
535 	u32Status = shm_malloc(sizeof(UTOPIA_MODULE_SHM),
536 			moduleNames[u32ModuleID], (void**)&pModuleShm, &u32ShmID);
537 	if (u32Status != UTOPIA_STATUS_SHM_EXIST)
538 	{
539 		pModuleShm->shmid_self.ID = u32ShmID;
540 		strncpy(pModuleShm->shmid_self.name, moduleNames[u32ModuleID]
541 				, sizeof(pModuleShm->shmid_self.name));
542 		pModuleShm->shmid_rpool_head.ID = 0xFFFFFFFF;
543 	}
544 
545 	/* 2. create module */
546 	pModule = malloc(sizeof(UTOPIA_MODULE));
547     memset(pModule, 0, sizeof(UTOPIA_MODULE));
548 	pModule->u32ModuleID = u32ModuleID;
549 	pModule->psModuleShm = pModuleShm;
550 
551 	/* 3. create private of module */
552 	snprintf(privateName, sizeof(privateName)
553 			, "%s_PRI", moduleNames[u32ModuleID]);
554 	shm_malloc(u32PrivateSize, privateName,
555 			&pPrivate, &(pModule->shmid_private.ID));
556 
557     /* 4. initial str private */
558     pModule->shmid_str.ID=0xFFFFFFFF;
559 
560 	*ppModule = pModule;
561 	return u32Status;
562 }
563 
UtopiaModuleGetPrivate(void * pModule,void ** ppPrivate)564 MS_U32 UtopiaModuleGetPrivate(void* pModule, void** ppPrivate)
565 {
566 	*ppPrivate = shmid2va(TO_MODULE_PTR(pModule)->shmid_private.ID);
567 	return UTOPIA_STATUS_SUCCESS;
568 }
569 
UtopiaModuleSetSTRPrivate(void * pModule,MS_U32 u32STRPrivateSize)570 MS_U32 UtopiaModuleSetSTRPrivate(void* pModule, MS_U32 u32STRPrivateSize)
571 {
572     void* pPrivate = NULL;
573     char privateName[50]; // FIXME: potential bug
574     MS_U32 shmid_str=0xFFFFFFFF;
575 
576     /* check str private exist? */
577     if (MSOS_BRANCH_PREDICTION_UNLIKELY(!pModule))
578     {
579 		printu("[utopia param error] module pointer should not be null\n");
580 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
581     }
582     if (MSOS_BRANCH_PREDICTION_UNLIKELY(0xFFFFFFFF != TO_MODULE_PTR(pModule)->shmid_str.ID))
583     {
584 		printu("[utopia module error] set duplicated STR private of module: %s\n"
585 				, moduleNames[TO_MODULE_PTR(pModule)->u32ModuleID]);
586 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
587     }
588 
589     /* create str private of module */
590 	snprintf(privateName, sizeof(privateName)
591 			, "%s_STR", moduleNames[TO_MODULE_PTR(pModule)->u32ModuleID]);
592 	shm_malloc(u32STRPrivateSize, privateName,
593 			&pPrivate, &shmid_str);
594 
595     TO_MODULE_PTR(pModule)->shmid_str.ID = shmid_str;
596 
597     return UTOPIA_STATUS_SUCCESS;
598 }
599 
UtopiaModuleGetSTRPrivate(void * pModule,void ** ppPrivate)600 MS_U32 UtopiaModuleGetSTRPrivate(void* pModule, void** ppPrivate)
601 {
602     /* check str private exist? */
603     if (MSOS_BRANCH_PREDICTION_UNLIKELY(!pModule))
604     {
605 		printu("[utopia param error] module pointer should not be null\n");
606 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
607     }
608     if (MSOS_BRANCH_PREDICTION_UNLIKELY(0xFFFFFFFF == TO_MODULE_PTR(pModule)->shmid_str.ID))
609     {
610 		printu("[utopia module error] NULL STR private of module: %s\n"
611 				, moduleNames[TO_MODULE_PTR(pModule)->u32ModuleID]);
612         RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
613     }
614 
615     *ppPrivate = shmid2va(TO_MODULE_PTR(pModule)->shmid_str.ID);
616     return UTOPIA_STATUS_SUCCESS;
617 }
618 
619 #ifdef CONFIG_UTOPIA_PROC_DBG_SUPPORT
UtopiaModuleRegisterMdbNode(char sMdbNodeName[MDB_NODE_NAME_MAX],FUtopiaMdbIoctl fpMdbIoctl)620 MS_U32 UtopiaModuleRegisterMdbNode(char sMdbNodeName[MDB_NODE_NAME_MAX], FUtopiaMdbIoctl fpMdbIoctl)
621 {
622     mdb_node_create_table(sMdbNodeName, fpMdbIoctl);
623     return UTOPIA_STATUS_SUCCESS;
624 }
625 
UtopiaCreateMdbNode()626 MS_U32 UtopiaCreateMdbNode()
627 {
628     mdb_node_create();
629     return UTOPIA_STATUS_SUCCESS;
630 }
631 
UtopiaModuleGetLocalInstantList(MS_U32 u32ModuleID,void * pLastInstance)632 void* UtopiaModuleGetLocalInstantList(MS_U32 u32ModuleID, void* pLastInstance)
633 {
634     UTOPIA_PID_LIST *CurrNode;
635     int i,j;
636     MS_BOOL bExist = FALSE, bMatchLast = FALSE, bMatchOnce = FALSE;
637 
638     mutex_lock(&_Utopia_Instance_Mutex);
639     if(g_Utopia_PID_root)
640     {
641         CurrNode = g_Utopia_PID_root;
642         for(i=0;CurrNode && i < PROCESS_MAX;i++)
643         {
644             for (j = 0; j < INSTANCE_MAX; j++)
645             {
646                 if (NULL == CurrNode->instance_list[j])
647                 {
648                     break;
649                 }
650                 if(u32ModuleID == TO_INSTANCE_PTR(CurrNode->instance_list[j])->psModule->u32ModuleID)
651                 {
652                     bMatchOnce = TRUE;
653                     if(NULL == pLastInstance || TRUE == bMatchLast)
654                     {
655                         bExist=TRUE;
656                         break;
657                     }
658                     if(CurrNode->instance_list[j] == pLastInstance)
659                     {
660                         bMatchLast = TRUE;
661                     }
662                 }
663             }
664             if(TRUE == bExist)
665             {
666                 break;
667             }
668             CurrNode = (NULL == CurrNode->pNext)?g_Utopia_PID_root:CurrNode->pNext;
669         }
670         if(PROCESS_MAX == i)
671         {
672             if(TRUE == bMatchOnce)
673             {
674                 printu("[utopia error] some instance had been deleted, please retry\n", moduleNames[u32ModuleID]);
675             }
676             else
677             {
678                 printu("[utopia error] no instance for %s\n", moduleNames[u32ModuleID]);
679             }
680             mutex_unlock(&_Utopia_Instance_Mutex);
681             return NULL;
682         }
683     }
684     mutex_unlock(&_Utopia_Instance_Mutex);
685     return (CurrNode->instance_list[j]);
686 }
687 
MdbPrint(MS_U64 * u64ReqHdl,const char * fmt,...)688 MS_U32 MdbPrint(MS_U64* u64ReqHdl, const char* fmt, ...)
689 {
690     va_list argp;
691     char ch, hex[32];
692     MS_BOOL flag_long = FALSE;
693 
694     va_start(argp, fmt);
695     for(;*fmt;fmt++)
696     {
697         if(*fmt!='%')
698         {
699             printk("%c", *fmt);
700             continue;
701         }
702 NEXT_CH:
703         ch = *(++fmt);
704         switch((ch))
705         {
706             case 'l':
707                 flag_long = TRUE;
708                 goto NEXT_CH;
709             case 'd':
710                 if(TRUE == flag_long)
711                 {
712                     printk("%ld", va_arg(argp, long));
713                     flag_long = FALSE;
714                 }
715                 else
716                 {
717                     printk("%d", va_arg(argp, int));
718                 }
719                 break;
720             case 'x':
721                 if(TRUE == flag_long)
722                 {
723                     sprintf(hex,"%lx",va_arg(argp, long));
724                     printk("%s", hex);
725                     flag_long = FALSE;
726                 }
727                 else
728                 {
729                     sprintf(hex,"%x",va_arg(argp, int));
730                     printk("%s", hex);
731                 }
732                 break;
733             case 'c':
734                 printk("%c", va_arg(argp, int));
735                 break;
736             case 's':
737                 printk("%s", va_arg(argp, char*));
738                 break;
739         }
740     }
741     va_end(argp);
742     return UTOPIA_STATUS_SUCCESS;
743 }
744 #endif
745 
UtopiaModuleRegister(void * pModuleTmp)746 MS_U32  UtopiaModuleRegister(void* pModuleTmp)
747 {
748 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
749 	UTOPIA_MODULE* pLocatedModule = NULL;
750 
751 	/* check para. */
752 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(pModule == NULL))
753 	{
754 		printu("[utopia param error] module pointer should not be null\n");
755 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
756 	}
757 
758 	pLocatedModule = TO_MODULE_PTR(locate_module(pModule->u32ModuleID));
759 	if (MSOS_BRANCH_PREDICTION_LIKELY(pLocatedModule == NULL)) /* module is not yet registered */
760 	{
761 		/* insert module into list head */
762 		printu("[utopia info] register module: %s\n"
763 				, moduleNames[pModule->u32ModuleID]);
764 		pModule->psNext = psUtopiaPrivate->psModuleHead;
765 		psUtopiaPrivate->psModuleHead = pModule;
766 		return UTOPIA_STATUS_SUCCESS;
767 	}
768 	else  /* module is already registered */
769     {
770 		printu("[utopia module error] register duplicated module: %s\n"
771 				, moduleNames[pModule->u32ModuleID]);
772 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
773     }
774 }
775 
UtopiaModuleSetupFunctionPtr(void * pModuleTmp,FUtopiaOpen fpOpen,FUtopiaClose fpClose,FUtopiaIOctl fpIoctl)776 MS_U32 UtopiaModuleSetupFunctionPtr(void* pModuleTmp
777 		, FUtopiaOpen fpOpen, FUtopiaClose fpClose, FUtopiaIOctl fpIoctl)
778 {
779 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
780 
781 	pModule->fpOpen = fpOpen;
782 	pModule->fpClose = fpClose;
783 	pModule->fpIoctl = fpIoctl;
784 
785 	return UTOPIA_STATUS_SUCCESS;
786 }
787 
UtopiaModuleSetupSTRFunctionPtr(void * pModuleTmp,FUtopiaSTR fpSTR)788 MS_U32 UtopiaModuleSetupSTRFunctionPtr(void* pModuleTmp, FUtopiaSTR fpSTR)
789 {
790 #if CONFIG_MSTAR_UTOPIA2K_STR
791     extern int mdrv_utopia2k_str_setup_function_ptr(void* pModuleTmp, FUtopiaSTR fpSTR);
792     int ret = mdrv_utopia2k_str_setup_function_ptr(pModuleTmp, fpSTR);
793     if (ret < 0)
794     {
795         return UTOPIA_STATUS_FAIL;
796     }
797     else
798     {
799         return UTOPIA_STATUS_SUCCESS;
800     }
801 #else
802 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
803 
804     if (MSOS_BRANCH_PREDICTION_UNLIKELY(!pModuleTmp))
805     {
806 		printu("[utopia param error] module pointer should not be null\n");
807 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
808     }
809 
810     pModule->fpSTR = fpSTR;
811 
812     return UTOPIA_STATUS_SUCCESS;
813 #endif
814 }
815 
UtopiaModuleSetVersion(void * pModule,MS_U32 u32Version)816 MS_U32 UtopiaModuleSetVersion(void* pModule, MS_U32 u32Version)
817 {
818 	TO_MODULE_PTR(pModule)->u32Version = u32Version;
819 
820 	return UTOPIA_STATUS_SUCCESS;
821 }
822 
UtopiaModuleGetDebugLevel(void * pInstance,MS_U32 * pu32DebugLevel)823 MS_U32 UtopiaModuleGetDebugLevel(void* pInstance, MS_U32* pu32DebugLevel)
824 {
825 	*pu32DebugLevel = TO_INSTANCE_PTR(pInstance)->psModule->u32DeviceDebugLevel;
826 	return UTOPIA_STATUS_SUCCESS;
827 }
828 
UtopiaModuleGetPtr(MS_U32 u32ModuleID,void ** ppModule)829 MS_U32 UtopiaModuleGetPtr(MS_U32 u32ModuleID, void** ppModule)
830 {
831 	*ppModule = locate_module(u32ModuleID);
832 
833 	return UTOPIA_STATUS_SUCCESS;
834 }
835 
UtopiaResourceCreate(char * resourceName,MS_U32 u32PrivateSize,void ** ppResource)836 MS_U32 UtopiaResourceCreate(char* resourceName
837 		, MS_U32 u32PrivateSize, void** ppResource)
838 {
839 	MS_U32 u32RetShmID, u32Status;
840 	UTOPIA_RESOURCE* pResource = NULL;
841 	char privateName[50]; // FIXME: potential bug
842 	void* pPrivate = NULL;
843 
844 	/* 1. create resource */
845 	u32Status = shm_malloc(sizeof(UTOPIA_RESOURCE), resourceName,
846 			(void**)&pResource, &(u32RetShmID));
847 	if (u32Status != UTOPIA_STATUS_SHM_EXIST)
848 	{
849 		pResource->shmid_self.ID = u32RetShmID;
850 		pResource->shmid_next_resource.ID = 0xFFFFFFFF;
851 	}
852 	*ppResource = pResource;
853 
854 	/* 2. create resource private */
855 	snprintf(privateName, sizeof(privateName), "%s_PRI", resourceName);
856 	shm_malloc(u32PrivateSize, privateName,
857 			&pPrivate, &(pResource->shmid_private.ID));
858 
859 	return u32Status;
860 }
861 
UtopiaResourceGetPrivate(void * pResource,void ** ppPrivate)862 MS_U32 UtopiaResourceGetPrivate(void* pResource, void** ppPrivate)
863 {
864 	*ppPrivate = shmid2va(TO_RESOURCE_PTR(pResource)->shmid_private.ID);
865 	return 0;
866 }
867 
868 /*
869  * case 1: no resource pool -
870  * 		--> create resource pool & attach resource to it. combine with case 2
871  * case 2: resource pool exists, but no mathcing resource pool
872  * 		--> create resource pool & attach resource to it. combine with case 1
873  * case 3: resource pool exists, and there's matching resource pool
874  *		--> attach resource to it
875  */
UtopiaResourceRegister(void * pModuleTmp,void * pResourceTmp,MS_U32 u32RPoolID)876 MS_U32 UtopiaResourceRegister(void* pModuleTmp
877 		, void* pResourceTmp, MS_U32 u32RPoolID)
878 {
879 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
880 	UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(pResourceTmp);
881 	char rpoolName[50];
882 	MS_U32 u32Status;
883 
884 	/* 1. deal with resource pool */
885 	UTOPIA_RESOURCE_POOL* pRPool = NULL;
886 	UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
887 	locate_resource_pool(pModule, u32RPoolID, &pRPool, &pRPoolPrev);
888 
889 	/* rpool semaphore has been created in this process */
890 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(pRPool != NULL && pRPool->u32ResourcesSemaphore != 0))
891 	{
892 		printu("[utopia rpool error] %s has already been established in this process%s\n"
893 				, moduleNames[pModule->u32ModuleID], pRPool->shmid_self.name);
894 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
895 	}
896 
897 	/*
898 	 * case 1: there's no resource pool
899 	 *		--> *ppRPool = NULL & *ppRPoolPrev = NULL
900 	 * case 2: at least one resource pool exists, but not the located one
901 	 * 		--> *ppRPool = NULL & *ppRPoolPrev != NULL
902 	 * case 3: at least one resource pool exists, and so is the located one
903 	 *		--> *ppRPool != NULL & ppRPoolPrev doesn't matter
904 	 */
905 	if (pRPool == NULL) { /* case 1 or 2 */
906 		MS_U32 u32RetRPoolShmID;
907 		MS_U32 u32ModuleID = pModule->u32ModuleID;
908 
909 		snprintf(rpoolName, sizeof(rpoolName), "%s_%d"
910 				, rpoolNames[u32ModuleID], (int)u32RPoolID);
911 		u32Status = shm_malloc(sizeof(UTOPIA_RESOURCE_POOL), rpoolName,
912 				(void**)&pRPool, &u32RetRPoolShmID);
913 		if (u32Status != UTOPIA_STATUS_SHM_EXIST)
914 		{
915 			pRPool->shmid_self.ID = u32RetRPoolShmID;
916 			strncpy(pRPool->shmid_self.name, rpoolName
917 					, sizeof(pRPool->shmid_self.name));
918 			pRPool->u32PoolID = u32RPoolID;
919 			pRPool->shmid_next_rpool.ID = 0xFFFFFFFF;
920 			pRPool->shmid_resource_head.ID = 0xFFFFFFFF;
921 			//pRPool->u32MutexID = MsOS_CreateNamedMutex((MS_S8*)rpoolName);
922 			pRPool->u32MutexID = MsOS_CreateMutex(E_MSOS_FIFO
923 				, rpoolName, MSOS_PROCESS_SHARED);
924 		}
925 		/* check param. */
926 		if (pResource->shmid_rpool.ID != 0)
927 		{
928 			return UTOPIA_STATUS_SUCCESS;
929 		}
930 
931 		/* set up connection */
932 		if (pRPoolPrev == NULL) // case 1
933 		{
934 			pModule->psModuleShm->shmid_rpool_head.ID = u32RetRPoolShmID;
935 		}
936 		else /* case 2 */
937 		{
938 			pRPoolPrev->shmid_next_rpool.ID = u32RetRPoolShmID;
939 		}
940 
941 		pModule->psModuleShm->u32ResourcePoolTotal++;
942 	}
943 
944 	/* 2. deal with resource */
945 	pResource->shmid_rpool = pRPool->shmid_self;
946 
947 	UTOPIA_RESOURCE* pTargetRes = NULL;
948 	UTOPIA_RESOURCE* pTargetResPrev = NULL;
949 	locate_resource(pRPool, pResource->shmid_self.ID
950 			, &pTargetRes, &pTargetResPrev);
951 	/* case 1: there's no resource in pool */
952 	/*		--> pTargetRes = NULL, pTargetResPrev = NULL */
953 	/* case 2: at least one resource exists, but not the located one */
954 	/*		--> pTargetRes = NULL, pTargetResPrev != NULL */
955 	/* case 3: at least one resource exists, and so is the located one */
956 	/*		--> pTargetRes != NULL, pTargetResPrev doesn't matter */
957 	if (pTargetRes == NULL) /* case 1 or 2 */
958 	{
959 		if (pTargetResPrev == NULL) /* case 1 */
960 		{
961 			pRPool->shmid_resource_head.ID = pResource->shmid_self.ID;
962 		}
963 		else /* case 2 */
964 		{
965 			pTargetResPrev->shmid_next_resource.ID = pResource->shmid_self.ID;
966 		}
967 		pRPool->u32ResourceTotal++;
968 
969 		return UTOPIA_STATUS_SUCCESS;
970 	}
971 	else /* case 3 */
972 	{
973 		/* duplicated registration: it may be registered by other process */
974 		return UTOPIA_STATUS_SHM_EXIST ;
975 	}
976 }
977 
UtopiaResourceTryObtain(void * pModuleTmp,MS_U32 u32RPoolID,void ** ppResource)978 MS_U32 UtopiaResourceTryObtain(void* pModuleTmp
979 		, MS_U32 u32RPoolID, void** ppResource)
980 {
981 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
982 	UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
983 	UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
984 	UTOPIA_RESOURCE* pAvailResource = NULL;
985 	locate_resource_pool(pModule, u32RPoolID
986 			, &pLocatedRPool, &pLocatedRPoolPrev);
987 
988 	if (!(pLocatedRPool->u32ResourceAvail))
989 		return UTOPIA_STATUS_NO_RESOURCE;
990 	obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
991 
992 	pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
993 	//MsOS_LockMutex(pLocatedRPool->u32MutexID, 0);
994 	MsOS_ObtainMutex(pLocatedRPool->u32MutexID, MSOS_WAIT_FOREVER);
995 	while (pAvailResource != NULL)
996 	{
997 		if (!(pAvailResource->bInUse))
998 		{
999 			pAvailResource->bInUse = true;
1000 			*ppResource	= pAvailResource;
1001 			pLocatedRPool->u32ResourceAvail--;
1002 			//MsOS_UnlockMutex(pLocatedRPool->u32MutexID, 0);
1003 			MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
1004 			return UTOPIA_STATUS_SUCCESS;
1005 		}
1006 		else
1007 		{
1008 			pAvailResource = next_resource(pAvailResource, E_TYPE_RESOURCE);
1009 		}
1010 	}
1011 	//MsOS_UnlockMutex(pLocatedRPool->u32MutexID, 0);
1012 	MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
1013 
1014 	printu("[utopia resource error] code flow should not reach here\n");
1015 	RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
1016 }
1017 
UtopiaResourceObtain(void * pModTmp,MS_U32 u32RPoolID,void ** ppResource)1018 MS_U32 UtopiaResourceObtain(void* pModTmp, MS_U32 u32RPoolID, void** ppResource)
1019 {
1020     //Search and get one resource from psModuleNode->psResourcePoolHeads
1021     //set flag bit0 to 1 for using
1022     int ret; /* check semop return value */
1023 #if DEADLOCK_DEBUG == 1
1024 	unsigned int count = 0;
1025 	while(UTOPIA_STATUS_NO_RESOURCE ==
1026 			UtopiaResourceTryObtain(pModTmp, u32RPoolID, ppResource))
1027 	{
1028 		usleep(1000);
1029 		count++;
1030 		if ((count >= bt_threshold) && ((count % bt_period) == 0))
1031 		{
1032 			printu("%s deadlock!!!???\n",
1033 					moduleNames[TO_MODULE_PTR(pModTmp)->u32ModuleID]);
1034 			print_trace ();
1035 		}
1036 	}
1037 	return 0;
1038 #endif
1039 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModTmp);
1040 	UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
1041 	UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
1042 	UTOPIA_RESOURCE* pAvailResource = NULL;
1043 
1044 	/* check param. */
1045 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(pModTmp == NULL))
1046 	{
1047 		printu("[utopia param error] module pointer should not be null\n");
1048 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
1049 	}
1050 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(ppResource == NULL))
1051 	{
1052 		printu("[utopia param error] resource ppointer should not be null\n");
1053 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
1054 	}
1055 
1056 	locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
1057 
1058 retry:
1059 	ret = obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
1060 	if (ret != TRUE) /* -1 for error */
1061 	{
1062 
1063 	    printu("[utopia error] UtopiaResourceObtain\n");
1064 		goto retry;
1065 	}
1066 
1067 	pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
1068 	//MsOS_LockMutex(pLocatedRPool->u32MutexID, 0);
1069 	MsOS_ObtainMutex(pLocatedRPool->u32MutexID, MSOS_WAIT_FOREVER);
1070 	while (pAvailResource != NULL)
1071 	{
1072 		if (!(pAvailResource->bInUse))
1073 		{
1074 			pAvailResource->bInUse = true;
1075             pAvailResource->u32Pid = (unsigned int)current->tgid;
1076 			*ppResource	= pAvailResource;
1077 			pLocatedRPool->u32ResourceAvail--;
1078 			//MsOS_UnlockMutex(pLocatedRPool->u32MutexID, 0);
1079 			MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
1080 			return UTOPIA_STATUS_SUCCESS;
1081 		}
1082 		else
1083 		{
1084 			pAvailResource = next_resource(pAvailResource, E_TYPE_RESOURCE);
1085 		}
1086 	}
1087 	//MsOS_UnlockMutex(pLocatedRPool->u32MutexID, 0);
1088 	MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
1089 
1090 	printu("[utopia error] code flow should not reach here\n");
1091 	RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
1092 }
1093 
UtopiaResourceRelease(void * pResource)1094 MS_U32 UtopiaResourceRelease(void* pResource)
1095 {
1096 	UTOPIA_RESOURCE_POOL* pRPool
1097 		= RESOURCE_PTR_TO_RPOOL_PTR(TO_RESOURCE_PTR(pResource));
1098 
1099 	/* modify resource before releasing it, to avoid race condition */
1100 	//MsOS_LockMutex(pRPool->u32MutexID, 0);
1101 	MsOS_ObtainMutex(pRPool->u32MutexID, MSOS_WAIT_FOREVER);
1102 	TO_RESOURCE_PTR(pResource)->bInUse = false;
1103     TO_RESOURCE_PTR(pResource)->u32Pid = UTOPIA_RESOURCE_NO_OCCUPY;
1104 	pRPool->u32ResourceAvail++;
1105 	release_sem(pRPool->u32ResourcesSemaphore);
1106 	//MsOS_UnlockMutex(pRPool->u32MutexID, 0);
1107 	MsOS_ReleaseMutex(pRPool->u32MutexID);
1108 
1109 	return UTOPIA_STATUS_SUCCESS;
1110 }
1111 
UtopiaResourceGetPid(void * pResource)1112 MS_U32 UtopiaResourceGetPid(void* pResource)
1113 {
1114     return TO_RESOURCE_PTR(pResource)->u32Pid;
1115 }
1116 
UtopiaResourceGetNext(void * pModTmp,void ** ppResource)1117 MS_U32 UtopiaResourceGetNext(void* pModTmp, void** ppResource)
1118 {
1119 	/* check param. */
1120 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(pModTmp == NULL))
1121 	{
1122 		printu("[utopia param error] module pointer should not be null\n");
1123 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
1124 	}
1125 	if (MSOS_BRANCH_PREDICTION_UNLIKELY(ppResource == NULL))
1126 	{
1127 		printu("[utopia param error] resource ppointer should not be null\n");
1128 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
1129 	}
1130 
1131 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModTmp);
1132 	MS_BOOL bMatch = false;
1133 
1134 	if (!*ppResource) /* trick to get first resource */
1135 	{
1136 		bMatch = true;
1137 	}
1138 
1139 	UTOPIA_RESOURCE_POOL *pRPool =
1140 		TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
1141 	MS_U32 u32RPoolTotal = pModule->psModuleShm->u32ResourcePoolTotal;
1142 	MS_U32 u32RPoolIdx = 0, u32ResourceIdx = 0;
1143 	while (u32RPoolTotal--) /* traverse rpool@module */
1144 	{
1145 		/* get first resource@rpool */
1146 		UTOPIA_RESOURCE *pTmpResource = next_resource(pRPool, E_TYPE_RESOURCE_POOL);
1147 		u32ResourceIdx = 0;
1148 		if (bMatch) /* get next resource(the one after match) */
1149 		{
1150 			*ppResource = pTmpResource;
1151 			return UTOPIA_STATUS_SUCCESS;
1152 		}
1153 		if (*ppResource == pTmpResource)
1154 		{
1155 			bMatch = true;
1156 		}
1157 		u32ResourceIdx++;
1158 
1159 		MS_U32 u32ResourceTotal = pRPool->u32ResourceTotal - 1; /* already got one */
1160 		while (u32ResourceTotal--) /* traverse resource@rpool */
1161 		{
1162 			pTmpResource = next_resource(pTmpResource, E_TYPE_RESOURCE);
1163 			if (bMatch) /* get next resource(the one after match) */
1164 			{
1165 				*ppResource = pTmpResource;
1166 				return UTOPIA_STATUS_SUCCESS;
1167 			}
1168 			if (*ppResource == pTmpResource)
1169 			{
1170 				bMatch = true;
1171 			}
1172 			u32ResourceIdx++;
1173 		}
1174 
1175 		pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
1176 		u32RPoolIdx++;
1177 	}
1178 
1179 	return UTOPIA_STATUS_FAIL;
1180 }
1181 
1182 
UtopiaModuleAddResourceStart(void * psModuleTmp,MS_U32 u32PoolID)1183 MS_U32 UtopiaModuleAddResourceStart(void* psModuleTmp, MS_U32 u32PoolID)
1184 {
1185 	return UTOPIA_STATUS_SUCCESS;
1186 }
1187 
1188 #define PERMS 0666
1189 #define SEM_NUM 1
1190 /* semaphore num isn't equal to resource count */
UtopiaModuleAddResourceEnd(void * pModuleTmp,MS_U32 u32RPoolID)1191 MS_U32 UtopiaModuleAddResourceEnd(void* pModuleTmp, MS_U32 u32RPoolID)
1192 {
1193 	int u32SemaphoreID;
1194 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
1195 
1196 	UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
1197 	UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
1198 	locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
1199 
1200 	if (pLocatedRPool->u32ResourcesSemaphore != 0 && pLocatedRPool->u32ResourcesSemaphore != 0xFFFFFFFF)
1201 	{
1202         printu("semaphore id %d already exists\n", (int)pLocatedRPool->u32ResourcesSemaphore);
1203 		return UTOPIA_STATUS_RPOOL_ESTABLISHED;
1204 	}
1205 
1206     /* Create RPOOL Semaphore */
1207     u32SemaphoreID = MsOS_CreateSemaphore(pLocatedRPool->u32ResourceTotal, E_MSOS_FIFO , "dont care");
1208     if (MSOS_BRANCH_PREDICTION_UNLIKELY(u32SemaphoreID < 0))
1209     {
1210         printf("[utopia error] create semaphore fail\n");
1211         RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
1212     }
1213 	pLocatedRPool->u32ResourceAvail = pLocatedRPool->u32ResourceTotal;
1214 
1215 	pLocatedRPool->u32ResourcesSemaphore = u32SemaphoreID;
1216 
1217 	return UTOPIA_STATUS_SUCCESS;
1218 }
1219 
UtopiaModuleResetPool(void * pModuleTmp,MS_U32 u32RPoolID)1220 MS_U32 UtopiaModuleResetPool(void* pModuleTmp, MS_U32 u32RPoolID)
1221 {
1222     return 0;
1223 }
1224 
UtopiaSetIPAUTH(ST_IPAUTH_SHARED_VARS * IpControl,MS_U8 * gCusID,MS_U8 * gCusHush)1225 MS_U32 UtopiaSetIPAUTH(ST_IPAUTH_SHARED_VARS *IpControl, MS_U8 *gCusID, MS_U8 *gCusHush)
1226 {
1227     return 0;
1228 }
1229 
UtopiaModuleQueryMode(MS_U32 u32ModuleID)1230 MS_U32 UtopiaModuleQueryMode(MS_U32 u32ModuleID)
1231 {
1232 
1233     return KERNEL_MODE;
1234 
1235 }