blob: 82e715785bf40790bfc752a3e8512da1ff564901 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*===========================================================================
43 @file vos_memory.c
44
45 @brief Virtual Operating System Services Memory API
46
47
48 Copyright (c) 2008 QUALCOMM Incorporated.
49 All Rights Reserved.
50 Qualcomm Confidential and Proprietary
51===========================================================================*/
52
53/*===========================================================================
54
55 EDIT HISTORY FOR FILE
56
57
58 This section contains comments describing changes made to the module.
59 Notice that changes are listed in reverse chronological order.
60
61
62 $Header:$ $DateTime: $ $Author: $
63
64
65 when who what, where, why
66 -------- --- --------------------------------------------------------
67
68===========================================================================*/
69
70/*---------------------------------------------------------------------------
71 * Include Files
72 * ------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070073#include "vos_memory.h"
74#include "vos_trace.h"
75
Mohit Khanna49a87a82012-09-11 18:03:14 -070076#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
77#include <linux/wcnss_wlan.h>
78#define WCNSS_PRE_ALLOC_GET_THRESHOLD (4*1024)
79#endif
80
Jeff Johnson295189b2012-06-20 16:38:30 -070081#ifdef MEMORY_DEBUG
82#include "wlan_hdd_dp_utils.h"
83
84hdd_list_t vosMemList;
85
86static v_U8_t WLAN_MEM_HEADER[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68 };
87static v_U8_t WLAN_MEM_TAIL[] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87};
88
89struct s_vos_mem_struct
90{
91 hdd_list_node_t pNode;
92 char* fileName;
93 unsigned int lineNum;
94 unsigned int size;
95 v_U8_t header[8];
96};
97#endif
98
99/*---------------------------------------------------------------------------
100 * Preprocessor Definitions and Constants
101 * ------------------------------------------------------------------------*/
102
103/*---------------------------------------------------------------------------
104 * Type Declarations
105 * ------------------------------------------------------------------------*/
106
107/*---------------------------------------------------------------------------
108 * Data definitions
109 * ------------------------------------------------------------------------*/
110
111/*---------------------------------------------------------------------------
112 * External Function implementation
113 * ------------------------------------------------------------------------*/
114#ifdef MEMORY_DEBUG
115void vos_mem_init()
116{
117 /* Initalizing the list with maximum size of 60000 */
118 hdd_list_init(&vosMemList, 60000);
119 return;
120}
121
122void vos_mem_clean()
123{
124 v_SIZE_t listSize;
125 hdd_list_size(&vosMemList, &listSize);
126
127 if(listSize)
128 {
129 hdd_list_node_t* pNode;
130 VOS_STATUS vosStatus;
131
132 struct s_vos_mem_struct* memStruct;
133
134 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700135 "%s: List is not Empty. listSize %d ", __func__, (int)listSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700136
137 do
138 {
139 spin_lock(&vosMemList.lock);
140 vosStatus = hdd_list_remove_front(&vosMemList, &pNode);
141 spin_unlock(&vosMemList.lock);
142 if(VOS_STATUS_SUCCESS == vosStatus)
143 {
144 memStruct = (struct s_vos_mem_struct*)pNode;
145 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
146 "Memory Leak@ File %s, @Line %d, size %d",
147 memStruct->fileName, (int)memStruct->lineNum, memStruct->size);
148 kfree((v_VOID_t*)memStruct);
149 }
150 }while(vosStatus == VOS_STATUS_SUCCESS);
lukez092ea1a2013-03-15 14:53:55 -0700151
152#ifdef CONFIG_HALT_KMEMLEAK
153 BUG_ON(0);
154#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700155 }
156}
157
158void vos_mem_exit()
159{
160 vos_mem_clean();
161 hdd_list_destroy(&vosMemList);
162}
163
164v_VOID_t * vos_mem_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum)
165{
166 struct s_vos_mem_struct* memStruct;
167 v_VOID_t* memPtr = NULL;
168 v_SIZE_t new_size;
169
170 if (size > (1024*1024))
171 {
172 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700173 "%s: called with arg > 1024K; passed in %d !!!", __func__,size);
Jeff Johnson295189b2012-06-20 16:38:30 -0700174 return NULL;
175 }
Madan Mohan Koyyalamudi5c0fe232013-09-16 22:21:26 +0530176
Jeff Johnson295189b2012-06-20 16:38:30 -0700177 if (in_interrupt())
178 {
Madan Mohan Koyyalamudi5c0fe232013-09-16 22:21:26 +0530179 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be "
180 "called from interrupt context!!!", __func__);
181 return NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700182 }
183
184 new_size = size + sizeof(struct s_vos_mem_struct) + 8;
185
186 memStruct = (struct s_vos_mem_struct*)kmalloc(new_size,GFP_KERNEL);
187
188 if(memStruct != NULL)
189 {
190 VOS_STATUS vosStatus;
191
192 memStruct->fileName = fileName;
193 memStruct->lineNum = lineNum;
194 memStruct->size = size;
195
196 vos_mem_copy(&memStruct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER));
197 vos_mem_copy( (v_U8_t*)(memStruct + 1) + size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL));
198
199 spin_lock(&vosMemList.lock);
200 vosStatus = hdd_list_insert_front(&vosMemList, &memStruct->pNode);
201 spin_unlock(&vosMemList.lock);
202 if(VOS_STATUS_SUCCESS != vosStatus)
203 {
204 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700205 "%s: Unable to insert node into List vosStatus %d\n", __func__, vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 }
207
208 memPtr = (v_VOID_t*)(memStruct + 1);
209 }
210 return memPtr;
211}
212
213v_VOID_t vos_mem_free( v_VOID_t *ptr )
214{
Madan Mohan Koyyalamudi5c0fe232013-09-16 22:21:26 +0530215
216 if (in_interrupt())
217 {
218 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be "
219 "called from interrupt context!!!", __func__);
220 return;
221 }
222
Jeff Johnson295189b2012-06-20 16:38:30 -0700223 if (ptr != NULL)
224 {
225 VOS_STATUS vosStatus;
226 struct s_vos_mem_struct* memStruct = ((struct s_vos_mem_struct*)ptr) - 1;
227
228 spin_lock(&vosMemList.lock);
229 vosStatus = hdd_list_remove_node(&vosMemList, &memStruct->pNode);
230 spin_unlock(&vosMemList.lock);
231
232 if(VOS_STATUS_SUCCESS == vosStatus)
233 {
234 if(0 == vos_mem_compare(memStruct->header, &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)) )
235 {
236 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
237 "Memory Header is corrupted. MemInfo: Filename %s, LineNum %d",
238 memStruct->fileName, (int)memStruct->lineNum);
239 }
240 if(0 == vos_mem_compare( (v_U8_t*)ptr + memStruct->size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL ) ) )
241 {
242 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
243 "Memory Trailer is corrupted. MemInfo: Filename %s, LineNum %d",
244 memStruct->fileName, (int)memStruct->lineNum);
245 }
246 kfree((v_VOID_t*)memStruct);
247 }
248 else
249 {
250 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700251 "%s: Unallocated memory (double free?)", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700252 VOS_ASSERT(0);
253 }
254 }
255}
256#else
257v_VOID_t * vos_mem_malloc( v_SIZE_t size )
258{
Mohit Khanna49a87a82012-09-11 18:03:14 -0700259#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
260 v_VOID_t* pmem;
261#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 if (size > (1024*1024))
263 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700264 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: called with arg > 1024K; passed in %d !!!", __func__,size);
Jeff Johnson295189b2012-06-20 16:38:30 -0700265 return NULL;
266 }
267 if (in_interrupt())
268 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700269 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 return NULL;
271 }
Mohit Khanna49a87a82012-09-11 18:03:14 -0700272#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
273 if(size > WCNSS_PRE_ALLOC_GET_THRESHOLD)
274 {
275 pmem = wcnss_prealloc_get(size);
276 if(NULL != pmem)
277 return pmem;
278 }
279#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 return kmalloc(size, GFP_KERNEL);
281}
282
283v_VOID_t vos_mem_free( v_VOID_t *ptr )
284{
285 if (ptr == NULL)
286 return;
Mohit Khanna49a87a82012-09-11 18:03:14 -0700287
288 if (in_interrupt())
289 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700290 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__);
Mohit Khanna49a87a82012-09-11 18:03:14 -0700291 return;
292 }
293#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
294 if(wcnss_prealloc_put(ptr))
295 return;
296#endif
297
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 kfree(ptr);
299}
300#endif
301
302v_VOID_t vos_mem_set( v_VOID_t *ptr, v_SIZE_t numBytes, v_BYTE_t value )
303{
304 if (ptr == NULL)
305 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700306 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s called with NULL parameter ptr", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 return;
308 }
309 memset(ptr, value, numBytes);
310}
311
312v_VOID_t vos_mem_zero( v_VOID_t *ptr, v_SIZE_t numBytes )
313{
314 if (0 == numBytes)
315 {
316 // special case where ptr can be NULL
317 return;
318 }
319
320 if (ptr == NULL)
321 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700322 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s called with NULL parameter ptr", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 return;
324 }
325 memset(ptr, 0, numBytes);
326
327}
328
329
330//This function is to validate one list in SME. We suspect someone corrupt te list. This code need to be removed
331//once the issue is fixed.
332extern int csrCheckValidateLists(void * dest, const void *src, v_SIZE_t num, int idx);
333
334v_VOID_t vos_mem_copy( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes )
335{
336 if (0 == numBytes)
337 {
338 // special case where pDst or pSrc can be NULL
339 return;
340 }
341
342 if ((pDst == NULL) || (pSrc==NULL))
343 {
344 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
345 "%s called with NULL parameter, source:%p destination:%p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700346 __func__, pSrc, pDst);
Jeff Johnson295189b2012-06-20 16:38:30 -0700347 VOS_ASSERT(0);
348 return;
349 }
350 //These two check function calls are to see if someone corrupt the list while doing mem copy.
351 csrCheckValidateLists(pDst, pSrc, numBytes, 1);
352 memcpy(pDst, pSrc, numBytes);
353 csrCheckValidateLists(pDst, pSrc, numBytes, 2);
354}
355
356v_VOID_t vos_mem_move( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes )
357{
358 if (0 == numBytes)
359 {
360 // special case where pDst or pSrc can be NULL
361 return;
362 }
363
364 if ((pDst == NULL) || (pSrc==NULL))
365 {
366 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
367 "%s called with NULL parameter, source:%p destination:%p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700368 __func__, pSrc, pDst);
Jeff Johnson295189b2012-06-20 16:38:30 -0700369 VOS_ASSERT(0);
370 return;
371 }
372 memmove(pDst, pSrc, numBytes);
373}
374
375v_BOOL_t vos_mem_compare( v_VOID_t *pMemory1, v_VOID_t *pMemory2, v_U32_t numBytes )
376{
377 if (0 == numBytes)
378 {
379 // special case where pMemory1 or pMemory2 can be NULL
380 return VOS_TRUE;
381 }
382
383 if ((pMemory1 == NULL) || (pMemory2==NULL))
384 {
385 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
386 "%s called with NULL parameter, p1:%p p2:%p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700387 __func__, pMemory1, pMemory2);
Jeff Johnson295189b2012-06-20 16:38:30 -0700388 VOS_ASSERT(0);
389 return VOS_FALSE;
390 }
391 return (memcmp(pMemory1, pMemory2, numBytes)?VOS_FALSE:VOS_TRUE);
392}
393
394
395v_SINT_t vos_mem_compare2( v_VOID_t *pMemory1, v_VOID_t *pMemory2, v_U32_t numBytes )
396
397{
398 return( (v_SINT_t) memcmp( pMemory1, pMemory2, numBytes ) );
399}
400
401/*----------------------------------------------------------------------------
402
403 \brief vos_mem_dma_malloc() - vOSS DMA Memory Allocation
404
405 This function will dynamicallly allocate the specified number of bytes of
406 memory. This memory will have special attributes making it DMA friendly i.e.
407 it will exist in contiguous, 32-byte aligned uncached memory. A normal
408 vos_mem_malloc does not yield memory with these attributes.
409
410 NOTE: the special DMA friendly memory is very scarce and this API must be
411 used sparingly
412
413 On WM, there is nothing special about this memory. SDHC allocates the
414 DMA friendly buffer and copies the data into it
415
416 \param size - the number of bytes of memory to allocate.
417
418 \return Upon successful allocate, returns a non-NULL pointer to the
419 allocated memory. If this function is unable to allocate the amount of
420 memory specified (for any reason) it returns NULL.
421
422 \sa
423
424 --------------------------------------------------------------------------*/
425#ifdef MEMORY_DEBUG
426v_VOID_t * vos_mem_dma_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum)
427{
428 struct s_vos_mem_struct* memStruct;
429 v_VOID_t* memPtr = NULL;
430 v_SIZE_t new_size;
431
432 if (in_interrupt())
433 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700434 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700435 return NULL;
436 }
437
438 new_size = size + sizeof(struct s_vos_mem_struct) + 8;
439
440 memStruct = (struct s_vos_mem_struct*)kmalloc(new_size,GFP_KERNEL);
441
442 if(memStruct != NULL)
443 {
444 VOS_STATUS vosStatus;
445
446 memStruct->fileName = fileName;
447 memStruct->lineNum = lineNum;
448 memStruct->size = size;
449
450 vos_mem_copy(&memStruct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER));
451 vos_mem_copy( (v_U8_t*)(memStruct + 1) + size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL));
452
453 spin_lock(&vosMemList.lock);
454 vosStatus = hdd_list_insert_front(&vosMemList, &memStruct->pNode);
455 spin_unlock(&vosMemList.lock);
456 if(VOS_STATUS_SUCCESS != vosStatus)
457 {
458 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700459 "%s: Unable to insert node into List vosStatus %d\n", __func__, vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700460 }
461
462 memPtr = (v_VOID_t*)(memStruct + 1);
463 }
464
465 return memPtr;
466}
467
468v_VOID_t vos_mem_dma_free( v_VOID_t *ptr )
469{
470 if (ptr != NULL)
471 {
472 VOS_STATUS vosStatus;
473 struct s_vos_mem_struct* memStruct = ((struct s_vos_mem_struct*)ptr) - 1;
474
475 spin_lock(&vosMemList.lock);
476 vosStatus = hdd_list_remove_node(&vosMemList, &memStruct->pNode);
477 spin_unlock(&vosMemList.lock);
478
479 if(VOS_STATUS_SUCCESS == vosStatus)
480 {
481 if(0 == vos_mem_compare(memStruct->header, &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)) )
482 {
483 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
484 "Memory Header is corrupted. MemInfo: Filename %s, LineNum %d",
485 memStruct->fileName, (int)memStruct->lineNum);
486 }
487 if(0 == vos_mem_compare( (v_U8_t*)ptr + memStruct->size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL ) ) )
488 {
489 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
490 "Memory Trailer is corrupted. MemInfo: Filename %s, LineNum %d",
491 memStruct->fileName, (int)memStruct->lineNum);
492 }
493 kfree((v_VOID_t*)memStruct);
494 }
495 }
496}
497#else
498v_VOID_t* vos_mem_dma_malloc( v_SIZE_t size )
499{
500 if (in_interrupt())
501 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700502 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700503 return NULL;
504 }
505 return kmalloc(size, GFP_KERNEL);
506}
507
508/*----------------------------------------------------------------------------
509
510 \brief vos_mem_dma_free() - vOSS DMA Free Memory
511
512 This function will free special DMA friendly memory pointed to by 'ptr'.
513
514 On WM, there is nothing special about the memory being free'd. SDHC will
515 take care of free'ing the DMA friendly buffer
516
517 \param ptr - pointer to the starting address of the memory to be
518 free'd.
519
520 \return Nothing
521
522 \sa
523
524 --------------------------------------------------------------------------*/
525v_VOID_t vos_mem_dma_free( v_VOID_t *ptr )
526{
527 if (ptr == NULL)
528 return;
529 kfree(ptr);
530}
531#endif