xref: /utopia/UTPA2-700.0.x/modules/msos/msos/linux_kernel_V2/drvIPAPool.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2008-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // ("MStar Confidential Information") by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file    drvIPAPool.c
98 /// @brief  IPA Pool Driver
99 /// @author MStar Semiconductor Inc.
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101 
102 
103 //-------------------------------------------------------------------------------------------------
104 //  Include Files
105 //-------------------------------------------------------------------------------------------------
106 #if defined (CONFIG_MSTAR_IPAPOOL)
107 
108 //TEST_USE_SELF_KO_MAKEFILE is
109 //only test code use,p4 code not use!!!!
110 //never set this macro in p4 with 1.any question ,contact with samson.huang
111 //though test code,please do not delete this test code.
112 #define TEST_USE_SELF_KO_MAKEFILE 0
113 
114 #if TEST_USE_SELF_KO_MAKEFILE
115 #include <linux/module.h>
116 #else
117 #include "MsCommon.h"
118 #include "halCHIP.h"
119 #include "halMPool.h"
120 #endif
121 #include <linux/slab.h>
122 
123 #include <linux/kthread.h>
124 
125 #if defined(CONFIG_COMPAT)
126 #include <linux/compat.h>
127 #endif
128 
129 #include "../../include/drvIPAPool.h"
130 #include "../mstar2/drv/ipa_pool/mdrv_ipa_pool_uapi.h"
131 
132 #include <linux/sched.h>
133 #include <linux/fs.h>
134 #include <linux/uaccess.h>//for get_fs() /set_fs() use.
135 
136 #include <linux/version.h>
137 #if (LINUX_VERSION_CODE  == KERNEL_VERSION(3,10,40))
138 #include <linux/hardirq.h>
139 #endif
140 
141 
142 //debug macro,can not enable in p4.
143 #define DEBUG_IPA_KERNEL_MODE 1
144 
145 //-------------------------------------------------------------------------------------------------
146 //  Local Defines
147 //-------------------------------------------------------------------------------------------------
148 #define MAX_IPAPOOLSIZE 16UL
149 
150 //
151 //
152 //for example:
153 //area 1 map 2 times,area 2 map 2times,area 3 map 1 times,total map 2+2+1=5
154 //
155 //   map 2t  map 2t map 1t
156 //   ------   ----
157 //   ------   ----   ---
158 //     1        2    3
159 //   ------   ---- ------
160 //-----------------------------same client
161 #define MAX_CLIENT_MAP_NUM 8UL
162 //-------------------------------------------------------------------------------------------------
163 //  Local Structurs
164 //-------------------------------------------------------------------------------------------------
165 
166 struct VIRT_MAP_INFO
167 {
168     MS_U64 virt_addr;
169     MS_U64 length;
170     MS_BOOL bNonCache;
171     MS_U64 Physaddr;
172 };
173 struct IPA_Pool_Init_Param_No_P
174 {
175     MS_U32 heap_id;     //in: heap id the pool will be created in
176     MS_U64 pool_name;//in: global identify name for pool to shared between multiple process
177 
178     MS_U64 offset_in_heap;    //in: pool location in heap
179     MS_U64 len;       //in: pool length in  heap
180 
181     MS_U32 pool_handle_id; //out: generate pool id based on heap specified by heap_id
182     MS_U32 miu;  //out: miu id this heap belongs, index from 0.
183     enum IPA_SPACE_TYPE heap_type;//out: return heap type to application
184     MS_S32 error_code; // error code when pool init failed
185 
186     MS_U64 heap_length; //out: heap leagth
187     MS_U64 heap_miu_start_offset; //out: heap start offset in miu
188 };
189 
190 typedef struct
191 {
192     struct IPA_Pool_Init_Param_No_P Init_Param;
193     MS_BOOL bIsUsed;
194     struct VIRT_MAP_INFO map_info[MAX_CLIENT_MAP_NUM];
195     volatile MS_BOOL polling_thread_delete_task_flag;
196     pid_t pthIPAPollingId;
197     void (*polling_callback)(MS_U32 pool_handle_id,MS_U64 start,MS_U64 length);
198 } IPAPOOL_INFO;
199 
200 //-------------------------------------------------------------------------------------------------
201 //  Global Variables
202 //-------------------------------------------------------------------------------------------------
203 static struct file * _fileIPAPool = NULL;
204 static struct mutex  _IPA_POOL_Mutex = __MUTEX_INITIALIZER(_IPA_POOL_Mutex);
205 
206 #if TEST_USE_SELF_KO_MAKEFILE_TOTAL
207 IPAPOOL_INFO IPAPool_Info[MAX_IPAPOOLSIZE];
208 #else
209 static IPAPOOL_INFO IPAPool_Info[MAX_IPAPOOLSIZE];
210 #endif
211 //-------------------------------------------------------------------------------------------------
212 //  Debug Functions
213 //-------------------------------------------------------------------------------------------------
214 
215 
216 //-------------------------------------------------------------------------------------------------
217 //  Local Functions
218 //-------------------------------------------------------------------------------------------------
_findEmpty_IPA_Pool_Entry(MS_U32 * index)219 static MS_BOOL _findEmpty_IPA_Pool_Entry(MS_U32 *index)
220 {
221     MS_BOOL find = FALSE;
222     MS_U32 i;
223 
224     *index = 0;
225     for (i = 0; i < MAX_IPAPOOLSIZE; i++)
226     {
227         if(IPAPool_Info[i].bIsUsed == FALSE)
228         {
229             find = TRUE;
230             *index = i;
231             break;
232         }
233     }
234 
235     if(find == FALSE)
236         printk("%s:%d  Not enough IPAPool, must increase MAX_IPAPOOLSIZE!!\n",__FUNCTION__,__LINE__);
237 
238     return find;
239 }
240 
_findPoolHandleId_InIPA_Pool_Table(MS_U32 pool_handle_id,MS_U32 * index)241 static MS_BOOL _findPoolHandleId_InIPA_Pool_Table(MS_U32 pool_handle_id, MS_U32 *index)
242 {
243     MS_BOOL find = FALSE;
244     MS_U32 i;
245 
246     *index = 0;
247     for (i = 0; i < MAX_IPAPOOLSIZE; i++)
248     {
249         if((IPAPool_Info[i].bIsUsed == TRUE) && (IPAPool_Info[i].Init_Param.pool_handle_id == pool_handle_id))
250         {
251             find = TRUE;
252             *index = i;
253             break;
254         }
255     }
256 
257     return find;
258 }
259 
_findHeapId_InIPA_Pool_Table(struct IPA_Pool_Init_Param * Init_Param,MS_U32 * index)260 static MS_BOOL _findHeapId_InIPA_Pool_Table(struct IPA_Pool_Init_Param * Init_Param,MS_U32 *index)
261 {
262     MS_BOOL find = FALSE;
263     MS_U32 i;
264 
265     *index = 0;
266     for (i = 0; i < MAX_IPAPOOLSIZE; i++)
267     {
268         if((IPAPool_Info[i].bIsUsed == TRUE)
269 			&& (IPAPool_Info[i].Init_Param.heap_id == Init_Param->space_id)
270 			&&(!strncmp((char *)IPAPool_Info[i].Init_Param.pool_name, Init_Param->pool_name,strlen(Init_Param->pool_name)))
271 			&& (IPAPool_Info[i].Init_Param.offset_in_heap == Init_Param->offset_in_heap)
272 			&& (IPAPool_Info[i].Init_Param.len == Init_Param->len))
273         {
274             find = TRUE;
275             *index = i;
276             break;
277         }
278     }
279 
280     return find;
281 }
282 
283 
284 //-------------------------------------------------------------------------------------------------
285 //  Global Functions
286 //-------------------------------------------------------------------------------------------------
287 
288 //-------------------------------------------------------------------------------------------------
289 /// System initialzation
290 /// @return TRUE(Success), FALSE(Failure)
291 //-------------------------------------------------------------------------------------------------
MApi_IPA_Pool_Init(struct IPA_Pool_Init_Param * Init_Param)292 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_Init(struct IPA_Pool_Init_Param * Init_Param)
293 {
294     if (in_interrupt() || (current->flags & PF_KTHREAD))
295     {
296         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
297         return false;
298     }
299 
300     struct IPA_Pool_Init_Args ipa_init_args;
301 
302     MS_BOOL ret = TRUE;
303     MS_U32 idx = 0;
304     int res = 0;
305     mm_segment_t old_fs;
306 #if DEBUG_IPA_KERNEL_MODE
307     printk("%s:%d heap_id %u  Init_Param->pool_name=%s\n",__FUNCTION__,__LINE__, Init_Param->space_id,Init_Param->pool_name);
308 #endif
309 
310 #ifdef DEBUG_IPA_KERNEL_MODE
311     printk("%s:%d ,Init_Param=%p  heap_id %u\n",__FUNCTION__,__LINE__,Init_Param, Init_Param->space_id);
312     printk("%s:%d Init_Param->pool_name=%s\n",__FUNCTION__,__LINE__,Init_Param->pool_name);
313 #endif
314 
315 
316 #if DEBUG_IPA_KERNEL_MODE
317     printk("%s:%d  heap_id %u  Init_Param->pool_name=%s\n",__FUNCTION__,__LINE__, Init_Param->space_id,Init_Param->pool_name);
318 #endif
319 
320     mutex_lock(&_IPA_POOL_Mutex);
321     if (!_fileIPAPool)
322     {
323         int flags=O_RDWR;
324 #ifdef DEBUG_IPA_KERNEL_MODE
325         printk("%s:%d  heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
326 #endif
327         _fileIPAPool = filp_open( "/dev/ipapool", flags, 0);
328         if (IS_ERR(_fileIPAPool) )
329         {
330             printk("%s:%d open /dev/ipapool fail\n",__FUNCTION__,__LINE__);
331             ret =  FALSE;
332             goto IPA_POOL_INIT_DONE;
333         }
334 
335         memset(IPAPool_Info, 0, sizeof(IPAPOOL_INFO)*MAX_IPAPOOLSIZE);
336     }
337 
338 #ifdef DEBUG_IPA_KERNEL_MODE
339     printk("%s:%d  heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
340 #endif
341 
342     //avoid mmap more than one time
343     ret = _findHeapId_InIPA_Pool_Table(Init_Param, &idx);
344 #ifdef DEBUG_IPA_KERNEL_MODE
345     printk("%s:%d  heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
346 #endif
347 
348     if(ret == TRUE)
349     {
350          //memcpy(Init_Param,IPAPool_Info[idx].Init_Param,sizeof(struct IPA_Pool_Init_Param));
351          Init_Param->space_id = IPAPool_Info[idx].Init_Param.heap_id;
352          Init_Param->pool_name = (char *)IPAPool_Info[idx].Init_Param.pool_name;
353          Init_Param->offset_in_heap = IPAPool_Info[idx].Init_Param.offset_in_heap;
354          Init_Param->len = IPAPool_Info[idx].Init_Param.len;
355          Init_Param->pool_handle_id = IPAPool_Info[idx].Init_Param.pool_handle_id;
356          Init_Param->miu = IPAPool_Info[idx].Init_Param.miu;
357          Init_Param->space_type = IPAPool_Info[idx].Init_Param.heap_type;
358          Init_Param->error_code = IPAPool_Info[idx].Init_Param.error_code;
359          Init_Param->space_length = IPAPool_Info[idx].Init_Param.heap_length;
360          Init_Param->space_miu_start_offset = IPAPool_Info[idx].Init_Param.heap_miu_start_offset;
361 
362          printk("%s:%d pool_handle_id %u already init!\n",__FUNCTION__,__LINE__, IPAPool_Info[idx].Init_Param.pool_handle_id);
363          goto IPA_POOL_INIT_DONE;
364     }
365 #ifdef DEBUG_IPA_KERNEL_MODE
366     printk("%s:%d ,  heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
367 #endif
368 
369     ipa_init_args.heap_id = Init_Param->space_id;
370 #ifdef DEBUG_IPA_KERNEL_MODE
371     printk("%s:%d ,  heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
372 #endif
373 
374     if(sizeof(Init_Param->pool_name) > IPAPOOL_NAME_MAX_LONG+1)
375     {
376         printk("%s:%d pool name %s is too long size is %lu\n",__FUNCTION__,__LINE__,Init_Param->pool_name,sizeof(Init_Param->pool_name));
377         BUG();
378     }
379 
380     strcpy(ipa_init_args.pool_name,Init_Param->pool_name);
381 
382 #ifdef DEBUG_IPA_KERNEL_MODE
383     printk("%s:%d ,  heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
384 #endif
385 
386     ipa_init_args.offset_in_heap = Init_Param->offset_in_heap;
387     ipa_init_args.len = Init_Param->len;
388 #ifdef DEBUG_IPA_KERNEL_MODE
389     printk("%s:%d Init_Param  heapid %u  ,offset=0x%llx,len=0x%llx\n",__FUNCTION__,__LINE__, Init_Param->space_id,(long long unsigned int)Init_Param->offset_in_heap,(long long unsigned int)Init_Param->len);
390     printk("%s:%d Init_Param->pool_name=%s,ipa_init_args->pool_name=%s\n",__FUNCTION__,__LINE__,Init_Param->pool_name,ipa_init_args.pool_name);
391 #endif
392     old_fs = get_fs();
393     set_fs(KERNEL_DS);
394 
395     res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_INIT, (unsigned long )(&ipa_init_args));
396     set_fs(old_fs);
397     if (res < 0 || ipa_init_args.error_code != IPAERROR_OK)
398     {
399         printk("%s:%d error: ipa init failed, heapid %u error_code %d\n",__FUNCTION__,__LINE__, Init_Param->space_id, ipa_init_args.error_code);
400         ret =  FALSE;
401         goto IPA_POOL_INIT_CLOSE;
402     }
403 #if DEBUG_IPA_KERNEL_MODE
404     printk("%s:%d   heap_id %u, pool_handle_id %u heap_length %llu\n",__FUNCTION__,__LINE__,
405 		Init_Param->space_id, ipa_init_args.pool_handle_id, (long long unsigned int)ipa_init_args.heap_length);
406 #endif
407     Init_Param->pool_handle_id = ipa_init_args.pool_handle_id;
408     Init_Param->miu = ipa_init_args.miu;
409     Init_Param->space_type = ipa_init_args.heap_type;
410     Init_Param->error_code = ipa_init_args.error_code;
411     Init_Param->space_length = ipa_init_args.heap_length;
412     Init_Param->space_miu_start_offset = ipa_init_args.heap_miu_start_offset;
413     ret = _findEmpty_IPA_Pool_Entry(&idx);
414     if(ret == FALSE)
415     {
416         printk("%s:%d   error: pool_handle_id %u init failed!\n",__FUNCTION__,__LINE__, ipa_init_args.pool_handle_id);
417         goto IPA_POOL_INIT_DONE;
418     }
419     /* IPA Pool setting*/
420     IPAPool_Info[idx].Init_Param.heap_id = Init_Param->space_id;
421 
422 #if defined (__aarch64__)
423     IPAPool_Info[idx].Init_Param.pool_name = (MS_U64)Init_Param->pool_name;
424 #else
425     IPAPool_Info[idx].Init_Param.pool_name = (MS_U32)Init_Param->pool_name;
426 #endif
427     IPAPool_Info[idx].Init_Param.offset_in_heap =Init_Param->offset_in_heap;
428     IPAPool_Info[idx].Init_Param.len =Init_Param->len;
429     IPAPool_Info[idx].Init_Param.pool_handle_id =Init_Param->pool_handle_id;
430     IPAPool_Info[idx].Init_Param.miu =Init_Param->miu;
431     IPAPool_Info[idx].Init_Param.heap_type =Init_Param->space_type;
432     IPAPool_Info[idx].Init_Param.error_code =Init_Param->error_code;
433     IPAPool_Info[idx].Init_Param.heap_length =Init_Param->space_length;
434     IPAPool_Info[idx].Init_Param.heap_miu_start_offset =Init_Param->space_miu_start_offset;
435     IPAPool_Info[idx].bIsUsed = TRUE;
436     IPAPool_Info[idx].pthIPAPollingId = -1;//in init,no polling id yet.
437     IPAPool_Info[idx].polling_thread_delete_task_flag = FALSE;
438 
439 #if DEBUG_IPA_KERNEL_MODE
440     printk("%s:%d    heap_id %u pool_handle_id %u miu %u offset 0x%llx len 0x%llx\n",__FUNCTION__,__LINE__,
441 		Init_Param->space_id, Init_Param->pool_handle_id, Init_Param->miu, (long long unsigned int)Init_Param->offset_in_heap, (long long unsigned int)Init_Param->len);
442 #endif
443     mutex_unlock(&_IPA_POOL_Mutex);
444 #if DEBUG_IPA_KERNEL_MODE
445     printk("%s:%d   return %d\n",__FUNCTION__,__LINE__,ret);
446 #endif
447 
448     return ret;
449 
450 IPA_POOL_INIT_CLOSE:
451     filp_close(_fileIPAPool,NULL);
452 IPA_POOL_INIT_DONE:
453     printk("%s:%d  ret=%d\n",__FUNCTION__,__LINE__,ret);
454     mutex_unlock(&_IPA_POOL_Mutex);
455 
456     return ret;
457 }
458 
459 //MS_U32 u32flag. Special Flag for customer mem allocation
MApi_IPA_Pool_GetMem(struct IPA_Pool_GetMem_Param * get_param)460 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_GetMem(struct IPA_Pool_GetMem_Param * get_param)
461 {
462     MS_BOOL ret = TRUE;
463     struct IPA_Pool_Alloc_Args  ipa_alloc_args;
464 
465     int res = 0;
466     mm_segment_t old_fs;
467 
468     if (in_interrupt() || (current->flags & PF_KTHREAD))
469     {
470         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
471         return false;
472     }
473 
474 #if DEBUG_IPA_KERNEL_MODE
475     printk("%s:%d handle_id 0x%x length 0x%llx\n",__FUNCTION__,__LINE__, get_param->pool_handle_id, (long long unsigned int)get_param->length);
476 #endif
477 
478     mutex_lock(&_IPA_POOL_Mutex);
479     if (IS_ERR(_fileIPAPool))
480     {
481         ret = FALSE;
482         goto IPA_POOL_GETMEM_DONE;
483     }
484 
485     ipa_alloc_args.pool_handle_id = get_param->pool_handle_id;
486     ipa_alloc_args.offset_in_pool = get_param->offset_in_pool;
487     ipa_alloc_args.length = get_param->length;
488     ipa_alloc_args.timeout = 0;// 0 means if fail ,will not try again
489     old_fs = get_fs();
490     set_fs(KERNEL_DS);
491     res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_ALLOC, (unsigned long)(&ipa_alloc_args));
492     set_fs(old_fs);
493     if (res < 0 || ipa_alloc_args.error_code != IPAERROR_OK)
494     {
495         printk("%s:%d fail: pool_handle_id %u, offset 0x%llx, len 0x%llx  ipa_alloc_args.error_code=0x%x  res=%d\n",__FUNCTION__,__LINE__, get_param->pool_handle_id,
496 			(long long unsigned int)get_param->offset_in_pool, (long long unsigned int)get_param->length,ipa_alloc_args.error_code,res);
497         ret = FALSE;
498         goto IPA_POOL_GETMEM_DONE;
499     }
500 
501     get_param->error_code = ipa_alloc_args.error_code;
502 
503 IPA_POOL_GETMEM_DONE:
504     mutex_unlock(&_IPA_POOL_Mutex);
505 
506     return ret;
507 }
508 
MApi_IPA_Pool_PutMem(struct IPA_Pool_PutMem_Param * put_param)509 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_PutMem(struct IPA_Pool_PutMem_Param * put_param)
510 {
511     MS_BOOL ret = TRUE;
512     struct IPA_Pool_free_Args ipa_free_args;
513     mm_segment_t old_fs;
514 
515     if (in_interrupt() || (current->flags & PF_KTHREAD))
516     {
517         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
518         return false;
519     }
520 
521 #if DEBUG_IPA_KERNEL_MODE
522     printk("%s:%d handle_id 0x%x length 0x%llx offset 0x%llx\n",__FUNCTION__,__LINE__,
523 		put_param->pool_handle_id, (long long unsigned int)put_param->length, (long long unsigned int)put_param->offset_in_pool);
524 #endif
525 
526     mutex_lock(&_IPA_POOL_Mutex);
527     if(IS_ERR(_fileIPAPool) )
528     {
529         ret = FALSE;
530         goto IPA_POOL_PUTMEM_DONE;
531     }
532 
533     ipa_free_args.pool_handle_id = put_param->pool_handle_id;
534     ipa_free_args.offset_in_pool = put_param->offset_in_pool;
535     ipa_free_args.length = put_param->length;
536     old_fs = get_fs();
537     set_fs(KERNEL_DS);
538     if(file_ioctl(_fileIPAPool, IPA_POOL_IOC_FREE, (unsigned long)(&ipa_free_args)))
539     {
540         set_fs(old_fs);
541         printk("%s:%d fail: pool_handle_id 0x%x, offset 0x%llx, len 0x%llx\n",__FUNCTION__,__LINE__,
542 			put_param->pool_handle_id, (long long unsigned int)put_param->offset_in_pool, (long long unsigned int)put_param->length);
543         ret = FALSE;
544         goto IPA_POOL_PUTMEM_DONE;
545     }
546     set_fs(old_fs);
547 
548 IPA_POOL_PUTMEM_DONE:
549     mutex_unlock(&_IPA_POOL_Mutex);
550 
551     return ret;
552 }
553 
MApi_IPA_Pool_Release(MS_U32 pool_handle_id)554 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_Release(MS_U32 pool_handle_id)
555 {
556     MS_BOOL ret = TRUE;
557 
558     struct IPA_Pool_Deinit_Args  deinit_args;
559     struct IPA_Pool_Unmap_Args  unmap_args;
560 
561     MS_U32 idx = 0;
562     int res = 0,i=0;
563     mm_segment_t old_fs;
564 
565     if (in_interrupt() || (current->flags & PF_KTHREAD))
566     {
567         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
568         return false;
569     }
570 
571 #if DEBUG_IPA_KERNEL_MODE
572     printk("%s:%d handle_id %u\n",__FUNCTION__,__LINE__, pool_handle_id);
573 #endif
574 
575     mutex_lock(&_IPA_POOL_Mutex);
576     if (IS_ERR(_fileIPAPool) )
577     {
578         ret = FALSE;
579         goto IPA_POOL_RELEASE_DONE;
580     }
581 
582     ret = _findPoolHandleId_InIPA_Pool_Table(pool_handle_id, &idx);
583     if(ret == TRUE)
584     {
585         for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
586         {
587             // tmp_map_info
588             if((0 !=IPAPool_Info[idx].map_info[i].virt_addr)
589 			    && (0 != IPAPool_Info[idx].map_info[i].length))
590             {
591                 unmap_args.virt_addr =	IPAPool_Info[idx].map_info[i].virt_addr;
592                 unmap_args.length = IPAPool_Info[idx].map_info[i].length;
593 #if TEST_USE_SELF_KO_MAKEFILE
594 #else
595                 MsOS_MPool_Remove_PA2VARange(IPAPool_Info[idx].map_info[i].Physaddr, IPAPool_Info[idx].map_info[i].virt_addr, IPAPool_Info[idx].map_info[i].length, IPAPool_Info[idx].map_info[i].bNonCache);
596 #endif
597                 old_fs = get_fs();
598                 set_fs(KERNEL_DS);
599                 res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_UNMAP, (unsigned long)(&unmap_args));
600                 set_fs(old_fs);
601                 if (res < 0)
602                 {
603                     printk("%s:%d error: pool_handle_id %u unmap failed\n",__FUNCTION__,__LINE__, pool_handle_id);
604                     ret = FALSE;
605                     goto IPA_POOL_RELEASE_DONE;
606                 }
607                 IPAPool_Info[idx].map_info[i].virt_addr = 0;
608                 IPAPool_Info[idx].map_info[i].length = 0;
609             }
610         }
611 
612         if(MAX_CLIENT_MAP_NUM == i)
613         {
614             // if same client all maps have been unmapped ,set  IPAPool_Info[idx].bIsUsed be FALSE
615             IPAPool_Info[idx].bIsUsed = FALSE;
616             IPAPool_Info[idx].Init_Param.pool_handle_id = 0;
617         }
618     }
619 
620     deinit_args.pool_handle_id = pool_handle_id;
621     old_fs = get_fs();
622     set_fs(KERNEL_DS);
623     if (file_ioctl(_fileIPAPool, IPA_POOL_IOC_DEINIT, (unsigned long)(&deinit_args)))
624     {
625         set_fs(old_fs);
626         printk("%s:%d pool_handle_id %u deinit fail\n",__FUNCTION__,__LINE__, pool_handle_id);
627         ret = FALSE;
628         goto IPA_POOL_RELEASE_DONE;
629     }
630     set_fs(old_fs);
631     ret = TRUE; //not find the pool hand id
632 
633     //after deinit, if have polling thread,should delete task
634     if(IPAPool_Info[idx].pthIPAPollingId != -1)
635     {
636         #if 0//no need this while,for later pthread_join + pthread_cancel will wait for set delete_task_flag.
637         while(1)
638         {
639             if(TRUE == IPAPool_Info[idx].polling_thread_delete_task_flag)
640                 break;
641         }
642         #endif
643 
644         //should add some code about waitting polling thread to finish???
645         //free_task(find_task_by_vpid(IPAPool_Info[idx].pthIPAPollingId));
646         //mb();
647         //__put_task_struct(find_task_by_vpid(IPAPool_Info[idx].pthIPAPollingId));
648 
649         if(TRUE != IPAPool_Info[idx].polling_thread_delete_task_flag)
650         {
651             printk("%s:%d error !!!!!!   after free_task  polling_thread_delete_task_flag is not TRUE!!!\n",__FUNCTION__,__LINE__);
652             ret = FALSE;
653         }
654 
655     }
656 
657 IPA_POOL_RELEASE_DONE:
658     mutex_unlock(&_IPA_POOL_Mutex);
659     return ret;
660 }
661 
662 #if 0//in user mode,use MapUserVA and UnmapUserVA,but in kernel mode use MapKerVA and UnmapKerVA.
663 //allow a same input [pool_handle_id, offset_in_pool, length, cache_type] map for more than once,
664 //and get different result output [virt_addr]
665 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_MapUserVA(struct IPA_Pool_Map_User_Param * map_param)
666 {
667     MS_BOOL ret = TRUE;
668     int res = 0;
669 
670     struct IPA_Pool_Map_Args map_args;
671 
672     MS_U32 idx = 0;
673     mm_segment_t old_fs;
674 
675     if (in_interrupt() || (current->flags & PF_KTHREAD))
676     {
677         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
678         return false;
679     }
680 
681 #if DEBUG_IPA_KERNEL_MODE
682     printk("%s:%d pool_handle_id %u, offset_in_pool 0x%llx, len 0x%llx,  cache_type %u\n",__FUNCTION__,__LINE__, map_param->pool_handle_id,
683 		(long long unsigned int)map_param->offset_in_pool, (long long unsigned int)map_param->length,map_param->cache_type);
684 #endif
685 
686     mutex_lock(&_IPA_POOL_Mutex);
687     if (IS_ERR(_fileIPAPool) )
688     {
689         ret = FALSE;
690         goto IPA_POOL_MapUserVA_DONE;
691     }
692 
693     if(0 == map_param->length)
694     {
695         printk("%s:%d  error, len 0x%llx is invalid\n",__FUNCTION__,__LINE__,  (long long unsigned int)map_param->length);
696         ret = FALSE;
697         goto IPA_POOL_MapUserVA_DONE;
698     }
699 
700     map_args.pool_handle_id = map_param->pool_handle_id;
701     map_args.offset_in_pool = map_param->offset_in_pool;
702     map_args.length = map_param->length;
703     map_args.map_va_type = map_param->cache_type;
704 
705     old_fs = get_fs();
706     set_fs(KERNEL_DS);
707     res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_MAP, (unsigned long)(&map_args));
708     set_fs(old_fs);
709     if (res < 0 || map_args.error_code != IPAERROR_OK)
710     {
711         printk("%s:%d  fail: pool_handle_id %u, offset_in_pool 0x%llx, len 0x%llx,  cache_type %u\n",__FUNCTION__,__LINE__, map_param->pool_handle_id,
712 			(long long unsigned int)map_param->offset_in_pool, (long long unsigned int)map_param->length,map_param->cache_type);
713         ret = FALSE;
714         goto IPA_POOL_MapUserVA_DONE;
715     }
716     map_param->virt_addr = map_args.virt_addr;
717     map_param->error_code = map_args.error_code;
718 
719     ret = _findPoolHandleId_InIPA_Pool_Table(map_param->pool_handle_id, &idx);
720     if(ret == TRUE)
721     {
722         int i=0;
723         for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
724         {
725             if((0 == IPAPool_Info[idx].map_info[i].virt_addr)
726 			  || (0 == IPAPool_Info[idx].map_info[i].length))
727             {
728                 IPAPool_Info[idx].map_info[i].virt_addr  = map_args.virt_addr;
729                 IPAPool_Info[idx].map_info[i].length = map_args.length;
730 #if TEST_USE_SELF_KO_MAKEFILE
731 #else
732                 _miu_offset_to_phy(IPAPool_Info[idx].Init_Param.miu, IPAPool_Info[idx].Init_Param.offset_in_heap + map_param->offset_in_pool, IPAPool_Info[idx].map_info[i].Physaddr); // get miu base addr
733                 if(IPA_VA_CACHE_NONE_CACHE_Param == map_param->cache_type)
734                     IPAPool_Info[idx].map_info[i].bNonCache = TRUE;
735                 else
736                     IPAPool_Info[idx].map_info[i].bNonCache = FALSE;
737 
738                 MsOS_MPool_Add_PA2VARange(IPAPool_Info[idx].map_info[i].Physaddr, IPAPool_Info[idx].map_info[i].virt_addr, IPAPool_Info[idx].map_info[i].length, IPAPool_Info[idx].map_info[i].bNonCache);
739 #endif
740                 break;
741             }
742         }
743 
744         if(MAX_CLIENT_MAP_NUM == i)
745         {
746             printk("print important log for 3 times :a same client mapped %lu times,unable  map once more!!!!\n", MAX_CLIENT_MAP_NUM);
747             printk("print important log for 3 times :a same client mapped %lu times,unable  map once more!!!!\n", MAX_CLIENT_MAP_NUM);
748             printk("print important log for 3 times :a same client mapped %lu times,unable  map once more!!!!\n", MAX_CLIENT_MAP_NUM);
749             //here later can add code for dump map info
750             ret = FALSE;
751             goto IPA_POOL_MapUserVA_DONE;
752         }
753     }
754 
755 IPA_POOL_MapUserVA_DONE:
756 #if DEBUG_IPA_KERNEL_MODE
757     printk("%s:%d ret=%d\n",__FUNCTION__,__LINE__,ret);
758 #endif
759     mutex_unlock(&_IPA_POOL_Mutex);
760 
761     return ret;
762 }
763 
764 void  __attribute__((weak)) MApi_IPA_Pool_UnmapUserVA(struct IPA_Pool_Unmap_User_Param * unmap_param)
765 {
766     MS_BOOL ret = TRUE;
767     int res = 0;
768     int i=0,idx=0,find_virt_info_i=-1,find_virt_info_idx=-1;
769     MS_BOOL find_virt_info = FALSE;
770 
771     struct IPA_Pool_Unmap_Args  unmap_args;
772     mm_segment_t old_fs;
773 
774     if (in_interrupt() || (current->flags & PF_KTHREAD))
775     {
776         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
777         return;
778     }
779 #if DEBUG_IPA_KERNEL_MODE
780     printk("%s:%d   virt_addr 0x%llx, len 0x%llx \n",__FUNCTION__,__LINE__,(long long unsigned int)unmap_param->virt_addr, (long long unsigned int)unmap_param->length);
781 #endif
782 
783     mutex_lock(&_IPA_POOL_Mutex);
784     if (IS_ERR(_fileIPAPool))
785     {
786         ret = FALSE;
787         goto IPA_POOL_UnmapUserVA_DONE;
788     }
789     for(idx=0;idx < MAX_IPAPOOLSIZE;idx++)
790     {
791         if(TRUE == IPAPool_Info[idx].bIsUsed)
792         {
793             for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
794             {
795                 if((unmap_param->virt_addr == IPAPool_Info[idx].map_info[i].virt_addr)
796 			  	 && (unmap_param->length == IPAPool_Info[idx].map_info[i].length))
797                 {
798                     find_virt_info = TRUE;
799                     find_virt_info_idx = idx;
800                     find_virt_info_i = i;
801                 }
802             }
803         }
804     }
805     if(FALSE == find_virt_info)
806     {
807         printk("print important log for 3 times :map and unmap area should be strict equal !!!!  virt_addr=0x%llx,length=0x%llx\n", (long long unsigned int)unmap_param->virt_addr,(long long unsigned int)unmap_param->length);
808         printk("print important log for 3 times :map and unmap area should be strict equal !!!!  virt_addr=0x%llx,length=0x%llx\n", (long long unsigned int)unmap_param->virt_addr,(long long unsigned int)unmap_param->length);
809         printk("print important log for 3 times :map and unmap area should be strict equal !!!!  virt_addr=0x%llx,length=0x%llx\n", (long long unsigned int)unmap_param->virt_addr,(long long unsigned int)unmap_param->length);
810         //later will add some debug code
811         ret = FALSE;
812         goto IPA_POOL_UnmapUserVA_DONE;
813     }
814 
815     unmap_args.virt_addr = unmap_param->virt_addr;
816     unmap_args.length = unmap_param->length;
817 #if TEST_USE_SELF_KO_MAKEFILE
818 #else
819     MsOS_MPool_Remove_PA2VARange(IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].Physaddr, IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].virt_addr, IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].length, IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].bNonCache);
820 #endif
821     old_fs = get_fs();
822     set_fs(KERNEL_DS);
823 
824     res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_UNMAP,(unsigned long)(&unmap_args));
825     set_fs(old_fs);
826     if (res < 0)
827     {
828         printk("%s:%d  fail:  virt_addr 0x%llx, len 0x%llx \n",__FUNCTION__,__LINE__,
829 			(long long unsigned int)unmap_param->virt_addr, (long long unsigned int)unmap_param->length);
830         ret = FALSE;
831         goto IPA_POOL_UnmapUserVA_DONE;
832     }
833     IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].virt_addr = 0;
834     IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].length = 0;
835 
836 IPA_POOL_UnmapUserVA_DONE:
837     mutex_unlock(&_IPA_POOL_Mutex);
838 
839     return;
840 }
841 #endif
MApi_IPA_Pool_MapKerVA(struct IPA_Pool_Map_Param * map_param)842 static MS_BOOL MApi_IPA_Pool_MapKerVA(struct IPA_Pool_Map_Param * map_param)
843 {
844     MS_BOOL ret = TRUE;
845     int res = 0;
846 
847     struct IPA_Pool_Map_Args map_args;
848 
849     MS_U32 idx = 0;
850     mm_segment_t old_fs;
851 
852     if (in_interrupt() || (current->flags & PF_KTHREAD))
853     {
854         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
855         return false;
856     }
857 
858 #if DEBUG_IPA_KERNEL_MODE
859     printk("%s:%d pool_handle_id %u, offset_in_pool 0x%llx, len 0x%llx,  cache_type %u\n",__FUNCTION__,__LINE__, map_param->pool_handle_id,
860         (long long unsigned int)map_param->offset_in_pool, (long long unsigned int)map_param->length,map_param->cache_type);
861 #endif
862 
863     mutex_lock(&_IPA_POOL_Mutex);
864     if (IS_ERR(_fileIPAPool) )
865     {
866         ret = FALSE;
867         goto IPA_POOL_MapUserVA_DONE;
868     }
869 
870     if(0 == map_param->length)
871     {
872         printk("%s:%d  error, len 0x%llx is invalid\n",__FUNCTION__,__LINE__,  (long long unsigned int)map_param->length);
873         ret = FALSE;
874         goto IPA_POOL_MapUserVA_DONE;
875     }
876 
877     map_args.pool_handle_id = map_param->pool_handle_id;
878     map_args.offset_in_pool = map_param->offset_in_pool;
879     map_args.length = map_param->length;
880     map_args.map_va_type = map_param->cache_type;
881 
882 
883     old_fs = get_fs();
884     set_fs(KERNEL_DS);
885     res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_KERNEL_MAP, (unsigned long)(&map_args));
886     set_fs(old_fs);
887 
888     if (res < 0 || map_args.error_code != IPAERROR_OK)
889     {
890         printk("%s:%d  fail: pool_handle_id %u, offset_in_pool 0x%llx, len 0x%llx,  cache_type %u\n",__FUNCTION__,__LINE__, map_param->pool_handle_id,
891             (long long unsigned int)map_param->offset_in_pool, (long long unsigned int)map_param->length,map_param->cache_type);
892         ret = FALSE;
893         goto IPA_POOL_MapUserVA_DONE;
894     }
895     map_param->virt_addr = map_args.virt_addr;
896     map_param->error_code = map_args.error_code;
897 
898     ret = _findPoolHandleId_InIPA_Pool_Table(map_param->pool_handle_id, &idx);
899     if(ret == TRUE)
900     {
901         int i=0;
902         for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
903         {
904             if((0 == IPAPool_Info[idx].map_info[i].virt_addr)
905               || (0 == IPAPool_Info[idx].map_info[i].length))
906             {
907                 IPAPool_Info[idx].map_info[i].virt_addr  = map_args.virt_addr;
908                 IPAPool_Info[idx].map_info[i].length = map_args.length;
909 #if TEST_USE_SELF_KO_MAKEFILE
910 #else
911                 _miu_offset_to_phy(IPAPool_Info[idx].Init_Param.miu, IPAPool_Info[idx].Init_Param.offset_in_heap + map_param->offset_in_pool, IPAPool_Info[idx].map_info[i].Physaddr); // get miu base addr
912                 if(IPA_VA_CACHE_NONE_CACHE_Param == map_param->cache_type)
913                     IPAPool_Info[idx].map_info[i].bNonCache = TRUE;
914                 else
915                     IPAPool_Info[idx].map_info[i].bNonCache = FALSE;
916                 MsOS_MPool_Add_PA2VARange(IPAPool_Info[idx].map_info[i].Physaddr, IPAPool_Info[idx].map_info[i].virt_addr, IPAPool_Info[idx].map_info[i].length, IPAPool_Info[idx].map_info[i].bNonCache);
917 #endif
918                 break;
919             }
920         }
921         if(MAX_CLIENT_MAP_NUM == i)
922         {
923             printk("print important log for 3 times :a same client mapped %lu times,unable  map once more!!!!\n", MAX_CLIENT_MAP_NUM);
924             printk("print important log for 3 times :a same client mapped %lu times,unable  map once more!!!!\n", MAX_CLIENT_MAP_NUM);
925             printk("print important log for 3 times :a same client mapped %lu times,unable  map once more!!!!\n", MAX_CLIENT_MAP_NUM);
926             //here later can add code for dump map info
927             ret = FALSE;
928             goto IPA_POOL_MapUserVA_DONE;
929         }
930     }
931 
932 IPA_POOL_MapUserVA_DONE:
933     printk("%s ret=%d\n",__FUNCTION__,ret);
934     mutex_unlock(&_IPA_POOL_Mutex);
935 
936     return ret;
937 }
938 
MApi_IPA_Pool_MapVA(struct IPA_Pool_Map_Param * map_param)939 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_MapVA(struct IPA_Pool_Map_Param * map_param)
940 {
941     return MApi_IPA_Pool_MapKerVA(map_param);
942 }
943 
MApi_IPA_Pool_UnmapKerVA(struct IPA_Pool_Unmap_Param * unmap_param)944 static void MApi_IPA_Pool_UnmapKerVA(struct IPA_Pool_Unmap_Param * unmap_param)
945 {
946     MS_BOOL ret = TRUE;
947     int res = 0;
948     int i=0,idx=0,find_virt_info_i=-1,find_virt_info_idx=-1;
949     MS_BOOL find_virt_info = FALSE;
950 
951     struct IPA_Pool_Unmap_Args unmap_args;
952     mm_segment_t old_fs;
953 
954     if (in_interrupt() || (current->flags & PF_KTHREAD))
955     {
956         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
957         return;
958     }
959 
960 #if DEBUG_IPA_KERNEL_MODE
961     printk("%s:%d   virt_addr 0x%llx \n",__FUNCTION__,__LINE__, (long long unsigned int)unmap_param->virt_addr);
962 #endif
963 
964     mutex_lock(&_IPA_POOL_Mutex);
965     if (IS_ERR(_fileIPAPool))
966     {
967         ret = FALSE;
968         goto IPA_POOL_UnmapUserVA_DONE;
969     }
970     for(idx=0;idx < MAX_IPAPOOLSIZE;idx++)
971     {
972         if(TRUE == IPAPool_Info[idx].bIsUsed)
973         {
974             for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
975             {
976                 if(unmap_param->virt_addr == IPAPool_Info[idx].map_info[i].virt_addr)
977                 {
978                     find_virt_info = TRUE;
979                     find_virt_info_idx = idx;
980                     find_virt_info_i = i;
981                 }
982             }
983         }
984     }
985     if(FALSE == find_virt_info)
986     {
987         printk("print important log for 3 times :map and unmap area should be strict equal !!!!  virt_addr=0x%llx\n", (long long unsigned int)unmap_param->virt_addr);
988         printk("print important log for 3 times :map and unmap area should be strict equal !!!!  virt_addr=0x%llx\n", (long long unsigned int)unmap_param->virt_addr);
989         printk("print important log for 3 times :map and unmap area should be strict equal !!!!  virt_addr=0x%llx\n", (long long unsigned int)unmap_param->virt_addr);
990         //later will add some debug code
991         ret = FALSE;
992         goto IPA_POOL_UnmapUserVA_DONE;
993     }
994 
995     unmap_args.virt_addr = unmap_param->virt_addr;
996 #if TEST_USE_SELF_KO_MAKEFILE
997 #else
998     MsOS_MPool_Remove_PA2VARange(IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].Physaddr, IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].virt_addr, IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].length, IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].bNonCache);
999 #endif
1000     old_fs = get_fs();
1001     set_fs(KERNEL_DS);
1002 
1003     res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_KERNEL_UNMAP,(unsigned long)(&unmap_args));
1004     set_fs(old_fs);
1005     if (res < 0)
1006     {
1007         printk("%s:%d  fail:  virt_addr 0x%llx\n",__FUNCTION__,__LINE__, (long long unsigned int)unmap_param->virt_addr);
1008         ret = FALSE;
1009         goto IPA_POOL_UnmapUserVA_DONE;
1010     }
1011     IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].virt_addr = 0;
1012     IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].length = 0;
1013 
1014 IPA_POOL_UnmapUserVA_DONE:
1015     mutex_unlock(&_IPA_POOL_Mutex);
1016 
1017     return;
1018 }
1019 
MApi_IPA_Pool_UnmapVA(struct IPA_Pool_Unmap_Param * unmap_param)1020 void __attribute__((weak)) MApi_IPA_Pool_UnmapVA(struct IPA_Pool_Unmap_Param * unmap_param)
1021 {
1022     return MApi_IPA_Pool_UnmapKerVA(unmap_param);
1023 }
1024 
MApi_IPA_Pool_DCacheFlush(struct IPA_Pool_DCacheFlush_Param * dcache_flush_param)1025 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_DCacheFlush(struct IPA_Pool_DCacheFlush_Param* dcache_flush_param)
1026 {
1027     MS_BOOL ret = TRUE;
1028     int res = 0;
1029 
1030     struct IPA_Pool_DCacheFlush_Args dcache_flush_args;
1031     mm_segment_t old_fs;
1032 
1033     if (in_interrupt() || (current->flags & PF_KTHREAD))
1034     {
1035         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
1036         return false;
1037     }
1038 
1039 #if DEBUG_IPA_KERNEL_MODE
1040     printk("%s:%d  virt_addr 0x%llx, length 0x%llx flush_type 0x%x\n",
1041 		__FUNCTION__,__LINE__,(long long unsigned int)dcache_flush_param->virt_addr, (long long unsigned int)dcache_flush_param->length, dcache_flush_param->flush_type);
1042 #endif
1043 
1044     mutex_lock(&_IPA_POOL_Mutex);
1045     if (IS_ERR(_fileIPAPool))
1046     {
1047         ret = FALSE;
1048         goto IPA_POOL_DCacheFlush_DONE;
1049     }
1050 
1051     dcache_flush_args.virt_addr = dcache_flush_param->virt_addr;
1052     dcache_flush_args.length = dcache_flush_param->length;
1053     dcache_flush_args.flush_type = dcache_flush_param->flush_type;
1054     old_fs = get_fs();
1055     set_fs(KERNEL_DS);
1056     res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_FLUSH,(unsigned long)(&dcache_flush_args));
1057     set_fs(old_fs);
1058     if (res < 0)
1059     {
1060         printk("%s:%d  fail:  virt_addr 0x%llx, length 0x%llx , flush_type 0x%x\n",
1061             __FUNCTION__,__LINE__,(long long unsigned int)dcache_flush_param->virt_addr, (long long unsigned int)dcache_flush_param->length, dcache_flush_param->flush_type);
1062         ret = FALSE;
1063         goto IPA_POOL_DCacheFlush_DONE;
1064     }
1065 
1066 IPA_POOL_DCacheFlush_DONE:
1067     mutex_unlock(&_IPA_POOL_Mutex);
1068 
1069     return ret;
1070 }
1071 
MApi_IPA_Pool_HEAP_ATTR(struct IPA_Pool_Heap_Attr_Param * heap_attr_param)1072 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_HEAP_ATTR(struct IPA_Pool_Heap_Attr_Param* heap_attr_param)
1073 {
1074     MS_BOOL ret = TRUE;
1075     int res = 0;
1076 
1077     struct IPA_Pool_Heap_Attr  heap_attr_args;
1078     mm_segment_t old_fs;
1079 
1080     if (in_interrupt() || (current->flags & PF_KTHREAD))
1081     {
1082         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
1083         return false;
1084     }
1085 
1086 #if DEBUG_IPA_KERNEL_MODE
1087     printk("%s:%d  heap_id 0x%x\n",__FUNCTION__,__LINE__, heap_attr_param->heap_id);
1088 #endif
1089 
1090     mutex_lock(&_IPA_POOL_Mutex);
1091     if (IS_ERR(_fileIPAPool ))
1092     {
1093         ret = FALSE;
1094         goto IPA_POOL_HEAP_ATTR_DONE;
1095     }
1096 
1097     heap_attr_args.heap_id = heap_attr_param->heap_id;
1098 
1099     old_fs = get_fs();
1100     set_fs(KERNEL_DS);
1101     res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_HEAP_ATTR,(unsigned long)(&heap_attr_args));
1102     set_fs(old_fs);
1103     if (res < 0 || heap_attr_args.error_code != IPAERROR_OK)
1104     {
1105         printk("%s:%d  fail:  heap_id 0x%x\n",__FUNCTION__,__LINE__,heap_attr_param->heap_id);
1106         ret = FALSE;
1107         goto IPA_POOL_HEAP_ATTR_DONE;
1108     }
1109     memcpy(heap_attr_param->name,heap_attr_args.name,IPAPOOL_HEAP_NAME_MAX_LEN);
1110     heap_attr_param->heap_miu_start_offset = heap_attr_args.heap_miu_start_offset;
1111     heap_attr_param->heap_length = heap_attr_args.heap_length;
1112     heap_attr_param->miu = heap_attr_args.miu;
1113     heap_attr_param->heap_type = heap_attr_args.heap_type;
1114     heap_attr_param->error_code = heap_attr_args.error_code;
1115 
1116 IPA_POOL_HEAP_ATTR_DONE:
1117     mutex_unlock(&_IPA_POOL_Mutex);
1118 
1119     return ret;
1120 }
1121 
MApi_IPA_Pool_GETIPCHANDLE(struct IPA_Pool_GetIpcHandle_Param * getipchandle_param)1122 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_GETIPCHANDLE(struct IPA_Pool_GetIpcHandle_Param* getipchandle_param)
1123 {
1124     MS_BOOL ret = TRUE;
1125     int res = 0;
1126 
1127     struct IPA_Pool_GetIpcHandle_Args  getipchandle_args;
1128     mm_segment_t old_fs;
1129 
1130     if (in_interrupt() || (current->flags & PF_KTHREAD))
1131     {
1132         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
1133         return false;
1134     }
1135 
1136 #if DEBUG_IPA_KERNEL_MODE
1137     printk("%s:%d    pool_handle_id 0x%x\n",__FUNCTION__,__LINE__, getipchandle_param->pool_handle_id);
1138 #endif
1139 
1140     mutex_lock(&_IPA_POOL_Mutex);
1141     if (IS_ERR(_fileIPAPool))
1142     {
1143         printk("%s:%d  fail  pool_handle_id=0x%x,   _fileIPAPool=%p \n",__FUNCTION__,__LINE__, getipchandle_param->pool_handle_id,_fileIPAPool);
1144         ret = FALSE;
1145         goto IPA_POOL_GETIPCHANDLE_DONE;
1146     }
1147 
1148     getipchandle_args.pool_handle_id = getipchandle_param->pool_handle_id;
1149     old_fs = get_fs();
1150     set_fs(KERNEL_DS);
1151     res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_GETIPCHANDLE,(unsigned long)(&getipchandle_args));
1152     set_fs(old_fs);
1153     if (res < 0 || getipchandle_args.error_code != IPAERROR_OK)
1154     {
1155         printk("%s:%d  fail:  pool_handle_id 0x%x\n",__FUNCTION__,__LINE__,getipchandle_param->pool_handle_id);
1156         ret = FALSE;
1157         goto IPA_POOL_GETIPCHANDLE_DONE;
1158     }
1159     getipchandle_param->ipc_handle_id = getipchandle_args.ipc_handle_id;
1160     getipchandle_param->error_code = getipchandle_args.error_code;
1161 
1162 IPA_POOL_GETIPCHANDLE_DONE:
1163     mutex_unlock(&_IPA_POOL_Mutex);
1164 
1165     return ret;
1166 }
1167 
MApi_IPA_Pool_InstallIpcHandle(struct IPA_Pool_InstallIpcHandle_Param * installipchandle_param)1168 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_InstallIpcHandle(struct IPA_Pool_InstallIpcHandle_Param* installipchandle_param)
1169 {
1170     MS_BOOL ret = TRUE;
1171     int res = 0;
1172 
1173     struct IPA_Pool_InstallIpcHandle_Args installipchandle_args;
1174     mm_segment_t old_fs;
1175 
1176     if (in_interrupt() || (current->flags & PF_KTHREAD))
1177     {
1178         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
1179         return false;
1180     }
1181 
1182 #if DEBUG_IPA_KERNEL_MODE
1183     printk("%s:%d  ipc_handle_id 0x%x\n",__FUNCTION__,__LINE__, installipchandle_param->ipc_handle_id);
1184 #endif
1185 
1186     mutex_lock(&_IPA_POOL_Mutex);
1187     if ( !_fileIPAPool || IS_ERR(_fileIPAPool))
1188     {
1189 #if DEBUG_IPA_KERNEL_MODE
1190         printk("%s:%d ipc_handle_id=0x%x,   _fileIPAPool=%p \n",__FUNCTION__,__LINE__, installipchandle_param->ipc_handle_id,_fileIPAPool);
1191 #endif
1192         //this process may not open ipapool yet,need we open for this process.
1193         int flags=O_RDWR;
1194         _fileIPAPool = filp_open( "/dev/ipapool", flags, 0);
1195         if (IS_ERR(_fileIPAPool) )
1196         {
1197             printk("%s:%d open /dev/ipapool fail   ipc_handle_id=0x%x,   _fileIPAPool=%p\n",__FUNCTION__,__LINE__, installipchandle_param->ipc_handle_id,_fileIPAPool);
1198             ret =  FALSE;
1199             goto IPA_POOL_InstallIpcHandle_DONE;
1200         }
1201 
1202         memset(IPAPool_Info, 0, sizeof(IPAPOOL_INFO)*MAX_IPAPOOLSIZE);
1203 
1204     }
1205 
1206     installipchandle_args.ipc_handle_id = installipchandle_param->ipc_handle_id;
1207 
1208     old_fs = get_fs();
1209     set_fs(KERNEL_DS);
1210     res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_INSTALLIPCHANDLE,(unsigned long)(&installipchandle_args));
1211     set_fs(old_fs);
1212 
1213     if (res < 0 || installipchandle_args.error_code != IPAERROR_OK)
1214     {
1215         printk("%s:%d  fail:  heap_id 0x%x\n",__FUNCTION__,__LINE__,installipchandle_param->ipc_handle_id);
1216         ret = FALSE;
1217         goto IPA_POOL_InstallIpcHandle_DONE;
1218     }
1219     installipchandle_param->pool_handle_id = installipchandle_args.pool_handle_id;
1220     installipchandle_param->error_code = installipchandle_args.error_code;
1221 
1222 IPA_POOL_InstallIpcHandle_DONE:
1223     mutex_unlock(&_IPA_POOL_Mutex);
1224 
1225     return ret;
1226 }
1227 
1228 //unit of timeout is millisecond.
MApi_IPA_Pool_GetMem_Timeout(struct IPA_Pool_GetMem_Param * get_param,MS_U32 timeout_ms)1229 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_GetMem_Timeout(struct IPA_Pool_GetMem_Param* get_param,MS_U32 timeout_ms)
1230 {
1231     MS_BOOL ret = TRUE;
1232 
1233     struct IPA_Pool_Alloc_Args  ipa_alloc_args;
1234 
1235     int res = 0;
1236     mm_segment_t old_fs;
1237 
1238     if (in_interrupt() || (current->flags & PF_KTHREAD))
1239     {
1240         printk("should only use kernel mode  utopia API %s in user process\n",__FUNCTION__);
1241         return false;
1242     }
1243 
1244 #if DEBUG_IPA_KERNEL_MODE
1245     printk("%s:%d handle_id 0x%x length 0x%llx timeout 0x%x\n",__FUNCTION__,__LINE__,
1246 		get_param->pool_handle_id, (long long unsigned int)get_param->length,timeout_ms);
1247 #endif
1248 
1249     mutex_lock(&_IPA_POOL_Mutex);
1250     if (IS_ERR(_fileIPAPool ))
1251     {
1252         ret = FALSE;
1253         goto IPA_POOL_GETMEM_DONE;
1254     }
1255 
1256     ipa_alloc_args.pool_handle_id = get_param->pool_handle_id;
1257     ipa_alloc_args.offset_in_pool = get_param->offset_in_pool;
1258     ipa_alloc_args.length = get_param->length;
1259 
1260     ipa_alloc_args.timeout = timeout_ms;
1261 
1262     old_fs = get_fs();
1263     set_fs(KERNEL_DS);
1264     res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_ALLOC, (unsigned long)(&ipa_alloc_args));
1265     set_fs(old_fs);
1266     if (res < 0 || ipa_alloc_args.error_code != IPAERROR_OK)
1267     {
1268         MS_U32 each_delay_ms = 50;//empirical value in our test.
1269         MS_U32 now_delay_ms=0;
1270         while(1)
1271         {
1272             // delay and try again
1273             mutex_unlock(&_IPA_POOL_Mutex);
1274 
1275 #if DEBUG_IPA_KERNEL_MODE
1276             printk("%s:%d each_delay_ms=%u, delay and try alloc again now_delay_ms=%u\n",__FUNCTION__,__LINE__,each_delay_ms,now_delay_ms);
1277 #endif
1278 
1279             ipa_alloc_args.timeout = 0;//into kernel will not consider timeout again
1280 #if TEST_USE_SELF_KO_MAKEFILE
1281             schedule_timeout_interruptible(msecs_to_jiffies(each_delay_ms));
1282 #else
1283             MsOS_DelayTask(each_delay_ms);
1284 #endif
1285             mutex_lock(&_IPA_POOL_Mutex);
1286 
1287             old_fs = get_fs();
1288             set_fs(KERNEL_DS);
1289             res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_ALLOC, (unsigned long)(&ipa_alloc_args));
1290             set_fs(old_fs);
1291             if ((res == 0) && (ipa_alloc_args.error_code == IPAERROR_OK))
1292                 break;
1293             now_delay_ms += each_delay_ms;
1294             if(now_delay_ms >= timeout_ms)
1295                 break;
1296         }
1297         if (res < 0 || ipa_alloc_args.error_code != IPAERROR_OK)
1298         {
1299             printk("%s:%d fail: pool_handle_id %u, offset 0x%llx, len 0x%llx  ipa_alloc_args.error_code=0x%x ipa_alloc_args.timeout=%u res=%d\n",__FUNCTION__,__LINE__, get_param->pool_handle_id,
1300 			(long long unsigned int)get_param->offset_in_pool, (long long unsigned int)get_param->length,ipa_alloc_args.error_code,ipa_alloc_args.timeout,res);
1301             ret = FALSE;
1302             goto IPA_POOL_GETMEM_DONE;
1303         }
1304     }
1305 
1306     get_param->error_code = ipa_alloc_args.error_code;
1307 
1308 IPA_POOL_GETMEM_DONE:
1309     mutex_unlock(&_IPA_POOL_Mutex);
1310 
1311     return ret;
1312 
1313 }
1314 
IPA_Pool_Polling_Task(void * argc)1315 int __attribute__((weak)) IPA_Pool_Polling_Task(void *argc)
1316 {
1317 #if 1
1318     printk("%s:%d not realize yet!\n",__FUNCTION__,__LINE__);
1319 	return -1;
1320 #else
1321     MS_BOOL ret = TRUE;
1322     int res=0;
1323     MS_U32 idx = 0;
1324     mm_segment_t old_fs;
1325 
1326     struct IPA_Pool_Event_Args  *pool_event_args =kmalloc(sizeof(struct IPA_Pool_Event_Args),GFP_KERNEL);
1327     if(!pool_event_args)
1328     {
1329         printk("%s:%d  alloc fail  \n",__FUNCTION__,__LINE__);
1330         return -1;
1331     }
1332 
1333     memset(pool_event_args, 0, sizeof(struct IPA_Pool_Event_Args));
1334 
1335     struct IPA_Pool_InstallIpcHandle_Param installipchandle_param;
1336     installipchandle_param.ipc_handle_id = (*(MS_U32 *)argc);
1337 
1338     ret = MApi_IPA_Pool_InstallIpcHandle(&installipchandle_param);
1339     if(ret == FALSE || installipchandle_param.error_code != 0)
1340     {
1341         printk("%s:%d  fail\n",__FUNCTION__,__LINE__);
1342         return -1;
1343     }
1344 
1345     MS_U32 pool_handle_id  = installipchandle_param.pool_handle_id;
1346 
1347 
1348     mutex_lock(&_IPA_POOL_Mutex);
1349     if (IS_ERR(_fileIPAPool))
1350     {
1351         printk("%s:%d  fail  \n",__FUNCTION__,__LINE__);
1352         ret = FALSE;
1353         mutex_unlock(&_IPA_POOL_Mutex);
1354         return -1;
1355     }
1356     pool_event_args->pool_handle_id = pool_handle_id;
1357 
1358     ret = _findPoolHandleId_InIPA_Pool_Table(pool_event_args->pool_handle_id, &idx);
1359     mutex_unlock(&_IPA_POOL_Mutex);
1360     if(ret == FALSE)
1361     {
1362         printk("%s:%d  fail not find in pool table\n",__FUNCTION__,__LINE__);
1363         return -1;
1364     }
1365 #ifdef DEBUG_IPA_KERNEL_MODE
1366     printk("%s:%d  before while\n",__FUNCTION__,__LINE__);
1367 #endif
1368     old_fs = get_fs();
1369     set_fs(KERNEL_DS);
1370 
1371     while(1)
1372     {
1373         //ioctl for event and after callback,shoud ioctl again.
1374         //before each ioctl,should clear invalid event value.
1375         memset(pool_event_args,0,sizeof(struct IPA_Pool_Event_Args));
1376         pool_event_args->pool_handle_id = pool_handle_id;
1377         res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_POLL,(unsigned long)pool_event_args);
1378         if(res < 0)
1379         {
1380             printk("%s:%d  fail\n",__FUNCTION__,__LINE__);
1381             ret = FALSE;
1382             goto IPA_POOL_POLLING_TASK_DONE;
1383         }
1384 
1385         if(IPA_EVENT_NO_WAIT== pool_event_args->event )
1386         {
1387 #ifdef DEBUG_IPA_KERNEL_MODE
1388         printk("%s:%d  break\n",__FUNCTION__,__LINE__);
1389 #endif
1390             break;
1391         }
1392         else if(IPA_EVENT_CONFLICT == pool_event_args->event )
1393         {
1394             //invoke callback corresponding to that pool event
1395             IPAPool_Info[idx].polling_callback(pool_event_args->pool_handle_id,pool_event_args->start,pool_event_args->length);//call callback
1396         }
1397         else
1398         {
1399             printk("%s error ,event %d is invalid !!! but continue while\n",__FUNCTION__,pool_event_args->event);
1400         }
1401     }
1402 #ifdef DEBUG_IPA_KERNEL_MODE
1403     printk("%s:%d  after while\n",__FUNCTION__,__LINE__);
1404 #endif
1405 
1406 IPA_POOL_POLLING_TASK_DONE:
1407 
1408     //before return ,set this flag.And this flag will be checked in MApi_IPA_Pool_Release.
1409     IPAPool_Info[idx].polling_thread_delete_task_flag = TRUE;
1410 #ifdef DEBUG_IPA_KERNEL_MODE
1411     printk("%s:%d  have set polling_thread_delete_task_flag\n",__FUNCTION__,__LINE__);
1412 #endif
1413     kfree(pool_event_args);
1414 
1415     set_fs(old_fs);
1416 
1417 #ifdef DEBUG_IPA_KERNEL_MODE
1418     printk("%s:%d  \n",__FUNCTION__,__LINE__);
1419 #endif
1420 #endif
1421     return 0;
1422 }
1423 
1424 //suggest this API be invoked after MApi_IPA_Pool_Init.
MApi_IPA_Pool_Notify(struct IPA_Pool_Polling_Param * polling_param)1425 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_Notify(struct IPA_Pool_Polling_Param *polling_param)
1426 {
1427 #if 1
1428 
1429     printk("[%s:%d]error message no need and can not  realize %s for kernel mode utopia ,please use %s in user mode!!!!  \n",__FUNCTION__,__LINE__,__FUNCTION__,__FUNCTION__);
1430     BUG();
1431     return false;
1432 
1433 #else
1434 
1435     MS_BOOL ret = TRUE;
1436     struct task_struct  *IPAPolling_struct = NULL;
1437     MS_U32 idx = 0;
1438 
1439     printk("%s\n",__FUNCTION__);
1440     mutex_lock(&_IPA_POOL_Mutex);
1441     if(!polling_param->polling_callback)
1442     {
1443         printk("%u have no polling_callback function , %s return directly\n",polling_param->pool_handle_id,__FUNCTION__);
1444         mutex_unlock(&_IPA_POOL_Mutex);
1445         return TRUE;
1446     }
1447 
1448     ret = _findPoolHandleId_InIPA_Pool_Table(polling_param->pool_handle_id, &idx);
1449 
1450     if(ret == FALSE)//not find idx
1451     {
1452          printk(" %s ipa pool fail not find pool_handle_id %u in pool table\n",__FUNCTION__,polling_param->pool_handle_id);
1453          mutex_unlock(&_IPA_POOL_Mutex);
1454          return FALSE;
1455     }
1456 
1457     if(-1 == IPAPool_Info[idx].pthIPAPollingId) //no polling id refer to pool handle id
1458     {
1459 
1460         struct IPA_Pool_GetIpcHandle_Param getipchandle_param;
1461         getipchandle_param.pool_handle_id = polling_param->pool_handle_id;
1462 
1463         ret = MApi_IPA_Pool_GETIPCHANDLE(&getipchandle_param);
1464         if(ret == FALSE)
1465         {
1466                  mutex_unlock(&_IPA_POOL_Mutex);
1467             return ret;
1468         }
1469 
1470         //N.B. use kthread_create to create a thread,do not use kernel_thread.
1471         //For kernel_thread use in ko cause many issues in our test.samson.huang 20151105
1472         IPAPolling_struct = kthread_create(IPA_Pool_Polling_Task,(void *)(&(getipchandle_param.ipc_handle_id)),"iap_polling");
1473         if (!IS_ERR(IPAPolling_struct))
1474         {
1475             wake_up_process(IPAPolling_struct);
1476             printk("%s:%d tmp_struct=%p\n",__FUNCTION__,__LINE__,IPAPolling_struct);
1477         }
1478         else
1479         {
1480             printk("%s:%d fail\n",__FUNCTION__,__LINE__);
1481         }
1482         printk("%s:%d  debug\n",__FUNCTION__,__LINE__);
1483 
1484         if(IS_ERR(IPAPolling_struct))
1485         {
1486             printk("%s   can't create thread  \n",__FUNCTION__);
1487             ret= FALSE;
1488             mutex_unlock(&_IPA_POOL_Mutex);
1489             return ret;
1490         }
1491         else
1492         {
1493             //corresponding pthIPAPollingId to pool_handle_id
1494             IPAPool_Info[idx].pthIPAPollingId = get_task_pid(IPAPolling_struct, PIDTYPE_PID);
1495             IPAPool_Info[idx].polling_callback = polling_param->polling_callback;
1496 #ifdef DEBUG_IPA_KERNEL_MODE
1497             printk("%s:%d  kernel_thread success  pthIPAPollingId=%d\n",__FUNCTION__,__LINE__,IPAPool_Info[idx].pthIPAPollingId);
1498 #endif
1499         }
1500     }
1501     else//already have polling id refer to pool handle id.
1502     {
1503         ret=FALSE;
1504         printk("pool handle id %u has its polling id %lu ,error,will not set callback again\n",polling_param->pool_handle_id,IPAPool_Info[idx].pthIPAPollingId);
1505     }
1506 
1507     mutex_unlock(&_IPA_POOL_Mutex);
1508 #ifdef DEBUG_IPA_KERNEL_MODE
1509     printk("%s:%d  success ret=%d\n",__FUNCTION__,__LINE__,ret);
1510 #endif
1511     return ret;
1512 
1513 #endif
1514 }
1515 
1516 #if (TEST_USE_SELF_KO_MAKEFILE || TEST_USE_SELF_KO_MAKEFILE_TOTAL)//these just test code!!!
1517 #define DFB_TEMP_HID 27
1518 
1519 #define PAGE 4096
1520 #define MILLION (1<<20)
1521 
1522 static char * Pool_Name1 = "DFB_TEMP";
1523 static char * Pool_Name1_2 = "DFB_TEMP_2";
1524 static char * Pool_Name1_3 = "DFB_TEMP_3";
1525 
DFB_callback_id_1(MS_U32 pool_handle_id,MS_U64 start,MS_U64 length)1526 void *DFB_callback_id_1(MS_U32 pool_handle_id,MS_U64 start,MS_U64 length)
1527 {
1528     printk("inside %s ,pool_handle_id=%u\n",__FUNCTION__,pool_handle_id);
1529 }
1530 
test_case_2()1531 int test_case_2()
1532 {
1533     bool err;
1534     MS_U32 timeout_ms = 2;
1535     printk("debug in %s \n",__FUNCTION__);
1536 
1537 #if 1
1538     printk("[%s:%d] will MApi_IPA_Pool_Init\n",__FUNCTION__,__LINE__);
1539 
1540     struct IPA_Pool_Init_Param Init_Param;
1541     Init_Param.heap_id= DFB_TEMP_HID;
1542     Init_Param.pool_name = Pool_Name1;
1543     printk("%s:%d Pool_Name1=%p,Init_Param.pool_name=%s\n",__FUNCTION__,__LINE__,Pool_Name1,Init_Param.pool_name);
1544     Init_Param.offset_in_heap = 6.5*MILLION;
1545     Init_Param.len = 8*MILLION;
1546 
1547 #if DEBUG_IPA_KERNEL_MODE
1548     printk("[%s:%d]Init_Param->heap_id=%u,Init_Param->offset=0x%llx,Init_Param->len=0x%llx\n",__FUNCTION__,__LINE__,Init_Param.heap_id
1549                              ,Init_Param.offset_in_heap,Init_Param.len);
1550     printk("%s:%d Init_Param.pool_name=%s\n",__FUNCTION__,__LINE__,Init_Param.pool_name);
1551 #endif
1552 
1553     err = MApi_IPA_Pool_Init(&Init_Param);
1554     if(err ==FALSE)
1555     {
1556         printk("[%s:%d] ipa_init fail  Init_Param->heap_id=%u,Init_Param->offset=0x%llx,Init_Param->len=0x%llx\n",__FUNCTION__,__LINE__,Init_Param.heap_id
1557                           ,Init_Param.offset_in_heap,Init_Param.len);
1558         return -1;
1559     }
1560 
1561     printk("[%s:%d] will ipa_alloc\n",__FUNCTION__,__LINE__);
1562     struct IPA_Pool_GetMem_Param get_param;
1563     get_param.pool_handle_id=Init_Param.pool_handle_id;
1564     get_param.offset_in_pool=0;
1565     get_param.length= PAGE;
1566     err = MApi_IPA_Pool_GetMem_Timeout(&get_param,timeout_ms);
1567     printk("[%s:%d] after ipa_alloc   get_param.pool_handle_id=%u\n",__FUNCTION__,__LINE__,get_param.pool_handle_id);
1568     if(err ==FALSE)
1569     {
1570         printk("[%s:%d] err return\n",__FUNCTION__,__LINE__);
1571         return -1;
1572     }
1573 #endif
1574 
1575     struct IPA_Pool_Polling_Param polling_param;
1576     polling_param.pool_handle_id = Init_Param.pool_handle_id;
1577     printk("[%s:%d] \n",__FUNCTION__,__LINE__);
1578     polling_param.polling_callback=DFB_callback_id_1;
1579     printk("[%s:%d]   polling_param.pool_handle_id=%u\n",__FUNCTION__,__LINE__,polling_param.pool_handle_id);
1580     MApi_IPA_Pool_Notify(&polling_param);
1581     printk("[%s:%d] \n",__FUNCTION__,__LINE__);
1582 
1583      //must delay before free to ensure polling having sleep��
1584      printk("before sleep\n");
1585 
1586 #if 0
1587     while(1);
1588 #else
1589     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1590     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1591     /*schedule_timeout_interruptible(msecs_to_jiffies(1000));
1592     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1593     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1594     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1595     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1596     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1597     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1598     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1599     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1600     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1601     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1602     schedule_timeout_interruptible(msecs_to_jiffies(1000));
1603     schedule_timeout_interruptible(msecs_to_jiffies(1000));   */
1604 
1605     printk("after sleep\n");
1606     printk("[%s:%d] before MApi_IPA_Pool_PutMem\n",__FUNCTION__,__LINE__);
1607     struct IPA_Pool_PutMem_Param put_param;
1608     put_param.length=PAGE;
1609     put_param.offset_in_pool=0;
1610     put_param.pool_handle_id =Init_Param.pool_handle_id;
1611     err = MApi_IPA_Pool_PutMem(&put_param);
1612     if(err ==FALSE)
1613     {
1614         printk("[%s:%d] err return\n",__FUNCTION__,__LINE__);
1615         return -1;
1616     }
1617 
1618 #if 1
1619     printk(" %s  before MApi_IPA_Pool_Release \n",__FUNCTION__);
1620     err = MApi_IPA_Pool_Release(Init_Param.pool_handle_id);
1621     printk(" %s  after MApi_IPA_Pool_Release  err=%d\n",__FUNCTION__,err);
1622     if(err == FALSE)
1623     {
1624         printk("[%s:%d] err return\n",__FUNCTION__,__LINE__);
1625         return -1;
1626     }
1627 #endif
1628 
1629 #endif
1630 
1631     return 0;
1632 }
1633 
1634 #endif
1635 #if TEST_USE_SELF_KO_MAKEFILE
1636 
drvIPAPool_init(void)1637 static int drvIPAPool_init(void)
1638 {
1639     printk(KERN_ERR"%s !!! \n",__FUNCTION__);
1640 
1641     //test_case_2();
1642 
1643     return 0;
1644 }
1645 
drvIPAPool_exit(void)1646 static void drvIPAPool_exit(void)
1647 {
1648     printk(KERN_ERR"%s !!! \n",__FUNCTION__);
1649 }
1650 
1651 module_init(drvIPAPool_init);
1652 module_exit(drvIPAPool_exit);
1653 MODULE_LICENSE("GPL");
1654 MODULE_AUTHOR("Mstar");
1655 MODULE_DESCRIPTION("A module used for drvIPAPool!");
1656 #endif
1657 
1658 
1659 #endif
1660