xref: /utopia/UTPA2-700.0.x/modules/msos/utopia_core/nos/utopia_dapi.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
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 #if defined (MSOS_TYPE_LINUX)
10 #include <sys/sem.h>
11 #endif
12 
13 #ifdef __compiler_offsetof
14 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
15 #else
16 #ifndef offsetof
17 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
18 #endif
19 #endif
20 
21 #define container_of(ptr, type, member) ({          \
22 		const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
23 		(type *)( (char *)__mptr - offsetof(type,member) );})
24 
25 #define TO_MODULE_PTR(pTmp) ((UTOPIA_MODULE*)pTmp)
26 #define TO_MODULE_SHM_PTR(pTmp) ((UTOPIA_MODULE_SHM*)pTmp)
27 // attention: this macro doesn't consider synchronization problem, just for tmp use
28 #define MODULE_PTR_TO_RPOOL_PTR(pModule) ((UTOPIA_RESOURCE_POOL*)shmid2va(pModule->psModuleShm->shmid_rpool_head.ID))
29 
30 #define TO_RESOURCE_PTR(pTmp) ((UTOPIA_RESOURCE*)pTmp)
31 // attention: this macro doesn't consider synchronization problem, just for tmp use
32 #define RESOURCE_PTR_TO_RPOOL_PTR(pResource) ((UTOPIA_RESOURCE_POOL*)shmid2va(pResource->shmid_rpool.ID))
33 
34 #define TO_INSTANCE_PTR(pTmp) ((UTOPIA_INSTANCE*)pTmp)
35 #define TO_RPOOL_PTR(pTmp) ((UTOPIA_RESOURCE_POOL*)pTmp)
36 // length should be the same to definition
37 extern char moduleNames[][40];
38 extern char rpoolNames[][40];
39 extern char ResourceNames[][40];
40 
41 UTOPIA_SHM_ID* utopiaShmIdArray[50]; // FIXME: enum
42 MS_U32 utopiaShmIdIndex = 0;
43 
44 struct shm_info {
45 	void* va;
46 	char name[40]; // FIXME: array length should be unify
47 };
48 
49 /*
50  * could be equal to MAX_SHM_CLIENT_NUM=320 defined in MsOS_linux.c
51  * cause we ues shm id as table index, there may be holes in the table
52  */
53 #define SHM_INFO_TABLE_LENGTH 200
54 struct shm_info shm_info_table[SHM_INFO_TABLE_LENGTH] = {{NULL, ""}};
55 
56 extern UTOPIA_PRIVATE* psUtopiaPrivate;
57 
58 //############################
59 //## Static Functions Start ##
60 //############################
61 enum eObjectType
62 {
63 	E_TYPE_INSTANCE,
64 	E_TYPE_MODULE,
65 	E_TYPE_MODULE_SHM,
66 	E_TYPE_RESOURCE_POOL,
67 	E_TYPE_RESOURCE,
68 };
69 
obtain_sem(MS_U32 u32SemID)70 static void obtain_sem(MS_U32 u32SemID)
71 {
72     /* Perform down operation */
73     //printf("[FAKE][SEMAPHORE], try to get semaphore: 0x%X\n", (unsigned int)u32SemID);
74     //printf("[FAKE][SEMAPHORE], semaphore got: 0x%X\n", (unsigned int)u32SemID);
75 }
76 
release_sem(MS_U32 u32SemID)77 static void release_sem(MS_U32 u32SemID)
78 {
79     /* Perform down operation */
80     //printf("[FAKE][SEMAPHORE], release semaphore: 0x%X\n", (unsigned int)u32SemID);
81 }
82 
83 
shmid2va(MS_U32 u32ShmID)84 static inline void* shmid2va(MS_U32 u32ShmID)
85 {
86 	if (u32ShmID == 0xFFFFFFFF)
87 		return NULL;
88 	return shm_info_table[u32ShmID].va;
89 }
90 
isFirstCreation(void * pUnknown,enum eObjectType eObjectType)91 static inline int isFirstCreation(void* pUnknown, enum eObjectType eObjectType)
92 {
93 	switch(eObjectType)
94 	{
95 		case E_TYPE_MODULE_SHM:
96 			return TO_MODULE_SHM_PTR(pUnknown)->shmid_self.ID == 0;
97 		case E_TYPE_RESOURCE:
98 			return TO_RESOURCE_PTR(pUnknown)->shmid_self.ID == 0;
99 		case E_TYPE_RESOURCE_POOL:
100 			return TO_RPOOL_PTR(pUnknown)->shmid_self.ID == 0;
101 		default:
102 			printf("%s, %d, %s, what the fuck!\n", __FUNCTION__, __LINE__, __FILE__);
103 			while(1);
104 	}
105 }
106 
107 /*
108  * u32ShmSize: user specified shared memory size
109  * shmName: user specified shared memory name
110  * p32RetShmID: for returning shared memory id
111  * return: shared memory address in virtual
112  */
shm_malloc(MS_U32 u32ShmSize,char * shmName,MS_U32 * pu32RetShmID)113 static void* shm_malloc(MS_U32 u32ShmSize, char* shmName, MS_U32* pu32RetShmID)
114 {
115 	static MS_U32 u32RetShmID = 0;
116     MS_U32 u32RetAddr = 0, u32RetShmSize = 0;
117 	MS_U32 u32Ret;
118 
119 	/*
120 	 * check parameter
121 	 */
122 	if (strcmp(shmName, "") == 0)
123 	{
124 		printf("shmem name string should not be empty\n");
125 		while(1);
126 	}
127 
128 	u32RetAddr = (MS_U32)malloc(u32ShmSize);
129 	u32RetShmID++;
130 
131 	/*
132 	 * check whether table limit is reached?
133 	 */
134     // shm_info_table is for the shm_id and shm_addr mapping
135 	if(u32RetShmID >= SHM_INFO_TABLE_LENGTH)
136 	{
137 		printf("[%s error] returned shm id %d exceeds shm-info table length %d\n"
138 				, __FUNCTION__, (int)u32RetShmID, SHM_INFO_TABLE_LENGTH);
139 		while(1);
140 	}
141 	if(shm_info_table[u32RetShmID].va != NULL)
142 	{
143 		printf("error: register duplicated shared memory ID %d: %s@%p\n"
144 		, (int)u32RetShmID, shm_info_table[u32RetShmID].name, shm_info_table[u32RetShmID].va);
145 		while(1);
146 	}
147     else
148     {
149 		shm_info_table[u32RetShmID].va = (void*)u32RetAddr;
150 		strncpy(shm_info_table[u32RetShmID].name, shmName, sizeof(shm_info_table[u32RetShmID].name));
151         if(!(0 == strcmp(shm_info_table[u32RetShmID].name, shmName)))
152         {
153             printf("\033[35mFunction = %s, Line = %d, error, strncpy failed!!\033[m\n", __PRETTY_FUNCTION__, __LINE__);
154             while(1);
155         }
156 		//printf("shm_info_table[%d] = %s@%p\n", (int)u32RetShmID, shmName, (void*)u32RetAddr);
157 	}
158 
159 	// u32Ret: TRUE for success, FALSE for failure
160 	// if failure --> first time allocation, memset to 0
161 	if(u32Ret != 1)
162 		memset((void*)u32RetAddr, 0, u32RetShmSize);
163 
164 	*pu32RetShmID = u32RetShmID;
165 	return (void*)u32RetAddr;
166 }
167 
next_resource(void * pUnkown,enum eObjectType eObjectType)168 static UTOPIA_RESOURCE* next_resource(void* pUnkown, enum eObjectType eObjectType)
169 {
170 	switch(eObjectType)
171 	{
172 		case E_TYPE_RESOURCE_POOL:
173 			return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE_POOL*)pUnkown)->shmid_resource_head.ID);
174 		case E_TYPE_RESOURCE:
175 			return (UTOPIA_RESOURCE*)shmid2va(((UTOPIA_RESOURCE*)pUnkown)->shmid_next_resource.ID);
176 		default:
177 			printf("%s, %d, %s, what the fuck!\n", __FUNCTION__, __LINE__, __FILE__);
178 			while(1);
179 	}
180 }
181 
182 // return located module address or NULL if not found
locate_module(MS_U32 u32ModuleID)183 void* locate_module(MS_U32 u32ModuleID)
184 {
185 	UTOPIA_MODULE* pLocatedModule = psUtopiaPrivate->psModuleHead;
186 
187 	while (pLocatedModule != NULL && pLocatedModule->u32ModuleID != u32ModuleID)
188 		pLocatedModule = pLocatedModule->psNext;
189 
190 	return pLocatedModule;
191 }
192 
193 // case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
194 // case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
195 // 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)196 static int locate_resource_pool(UTOPIA_MODULE* pModule, MS_U32 u32LocatedRPoolID
197 		, UTOPIA_RESOURCE_POOL** ppRPool, UTOPIA_RESOURCE_POOL** ppRPoolPrev)
198 {
199 	UTOPIA_RESOURCE_POOL* pRPool = TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
200 	UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
201 
202 	while (pRPool != NULL && pRPool->u32PoolID != u32LocatedRPoolID)
203 	{
204 		pRPoolPrev = pRPool;
205 		pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
206 	}
207 
208 	*ppRPool = pRPool;
209 	*ppRPoolPrev = pRPoolPrev;
210 	return 0;
211 }
212 
213 /*static void UtopiaResourcePoolLocate(MS_U32 u32PoolID, void** ppsResourcePoolTmp, void** ppsResourcePoolPrevTmp)
214 {
215 	UTOPIA_RESOURCE_POOL** ppsResourcePool = (UTOPIA_RESOURCE_POOL**)ppsResourcePoolTmp;
216 	UTOPIA_RESOURCE_POOL** ppsResourcePoolPrev = (UTOPIA_RESOURCE_POOL**)ppsResourcePoolPrevTmp;
217 	UTOPIA_RESOURCE_POOL* psResourcePool = *ppsResourcePool;
218 	UTOPIA_RESOURCE_POOL* psResourcePoolPrev = *ppsResourcePoolPrev = NULL;
219 
220 	while (psResourcePool != NULL && psResourcePool->u32PoolID != u32PoolID)
221 	{
222 		psResourcePoolPrev = psResourcePool;
223 		psResourcePool = (UTOPIA_RESOURCE_POOL*)shmid2va(psResourcePool->shmid_next_rpool.ID);
224 	}
225 	*ppsResourcePool = psResourcePool;
226 	*ppsResourcePoolPrev = psResourcePoolPrev;
227 }*/
228 
locate_resource(UTOPIA_RESOURCE_POOL * pRPool,MS_U32 u32LocatedResourceID,UTOPIA_RESOURCE ** ppResource,UTOPIA_RESOURCE ** ppResourcePrev)229 static int locate_resource(UTOPIA_RESOURCE_POOL* pRPool, MS_U32 u32LocatedResourceID
230 		, UTOPIA_RESOURCE** ppResource, UTOPIA_RESOURCE** ppResourcePrev)
231 {
232 	UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(shmid2va(pRPool->shmid_resource_head.ID));
233 	UTOPIA_RESOURCE* pResourcePrev = NULL;
234 
235 	while (pResource != NULL && (pResource->shmid_self.ID != u32LocatedResourceID))
236 	{
237 		pResourcePrev = pResource;
238 		pResource = TO_RESOURCE_PTR(shmid2va(pResource->shmid_next_resource.ID));
239 	}
240 
241 	*ppResource = pResource;
242 	*ppResourcePrev = pResourcePrev;
243 	return 0;
244 }
245 
check_rpool_semaphore(MS_U32 u32ModuleID)246 int check_rpool_semaphore(MS_U32 u32ModuleID)
247 {
248 	// locate target module in stupid way
249 	UTOPIA_MODULE* pModule = NULL;
250 	pModule = psUtopiaPrivate->psModuleHead;
251 	while (pModule != NULL && pModule->u32ModuleID != u32ModuleID)
252 	{
253 		pModule = pModule->psNext;
254 	}
255 
256 	// locate corresponding rpool in stupid way
257 	UTOPIA_RESOURCE_POOL* pRPool = NULL;
258 	if(pModule != NULL) // found
259 	{
260 		pRPool = TO_RPOOL_PTR(shmid2va(pModule->psModuleShm->shmid_rpool_head.ID));
261 	}
262     else
263     {
264 		printf("module of u32ModuleID isn't found\n");
265 		while(1);
266 	}
267 
268 	// check rpool semaphore one by one
269 	while (pRPool != NULL)
270 	{
271 		if (!(pRPool->u32ResourcesSemaphore))
272 		{
273 			printf("error: resource pool %s has no semaphore\n", pRPool->shmid_self.name);
274 			while(1);
275 		}
276 		pRPool = TO_RPOOL_PTR(shmid2va(pRPool->shmid_next_rpool.ID));
277 	}
278 
279 	return 0;
280 }
281 //##########################
282 //## Static Functions End ##
283 //##########################
284 
285 //#############################
286 //## Instance Functions Start ##
287 //#############################
UtopiaInstanceCreate(MS_U32 u32PrivateSize,void ** ppInstance)288 MS_U32 UtopiaInstanceCreate(MS_U32 u32PrivateSize, void** ppInstance)
289 {
290     UTOPIA_INSTANCE* pInstance = NULL;
291 
292 	// check parameters
293 	if (ppInstance == NULL)
294     {
295 		printf("ppInstance should not be NULL\n");
296         return 1;
297     }
298 
299     pInstance = malloc(sizeof(UTOPIA_INSTANCE));
300     memset(pInstance, 0, sizeof(UTOPIA_INSTANCE));
301     if (u32PrivateSize != 0)
302     {
303         pInstance->pPrivate = malloc(u32PrivateSize);
304         memset(pInstance->pPrivate, 0, u32PrivateSize);
305     }
306 	printf("create instance at %p with private size %d bytes at %p\n" \
307 			, pInstance, (int)u32PrivateSize, pInstance->pPrivate);
308     //pInstant->u32DeviceDebugLevel   = 0; // FIXME: u32DeviceDebugLevel is in UTOPIA_MODULE_NODE_SHM
309 
310 	*ppInstance = pInstance;
311     return 0; // FIXME: error code
312 }
313 
UtopiaInstanceDelete(void * pInstance)314 MS_U32 UtopiaInstanceDelete(void* pInstance)
315 {
316 	free(TO_INSTANCE_PTR(pInstance)->pPrivate);
317 	free(pInstance);
318 
319 	return 0; // FIXME: error code
320 }
321 
UtopiaInstanceGetPrivate(void * pInstance,void ** ppPrivate)322 MS_U32 UtopiaInstanceGetPrivate(void* pInstance, void** ppPrivate)
323 {
324 	*ppPrivate = TO_INSTANCE_PTR(pInstance)->pPrivate;
325 	return 0; // FIXME: error code
326 }
327 
UtopiaInstanceGetModule(void * pInstance,void ** ppModule)328 MS_U32 UtopiaInstanceGetModule(void* pInstance, void** ppModule)
329 {
330 	*ppModule = TO_INSTANCE_PTR(pInstance)->psModule;
331 	return 0; // FIXME: error code
332 }
333 
UtopiaInstanceGetModuleID(void * pInstance,MS_U32 * pu32ModuleID)334 MS_U32 UtopiaInstanceGetModuleID(void* pInstance, MS_U32* pu32ModuleID)
335 {
336 	*pu32ModuleID = TO_INSTANCE_PTR(pInstance)->psModule->u32ModuleID;
337 	return 0;
338 }
339 
UtopiaInstanceGetModuleVersion(void * pInstance,MS_U32 * pu32Version)340 MS_U32 UtopiaInstanceGetModuleVersion(void* pInstance, MS_U32* pu32Version)
341 {
342 	*pu32Version = TO_INSTANCE_PTR(pInstance)->psModule->u32Version;
343 	return 0;
344 }
345 
UtopiaInstanceGetAppRequiredModuleVersion(void * pInstance,MS_U32 * pu32ModuleVersion)346 MS_U32 UtopiaInstanceGetAppRequiredModuleVersion(void* pInstance, MS_U32* pu32ModuleVersion)
347 {
348 	*pu32ModuleVersion = TO_INSTANCE_PTR(pInstance)->u32AppRequireModuleVersion;
349 	return 0;
350 }
351 //###########################
352 //## Instant Functions End ##
353 //###########################
354 
355 //############################
356 //## Module Functions Start ##
357 //############################
358 // assume one module for each driver, otherwise they have to pass module name as parameter
UtopiaModuleCreate(MS_U32 u32ModuleID,MS_U32 u32PrivateSize,void ** ppModule)359 MS_U32 UtopiaModuleCreate(MS_U32 u32ModuleID, MS_U32 u32PrivateSize, void** ppModule)
360 {
361 	//printf("UtopiaModuleCreate for %s\n", moduleNames[u32ModuleID]);
362 
363 	MS_U32 u32ShmID;
364 	UTOPIA_MODULE_SHM* pModuleShm = NULL;
365 	UTOPIA_MODULE* pModule = NULL;
366 	void* pPrivate = NULL;
367 	char privateName[50]; // FIXME: potential bug
368 
369 	// 1. create module@shm
370 	pModuleShm = shm_malloc(sizeof(UTOPIA_MODULE_SHM), moduleNames[u32ModuleID], &u32ShmID);
371 	if (isFirstCreation(pModuleShm, E_TYPE_MODULE_SHM))
372 	{
373 		pModuleShm->shmid_self.ID = u32ShmID;
374 		strcpy(pModuleShm->shmid_self.name, moduleNames[u32ModuleID]);
375 		pModuleShm->shmid_rpool_head.ID = 0xFFFFFFFF;
376 	}
377 	//printf("create module@shm %s at %p\n", moduleNames[u32ModuleID], pModuleShm);
378 
379 	// 2. create module
380 	pModule = malloc(sizeof(UTOPIA_MODULE));
381     memset(pModule, 0, sizeof(UTOPIA_MODULE));
382 	pModule->u32ModuleID = u32ModuleID;
383 	pModule->psModuleShm = pModuleShm;
384 	//printf("create module %s at %p\n", moduleNames[u32ModuleID], pModule);
385 
386 	// 3. create private of module
387 	sprintf(privateName, "%s_PRI", moduleNames[u32ModuleID]); // FIXME: potential bug
388 	pPrivate = shm_malloc(u32PrivateSize, privateName, &(pModule->shmid_private.ID));
389 	//printf("create private of module %s at %p\n", privateName, pPrivate);
390 
391 	*ppModule = pModule;
392 	return 0; //FIXME: error code
393 }
394 
UtopiaModuleGetPrivate(void * pModule,void ** ppPrivate)395 MS_U32 UtopiaModuleGetPrivate(void* pModule, void** ppPrivate)
396 {
397 	*ppPrivate = shmid2va(TO_MODULE_PTR(pModule)->shmid_private.ID);
398 	return 0;
399 }
400 
UtopiaModuleRegister(void * pModuleTmp)401 MS_U32 UtopiaModuleRegister(void* pModuleTmp)
402 {
403 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
404 	UTOPIA_MODULE* pLocatedModule = NULL;
405 
406 	// check parameter
407 	if (pModule == NULL)
408 	{
409 		printf("module pointer can't be null\n");
410 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
411 	}
412 
413 	pLocatedModule = TO_MODULE_PTR(locate_module(pModule->u32ModuleID));
414 	if (pLocatedModule == NULL) // module is not yet registered
415 	{
416 		// insert module into list head
417 		//printf("register module: %s\n", moduleNames[pModule->u32ModuleID]);
418 		pModule->psNext = psUtopiaPrivate->psModuleHead;
419 		psUtopiaPrivate->psModuleHead = pModule;
420 		return UTOPIA_STATUS_SUCCESS;
421 	}
422 	else  // module is already registered
423     {
424         printf("error: register duplicated module: %s\n", moduleNames[pModule->u32ModuleID]);
425 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
426     }
427 }
428 
UtopiaModuleSetupFunctionPtr(void * pModuleTmp,FUtopiaOpen fpOpen,FUtopiaClose fpClose,FUtopiaIOctl fpIoctl)429 MS_U32 UtopiaModuleSetupFunctionPtr(void* pModuleTmp, FUtopiaOpen fpOpen, FUtopiaClose fpClose, FUtopiaIOctl fpIoctl)
430 {
431 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
432 
433 	//printf("setup function pointers of module %s\n", moduleNames[pModule->u32ModuleID]);
434 	pModule->fpOpen = fpOpen;
435 	pModule->fpClose = fpClose;
436 	pModule->fpIoctl = fpIoctl;
437 
438 	return 0; //FIXME: error code
439 }
440 
UtopiaModuleSetVersion(void * pModule,MS_U32 u32Version)441 MS_U32 UtopiaModuleSetVersion(void* pModule, MS_U32 u32Version)
442 {
443 	TO_MODULE_PTR(pModule)->u32Version = u32Version;
444 
445 	return 0;
446 }
447 
UtopiaModuleGetDebugLevel(void * pInstance,MS_U32 * pu32DebugLevel)448 MS_U32 UtopiaModuleGetDebugLevel(void* pInstance, MS_U32* pu32DebugLevel)
449 {
450 	*pu32DebugLevel = TO_INSTANCE_PTR(pInstance)->psModule->u32DeviceDebugLevel;
451 	return 0;
452 }
453 
UtopiaModuleGetPtr(MS_U32 u32ModuleID,void ** ppModule)454 MS_U32 UtopiaModuleGetPtr(MS_U32 u32ModuleID, void** ppModule)
455 {
456 	*ppModule = locate_module(u32ModuleID);
457 
458 	return 0;
459 }
460 //##########################
461 //## Module Functions End ##
462 //##########################
463 
464 //##############################
465 //## Resource Functions Start ##
466 //##############################
UtopiaResourceCreate(char * resourceName,MS_U32 u32PrivateSize,void ** ppResource)467 MS_U32 UtopiaResourceCreate(char* resourceName, MS_U32 u32PrivateSize, void** ppResource)
468 {
469 	MS_U32 u32RetShmID;
470 	UTOPIA_RESOURCE* pResource = NULL;
471 	char privateName[50]; // FIXME: potential bug
472 
473 	// 1. create resource
474 	//printf("create resource %s\n", resourceName);
475 	pResource = shm_malloc(sizeof(UTOPIA_RESOURCE), resourceName, &(u32RetShmID));
476 	if (isFirstCreation(pResource, E_TYPE_RESOURCE))
477 	{
478 		pResource->shmid_self.ID = u32RetShmID;
479 		pResource->shmid_next_resource.ID = 0xFFFFFFFF;
480 	}
481 	*ppResource = pResource;
482 
483 	// 2. create resource private
484 	sprintf(privateName, "%s_PRI", resourceName); // FIXME: potential bug
485 	//printf("create private %s of resource %s\n", privateName, resourceName);
486 	shm_malloc(u32PrivateSize, privateName, &(pResource->shmid_private.ID));
487 
488 	return 0; // FIXME: error code
489 }
490 
UtopiaResourceGetPrivate(void * pResource,void ** ppPrivate)491 MS_U32 UtopiaResourceGetPrivate(void* pResource, void** ppPrivate)
492 {
493 	*ppPrivate = shmid2va(TO_RESOURCE_PTR(pResource)->shmid_private.ID);
494 	return 0;
495 }
496 
497 // case 1: no resource pool -> create resource pool & attach resource to it. combine with case 2
498 // case 2: resource pool exists, but no mathcing resource pool -> create resource pool & attach resource to it. combine with case 1
499 // case 3: resource pool exists, and there's matching resource pool -> attach resource to it
UtopiaResourceRegister(void * pModuleTmp,void * pResourceTmp,MS_U32 u32RPoolID)500 MS_U32 UtopiaResourceRegister(void* pModuleTmp, void* pResourceTmp, MS_U32 u32RPoolID)
501 {
502     //lock(u32ResourcePoolsMutex)
503     //insert psResouce into psModuleNode->psResourcePoolHeads->psResourceHeads->psResource
504 
505 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
506 	UTOPIA_RESOURCE* pResource = TO_RESOURCE_PTR(pResourceTmp);
507 	char rpoolName[50];
508 
509 	// 1. deal with resource pool
510 	UTOPIA_RESOURCE_POOL* pRPool = NULL;
511 	UTOPIA_RESOURCE_POOL* pRPoolPrev = NULL;
512 	locate_resource_pool(pModule, u32RPoolID, &pRPool, &pRPoolPrev);
513 
514 	// rpool semaphore check
515 	if (pRPool != NULL && pRPool->u32ResourcesSemaphore != 0) // if rpool semaphore has been created
516 	{
517 		printf("%s has already created semaphroe for %s\n", moduleNames[pModule->u32ModuleID], pRPool->shmid_self.name);
518 		return 1; // FIXME: error code
519 	}
520 
521 	// case 1: there's no resource pool --> *ppRPool = NULL & *ppRPoolPrev = NULL
522 	// case 2: at least one resource pool exists, but not the located one --> *ppRPool = NULL & *ppRPoolPrev != NULL
523 	// case 3: at least one resource pool exists, and so is the located one --> *ppRPool != NULL & ppRPoolPrev doesn't matter
524 	if (pRPool == NULL) { // case 1 or 2
525 		MS_U32 u32RetRPoolShmID;
526 		MS_U32 u32ModuleID = pModule->u32ModuleID;
527 
528 		sprintf(rpoolName, "%s_%d", rpoolNames[u32ModuleID], (int)u32RPoolID);
529 		pRPool = shm_malloc(sizeof(UTOPIA_RESOURCE_POOL), rpoolName, &u32RetRPoolShmID);
530 		if (isFirstCreation(pRPool, E_TYPE_RESOURCE_POOL))
531 		{
532 			pRPool->shmid_self.ID = u32RetRPoolShmID;
533 			strncpy(pRPool->shmid_self.name, rpoolName, sizeof(pRPool->shmid_self.name)); // FIXME: potential bug
534             if(!(0 == strcmp(pRPool->shmid_self.name, rpoolName)))
535             {
536                 printf("\033[35mFunction = %s, Line = %d, error, strncpy failed!!\033[m\n", __PRETTY_FUNCTION__, __LINE__);
537                 while(1);
538             }
539 			pRPool->u32PoolID = u32RPoolID;
540 			pRPool->shmid_next_rpool.ID = 0xFFFFFFFF;
541 			pRPool->shmid_resource_head.ID = 0xFFFFFFFF;
542 			pRPool->u32MutexID = MsOS_CreateMutex(E_MSOS_FIFO, rpoolName, MSOS_PROCESS_SHARED);
543 		}
544 		//printf("create resource pool %s at %p\n", rpoolName, pRPool);
545 		// check param
546 		if (pResource->shmid_rpool.ID != 0)
547 		{
548 			return 0;
549 		}
550 
551 		// set up connection
552 		if (pRPoolPrev == NULL) // case 1
553 		{
554 			pModule->psModuleShm->shmid_rpool_head.ID = u32RetRPoolShmID;
555 		}
556 		else // case 2
557 		{
558 			pRPoolPrev->shmid_next_rpool.ID = u32RetRPoolShmID;
559 		}
560 
561 		pModule->psModuleShm->u32ResourcePoolTotal++;
562 	}
563 
564 	// 2. deal with resource
565 	pResource->shmid_rpool = pRPool->shmid_self;
566 
567 	UTOPIA_RESOURCE* pLocatedResource = NULL;
568 	UTOPIA_RESOURCE* pLocatedResourcePrev = NULL;
569 	locate_resource(pRPool, pResource->shmid_self.ID, &pLocatedResource, &pLocatedResourcePrev);
570 	// case 1: there's no resource in pool --> pLocatedResource = NULL, pLocatedResourcePrev = NULL
571 	// case 2: at least one resource exists, but not the located one --> pLocatedResource = NULL, pLocatedResourcePrev != NULL
572 	// case 3: at least one resource exists, and so is the located one --> pLocatedResource != NULL, pLocatedResourcePrev doesn't matter
573 	if (pLocatedResource == NULL) // case 1 or 2
574 	{
575 		//printf("register resource into pool %s\n", rpoolName);
576 		if (pLocatedResourcePrev == NULL) // case 1
577 		{
578 			pRPool->shmid_resource_head.ID = pResource->shmid_self.ID;
579 		}
580 		else // case 2
581 		{
582 			pLocatedResourcePrev->shmid_next_resource.ID = pResource->shmid_self.ID;
583 		}
584 		pRPool->u32ResourceTotal++;
585 
586 		return 0;
587 	}
588 	else // case 3
589 	{
590 		// duplicated registration: it may be registered by other process
591 		return 1;
592 	}
593 
594     //unlock(u32ResourcePoolsMutex)
595 }
596 
UtopiaResourceTryObtain(void * pModuleTmp,MS_U32 u32RPoolID,void ** ppResource)597 MS_U32 UtopiaResourceTryObtain(void* pModuleTmp, MS_U32 u32RPoolID, void** ppResource)
598 {
599     //Search and get one resource from psModuleNode->psResourcePoolHeads
600     //set flag bit0 to 1 for using
601 
602 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
603 	UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
604 	UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
605 	UTOPIA_RESOURCE* pAvailResource = NULL;
606 	locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
607 
608 	// FIXME: add try obtain api
609 
610 	// to avoid obtaining resource before UtopiaModuleAddResourceEnd()
611 	//printf("%s try to obtain %s semaphore\n", moduleNames[pModule->u32ModuleID], pLocatedRPool->shmid_self.name);
612 	//check_rpool_semaphore(pModule->u32ModuleID);
613 	if (!(pLocatedRPool->u32ResourceAvail))
614 		return 1; // FIXME: error code
615 	obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
616 
617 	pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
618     MsOS_ObtainMutex(pLocatedRPool->u32MutexID, MSOS_WAIT_FOREVER);
619 	while (pAvailResource != NULL)
620 	{
621 		if (!(pAvailResource->bInUse))
622 		{
623 			pAvailResource->bInUse = true;
624 			*ppResource	= pAvailResource;
625 			pLocatedRPool->u32ResourceAvail--;
626 			MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
627 			return 0;
628 		}
629 		else
630 		{
631 			pAvailResource = next_resource(pAvailResource, E_TYPE_RESOURCE);
632 		}
633 	}
634 	MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
635 
636 	return 1; // what kind of situation? FIXME: error code
637 }
638 
UtopiaResourceObtain(void * pModTmp,MS_U32 u32RPoolID,void ** ppResource)639 MS_U32 UtopiaResourceObtain(void* pModTmp, MS_U32 u32RPoolID, void** ppResource)
640 {
641     //Search and get one resource from psModuleNode->psResourcePoolHeads
642     //set flag bit0 to 1 for using
643 
644 	/* check param. */
645 	if (pModTmp == NULL)
646 	{
647 		printf("module pointer should not be null\n");
648 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
649 	}
650 	if (ppResource == NULL)
651 	{
652 		printf("resource ppointer should not be null\n");
653 		RET_OR_BLOCK(UTOPIA_STATUS_FAIL);
654 	}
655 
656 	UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModTmp);
657 	UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
658 	UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
659 	UTOPIA_RESOURCE* pAvailResource = NULL;
660 	locate_resource_pool(pModule, u32RPoolID
661 			, &pLocatedRPool, &pLocatedRPoolPrev);
662 
663 	// to avoid obtaining resource before UtopiaModuleAddResourceEnd()
664 	//printf("%s try to obtain %s semaphore\n", moduleNames[pModule->u32ModuleID], pLocatedRPool->shmid_self.name);
665 	//check_rpool_semaphore(pModule->u32ModuleID);
666 	obtain_sem(pLocatedRPool->u32ResourcesSemaphore);
667 
668 	pAvailResource = next_resource(pLocatedRPool, E_TYPE_RESOURCE_POOL);
669 	MsOS_ObtainMutex(pLocatedRPool->u32MutexID, MSOS_WAIT_FOREVER);
670 	while (pAvailResource != NULL)
671 	{
672 		if (!(pAvailResource->bInUse))
673 		{
674 			pAvailResource->bInUse = true;
675 			*ppResource	= pAvailResource;
676 			pLocatedRPool->u32ResourceAvail--;
677 			MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
678 			return UTOPIA_STATUS_SUCCESS;
679 		}
680 		else
681 		{
682 			pAvailResource = next_resource(pAvailResource, E_TYPE_RESOURCE);
683 		}
684 	}
685 	MsOS_ReleaseMutex(pLocatedRPool->u32MutexID);
686 
687 	return UTOPIA_STATUS_FAIL;
688 }
689 
UtopiaResourceRelease(void * pResource)690 MS_U32 UtopiaResourceRelease(void* pResource)
691 {
692 	UTOPIA_RESOURCE_POOL* pRPool = RESOURCE_PTR_TO_RPOOL_PTR(TO_RESOURCE_PTR(pResource));
693 
694 	// modify resource before releasing it, to avoid race condition
695 	MsOS_ObtainMutex(pRPool->u32MutexID, MSOS_WAIT_FOREVER);
696 	TO_RESOURCE_PTR(pResource)->bInUse = false;
697 	pRPool->u32ResourceAvail++;
698 	release_sem(pRPool->u32ResourcesSemaphore);
699 	MsOS_ReleaseMutex(pRPool->u32MutexID);
700 
701 	return 0;
702 }
703 
UtopiaModuleAddResourceStart(void * psModuleTmp,MS_U32 u32PoolID)704 MS_U32 UtopiaModuleAddResourceStart(void* psModuleTmp, MS_U32 u32PoolID)
705 {
706 	return 0;
707 }
708 
709 #define PERMS 0666
710 // semaphore num isn't equal to resource count
711 #define SEMAPHORE_NUM 1
712 //MS_U32 u32LastUtopiaSemID = UTOPIA_SEM_START;
UtopiaModuleAddResourceEnd(void * pModuleTmp,MS_U32 u32RPoolID)713 MS_U32 UtopiaModuleAddResourceEnd(void* pModuleTmp, MS_U32 u32RPoolID)
714 {
715     UTOPIA_MODULE* pModule = TO_MODULE_PTR(pModuleTmp);
716 
717     UTOPIA_RESOURCE_POOL* pLocatedRPool = NULL;
718     UTOPIA_RESOURCE_POOL* pLocatedRPoolPrev = NULL;
719     locate_resource_pool(pModule, u32RPoolID, &pLocatedRPool, &pLocatedRPoolPrev);
720 
721     if (pLocatedRPool->u32ResourcesSemaphore != 0 && pLocatedRPool->u32ResourcesSemaphore != 0xFFFFFFFF)
722     {
723         printf("semaphore id %d already exists\n", (int)pLocatedRPool->u32ResourcesSemaphore);
724         return 1; // FIXME: error code
725     }
726 
727     //printf("[FAKE] create semaphore of %s %s\n", moduleNames[pModule->u32ModuleID], pLocatedRPool->shmid_self.name);
728 	return 0;
729 }
730 //############################
731 //## Resource Functions End ##
732 //############################
733 
734 /***** debug function start *****/
735 /*MS_U32 UtopiaPrintTree(void* pModuleTmp)
736 {
737 	UTOPIA_MODULE_NODE* pModule = (UTOPIA_MODULE_NODE*)pModuleTmp;
738 	MS_U32 u32ShmID = pModule->psModuleNodeShm->shmid_UTOPIA_RESOURCE_POOL__Head.ID;
739 	UTOPIA_RESOURCE_POOL* pResourcePool = (UTOPIA_RESOURCE_POOL*)shmid2va(u32ShmID);
740 	do // resource pool
741 	{
742 		printf("\n->ID=0x%X, VA=0x%X", (unsigned int)u32ShmID, (unsigned int)pResourcePool);
743 		UTOPIA_RESOURCE* pResource = (UTOPIA_RESOURCE*)shmid2va(pResourcePool->shmid_UTOPIA_RESOURCE__Head.ID);
744 		while(pResource) // resrouce
745 		{
746 			printf("\n\t->ID=0x%X, VA=0x%X\n", (unsigned int)pResource->shmid__Self.ID, (unsigned int)pResource);
747 			pResource = (UTOPIA_RESOURCE*)shmid2va(pResource->shmid_UTOPIA_RESOURCE__Next.ID);
748 		}
749 		u32ShmID = pResourcePool->shmid_UTOPIA_RESOURCE_POOL__Next.ID;
750 		pResourcePool = (UTOPIA_RESOURCE_POOL*)shmid2va(u32ShmID);
751 	} while(pResourcePool);
752 
753 	return 0;
754 }*/
755 /***** debug function end *****/
756 
757 
758 UTOPIA_HIBERNATE_HEADER* pHibernateHeaderStartVA=NULL;
759 UTOPIA_HIBERNATE_BLOCK* pHibernateBlockStartVA=NULL;
760 MS_U32 u32HibernateMaxBlock=0;
761 MS_U32 u32HibernateHeaderSizeTotal = 0;
762 MS_U32 u32HibernateBlockSizeTotal = 0;
763 MS_U32 u32HibernateCurrentBlkNum = 0;
764 MS_U32 u32HibernateCurrentFileNum = 0;
765 MS_BOOL bHibernateInit=false;
766 
_serch_empyblock(void)767 MS_U32 _serch_empyblock(void)
768 {
769     UTOPIA_HIBERNATE_BLOCK* pBlockVA = pHibernateBlockStartVA;
770 	MS_U32 ret = 0;
771 	MS_U32 u32Count=0;
772 	while(pBlockVA->u32NextBlock != 0x0 && u32Count <= u32HibernateMaxBlock )
773 	{
774 	   u32Count+=1;
775 	   pBlockVA = pHibernateBlockStartVA + sizeof(UTOPIA_HIBERNATE_BLOCK)*u32Count;
776 	}
777 
778 	if(u32Count == u32HibernateMaxBlock)
779 		ret = u32HibernateMaxBlock;
780 
781     return ret;
782 }
783 
_EndOfFile(MS_U32 u32BlockNum)784 void _EndOfFile(MS_U32 u32BlockNum)
785 {
786     UTOPIA_HIBERNATE_BLOCK* pBlockVA = pHibernateBlockStartVA+sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
787 	pBlockVA->u32NextBlock = END_OF_BLOCK_LINKLIST;
788 }
789 
UtopiaHibernateInit(MS_U8 u8MiuSel,MS_U32 pBAddrMem,MS_U32 u32size,MS_BOOL bFormat)790 MS_U32 UtopiaHibernateInit(MS_U8 u8MiuSel,MS_U32 pBAddrMem,MS_U32 u32size,MS_BOOL bFormat) //return: Sucessed
791 {
792     if(MsOS_MPool_Mapping(u8MiuSel, pBAddrMem, u32size, 0) == false)
793    	{
794         printf("[%s] MsOS_MPool_Mapping fail\n",__FUNCTION__);
795         return false;
796    	}
797 
798 	u32HibernateHeaderSizeTotal = sizeof(UTOPIA_HIBERNATE_HEADER)*MAX_FILE_NUM;
799 
800 	if(u32HibernateHeaderSizeTotal>u32size)
801 	{
802         return UTOPIA_STATUS_FAIL;
803 	}
804 
805     u32HibernateBlockSizeTotal = u32size - u32HibernateHeaderSizeTotal;
806 	u32HibernateMaxBlock = u32HibernateBlockSizeTotal/BLOCK_SIZE;
807 
808     pHibernateHeaderStartVA = (void*)MsOS_MPool_PA2KSEG1(pBAddrMem);
809     pHibernateBlockStartVA = (void*)MsOS_MPool_PA2KSEG1(pBAddrMem+u32HibernateHeaderSizeTotal);
810 
811 	if(bFormat)
812     {
813        memset(pHibernateHeaderStartVA,u32size,0);
814     }
815 
816 	bHibernateInit=UTOPIA_STATUS_SUCCESS;
817 	return UTOPIA_STATUS_SUCCESS;
818 }
819 
UtopiaHibernateCreate(char * hibernateName)820 MS_U32 UtopiaHibernateCreate(char* hibernateName)  //return: Sucessed
821 {
822     UTOPIA_HIBERNATE_HEADER* TEMPaa=pHibernateHeaderStartVA;
823     MS_U32 ret = UTOPIA_STATUS_FAIL;
824     MS_U32 u32CountTmp=0;
825 
826     if(pHibernateHeaderStartVA == NULL)
827         return ret;
828 
829     for(u32CountTmp =0;u32CountTmp<MAX_FILE_NUM;u32CountTmp++)
830     {
831         TEMPaa = TEMPaa + sizeof(UTOPIA_HIBERNATE_HEADER)*u32CountTmp;
832         if(TEMPaa->u32HibernateFileExist != 0x0)
833         {
834             if(strcmp(TEMPaa->HibernateName,hibernateName)==0)
835             ret = UTOPIA_STATUS_SHM_EXIST ;
836             break;
837         }
838         else
839         {
840             TEMPaa->u32HibernateFileExist=0x1;
841             strcpy(TEMPaa->HibernateName,hibernateName);
842             //TEMPaa->u32FirstBlock= _serch_empyblock();
843             u32HibernateCurrentFileNum = u32HibernateCurrentFileNum +1;
844             ret = UTOPIA_STATUS_SUCCESS ;
845             break;
846         }
847     }
848 
849     return ret;
850 }
851 
UtopiaHibernateOpen(char * hibernateName)852 MS_U32 UtopiaHibernateOpen(char* hibernateName)//return: ID
853 {  MS_U32 ret = -1;
854    UTOPIA_HIBERNATE_HEADER* TEMPaa=pHibernateHeaderStartVA;
855    MS_U32 u32CountTmp=0;
856 
857    if(pHibernateHeaderStartVA == NULL )
858 	 	return ret;
859 
860    for(u32CountTmp =0;u32CountTmp<MAX_FILE_NUM;u32CountTmp++)
861 	 {
862 	    TEMPaa = TEMPaa + sizeof(UTOPIA_HIBERNATE_HEADER)*u32CountTmp;
863 	    if(TEMPaa->u32HibernateFileExist != 0x0)
864 	    {
865 	       if(strcmp(TEMPaa->HibernateName,hibernateName)==0)
866 	       	{
867 	       	    TEMPaa->bUSE=1;
868 		   	    ret = u32CountTmp;
869 	       	}
870 	    }else
871 	       break;
872 	 }
873 
874    return ret;
875 
876 
877 }
878 
UtopiaHibernateWrite(MS_U32 FILEid,void * buff,MS_U32 size)879 MS_U32 UtopiaHibernateWrite(MS_U32 FILEid, void* buff, MS_U32 size) //return: size
880 {
881     MS_U32 ret=0;
882 	UTOPIA_HIBERNATE_HEADER* TEMPaa = NULL;
883 	UTOPIA_HIBERNATE_BLOCK* TEMPBLKaa = NULL ;
884 	MS_U32 u32BlockNum=0;
885 	void* pTemBuff = buff;
886 	//MS_U32 u32NextBlockNum=0;
887 	//MS_U32 u32writeCount=size;
888 	//MS_U8 u8ArrayBlockContact[BLOCK_CONTACT_SIZE] = {0};
889 
890 	MS_U32 u32BlockNumOfFile = size/BLOCK_CONTACT_SIZE;
891 	MS_U32 u32RemanderOfFile = size%BLOCK_CONTACT_SIZE;
892 
893 	TEMPaa = pHibernateHeaderStartVA + sizeof(UTOPIA_HIBERNATE_HEADER)*FILEid;;
894 
895 	if(TEMPaa->bUSE ==0 || bHibernateInit == false || size==0)
896 		return ret;
897 
898 	if((u32HibernateMaxBlock-u32HibernateCurrentFileNum) < u32BlockNumOfFile)
899 		return ret;
900 
901 
902     TEMPaa->u32FirstBlock=_serch_empyblock();
903 	u32BlockNum = TEMPaa->u32FirstBlock;
904 
905 	TEMPBLKaa = pHibernateBlockStartVA+ sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
906 
907   //  u32BlockNum
908     while(u32BlockNumOfFile>0)
909     {
910        // u32BlockNum = _serch_empyblock();
911 		if(u32BlockNum>=u32HibernateMaxBlock)
912 			break;
913 		pTemBuff = (void*)((MS_U32)pTemBuff +ret);
914         memcpy((void*)TEMPBLKaa->u8File,pTemBuff,BLOCK_CONTACT_SIZE);
915 		_EndOfFile(u32BlockNum);
916         ret = ret+BLOCK_CONTACT_SIZE;
917 		u32BlockNumOfFile=u32BlockNumOfFile-1;
918 
919 		if(u32BlockNumOfFile==0)
920 			break;
921 
922 	    u32BlockNum = _serch_empyblock();
923 	    TEMPBLKaa->u32NextBlock = u32BlockNum;
924 	    TEMPBLKaa = pHibernateBlockStartVA+ sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
925 
926     }
927 
928 
929 
930 
931 
932 	if(u32RemanderOfFile > 0)
933 	{
934        u32BlockNum = _serch_empyblock();
935 	   TEMPBLKaa->u32NextBlock = u32BlockNum;
936 	   TEMPBLKaa = pHibernateBlockStartVA+ sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
937 
938 	   pTemBuff = (void*)((MS_U32)pTemBuff +ret);
939 	   memcpy((void*)TEMPBLKaa->u8File,pTemBuff,u32RemanderOfFile);
940 	   _EndOfFile(u32BlockNum);
941 	   ret+=u32RemanderOfFile;
942 	}
943 
944     return ret;
945 
946 }
947 
948 
UtopiaHibernateRead(MS_U32 FILEid,void * buff,MS_U32 size)949 MS_U32 UtopiaHibernateRead(MS_U32 FILEid,void* buff , MS_U32 size) ////return: size
950 {
951    MS_U32 ret=0;
952    UTOPIA_HIBERNATE_HEADER* TEMPaa = pHibernateHeaderStartVA + sizeof(UTOPIA_HIBERNATE_HEADER)*FILEid;
953    UTOPIA_HIBERNATE_BLOCK* TEMPBLKaa = NULL ;
954    //MS_U32 u32writeCount=size;
955    MS_U32 u32BlockNum=0;
956 
957    MS_U32 u32BlockNumOfFile = size/BLOCK_CONTACT_SIZE;
958    MS_U32 u32RemanderOfFile = size%BLOCK_CONTACT_SIZE;
959 
960    void* pTemBuff = buff;
961 
962 
963    if(TEMPaa->bUSE ==0)
964 		return ret;
965 
966    if(u32RemanderOfFile>0)
967       u32BlockNumOfFile = u32BlockNumOfFile + 1;
968 
969 
970    u32BlockNum = TEMPaa->u32FirstBlock;
971    TEMPBLKaa = pHibernateBlockStartVA+sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
972 
973    while((TEMPBLKaa->u32NextBlock != 0) && (u32BlockNumOfFile > 0))
974    {
975       if(TEMPBLKaa->u32NextBlock ==END_OF_BLOCK_LINKLIST )
976       {
977           pTemBuff = (void*)((MS_U32)pTemBuff +ret);
978 		  if(u32RemanderOfFile == 0)
979 		  {
980               memcpy(pTemBuff,(void*)TEMPBLKaa->u8File,BLOCK_CONTACT_SIZE);
981 			  ret = ret + BLOCK_CONTACT_SIZE;
982 		  }
983 		  else
984 		  {
985 		  	  memcpy(pTemBuff,(void*)TEMPBLKaa->u8File,u32RemanderOfFile);
986 			  ret = ret + u32RemanderOfFile;
987 		  }
988 
989 		  u32BlockNumOfFile = u32BlockNumOfFile -1;
990 
991 
992 
993       }else
994       {
995           pTemBuff = (void*)((MS_U32)pTemBuff +ret);
996 		  memcpy(pTemBuff,(void*)TEMPBLKaa->u8File,BLOCK_CONTACT_SIZE);
997 	      ret = ret + BLOCK_CONTACT_SIZE;
998           u32BlockNumOfFile = u32BlockNumOfFile -1;
999           u32BlockNum = TEMPBLKaa->u32NextBlock;
1000 		  TEMPBLKaa = pHibernateBlockStartVA+sizeof(UTOPIA_HIBERNATE_BLOCK)*u32BlockNum;
1001 
1002       	}
1003    }
1004 
1005 
1006 
1007    return ret;
1008 
1009 
1010 }
1011 
1012 
1013