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