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