blob: 16b6ce3ea36e92100be5b3978037def792630398 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18#include "gki_int.h"
19#include <cutils/log.h>
20
21#if (GKI_NUM_TOTAL_BUF_POOLS > 16)
22#error Number of pools out of range (16 Max)!
23#endif
24
The Android Open Source Project5738f832012-12-12 16:00:35 -080025/*******************************************************************************
26**
27** Function gki_init_free_queue
28**
29** Description Internal function called at startup to initialize a free
30** queue. It is called once for each free queue.
31**
32** Returns void
33**
34*******************************************************************************/
35static void gki_init_free_queue (UINT8 id, UINT16 size, UINT16 total, void *p_mem)
36{
37 UINT16 i;
38 UINT16 act_size;
39 BUFFER_HDR_T *hdr;
40 BUFFER_HDR_T *hdr1 = NULL;
41 UINT32 *magic;
42 INT32 tempsize = size;
43 tGKI_COM_CB *p_cb = &gki_cb.com;
44
45 /* Ensure an even number of longwords */
46 tempsize = (INT32)ALIGN_POOL(size);
47 act_size = (UINT16)(tempsize + BUFFER_PADDING_SIZE);
48
49 /* Remember pool start and end addresses */
50// btla-specific ++
51 if(p_mem)
52 {
53 p_cb->pool_start[id] = (UINT8 *)p_mem;
54 p_cb->pool_end[id] = (UINT8 *)p_mem + (act_size * total);
55 }
56// btla-specific --
57
58 p_cb->pool_size[id] = act_size;
59
60 p_cb->freeq[id].size = (UINT16) tempsize;
61 p_cb->freeq[id].total = total;
62 p_cb->freeq[id].cur_cnt = 0;
63 p_cb->freeq[id].max_cnt = 0;
64
65 /* Initialize index table */
66// btla-specific ++
67 if(p_mem)
68 {
69 hdr = (BUFFER_HDR_T *)p_mem;
70 p_cb->freeq[id].p_first = hdr;
71 for (i = 0; i < total; i++)
72 {
73 hdr->task_id = GKI_INVALID_TASK;
74 hdr->q_id = id;
75 hdr->status = BUF_STATUS_FREE;
76 magic = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + tempsize);
77 *magic = MAGIC_NO;
78 hdr1 = hdr;
79 hdr = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
80 hdr1->p_next = hdr;
81 }
82 hdr1->p_next = NULL;
83 p_cb->freeq[id].p_last = hdr1;
84 }
85// btla-specific --
86 return;
87}
88
89// btla-specific ++
90#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
91static BOOLEAN gki_alloc_free_queue(UINT8 id)
92{
93 FREE_QUEUE_T *Q;
94 tGKI_COM_CB *p_cb = &gki_cb.com;
95 GKI_TRACE("\ngki_alloc_free_queue in, id:%d \n", (int)id );
96
97 Q = &p_cb->freeq[p_cb->pool_list[id]];
98
99 if(Q->p_first == 0)
100 {
101 void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
102 if(p_mem)
103 {
104 //re-initialize the queue with allocated memory
105 GKI_TRACE("\ngki_alloc_free_queue calling gki_init_free_queue, id:%d size:%d, totol:%d\n", id, Q->size, Q->total);
106 gki_init_free_queue(id, Q->size, Q->total, p_mem);
107 GKI_TRACE("\ngki_alloc_free_queue ret OK, id:%d size:%d, totol:%d\n", id, Q->size, Q->total);
108 return TRUE;
109 }
110 GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "gki_alloc_free_queue: Not enough memory");
111 }
112 GKI_TRACE("\ngki_alloc_free_queue out failed, id:%d\n", id);
113 return FALSE;
114}
115
116void gki_dealloc_free_queue(void)
117{
118 UINT8 i;
119 tGKI_COM_CB *p_cb = &gki_cb.com;
120
121 for (i=0; i < p_cb->curr_total_no_of_pools; i++)
122 {
123 if ( 0 < p_cb->freeq[i].max_cnt )
124 {
125 GKI_os_free(p_cb->pool_start[i]);
126
127 p_cb->freeq[i].cur_cnt = 0;
128 p_cb->freeq[i].max_cnt = 0;
129 p_cb->freeq[i].p_first = NULL;
130 p_cb->freeq[i].p_last = NULL;
131
132 p_cb->pool_start[i] = NULL;
133 p_cb->pool_end[i] = NULL;
134 p_cb->pool_size[i] = 0;
135 }
136 }
137}
138
139#endif
140// btla-specific --
141
142/*******************************************************************************
143**
144** Function gki_buffer_init
145**
146** Description Called once internally by GKI at startup to initialize all
147** buffers and free buffer pools.
148**
149** Returns void
150**
151*******************************************************************************/
152void gki_buffer_init(void)
153{
154 UINT8 i, tt, mb;
155 tGKI_COM_CB *p_cb = &gki_cb.com;
156
157 /* Initialize mailboxes */
158 for (tt = 0; tt < GKI_MAX_TASKS; tt++)
159 {
160 for (mb = 0; mb < NUM_TASK_MBOX; mb++)
161 {
162 p_cb->OSTaskQFirst[tt][mb] = NULL;
163 p_cb->OSTaskQLast [tt][mb] = NULL;
164 }
165 }
166
167 for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
168 {
169 p_cb->pool_start[tt] = NULL;
170 p_cb->pool_end[tt] = NULL;
171 p_cb->pool_size[tt] = 0;
172
173 p_cb->freeq[tt].p_first = 0;
174 p_cb->freeq[tt].p_last = 0;
175 p_cb->freeq[tt].size = 0;
176 p_cb->freeq[tt].total = 0;
177 p_cb->freeq[tt].cur_cnt = 0;
178 p_cb->freeq[tt].max_cnt = 0;
179 }
180
181 /* Use default from target.h */
182 p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
183
184// btla-specific ++
185#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == TRUE))
186// btla-specific --
187
188#if (GKI_NUM_FIXED_BUF_POOLS > 0)
189 p_cb->bufpool0 = (UINT8 *)GKI_os_malloc ((GKI_BUF0_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX);
190#endif
191
192#if (GKI_NUM_FIXED_BUF_POOLS > 1)
193 p_cb->bufpool1 = (UINT8 *)GKI_os_malloc ((GKI_BUF1_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX);
194#endif
195
196#if (GKI_NUM_FIXED_BUF_POOLS > 2)
197 p_cb->bufpool2 = (UINT8 *)GKI_os_malloc ((GKI_BUF2_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX);
198#endif
199
200#if (GKI_NUM_FIXED_BUF_POOLS > 3)
201 p_cb->bufpool3 = (UINT8 *)GKI_os_malloc ((GKI_BUF3_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX);
202#endif
203
204#if (GKI_NUM_FIXED_BUF_POOLS > 4)
205 p_cb->bufpool4 = (UINT8 *)GKI_os_malloc ((GKI_BUF4_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX);
206#endif
207
208#if (GKI_NUM_FIXED_BUF_POOLS > 5)
209 p_cb->bufpool5 = (UINT8 *)GKI_os_malloc ((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 *)GKI_os_malloc ((GKI_BUF6_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX);
214#endif
215
216#if (GKI_NUM_FIXED_BUF_POOLS > 7)
217 p_cb->bufpool7 = (UINT8 *)GKI_os_malloc ((GKI_BUF7_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX);
218#endif
219
220#if (GKI_NUM_FIXED_BUF_POOLS > 8)
221 p_cb->bufpool8 = (UINT8 *)GKI_os_malloc ((GKI_BUF8_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX);
222#endif
223
224#if (GKI_NUM_FIXED_BUF_POOLS > 9)
225 p_cb->bufpool9 = (UINT8 *)GKI_os_malloc ((GKI_BUF9_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX);
226#endif
227
228#if (GKI_NUM_FIXED_BUF_POOLS > 10)
229 p_cb->bufpool10 = (UINT8 *)GKI_os_malloc ((GKI_BUF10_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX);
230#endif
231
232#if (GKI_NUM_FIXED_BUF_POOLS > 11)
233 p_cb->bufpool11 = (UINT8 *)GKI_os_malloc ((GKI_BUF11_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX);
234#endif
235
236#if (GKI_NUM_FIXED_BUF_POOLS > 12)
237 p_cb->bufpool12 = (UINT8 *)GKI_os_malloc ((GKI_BUF12_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX);
238#endif
239
240#if (GKI_NUM_FIXED_BUF_POOLS > 13)
241 p_cb->bufpool13 = (UINT8 *)GKI_os_malloc ((GKI_BUF13_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX);
242#endif
243
244#if (GKI_NUM_FIXED_BUF_POOLS > 14)
245 p_cb->bufpool14 = (UINT8 *)GKI_os_malloc ((GKI_BUF14_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX);
246#endif
247
248#if (GKI_NUM_FIXED_BUF_POOLS > 15)
249 p_cb->bufpool15 = (UINT8 *)GKI_os_malloc ((GKI_BUF15_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX);
250#endif
251
252#endif
253
254
255#if (GKI_NUM_FIXED_BUF_POOLS > 0)
256 gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
257#endif
258
259#if (GKI_NUM_FIXED_BUF_POOLS > 1)
260 gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
261#endif
262
263#if (GKI_NUM_FIXED_BUF_POOLS > 2)
264 gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
265#endif
266
267#if (GKI_NUM_FIXED_BUF_POOLS > 3)
268 gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
269#endif
270
271#if (GKI_NUM_FIXED_BUF_POOLS > 4)
272 gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
273#endif
274
275#if (GKI_NUM_FIXED_BUF_POOLS > 5)
276 gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
277#endif
278
279#if (GKI_NUM_FIXED_BUF_POOLS > 6)
280 gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
281#endif
282
283#if (GKI_NUM_FIXED_BUF_POOLS > 7)
284 gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
285#endif
286
287#if (GKI_NUM_FIXED_BUF_POOLS > 8)
288 gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
289#endif
290
291#if (GKI_NUM_FIXED_BUF_POOLS > 9)
292 gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
293#endif
294
295#if (GKI_NUM_FIXED_BUF_POOLS > 10)
296 gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
297#endif
298
299#if (GKI_NUM_FIXED_BUF_POOLS > 11)
300 gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
301#endif
302
303#if (GKI_NUM_FIXED_BUF_POOLS > 12)
304 gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
305#endif
306
307#if (GKI_NUM_FIXED_BUF_POOLS > 13)
308 gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
309#endif
310
311#if (GKI_NUM_FIXED_BUF_POOLS > 14)
312 gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
313#endif
314
315#if (GKI_NUM_FIXED_BUF_POOLS > 15)
316 gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
317#endif
318
319 /* add pools to the pool_list which is arranged in the order of size */
320 for(i=0; i < GKI_NUM_FIXED_BUF_POOLS ; i++)
321 {
322 p_cb->pool_list[i] = i;
323 }
324
325 p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
326
327 return;
328}
329
330
331/*******************************************************************************
332**
333** Function GKI_init_q
334**
335** Description Called by an application to initialize a buffer queue.
336**
337** Returns void
338**
339*******************************************************************************/
340void GKI_init_q (BUFFER_Q *p_q)
341{
342 p_q->p_first = p_q->p_last = NULL;
343 p_q->count = 0;
344
345 return;
346}
347
348
349/*******************************************************************************
350**
351** Function GKI_getbuf
352**
353** Description Called by an application to get a free buffer which
354** is of size greater or equal to the requested size.
355**
356** Note: This routine only takes buffers from public pools.
357** It will not use any buffers from pools
358** marked GKI_RESTRICTED_POOL.
359**
360** Parameters size - (input) number of bytes needed.
361**
362** Returns A pointer to the buffer, or NULL if none available
363**
364*******************************************************************************/
365void *GKI_getbuf (UINT16 size)
366{
367 UINT8 i;
368 FREE_QUEUE_T *Q;
369 BUFFER_HDR_T *p_hdr;
370 tGKI_COM_CB *p_cb = &gki_cb.com;
371
372 if (size == 0)
373 {
374 GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
375 return (NULL);
376 }
377
378 /* Find the first buffer pool that is public that can hold the desired size */
379 for (i=0; i < p_cb->curr_total_no_of_pools; i++)
380 {
381 if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
382 break;
383 }
384
385 if(i == p_cb->curr_total_no_of_pools)
386 {
387 GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
388 return (NULL);
389 }
390
391 /* Make sure the buffers aren't disturbed til finished with allocation */
392 GKI_disable();
393
394 /* search the public buffer pools that are big enough to hold the size
395 * until a free buffer is found */
396 for ( ; i < p_cb->curr_total_no_of_pools; i++)
397 {
398 /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
399 if (((UINT16)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask)
400 continue;
Hemant Gupta554485a2013-07-12 20:05:54 +0530401 if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
402 Q = &p_cb->freeq[p_cb->pool_list[i]];
403 else
404 continue;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800405
The Android Open Source Project5738f832012-12-12 16:00:35 -0800406 if(Q->cur_cnt < Q->total)
407 {
408// btla-specific ++
409 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
410 if(Q->p_first == 0 && gki_alloc_free_queue(i) != TRUE)
411 return NULL;
412 #endif
413// btla-specific --
414 p_hdr = Q->p_first;
415 Q->p_first = p_hdr->p_next;
416
417 if (!Q->p_first)
418 Q->p_last = NULL;
419
420 if(++Q->cur_cnt > Q->max_cnt)
421 Q->max_cnt = Q->cur_cnt;
422
423 GKI_enable();
424
425 p_hdr->task_id = GKI_get_taskid();
426
427 p_hdr->status = BUF_STATUS_UNLINKED;
428 p_hdr->p_next = NULL;
429 p_hdr->Type = 0;
430
431 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
432 }
433 }
434
435 GKI_enable();
436
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800437 GKI_exception (GKI_ERROR_OUT_OF_BUFFERS, "getbuf: out of buffers");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800438 return (NULL);
439}
440
441
442/*******************************************************************************
443**
444** Function GKI_getpoolbuf
445**
446** Description Called by an application to get a free buffer from
447** a specific buffer pool.
448**
449** Note: If there are no more buffers available from the pool,
450** the public buffers are searched for an available buffer.
451**
452** Parameters pool_id - (input) pool ID to get a buffer out of.
453**
454** Returns A pointer to the buffer, or NULL if none available
455**
456*******************************************************************************/
457void *GKI_getpoolbuf (UINT8 pool_id)
458{
459 FREE_QUEUE_T *Q;
460 BUFFER_HDR_T *p_hdr;
461 tGKI_COM_CB *p_cb = &gki_cb.com;
462
463 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800464 {
465 GKI_exception(GKI_ERROR_GETPOOLBUF_BAD_QID, "getpoolbuf bad pool");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800466 return (NULL);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800467 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800468
469 /* Make sure the buffers aren't disturbed til finished with allocation */
470 GKI_disable();
471
472 Q = &p_cb->freeq[pool_id];
473 if(Q->cur_cnt < Q->total)
474 {
475// btla-specific ++
476#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
477 if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
478 return NULL;
479#endif
480// btla-specific --
481 p_hdr = Q->p_first;
482 Q->p_first = p_hdr->p_next;
483
484 if (!Q->p_first)
485 Q->p_last = NULL;
486
487 if(++Q->cur_cnt > Q->max_cnt)
488 Q->max_cnt = Q->cur_cnt;
489
490 GKI_enable();
491
492
493 p_hdr->task_id = GKI_get_taskid();
494
495 p_hdr->status = BUF_STATUS_UNLINKED;
496 p_hdr->p_next = NULL;
497 p_hdr->Type = 0;
498
499 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
500 }
501
502 /* If here, no buffers in the specified pool */
503 GKI_enable();
504
505 /* try for free buffers in public pools */
506 return (GKI_getbuf(p_cb->freeq[pool_id].size));
507
508}
509
510/*******************************************************************************
511**
512** Function GKI_freebuf
513**
514** Description Called by an application to return a buffer to the free pool.
515**
516** Parameters p_buf - (input) address of the beginning of a buffer.
517**
518** Returns void
519**
520*******************************************************************************/
521void GKI_freebuf (void *p_buf)
522{
523 FREE_QUEUE_T *Q;
524 BUFFER_HDR_T *p_hdr;
525
526#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
527 if (!p_buf || gki_chk_buf_damage(p_buf))
528 {
529 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
530 return;
531 }
532#endif
533
534 p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
535
536 if (p_hdr->status != BUF_STATUS_UNLINKED)
537 {
538 GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
539 return;
540 }
541
542 if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
543 {
544 GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
545 return;
546 }
547
548 GKI_disable();
549
550 /*
551 ** Release the buffer
552 */
553 Q = &gki_cb.com.freeq[p_hdr->q_id];
554 if (Q->p_last)
555 Q->p_last->p_next = p_hdr;
556 else
557 Q->p_first = p_hdr;
558
559 Q->p_last = p_hdr;
560 p_hdr->p_next = NULL;
561 p_hdr->status = BUF_STATUS_FREE;
562 p_hdr->task_id = GKI_INVALID_TASK;
563 if (Q->cur_cnt > 0)
564 Q->cur_cnt--;
565
566 GKI_enable();
567
568 return;
569}
570
571
572/*******************************************************************************
573**
574** Function GKI_get_buf_size
575**
576** Description Called by an application to get the size of a buffer.
577**
578** Parameters p_buf - (input) address of the beginning of a buffer.
579**
580** Returns the size of the buffer
581**
582*******************************************************************************/
583UINT16 GKI_get_buf_size (void *p_buf)
584{
585 BUFFER_HDR_T *p_hdr;
586
587 p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE);
588
589 if ((UINT32)p_hdr & 1)
590 return (0);
591
592 if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS)
593 {
594 return (gki_cb.com.freeq[p_hdr->q_id].size);
595 }
596
597 return (0);
598}
599
600/*******************************************************************************
601**
602** Function gki_chk_buf_damage
603**
604** Description Called internally by OSS to check for buffer corruption.
605**
606** Returns TRUE if there is a problem, else FALSE
607**
608*******************************************************************************/
609BOOLEAN gki_chk_buf_damage(void *p_buf)
610{
611#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
612
613 UINT32 *magic;
614 magic = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf));
615
616 if ((UINT32)magic & 1)
617 return (TRUE);
618
619 if (*magic == MAGIC_NO)
620 return (FALSE);
621
622 return (TRUE);
623
624#else
625
626 return (FALSE);
627
628#endif
629}
630
631/*******************************************************************************
632**
633** Function GKI_send_msg
634**
635** Description Called by applications to send a buffer to a task
636**
637** Returns Nothing
638**
639*******************************************************************************/
640void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
641{
642 BUFFER_HDR_T *p_hdr;
643 tGKI_COM_CB *p_cb = &gki_cb.com;
644
645 /* If task non-existant or not started, drop buffer */
646 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
647 {
648 GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
649 GKI_freebuf (msg);
650 return;
651 }
652
653#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
654 if (gki_chk_buf_damage(msg))
655 {
656 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
657 return;
658 }
659#endif
660
661 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
662
663 if (p_hdr->status != BUF_STATUS_UNLINKED)
664 {
665 GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
666 return;
667 }
668
669 GKI_disable();
670
671 if (p_cb->OSTaskQFirst[task_id][mbox])
672 p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
673 else
674 p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
675
676 p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
677
678 p_hdr->p_next = NULL;
679 p_hdr->status = BUF_STATUS_QUEUED;
680 p_hdr->task_id = task_id;
681
682
683 GKI_enable();
684
685 GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
686
687 return;
688}
689
690/*******************************************************************************
691**
692** Function GKI_read_mbox
693**
694** Description Called by applications to read a buffer from one of
695** the task mailboxes. A task can only read its own mailbox.
696**
697** Parameters: mbox - (input) mailbox ID to read (0, 1, 2, or 3)
698**
699** Returns NULL if the mailbox was empty, else the address of a buffer
700**
701*******************************************************************************/
702void *GKI_read_mbox (UINT8 mbox)
703{
704 UINT8 task_id = GKI_get_taskid();
705 void *p_buf = NULL;
706 BUFFER_HDR_T *p_hdr;
707
708 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
709 return (NULL);
710
711 GKI_disable();
712
713 if (gki_cb.com.OSTaskQFirst[task_id][mbox])
714 {
715 p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
716 gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
717
718 p_hdr->p_next = NULL;
719 p_hdr->status = BUF_STATUS_UNLINKED;
720
721 p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
722 }
723
724 GKI_enable();
725
726 return (p_buf);
727}
728
729
730
731/*******************************************************************************
732**
733** Function GKI_enqueue
734**
735** Description Enqueue a buffer at the tail of the queue
736**
737** Parameters: p_q - (input) pointer to a queue.
738** p_buf - (input) address of the buffer to enqueue
739**
740** Returns void
741**
742*******************************************************************************/
743void GKI_enqueue (BUFFER_Q *p_q, void *p_buf)
744{
745 BUFFER_HDR_T *p_hdr;
746
747#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
748 if (gki_chk_buf_damage(p_buf))
749 {
750 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
751 return;
752 }
753#endif
754
755 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
756
757 if (p_hdr->status != BUF_STATUS_UNLINKED)
758 {
759 GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
760 return;
761 }
762
763 GKI_disable();
764
765 /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
766 if (p_q->p_last)
767 {
768 BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE);
769 p_last_hdr->p_next = p_hdr;
770 }
771 else
772 p_q->p_first = p_buf;
773
774 p_q->p_last = p_buf;
775 p_q->count++;
776
777 p_hdr->p_next = NULL;
778 p_hdr->status = BUF_STATUS_QUEUED;
779
780 GKI_enable();
781
782 return;
783}
784
785
786/*******************************************************************************
787**
788** Function GKI_enqueue_head
789**
790** Description Enqueue a buffer at the head of the queue
791**
792** Parameters: p_q - (input) pointer to a queue.
793** p_buf - (input) address of the buffer to enqueue
794**
795** Returns void
796**
797*******************************************************************************/
798void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf)
799{
800 BUFFER_HDR_T *p_hdr;
801
802#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
803 if (gki_chk_buf_damage(p_buf))
804 {
805 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
806 return;
807 }
808#endif
809
810 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
811
812 if (p_hdr->status != BUF_STATUS_UNLINKED)
813 {
814 GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked");
815 return;
816 }
817
818 GKI_disable();
819
820 if (p_q->p_first)
821 {
822 p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
823 p_q->p_first = p_buf;
824 }
825 else
826 {
827 p_q->p_first = p_buf;
828 p_q->p_last = p_buf;
829 p_hdr->p_next = NULL;
830 }
831 p_q->count++;
832
833 p_hdr->status = BUF_STATUS_QUEUED;
834
835 GKI_enable();
836
837 return;
838}
839
840
841/*******************************************************************************
842**
843** Function GKI_dequeue
844**
845** Description Dequeues a buffer from the head of a queue
846**
847** Parameters: p_q - (input) pointer to a queue.
848**
849** Returns NULL if queue is empty, else buffer
850**
851*******************************************************************************/
852void *GKI_dequeue (BUFFER_Q *p_q)
853{
854 BUFFER_HDR_T *p_hdr;
855
856 GKI_disable();
857
858 if (!p_q || !p_q->count)
859 {
860 GKI_enable();
861 return (NULL);
862 }
863
864 p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
865
866 /* Keep buffers such that GKI header is invisible
867 */
868 if (p_hdr->p_next)
869 p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
870 else
871 {
872 p_q->p_first = NULL;
873 p_q->p_last = NULL;
874 }
875
876 p_q->count--;
877
878 p_hdr->p_next = NULL;
879 p_hdr->status = BUF_STATUS_UNLINKED;
880
881 GKI_enable();
882
883 return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
884}
885
886
887/*******************************************************************************
888**
889** Function GKI_remove_from_queue
890**
891** Description Dequeue a buffer from the middle of the queue
892**
893** Parameters: p_q - (input) pointer to a queue.
894** p_buf - (input) address of the buffer to enqueue
895**
896** Returns NULL if queue is empty, else buffer
897**
898*******************************************************************************/
899void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
900{
901 BUFFER_HDR_T *p_prev;
902 BUFFER_HDR_T *p_buf_hdr;
903
904 GKI_disable();
905
906 if (p_buf == p_q->p_first)
907 {
908 GKI_enable();
909 return (GKI_dequeue (p_q));
910 }
911
912 p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE);
913 p_prev = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
914
915 for ( ; p_prev; p_prev = p_prev->p_next)
916 {
917 /* If the previous points to this one, move the pointers around */
918 if (p_prev->p_next == p_buf_hdr)
919 {
920 p_prev->p_next = p_buf_hdr->p_next;
921
922 /* If we are removing the last guy in the queue, update p_last */
923 if (p_buf == p_q->p_last)
924 p_q->p_last = p_prev + 1;
925
926 /* One less in the queue */
927 p_q->count--;
928
929 /* The buffer is now unlinked */
930 p_buf_hdr->p_next = NULL;
931 p_buf_hdr->status = BUF_STATUS_UNLINKED;
932
933 GKI_enable();
934 return (p_buf);
935 }
936 }
937
938 GKI_enable();
939 return (NULL);
940}
941
942/*******************************************************************************
943**
944** Function GKI_getfirst
945**
946** Description Return a pointer to the first buffer in a queue
947**
948** Parameters: p_q - (input) pointer to a queue.
949**
950** Returns NULL if queue is empty, else buffer address
951**
952*******************************************************************************/
953void *GKI_getfirst (BUFFER_Q *p_q)
954{
955 return (p_q->p_first);
956}
957
958
959/*******************************************************************************
960**
961** Function GKI_getlast
962**
963** Description Return a pointer to the last buffer in a queue
964**
965** Parameters: p_q - (input) pointer to a queue.
966**
967** Returns NULL if queue is empty, else buffer address
968**
969*******************************************************************************/
970void *GKI_getlast (BUFFER_Q *p_q)
971{
972 return (p_q->p_last);
973}
974
975/*******************************************************************************
976**
977** Function GKI_getnext
978**
979** Description Return a pointer to the next buffer in a queue
980**
981** Parameters: p_buf - (input) pointer to the buffer to find the next one from.
982**
983** Returns NULL if no more buffers in the queue, else next buffer address
984**
985*******************************************************************************/
986void *GKI_getnext (void *p_buf)
987{
988 BUFFER_HDR_T *p_hdr;
989
990 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
991
992 if (p_hdr->p_next)
993 return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
994 else
995 return (NULL);
996}
997
998
999
1000/*******************************************************************************
1001**
1002** Function GKI_queue_is_empty
1003**
1004** Description Check the status of a queue.
1005**
1006** Parameters: p_q - (input) pointer to a queue.
1007**
1008** Returns TRUE if queue is empty, else FALSE
1009**
1010*******************************************************************************/
1011BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q)
1012{
1013 return ((BOOLEAN) (p_q->count == 0));
1014}
1015
1016/*******************************************************************************
1017**
The Android Open Source Project5738f832012-12-12 16:00:35 -08001018** Function GKI_igetpoolbuf
1019**
1020** Description Called by an interrupt service routine to get a free buffer from
1021** a specific buffer pool.
1022**
1023** Parameters pool_id - (input) pool ID to get a buffer out of.
1024**
1025** Returns A pointer to the buffer, or NULL if none available
1026**
1027*******************************************************************************/
1028void *GKI_igetpoolbuf (UINT8 pool_id)
1029{
1030 FREE_QUEUE_T *Q;
1031 BUFFER_HDR_T *p_hdr;
1032
1033 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1034 return (NULL);
1035
1036
1037 Q = &gki_cb.com.freeq[pool_id];
1038 if(Q->cur_cnt < Q->total)
1039 {
1040 p_hdr = Q->p_first;
1041 Q->p_first = p_hdr->p_next;
1042
1043 if (!Q->p_first)
1044 Q->p_last = NULL;
1045
1046 if(++Q->cur_cnt > Q->max_cnt)
1047 Q->max_cnt = Q->cur_cnt;
1048
1049 p_hdr->task_id = GKI_get_taskid();
1050
1051 p_hdr->status = BUF_STATUS_UNLINKED;
1052 p_hdr->p_next = NULL;
1053 p_hdr->Type = 0;
1054
1055 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
1056 }
1057
1058 return (NULL);
1059}
1060
1061/*******************************************************************************
1062**
1063** Function GKI_poolcount
1064**
1065** Description Called by an application to get the total number of buffers
1066** in the specified buffer pool.
1067**
1068** Parameters pool_id - (input) pool ID to get the free count of.
1069**
1070** Returns the total number of buffers in the pool
1071**
1072*******************************************************************************/
1073UINT16 GKI_poolcount (UINT8 pool_id)
1074{
1075 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1076 return (0);
1077
1078 return (gki_cb.com.freeq[pool_id].total);
1079}
1080
1081/*******************************************************************************
1082**
1083** Function GKI_poolfreecount
1084**
1085** Description Called by an application to get the number of free buffers
1086** in the specified buffer pool.
1087**
1088** Parameters pool_id - (input) pool ID to get the free count of.
1089**
1090** Returns the number of free buffers in the pool
1091**
1092*******************************************************************************/
1093UINT16 GKI_poolfreecount (UINT8 pool_id)
1094{
1095 FREE_QUEUE_T *Q;
1096
1097 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1098 return (0);
1099
1100 Q = &gki_cb.com.freeq[pool_id];
1101
1102 return ((UINT16)(Q->total - Q->cur_cnt));
1103}
1104
The Android Open Source Project5738f832012-12-12 16:00:35 -08001105/*******************************************************************************
1106**
1107** Function GKI_get_pool_bufsize
1108**
1109** Description Called by an application to get the size of buffers in a pool
1110**
1111** Parameters Pool ID.
1112**
1113** Returns the size of buffers in the pool
1114**
1115*******************************************************************************/
1116UINT16 GKI_get_pool_bufsize (UINT8 pool_id)
1117{
1118 if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
1119 return (gki_cb.com.freeq[pool_id].size);
1120
1121 return (0);
1122}
1123
1124/*******************************************************************************
1125**
1126** Function GKI_poolutilization
1127**
1128** Description Called by an application to get the buffer utilization
1129** in the specified buffer pool.
1130**
1131** Parameters pool_id - (input) pool ID to get the free count of.
1132**
1133** Returns % of buffers used from 0 to 100
1134**
1135*******************************************************************************/
1136UINT16 GKI_poolutilization (UINT8 pool_id)
1137{
1138 FREE_QUEUE_T *Q;
1139
1140 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1141 return (100);
1142
1143 Q = &gki_cb.com.freeq[pool_id];
1144
1145 if (Q->total == 0)
1146 return (100);
1147
1148 return ((Q->cur_cnt * 100) / Q->total);
1149}
1150