1 /******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include "gki_int.h"
19 #include <stdio.h>
20
21 #if (GKI_NUM_TOTAL_BUF_POOLS > 16)
22 #error Number of pools out of range (16 Max)!
23 #endif
24
25 #if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
26 static void gki_add_to_pool_list(UINT8 pool_id);
27 static void gki_remove_from_pool_list(UINT8 pool_id);
28 #endif /* BTU_STACK_LITE_ENABLED == FALSE */
29
30 #if GKI_BUFFER_DEBUG
31 #define LOG_TAG "GKI_DEBUG"
32 #include <android/log.h>
33 #include <cutils/log.h>
34 #define LOGD(format, ...) LogMsg (TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC, format, ## __VA_ARGS__)
35 #endif
36 /*******************************************************************************
37 **
38 ** Function gki_init_free_queue
39 **
40 ** Description Internal function called at startup to initialize a free
41 ** queue. It is called once for each free queue.
42 **
43 ** Returns void
44 **
45 *******************************************************************************/
gki_init_free_queue(UINT8 id,UINT16 size,UINT16 total,void * p_mem)46 static void gki_init_free_queue (UINT8 id, UINT16 size, UINT16 total, void *p_mem)
47 {
48 UINT16 i;
49 UINT16 act_size;
50 BUFFER_HDR_T *hdr;
51 BUFFER_HDR_T *hdr1 = NULL;
52 UINT32 *magic;
53 INT32 tempsize = size;
54 tGKI_COM_CB *p_cb = &gki_cb.com;
55
56 /* Ensure an even number of longwords */
57 tempsize = (INT32)ALIGN_POOL(size);
58 act_size = (UINT16)(tempsize + BUFFER_PADDING_SIZE);
59
60 /* Remember pool start and end addresses */
61 if(p_mem)
62 {
63 p_cb->pool_start[id] = (UINT8 *)p_mem;
64 p_cb->pool_end[id] = (UINT8 *)p_mem + (act_size * total);
65 }
66
67 p_cb->pool_size[id] = act_size;
68
69 p_cb->freeq[id].size = (UINT16) tempsize;
70 p_cb->freeq[id].total = total;
71 p_cb->freeq[id].cur_cnt = 0;
72 p_cb->freeq[id].max_cnt = 0;
73
74 #if GKI_BUFFER_DEBUG
75 LOGD("gki_init_free_queue() init pool=%d, size=%d (aligned=%d) total=%d start=%p", id, size, tempsize, total, p_mem);
76 #endif
77
78 /* Initialize index table */
79 if(p_mem)
80 {
81 hdr = (BUFFER_HDR_T *)p_mem;
82 p_cb->freeq[id].p_first = hdr;
83 for (i = 0; i < total; i++)
84 {
85 hdr->task_id = GKI_INVALID_TASK;
86 hdr->q_id = id;
87 hdr->status = BUF_STATUS_FREE;
88 magic = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + tempsize);
89 *magic = MAGIC_NO;
90 hdr1 = hdr;
91 hdr = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
92 hdr1->p_next = hdr;
93 }
94 hdr1->p_next = NULL;
95 p_cb->freeq[id].p_last = hdr1;
96 }
97 return;
98 }
99
100 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
gki_alloc_free_queue(UINT8 id)101 static BOOLEAN gki_alloc_free_queue(UINT8 id)
102 {
103 FREE_QUEUE_T *Q;
104 tGKI_COM_CB *p_cb = &gki_cb.com;
105 #if GKI_BUFFER_DEBUG
106 ALOGD("\ngki_alloc_free_queue in, id:%d \n", id);
107 #endif
108
109 Q = &p_cb->freeq[p_cb->pool_list[id]];
110
111 if(Q->p_first == 0)
112 {
113 void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
114 if(p_mem)
115 {
116 //re-initialize the queue with allocated memory
117 #if GKI_BUFFER_DEBUG
118 ALOGD("\ngki_alloc_free_queue calling gki_init_free_queue, id:%d size:%d, totol:%d\n", id, Q->size, Q->total);
119 #endif
120 gki_init_free_queue(id, Q->size, Q->total, p_mem);
121 #if GKI_BUFFER_DEBUG
122 ALOGD("\ngki_alloc_free_queue ret OK, id:%d size:%d, totol:%d\n", id, Q->size, Q->total);
123 #endif
124 return TRUE;
125 }
126 GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "gki_alloc_free_queue: Not enough memory");
127 }
128 #if GKI_BUFFER_DEBUG
129 ALOGD("\ngki_alloc_free_queue out failed, id:%d\n", id);
130 #endif
131 return FALSE;
132 }
133 #endif
134
135 /*******************************************************************************
136 **
137 ** Function gki_buffer_init
138 **
139 ** Description Called once internally by GKI at startup to initialize all
140 ** buffers and free buffer pools.
141 **
142 ** Returns void
143 **
144 *******************************************************************************/
gki_buffer_init(void)145 void gki_buffer_init(void)
146 {
147 UINT8 i, tt, mb;
148 tGKI_COM_CB *p_cb = &gki_cb.com;
149
150 /* Initialize mailboxes */
151 for (tt = 0; tt < GKI_MAX_TASKS; tt++)
152 {
153 for (mb = 0; mb < NUM_TASK_MBOX; mb++)
154 {
155 p_cb->OSTaskQFirst[tt][mb] = NULL;
156 p_cb->OSTaskQLast [tt][mb] = NULL;
157 }
158 }
159
160 for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
161 {
162 p_cb->pool_start[tt] = NULL;
163 p_cb->pool_end[tt] = NULL;
164 p_cb->pool_size[tt] = 0;
165
166 p_cb->freeq[tt].p_first = 0;
167 p_cb->freeq[tt].p_last = 0;
168 p_cb->freeq[tt].size = 0;
169 p_cb->freeq[tt].total = 0;
170 p_cb->freeq[tt].cur_cnt = 0;
171 p_cb->freeq[tt].max_cnt = 0;
172 }
173
174 /* Use default from target.h */
175 p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
176
177 #if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == TRUE))
178
179 #if (GKI_NUM_FIXED_BUF_POOLS > 0)
180 p_cb->bufpool0 = (UINT8 *)GKI_os_malloc ((GKI_BUF0_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX);
181 #endif
182
183 #if (GKI_NUM_FIXED_BUF_POOLS > 1)
184 p_cb->bufpool1 = (UINT8 *)GKI_os_malloc ((GKI_BUF1_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX);
185 #endif
186
187 #if (GKI_NUM_FIXED_BUF_POOLS > 2)
188 p_cb->bufpool2 = (UINT8 *)GKI_os_malloc ((GKI_BUF2_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX);
189 #endif
190
191 #if (GKI_NUM_FIXED_BUF_POOLS > 3)
192 p_cb->bufpool3 = (UINT8 *)GKI_os_malloc ((GKI_BUF3_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX);
193 #endif
194
195 #if (GKI_NUM_FIXED_BUF_POOLS > 4)
196 p_cb->bufpool4 = (UINT8 *)GKI_os_malloc ((GKI_BUF4_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX);
197 #endif
198
199 #if (GKI_NUM_FIXED_BUF_POOLS > 5)
200 p_cb->bufpool5 = (UINT8 *)GKI_os_malloc ((GKI_BUF5_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX);
201 #endif
202
203 #if (GKI_NUM_FIXED_BUF_POOLS > 6)
204 p_cb->bufpool6 = (UINT8 *)GKI_os_malloc ((GKI_BUF6_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX);
205 #endif
206
207 #if (GKI_NUM_FIXED_BUF_POOLS > 7)
208 p_cb->bufpool7 = (UINT8 *)GKI_os_malloc ((GKI_BUF7_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX);
209 #endif
210
211 #if (GKI_NUM_FIXED_BUF_POOLS > 8)
212 p_cb->bufpool8 = (UINT8 *)GKI_os_malloc ((GKI_BUF8_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX);
213 #endif
214
215 #if (GKI_NUM_FIXED_BUF_POOLS > 9)
216 p_cb->bufpool9 = (UINT8 *)GKI_os_malloc ((GKI_BUF9_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX);
217 #endif
218
219 #if (GKI_NUM_FIXED_BUF_POOLS > 10)
220 p_cb->bufpool10 = (UINT8 *)GKI_os_malloc ((GKI_BUF10_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX);
221 #endif
222
223 #if (GKI_NUM_FIXED_BUF_POOLS > 11)
224 p_cb->bufpool11 = (UINT8 *)GKI_os_malloc ((GKI_BUF11_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX);
225 #endif
226
227 #if (GKI_NUM_FIXED_BUF_POOLS > 12)
228 p_cb->bufpool12 = (UINT8 *)GKI_os_malloc ((GKI_BUF12_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX);
229 #endif
230
231 #if (GKI_NUM_FIXED_BUF_POOLS > 13)
232 p_cb->bufpool13 = (UINT8 *)GKI_os_malloc ((GKI_BUF13_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX);
233 #endif
234
235 #if (GKI_NUM_FIXED_BUF_POOLS > 14)
236 p_cb->bufpool14 = (UINT8 *)GKI_os_malloc ((GKI_BUF14_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX);
237 #endif
238
239 #if (GKI_NUM_FIXED_BUF_POOLS > 15)
240 p_cb->bufpool15 = (UINT8 *)GKI_os_malloc ((GKI_BUF15_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX);
241 #endif
242
243 #endif
244
245
246 #if (GKI_NUM_FIXED_BUF_POOLS > 0)
247 gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
248 #endif
249
250 #if (GKI_NUM_FIXED_BUF_POOLS > 1)
251 gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
252 #endif
253
254 #if (GKI_NUM_FIXED_BUF_POOLS > 2)
255 gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
256 #endif
257
258 #if (GKI_NUM_FIXED_BUF_POOLS > 3)
259 gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
260 #endif
261
262 #if (GKI_NUM_FIXED_BUF_POOLS > 4)
263 gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
264 #endif
265
266 #if (GKI_NUM_FIXED_BUF_POOLS > 5)
267 gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
268 #endif
269
270 #if (GKI_NUM_FIXED_BUF_POOLS > 6)
271 gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
272 #endif
273
274 #if (GKI_NUM_FIXED_BUF_POOLS > 7)
275 gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
276 #endif
277
278 #if (GKI_NUM_FIXED_BUF_POOLS > 8)
279 gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
280 #endif
281
282 #if (GKI_NUM_FIXED_BUF_POOLS > 9)
283 gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
284 #endif
285
286 #if (GKI_NUM_FIXED_BUF_POOLS > 10)
287 gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
288 #endif
289
290 #if (GKI_NUM_FIXED_BUF_POOLS > 11)
291 gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
292 #endif
293
294 #if (GKI_NUM_FIXED_BUF_POOLS > 12)
295 gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
296 #endif
297
298 #if (GKI_NUM_FIXED_BUF_POOLS > 13)
299 gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
300 #endif
301
302 #if (GKI_NUM_FIXED_BUF_POOLS > 14)
303 gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
304 #endif
305
306 #if (GKI_NUM_FIXED_BUF_POOLS > 15)
307 gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
308 #endif
309
310 /* add pools to the pool_list which is arranged in the order of size */
311 for(i=0; i < GKI_NUM_FIXED_BUF_POOLS ; i++)
312 {
313 p_cb->pool_list[i] = i;
314 }
315
316 p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
317
318 return;
319 }
320
321
322 /*******************************************************************************
323 **
324 ** Function GKI_init_q
325 **
326 ** Description Called by an application to initialize a buffer queue.
327 **
328 ** Returns void
329 **
330 *******************************************************************************/
GKI_init_q(BUFFER_Q * p_q)331 void GKI_init_q (BUFFER_Q *p_q)
332 {
333 p_q->p_first = p_q->p_last = NULL;
334 p_q->count = 0;
335
336 return;
337 }
338
339
340 /*******************************************************************************
341 **
342 ** Function GKI_getbuf
343 **
344 ** Description Called by an application to get a free buffer which
345 ** is of size greater or equal to the requested size.
346 **
347 ** Note: This routine only takes buffers from public pools.
348 ** It will not use any buffers from pools
349 ** marked GKI_RESTRICTED_POOL.
350 **
351 ** Parameters size - (input) number of bytes needed.
352 **
353 ** Returns A pointer to the buffer, or NULL if none available
354 **
355 *******************************************************************************/
356 #if GKI_BUFFER_DEBUG
GKI_getbuf_debug(UINT16 size,const char * _function_,int _line_)357 void *GKI_getbuf_debug (UINT16 size, const char * _function_, int _line_)
358 #else
359 void *GKI_getbuf (UINT16 size)
360 #endif
361 {
362 UINT8 i;
363 FREE_QUEUE_T *Q;
364 BUFFER_HDR_T *p_hdr;
365 tGKI_COM_CB *p_cb = &gki_cb.com;
366 #if GKI_BUFFER_DEBUG
367 UINT8 x;
368 #endif
369
370 if (size == 0)
371 {
372 GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
373 return (NULL);
374 }
375
376 #if GKI_BUFFER_DEBUG
377 LOGD("GKI_getbuf() requesting %d func:%s(line=%d)", size, _function_, _line_);
378 #endif
379 /* Find the first buffer pool that is public that can hold the desired size */
380 for (i=0; i < p_cb->curr_total_no_of_pools; i++)
381 {
382 if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
383 break;
384 }
385
386 if(i == p_cb->curr_total_no_of_pools)
387 {
388 GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
389 return (NULL);
390 }
391
392 /* Make sure the buffers aren't disturbed til finished with allocation */
393 GKI_disable();
394
395 /* search the public buffer pools that are big enough to hold the size
396 * until a free buffer is found */
397 for ( ; i < p_cb->curr_total_no_of_pools; i++)
398 {
399 /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
400 if (((UINT16)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask)
401 continue;
402
403 Q = &p_cb->freeq[p_cb->pool_list[i]];
404 if(Q->cur_cnt < Q->total)
405 {
406 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
407 if(Q->p_first == 0 && gki_alloc_free_queue(i) != TRUE)
408 {
409 GKI_TRACE_ERROR_0("GKI_getbuf() out of buffer");
410 GKI_enable();
411 return NULL;
412 }
413 #endif
414
415 if(Q->p_first == 0)
416 {
417 /* gki_alloc_free_queue() failed to alloc memory */
418 GKI_TRACE_ERROR_0("GKI_getbuf() fail alloc free queue");
419 GKI_enable();
420 return NULL;
421 }
422
423 p_hdr = Q->p_first;
424 Q->p_first = p_hdr->p_next;
425
426 if (!Q->p_first)
427 Q->p_last = NULL;
428
429 if(++Q->cur_cnt > Q->max_cnt)
430 Q->max_cnt = Q->cur_cnt;
431
432 GKI_enable();
433
434 p_hdr->task_id = GKI_get_taskid();
435
436 p_hdr->status = BUF_STATUS_UNLINKED;
437 p_hdr->p_next = NULL;
438 p_hdr->Type = 0;
439 #if GKI_BUFFER_DEBUG
440 LOGD("GKI_getbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[i].total);
441
442 strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
443 p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
444 p_hdr->_line = _line_;
445 #endif
446 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
447 }
448 }
449
450 GKI_TRACE_ERROR_0("GKI_getbuf() unable to allocate buffer!!!!!");
451 #if GKI_BUFFER_DEBUG
452 LOGD("GKI_getbuf() unable to allocate buffer!!!!!");
453 LOGD("******************** GKI Memory Pool Dump ********************");
454
455 p_cb = &gki_cb.com;
456
457 LOGD("Dumping total of %d buffer pools", p_cb->curr_total_no_of_pools);
458
459 for (i=0 ; i < p_cb->curr_total_no_of_pools; i++)
460 {
461 p_hdr = (BUFFER_HDR_T *)p_cb->pool_start[i];
462
463 LOGD("pool %d has a total of %d buffers (start=%p)", i, p_cb->freeq[i].total, p_hdr);
464
465 for (x=0; p_hdr && x < p_cb->freeq[i].total; x++)
466 {
467 if (p_hdr->status != BUF_STATUS_FREE)
468 {
469 LOGD("pool:%d, buf[%d]:%x, hdr:%x status=%d func:%s(line=%d)", i, x, (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, p_hdr->status, p_hdr->_function, p_hdr->_line);
470 }
471
472 p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_hdr + p_cb->pool_size[i]);
473 }
474 }
475 LOGD("**************************************************************");
476 #endif
477
478 GKI_TRACE_ERROR_0("Failed to allocate GKI buffer");
479
480 GKI_enable();
481
482 return (NULL);
483 }
484
485
486 /*******************************************************************************
487 **
488 ** Function GKI_getpoolbuf
489 **
490 ** Description Called by an application to get a free buffer from
491 ** a specific buffer pool.
492 **
493 ** Note: If there are no more buffers available from the pool,
494 ** the public buffers are searched for an available buffer.
495 **
496 ** Parameters pool_id - (input) pool ID to get a buffer out of.
497 **
498 ** Returns A pointer to the buffer, or NULL if none available
499 **
500 *******************************************************************************/
501 #if GKI_BUFFER_DEBUG
GKI_getpoolbuf_debug(UINT8 pool_id,const char * _function_,int _line_)502 void *GKI_getpoolbuf_debug (UINT8 pool_id, const char * _function_, int _line_)
503 #else
504 void *GKI_getpoolbuf (UINT8 pool_id)
505 #endif
506 {
507 FREE_QUEUE_T *Q;
508 BUFFER_HDR_T *p_hdr;
509 tGKI_COM_CB *p_cb = &gki_cb.com;
510
511 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
512 return (NULL);
513
514 #if GKI_BUFFER_DEBUG
515 LOGD("GKI_getpoolbuf() requesting from %d func:%s(line=%d)", pool_id, _function_, _line_);
516 #endif
517 /* Make sure the buffers aren't disturbed til finished with allocation */
518 GKI_disable();
519
520 Q = &p_cb->freeq[pool_id];
521 if(Q->cur_cnt < Q->total)
522 {
523 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
524 if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
525 return NULL;
526 #endif
527
528 if(Q->p_first == 0)
529 {
530 /* gki_alloc_free_queue() failed to alloc memory */
531 GKI_TRACE_ERROR_0("GKI_getpoolbuf() fail alloc free queue");
532 return NULL;
533 }
534
535 p_hdr = Q->p_first;
536 Q->p_first = p_hdr->p_next;
537
538 if (!Q->p_first)
539 Q->p_last = NULL;
540
541 if(++Q->cur_cnt > Q->max_cnt)
542 Q->max_cnt = Q->cur_cnt;
543
544 GKI_enable();
545
546
547 p_hdr->task_id = GKI_get_taskid();
548
549 p_hdr->status = BUF_STATUS_UNLINKED;
550 p_hdr->p_next = NULL;
551 p_hdr->Type = 0;
552
553 #if GKI_BUFFER_DEBUG
554 LOGD("GKI_getpoolbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[pool_id].total);
555
556 strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
557 p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
558 p_hdr->_line = _line_;
559 #endif
560 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
561 }
562
563 /* If here, no buffers in the specified pool */
564 GKI_enable();
565
566 #if GKI_BUFFER_DEBUG
567 /* try for free buffers in public pools */
568 return (GKI_getbuf_debug(p_cb->freeq[pool_id].size, _function_, _line_));
569 #else
570 /* try for free buffers in public pools */
571 return (GKI_getbuf(p_cb->freeq[pool_id].size));
572 #endif
573 }
574
575 /*******************************************************************************
576 **
577 ** Function GKI_freebuf
578 **
579 ** Description Called by an application to return a buffer to the free pool.
580 **
581 ** Parameters p_buf - (input) address of the beginning of a buffer.
582 **
583 ** Returns void
584 **
585 *******************************************************************************/
GKI_freebuf(void * p_buf)586 void GKI_freebuf (void *p_buf)
587 {
588 FREE_QUEUE_T *Q;
589 BUFFER_HDR_T *p_hdr;
590
591 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
592 if (!p_buf || gki_chk_buf_damage(p_buf))
593 {
594 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
595 return;
596 }
597 #endif
598
599 p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
600
601 #if GKI_BUFFER_DEBUG
602 LOGD("GKI_freebuf() freeing, %x, %x, func:%s(line=%d)", p_buf, p_hdr, p_hdr->_function, p_hdr->_line);
603 #endif
604
605 if (p_hdr->status != BUF_STATUS_UNLINKED)
606 {
607 GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
608 return;
609 }
610
611 if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
612 {
613 GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
614 return;
615 }
616
617 GKI_disable();
618
619 /*
620 ** Release the buffer
621 */
622 Q = &gki_cb.com.freeq[p_hdr->q_id];
623 if (Q->p_last)
624 Q->p_last->p_next = p_hdr;
625 else
626 Q->p_first = p_hdr;
627
628 Q->p_last = p_hdr;
629 p_hdr->p_next = NULL;
630 p_hdr->status = BUF_STATUS_FREE;
631 p_hdr->task_id = GKI_INVALID_TASK;
632 if (Q->cur_cnt > 0)
633 Q->cur_cnt--;
634
635 GKI_enable();
636
637 return;
638 }
639
640
641 /*******************************************************************************
642 **
643 ** Function GKI_get_buf_size
644 **
645 ** Description Called by an application to get the size of a buffer.
646 **
647 ** Parameters p_buf - (input) address of the beginning of a buffer.
648 **
649 ** Returns the size of the buffer
650 **
651 *******************************************************************************/
GKI_get_buf_size(void * p_buf)652 UINT16 GKI_get_buf_size (void *p_buf)
653 {
654 BUFFER_HDR_T *p_hdr;
655
656 p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE);
657
658 if ((UINT32)p_hdr & 1)
659 return (0);
660
661 if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS)
662 {
663 return (gki_cb.com.freeq[p_hdr->q_id].size);
664 }
665
666 return (0);
667 }
668
669 /*******************************************************************************
670 **
671 ** Function gki_chk_buf_damage
672 **
673 ** Description Called internally by OSS to check for buffer corruption.
674 **
675 ** Returns TRUE if there is a problem, else FALSE
676 **
677 *******************************************************************************/
gki_chk_buf_damage(void * p_buf)678 BOOLEAN gki_chk_buf_damage(void *p_buf)
679 {
680 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
681
682 UINT32 *magic;
683 magic = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf));
684
685 if ((UINT32)magic & 1)
686 return (TRUE);
687
688 if (*magic == MAGIC_NO)
689 return (FALSE);
690
691 return (TRUE);
692
693 #else
694
695 return (FALSE);
696
697 #endif
698 }
699
700 /*******************************************************************************
701 **
702 ** Function GKI_send_msg
703 **
704 ** Description Called by applications to send a buffer to a task
705 **
706 ** Returns Nothing
707 **
708 *******************************************************************************/
GKI_send_msg(UINT8 task_id,UINT8 mbox,void * msg)709 void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
710 {
711 BUFFER_HDR_T *p_hdr;
712 tGKI_COM_CB *p_cb = &gki_cb.com;
713
714 /* If task non-existant or not started, drop buffer */
715 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
716 {
717 GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
718 GKI_freebuf (msg);
719 return;
720 }
721
722 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
723 if (gki_chk_buf_damage(msg))
724 {
725 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
726 return;
727 }
728 #endif
729
730 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
731
732 if (p_hdr->status != BUF_STATUS_UNLINKED)
733 {
734 GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
735 return;
736 }
737
738 GKI_disable();
739
740 if (p_cb->OSTaskQFirst[task_id][mbox])
741 p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
742 else
743 p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
744
745 p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
746
747 p_hdr->p_next = NULL;
748 p_hdr->status = BUF_STATUS_QUEUED;
749 p_hdr->task_id = task_id;
750
751
752 GKI_enable();
753
754 GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
755
756 return;
757 }
758
759 /*******************************************************************************
760 **
761 ** Function GKI_read_mbox
762 **
763 ** Description Called by applications to read a buffer from one of
764 ** the task mailboxes. A task can only read its own mailbox.
765 **
766 ** Parameters: mbox - (input) mailbox ID to read (0, 1, 2, or 3)
767 **
768 ** Returns NULL if the mailbox was empty, else the address of a buffer
769 **
770 *******************************************************************************/
GKI_read_mbox(UINT8 mbox)771 void *GKI_read_mbox (UINT8 mbox)
772 {
773 UINT8 task_id = GKI_get_taskid();
774 void *p_buf = NULL;
775 BUFFER_HDR_T *p_hdr;
776
777 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
778 return (NULL);
779
780 GKI_disable();
781
782 if (gki_cb.com.OSTaskQFirst[task_id][mbox])
783 {
784 p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
785 gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
786
787 p_hdr->p_next = NULL;
788 p_hdr->status = BUF_STATUS_UNLINKED;
789
790 p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
791 }
792
793 GKI_enable();
794
795 return (p_buf);
796 }
797
798
799
800 /*******************************************************************************
801 **
802 ** Function GKI_enqueue
803 **
804 ** Description Enqueue a buffer at the tail of the queue
805 **
806 ** Parameters: p_q - (input) pointer to a queue.
807 ** p_buf - (input) address of the buffer to enqueue
808 **
809 ** Returns void
810 **
811 *******************************************************************************/
GKI_enqueue(BUFFER_Q * p_q,void * p_buf)812 void GKI_enqueue (BUFFER_Q *p_q, void *p_buf)
813 {
814 BUFFER_HDR_T *p_hdr;
815
816 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
817 if (gki_chk_buf_damage(p_buf))
818 {
819 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
820 return;
821 }
822 #endif
823
824 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
825
826 if (p_hdr->status != BUF_STATUS_UNLINKED)
827 {
828 GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
829 return;
830 }
831
832 GKI_disable();
833
834 /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
835 if (p_q->p_first)
836 {
837 BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE);
838 p_last_hdr->p_next = p_hdr;
839 }
840 else
841 p_q->p_first = p_buf;
842
843 p_q->p_last = p_buf;
844 p_q->count++;
845
846 p_hdr->p_next = NULL;
847 p_hdr->status = BUF_STATUS_QUEUED;
848
849 GKI_enable();
850
851 return;
852 }
853
854
855 /*******************************************************************************
856 **
857 ** Function GKI_enqueue_head
858 **
859 ** Description Enqueue a buffer at the head of the queue
860 **
861 ** Parameters: p_q - (input) pointer to a queue.
862 ** p_buf - (input) address of the buffer to enqueue
863 **
864 ** Returns void
865 **
866 *******************************************************************************/
GKI_enqueue_head(BUFFER_Q * p_q,void * p_buf)867 void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf)
868 {
869 BUFFER_HDR_T *p_hdr;
870
871 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
872 if (gki_chk_buf_damage(p_buf))
873 {
874 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
875 return;
876 }
877 #endif
878
879 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
880
881 if (p_hdr->status != BUF_STATUS_UNLINKED)
882 {
883 GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked");
884 return;
885 }
886
887 GKI_disable();
888
889 if (p_q->p_first)
890 {
891 p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
892 p_q->p_first = p_buf;
893 }
894 else
895 {
896 p_q->p_first = p_buf;
897 p_q->p_last = p_buf;
898 p_hdr->p_next = NULL;
899 }
900 p_q->count++;
901
902 p_hdr->status = BUF_STATUS_QUEUED;
903
904 GKI_enable();
905
906 return;
907 }
908
909
910 /*******************************************************************************
911 **
912 ** Function GKI_dequeue
913 **
914 ** Description Dequeues a buffer from the head of a queue
915 **
916 ** Parameters: p_q - (input) pointer to a queue.
917 **
918 ** Returns NULL if queue is empty, else buffer
919 **
920 *******************************************************************************/
GKI_dequeue(BUFFER_Q * p_q)921 void *GKI_dequeue (BUFFER_Q *p_q)
922 {
923 BUFFER_HDR_T *p_hdr;
924
925 GKI_disable();
926
927 if (!p_q || !p_q->count)
928 {
929 GKI_enable();
930 return (NULL);
931 }
932
933 p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
934
935 /* Keep buffers such that GKI header is invisible
936 */
937 if (p_hdr->p_next)
938 p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
939 else
940 {
941 p_q->p_first = NULL;
942 p_q->p_last = NULL;
943 }
944
945 p_q->count--;
946
947 p_hdr->p_next = NULL;
948 p_hdr->status = BUF_STATUS_UNLINKED;
949
950 GKI_enable();
951
952 return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
953 }
954
955
956 /*******************************************************************************
957 **
958 ** Function GKI_remove_from_queue
959 **
960 ** Description Dequeue a buffer from the middle of the queue
961 **
962 ** Parameters: p_q - (input) pointer to a queue.
963 ** p_buf - (input) address of the buffer to enqueue
964 **
965 ** Returns NULL if queue is empty, else buffer
966 **
967 *******************************************************************************/
GKI_remove_from_queue(BUFFER_Q * p_q,void * p_buf)968 void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
969 {
970 BUFFER_HDR_T *p_prev;
971 BUFFER_HDR_T *p_buf_hdr;
972
973 GKI_disable();
974
975 if (p_buf == p_q->p_first)
976 {
977 GKI_enable();
978 return (GKI_dequeue (p_q));
979 }
980
981 p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE);
982 p_prev = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
983
984 for ( ; p_prev; p_prev = p_prev->p_next)
985 {
986 /* If the previous points to this one, move the pointers around */
987 if (p_prev->p_next == p_buf_hdr)
988 {
989 p_prev->p_next = p_buf_hdr->p_next;
990
991 /* If we are removing the last guy in the queue, update p_last */
992 if (p_buf == p_q->p_last)
993 p_q->p_last = p_prev + 1;
994
995 /* One less in the queue */
996 p_q->count--;
997
998 /* The buffer is now unlinked */
999 p_buf_hdr->p_next = NULL;
1000 p_buf_hdr->status = BUF_STATUS_UNLINKED;
1001
1002 GKI_enable();
1003 return (p_buf);
1004 }
1005 }
1006
1007 GKI_enable();
1008 return (NULL);
1009 }
1010
1011 /*******************************************************************************
1012 **
1013 ** Function GKI_getfirst
1014 **
1015 ** Description Return a pointer to the first buffer in a queue
1016 **
1017 ** Parameters: p_q - (input) pointer to a queue.
1018 **
1019 ** Returns NULL if queue is empty, else buffer address
1020 **
1021 *******************************************************************************/
GKI_getfirst(BUFFER_Q * p_q)1022 void *GKI_getfirst (BUFFER_Q *p_q)
1023 {
1024 return (p_q->p_first);
1025 }
1026
1027 /*******************************************************************************
1028 **
1029 ** Function GKI_getlast
1030 **
1031 ** Description Return a pointer to the last buffer in a queue
1032 **
1033 ** Parameters: p_q - (input) pointer to a queue.
1034 **
1035 ** Returns NULL if queue is empty, else buffer address
1036 **
1037 *******************************************************************************/
GKI_getlast(BUFFER_Q * p_q)1038 void *GKI_getlast (BUFFER_Q *p_q)
1039 {
1040 return (p_q->p_last);
1041 }
1042
1043 /*******************************************************************************
1044 **
1045 ** Function GKI_getnext
1046 **
1047 ** Description Return a pointer to the next buffer in a queue
1048 **
1049 ** Parameters: p_buf - (input) pointer to the buffer to find the next one from.
1050 **
1051 ** Returns NULL if no more buffers in the queue, else next buffer address
1052 **
1053 *******************************************************************************/
GKI_getnext(void * p_buf)1054 void *GKI_getnext (void *p_buf)
1055 {
1056 BUFFER_HDR_T *p_hdr;
1057
1058 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
1059
1060 if (p_hdr->p_next)
1061 return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
1062 else
1063 return (NULL);
1064 }
1065
1066
1067
1068 /*******************************************************************************
1069 **
1070 ** Function GKI_queue_is_empty
1071 **
1072 ** Description Check the status of a queue.
1073 **
1074 ** Parameters: p_q - (input) pointer to a queue.
1075 **
1076 ** Returns TRUE if queue is empty, else FALSE
1077 **
1078 *******************************************************************************/
GKI_queue_is_empty(BUFFER_Q * p_q)1079 BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q)
1080 {
1081 return ((BOOLEAN) (p_q->count == 0));
1082 }
1083
1084 /*******************************************************************************
1085 **
1086 ** Function GKI_find_buf_start
1087 **
1088 ** Description This function is called with an address inside a buffer,
1089 ** and returns the start address ofthe buffer.
1090 **
1091 ** The buffer should be one allocated from one of GKI's pools.
1092 **
1093 ** Parameters: p_user_area - (input) address of anywhere in a GKI buffer.
1094 **
1095 ** Returns void * - Address of the beginning of the specified buffer if successful,
1096 ** otherwise NULL if unsuccessful
1097 **
1098 *******************************************************************************/
GKI_find_buf_start(void * p_user_area)1099 void *GKI_find_buf_start (void *p_user_area)
1100 {
1101 UINT16 xx, size;
1102 UINT32 yy;
1103 tGKI_COM_CB *p_cb = &gki_cb.com;
1104 UINT8 *p_ua = (UINT8 *)p_user_area;
1105
1106 for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
1107 {
1108 if ((p_ua > p_cb->pool_start[xx]) && (p_ua < p_cb->pool_end[xx]))
1109 {
1110 yy = (UINT32)(p_ua - p_cb->pool_start[xx]);
1111
1112 size = p_cb->pool_size[xx];
1113
1114 yy = (yy / size) * size;
1115
1116 return ((void *) (p_cb->pool_start[xx] + yy + sizeof(BUFFER_HDR_T)) );
1117 }
1118 }
1119
1120 /* If here, invalid address - not in one of our buffers */
1121 GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "GKI_get_buf_start:: bad addr");
1122
1123 return (NULL);
1124 }
1125
1126
1127 /********************************************************
1128 * The following functions are not needed for light stack
1129 *********************************************************/
1130 #if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
1131
1132 /*******************************************************************************
1133 **
1134 ** Function GKI_set_pool_permission
1135 **
1136 ** Description This function is called to set or change the permissions for
1137 ** the specified pool ID.
1138 **
1139 ** Parameters pool_id - (input) pool ID to be set or changed
1140 ** permission - (input) GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL
1141 **
1142 ** Returns GKI_SUCCESS if successful
1143 ** GKI_INVALID_POOL if unsuccessful
1144 **
1145 *******************************************************************************/
GKI_set_pool_permission(UINT8 pool_id,UINT8 permission)1146 UINT8 GKI_set_pool_permission(UINT8 pool_id, UINT8 permission)
1147 {
1148 tGKI_COM_CB *p_cb = &gki_cb.com;
1149
1150 if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
1151 {
1152 if (permission == GKI_RESTRICTED_POOL)
1153 p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask | (1 << pool_id));
1154
1155 else /* mark the pool as public */
1156 p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask & ~(1 << pool_id));
1157
1158 return (GKI_SUCCESS);
1159 }
1160 else
1161 return (GKI_INVALID_POOL);
1162 }
1163
1164 /*******************************************************************************
1165 **
1166 ** Function gki_add_to_pool_list
1167 **
1168 ** Description Adds pool to the pool list which is arranged in the
1169 ** order of size
1170 **
1171 ** Returns void
1172 **
1173 *******************************************************************************/
gki_add_to_pool_list(UINT8 pool_id)1174 static void gki_add_to_pool_list(UINT8 pool_id)
1175 {
1176
1177 INT32 i, j;
1178 tGKI_COM_CB *p_cb = &gki_cb.com;
1179
1180 /* Find the position where the specified pool should be inserted into the list */
1181 for(i=0; i < p_cb->curr_total_no_of_pools; i++)
1182 {
1183
1184 if(p_cb->freeq[pool_id].size <= p_cb->freeq[ p_cb->pool_list[i] ].size)
1185 break;
1186 }
1187
1188 /* Insert the new buffer pool ID into the list of pools */
1189 for(j = p_cb->curr_total_no_of_pools; j > i; j--)
1190 {
1191 p_cb->pool_list[j] = p_cb->pool_list[j-1];
1192 }
1193
1194 p_cb->pool_list[i] = pool_id;
1195
1196 return;
1197 }
1198
1199 /*******************************************************************************
1200 **
1201 ** Function gki_remove_from_pool_list
1202 **
1203 ** Description Removes pool from the pool list. Called when a pool is deleted
1204 **
1205 ** Returns void
1206 **
1207 *******************************************************************************/
gki_remove_from_pool_list(UINT8 pool_id)1208 static void gki_remove_from_pool_list(UINT8 pool_id)
1209 {
1210 tGKI_COM_CB *p_cb = &gki_cb.com;
1211 UINT8 i;
1212
1213 for(i=0; i < p_cb->curr_total_no_of_pools; i++)
1214 {
1215 if(pool_id == p_cb->pool_list[i])
1216 break;
1217 }
1218
1219 while (i < (p_cb->curr_total_no_of_pools - 1))
1220 {
1221 p_cb->pool_list[i] = p_cb->pool_list[i+1];
1222 i++;
1223 }
1224
1225 return;
1226 }
1227
1228 /*******************************************************************************
1229 **
1230 ** Function GKI_igetpoolbuf
1231 **
1232 ** Description Called by an interrupt service routine to get a free buffer from
1233 ** a specific buffer pool.
1234 **
1235 ** Parameters pool_id - (input) pool ID to get a buffer out of.
1236 **
1237 ** Returns A pointer to the buffer, or NULL if none available
1238 **
1239 *******************************************************************************/
GKI_igetpoolbuf(UINT8 pool_id)1240 void *GKI_igetpoolbuf (UINT8 pool_id)
1241 {
1242 FREE_QUEUE_T *Q;
1243 BUFFER_HDR_T *p_hdr;
1244
1245 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1246 return (NULL);
1247
1248
1249 Q = &gki_cb.com.freeq[pool_id];
1250 if(Q->cur_cnt < Q->total)
1251 {
1252 p_hdr = Q->p_first;
1253 Q->p_first = p_hdr->p_next;
1254
1255 if (!Q->p_first)
1256 Q->p_last = NULL;
1257
1258 if(++Q->cur_cnt > Q->max_cnt)
1259 Q->max_cnt = Q->cur_cnt;
1260
1261 p_hdr->task_id = GKI_get_taskid();
1262
1263 p_hdr->status = BUF_STATUS_UNLINKED;
1264 p_hdr->p_next = NULL;
1265 p_hdr->Type = 0;
1266
1267 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
1268 }
1269
1270 return (NULL);
1271 }
1272
1273 /*******************************************************************************
1274 **
1275 ** Function GKI_poolcount
1276 **
1277 ** Description Called by an application to get the total number of buffers
1278 ** in the specified buffer pool.
1279 **
1280 ** Parameters pool_id - (input) pool ID to get the free count of.
1281 **
1282 ** Returns the total number of buffers in the pool
1283 **
1284 *******************************************************************************/
GKI_poolcount(UINT8 pool_id)1285 UINT16 GKI_poolcount (UINT8 pool_id)
1286 {
1287 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1288 return (0);
1289
1290 return (gki_cb.com.freeq[pool_id].total);
1291 }
1292
1293 /*******************************************************************************
1294 **
1295 ** Function GKI_poolfreecount
1296 **
1297 ** Description Called by an application to get the number of free buffers
1298 ** in the specified buffer pool.
1299 **
1300 ** Parameters pool_id - (input) pool ID to get the free count of.
1301 **
1302 ** Returns the number of free buffers in the pool
1303 **
1304 *******************************************************************************/
GKI_poolfreecount(UINT8 pool_id)1305 UINT16 GKI_poolfreecount (UINT8 pool_id)
1306 {
1307 FREE_QUEUE_T *Q;
1308
1309 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1310 return (0);
1311
1312 Q = &gki_cb.com.freeq[pool_id];
1313
1314 return ((UINT16)(Q->total - Q->cur_cnt));
1315 }
1316
1317 /*******************************************************************************
1318 **
1319 ** Function GKI_change_buf_owner
1320 **
1321 ** Description Called to change the task ownership of a buffer.
1322 **
1323 ** Parameters: p_buf - (input) pointer to the buffer
1324 ** task_id - (input) task id to change ownership to
1325 **
1326 ** Returns void
1327 **
1328 *******************************************************************************/
GKI_change_buf_owner(void * p_buf,UINT8 task_id)1329 void GKI_change_buf_owner (void *p_buf, UINT8 task_id)
1330 {
1331 BUFFER_HDR_T *p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
1332
1333 p_hdr->task_id = task_id;
1334
1335 return;
1336 }
1337
1338 #if (defined(GKI_SEND_MSG_FROM_ISR) && GKI_SEND_MSG_FROM_ISR == TRUE)
1339 /*******************************************************************************
1340 **
1341 ** Function GKI_isend_msg
1342 **
1343 ** Description Called from interrupt context to send a buffer to a task
1344 **
1345 ** Returns Nothing
1346 **
1347 *******************************************************************************/
GKI_isend_msg(UINT8 task_id,UINT8 mbox,void * msg)1348 void GKI_isend_msg (UINT8 task_id, UINT8 mbox, void *msg)
1349 {
1350 BUFFER_HDR_T *p_hdr;
1351 tGKI_COM_CB *p_cb = &gki_cb.com;
1352
1353 /* If task non-existant or not started, drop buffer */
1354 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
1355 {
1356 GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
1357 GKI_freebuf (msg);
1358 return;
1359 }
1360
1361 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
1362 if (gki_chk_buf_damage(msg))
1363 {
1364 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
1365 return;
1366 }
1367 #endif
1368
1369 #if (GKI_ENABLE_OWNER_CHECK == TRUE)
1370 if (gki_chk_buf_owner(msg))
1371 {
1372 GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner");
1373 return;
1374 }
1375 #endif
1376
1377 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
1378
1379 if (p_hdr->status != BUF_STATUS_UNLINKED)
1380 {
1381 GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
1382 return;
1383 }
1384
1385 if (p_cb->OSTaskQFirst[task_id][mbox])
1386 p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
1387 else
1388 p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
1389
1390 p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
1391
1392 p_hdr->p_next = NULL;
1393 p_hdr->status = BUF_STATUS_QUEUED;
1394 p_hdr->task_id = task_id;
1395
1396 GKI_isend_event(task_id, (UINT16)EVENT_MASK(mbox));
1397
1398 return;
1399 }
1400 #endif
1401
1402 /*******************************************************************************
1403 **
1404 ** Function GKI_create_pool
1405 **
1406 ** Description Called by applications to create a buffer pool.
1407 **
1408 ** Parameters: size - (input) length (in bytes) of each buffer in the pool
1409 ** count - (input) number of buffers to allocate for the pool
1410 ** permission - (input) restricted or public access?
1411 ** (GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL)
1412 ** p_mem_pool - (input) pointer to an OS memory pool, NULL if not provided
1413 **
1414 ** Returns the buffer pool ID, which should be used in calls to
1415 ** GKI_getpoolbuf(). If a pool could not be created, this
1416 ** function returns 0xff.
1417 **
1418 *******************************************************************************/
GKI_create_pool(UINT16 size,UINT16 count,UINT8 permission,void * p_mem_pool)1419 UINT8 GKI_create_pool (UINT16 size, UINT16 count, UINT8 permission, void *p_mem_pool)
1420 {
1421 UINT8 xx;
1422 UINT32 mem_needed;
1423 INT32 tempsize = size;
1424 tGKI_COM_CB *p_cb = &gki_cb.com;
1425
1426 /* First make sure the size of each pool has a valid size with room for the header info */
1427 if (size > MAX_USER_BUF_SIZE)
1428 return (GKI_INVALID_POOL);
1429
1430 /* First, look for an unused pool */
1431 for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
1432 {
1433 if (!p_cb->pool_start[xx])
1434 break;
1435 }
1436
1437 if (xx == GKI_NUM_TOTAL_BUF_POOLS)
1438 return (GKI_INVALID_POOL);
1439
1440 /* Ensure an even number of longwords */
1441 tempsize = (INT32)ALIGN_POOL(size);
1442
1443 mem_needed = (tempsize + BUFFER_PADDING_SIZE) * count;
1444
1445 if (!p_mem_pool)
1446 p_mem_pool = GKI_os_malloc(mem_needed);
1447
1448 if (p_mem_pool)
1449 {
1450 /* Initialize the new pool */
1451 gki_init_free_queue (xx, size, count, p_mem_pool);
1452 gki_add_to_pool_list(xx);
1453 (void) GKI_set_pool_permission (xx, permission);
1454 p_cb->curr_total_no_of_pools++;
1455
1456 return (xx);
1457 }
1458 else
1459 return (GKI_INVALID_POOL);
1460 }
1461
1462 /*******************************************************************************
1463 **
1464 ** Function GKI_delete_pool
1465 **
1466 ** Description Called by applications to delete a buffer pool. The function
1467 ** calls the operating specific function to free the actual memory.
1468 ** An exception is generated if an error is detected.
1469 **
1470 ** Parameters: pool_id - (input) Id of the poll being deleted.
1471 **
1472 ** Returns void
1473 **
1474 *******************************************************************************/
GKI_delete_pool(UINT8 pool_id)1475 void GKI_delete_pool (UINT8 pool_id)
1476 {
1477 FREE_QUEUE_T *Q;
1478 tGKI_COM_CB *p_cb = &gki_cb.com;
1479
1480 if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (!p_cb->pool_start[pool_id]))
1481 return;
1482
1483 GKI_disable();
1484 Q = &p_cb->freeq[pool_id];
1485
1486 if (!Q->cur_cnt)
1487 {
1488 Q->size = 0;
1489 Q->total = 0;
1490 Q->cur_cnt = 0;
1491 Q->max_cnt = 0;
1492 Q->p_first = NULL;
1493 Q->p_last = NULL;
1494
1495 GKI_os_free (p_cb->pool_start[pool_id]);
1496
1497 p_cb->pool_start[pool_id] = NULL;
1498 p_cb->pool_end[pool_id] = NULL;
1499 p_cb->pool_size[pool_id] = 0;
1500
1501 gki_remove_from_pool_list(pool_id);
1502 p_cb->curr_total_no_of_pools--;
1503 }
1504 else
1505 GKI_exception(GKI_ERROR_DELETE_POOL_BAD_QID, "Deleting bad pool");
1506
1507 GKI_enable();
1508
1509 return;
1510 }
1511
1512 #endif /* BTU_STACK_LITE_ENABLED == FALSE */
1513
1514 /*******************************************************************************
1515 **
1516 ** Function GKI_get_pool_bufsize
1517 **
1518 ** Description Called by an application to get the size of buffers in a pool
1519 **
1520 ** Parameters Pool ID.
1521 **
1522 ** Returns the size of buffers in the pool
1523 **
1524 *******************************************************************************/
GKI_get_pool_bufsize(UINT8 pool_id)1525 UINT16 GKI_get_pool_bufsize (UINT8 pool_id)
1526 {
1527 if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
1528 return (gki_cb.com.freeq[pool_id].size);
1529
1530 return (0);
1531 }
1532
1533 /*******************************************************************************
1534 **
1535 ** Function GKI_poolutilization
1536 **
1537 ** Description Called by an application to get the buffer utilization
1538 ** in the specified buffer pool.
1539 **
1540 ** Parameters pool_id - (input) pool ID to get the free count of.
1541 **
1542 ** Returns % of buffers used from 0 to 100
1543 **
1544 *******************************************************************************/
GKI_poolutilization(UINT8 pool_id)1545 UINT16 GKI_poolutilization (UINT8 pool_id)
1546 {
1547 FREE_QUEUE_T *Q;
1548
1549 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1550 return (100);
1551
1552 Q = &gki_cb.com.freeq[pool_id];
1553
1554 if (Q->total == 0)
1555 return (100);
1556
1557 return ((Q->cur_cnt * 100) / Q->total);
1558 }
1559
1560