1/******************************************************************************
2 *
3 *  Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18#include "gki_int.h"
19
20#ifndef BT_ERROR_TRACE_0
21#define BT_ERROR_TRACE_0(l,m)
22#endif
23
24/* Make sure that this has been defined in target.h */
25#ifndef GKI_NUM_TIMERS
26#error  NO TIMERS: Must define at least 1 timer in the system!
27#endif
28
29
30#define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL)   /* Largest signed positive timer count */
31#define GKI_UNUSED_LIST_ENTRY   (0x80000000L)   /* Marks an unused timer list entry (initial value) */
32#define GKI_MAX_INT32           (0x7fffffffL)
33
34/*******************************************************************************
35**
36** Function         gki_timers_init
37**
38** Description      This internal function is called once at startup to initialize
39**                  all the timer structures.
40**
41** Returns          void
42**
43*******************************************************************************/
44void gki_timers_init(void)
45{
46    UINT8   tt;
47
48    gki_cb.com.OSTicksTilExp = 0;       /* Remaining time (of OSTimeCurTimeout) before next timer expires */
49    gki_cb.com.OSNumOrigTicks = 0;
50#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
51    gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
52#endif
53
54    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
55    {
56        gki_cb.com.OSWaitTmr   [tt] = 0;
57
58#if (GKI_NUM_TIMERS > 0)
59        gki_cb.com.OSTaskTmr0  [tt] = 0;
60        gki_cb.com.OSTaskTmr0R [tt] = 0;
61#endif
62
63#if (GKI_NUM_TIMERS > 1)
64        gki_cb.com.OSTaskTmr1  [tt] = 0;
65        gki_cb.com.OSTaskTmr1R [tt] = 0;
66#endif
67
68#if (GKI_NUM_TIMERS > 2)
69        gki_cb.com.OSTaskTmr2  [tt] = 0;
70        gki_cb.com.OSTaskTmr2R [tt] = 0;
71#endif
72
73#if (GKI_NUM_TIMERS > 3)
74        gki_cb.com.OSTaskTmr3  [tt] = 0;
75        gki_cb.com.OSTaskTmr3R [tt] = 0;
76#endif
77    }
78
79    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
80    {
81        gki_cb.com.timer_queues[tt] = NULL;
82    }
83
84    gki_cb.com.p_tick_cb = NULL;
85    gki_cb.com.system_tick_running = FALSE;
86
87    return;
88}
89
90/*******************************************************************************
91**
92** Function         gki_timers_is_timer_running
93**
94** Description      This internal function is called to test if any gki timer are running
95**
96**
97** Returns          TRUE if at least one time is running in the system, FALSE else.
98**
99*******************************************************************************/
100BOOLEAN gki_timers_is_timer_running(void)
101{
102    UINT8   tt;
103    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
104    {
105
106#if (GKI_NUM_TIMERS > 0)
107        if(gki_cb.com.OSTaskTmr0  [tt])
108        {
109            return TRUE;
110        }
111#endif
112
113#if (GKI_NUM_TIMERS > 1)
114        if(gki_cb.com.OSTaskTmr1  [tt] )
115        {
116            return TRUE;
117        }
118#endif
119
120#if (GKI_NUM_TIMERS > 2)
121        if(gki_cb.com.OSTaskTmr2  [tt] )
122        {
123            return TRUE;
124        }
125#endif
126
127#if (GKI_NUM_TIMERS > 3)
128        if(gki_cb.com.OSTaskTmr3  [tt] )
129        {
130            return TRUE;
131        }
132#endif
133    }
134
135    return FALSE;
136
137}
138
139/*******************************************************************************
140**
141** Function         GKI_get_tick_count
142**
143** Description      This function returns the current system ticks
144**
145** Returns          The current number of system ticks
146**
147*******************************************************************************/
148UINT32  GKI_get_tick_count(void)
149{
150    return gki_cb.com.OSTicks;
151}
152
153
154/*******************************************************************************
155**
156** Function         GKI_ready_to_sleep
157**
158** Description      This function returns the number of system ticks until the
159**                  next timer will expire.  It is typically called by a power
160**                  savings manager to find out how long it can have the system
161**                  sleep before it needs to service the next entry.
162**
163** Parameters:      None
164**
165** Returns          Number of ticks til the next timer expires
166**                  Note: the value is a signed  value.  This value should be
167**                      compared to x > 0, to avoid misinterpreting negative tick
168**                      values.
169**
170*******************************************************************************/
171INT32    GKI_ready_to_sleep (void)
172{
173    return (gki_cb.com.OSTicksTilExp);
174}
175
176
177/*******************************************************************************
178**
179** Function         GKI_start_timer
180**
181** Description      An application can call this function to start one of
182**                  it's four general purpose timers. Any of the four timers
183**                  can be 1-shot or continuous. If a timer is already running,
184**                  it will be reset to the new parameters.
185**
186** Parameters       tnum            - (input) timer number to be started (TIMER_0,
187**                                              TIMER_1, TIMER_2, or TIMER_3)
188**                  ticks           - (input) the number of system ticks til the
189**                                              timer expires.
190**                  is_continuous   - (input) TRUE if timer restarts automatically,
191**                                              else FALSE if it is a 'one-shot'.
192**
193** Returns          void
194**
195*******************************************************************************/
196void GKI_start_timer (UINT8 tnum, INT32 ticks, BOOLEAN is_continuous)
197{
198    INT32   reload;
199    INT32   orig_ticks;
200    UINT8   task_id = GKI_get_taskid();
201    BOOLEAN bad_timer = FALSE;
202
203    if (ticks <= 0)
204        ticks = 1;
205
206    orig_ticks = ticks;     /* save the ticks in case adjustment is necessary */
207
208
209    /* If continuous timer, set reload, else set it to 0 */
210    if (is_continuous)
211        reload = ticks;
212    else
213        reload = 0;
214
215    GKI_disable();
216
217    if(gki_timers_is_timer_running() == FALSE)
218    {
219#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
220        /* if inactivity delay timer is not running, start system tick */
221        if(gki_cb.com.OSTicksTilStop == 0)
222        {
223#endif
224            if(gki_cb.com.p_tick_cb)
225            {
226                /* start system tick */
227                gki_cb.com.system_tick_running = TRUE;
228                (gki_cb.com.p_tick_cb) (TRUE);
229            }
230#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
231        }
232        else
233        {
234            /* clear inactivity delay timer */
235            gki_cb.com.OSTicksTilStop = 0;
236        }
237#endif
238    }
239    /* Add the time since the last task timer update.
240    ** Note that this works when no timers are active since
241    ** both OSNumOrigTicks and OSTicksTilExp are 0.
242    */
243    if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) > ticks)
244    {
245        ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
246    }
247    else
248        ticks = GKI_MAX_INT32;
249
250    switch (tnum)
251    {
252#if (GKI_NUM_TIMERS > 0)
253        case TIMER_0:
254            gki_cb.com.OSTaskTmr0R[task_id] = reload;
255            gki_cb.com.OSTaskTmr0 [task_id] = ticks;
256            break;
257#endif
258
259#if (GKI_NUM_TIMERS > 1)
260        case TIMER_1:
261            gki_cb.com.OSTaskTmr1R[task_id] = reload;
262            gki_cb.com.OSTaskTmr1 [task_id] = ticks;
263            break;
264#endif
265
266#if (GKI_NUM_TIMERS > 2)
267        case TIMER_2:
268            gki_cb.com.OSTaskTmr2R[task_id] = reload;
269            gki_cb.com.OSTaskTmr2 [task_id] = ticks;
270            break;
271#endif
272
273#if (GKI_NUM_TIMERS > 3)
274        case TIMER_3:
275            gki_cb.com.OSTaskTmr3R[task_id] = reload;
276            gki_cb.com.OSTaskTmr3 [task_id] = ticks;
277            break;
278#endif
279        default:
280            bad_timer = TRUE;       /* Timer number is bad, so do not use */
281    }
282
283    /* Update the expiration timeout if a legitimate timer */
284    if (!bad_timer)
285    {
286        /* Only update the timeout value if it is less than any other newly started timers */
287        gki_adjust_timer_count (orig_ticks);
288    }
289
290    GKI_enable();
291
292}
293
294/*******************************************************************************
295**
296** Function         GKI_stop_timer
297**
298** Description      An application can call this function to stop one of
299**                  it's four general purpose timers. There is no harm in
300**                  stopping a timer that is already stopped.
301**
302** Parameters       tnum            - (input) timer number to be started (TIMER_0,
303**                                              TIMER_1, TIMER_2, or TIMER_3)
304** Returns          void
305**
306*******************************************************************************/
307void GKI_stop_timer (UINT8 tnum)
308{
309    UINT8  task_id = GKI_get_taskid();
310
311    GKI_disable();
312
313    switch (tnum)
314    {
315#if (GKI_NUM_TIMERS > 0)
316        case TIMER_0:
317            gki_cb.com.OSTaskTmr0R[task_id] = 0;
318            gki_cb.com.OSTaskTmr0 [task_id] = 0;
319            break;
320#endif
321
322#if (GKI_NUM_TIMERS > 1)
323        case TIMER_1:
324            gki_cb.com.OSTaskTmr1R[task_id] = 0;
325            gki_cb.com.OSTaskTmr1 [task_id] = 0;
326            break;
327#endif
328
329#if (GKI_NUM_TIMERS > 2)
330        case TIMER_2:
331            gki_cb.com.OSTaskTmr2R[task_id] = 0;
332            gki_cb.com.OSTaskTmr2 [task_id] = 0;
333            break;
334#endif
335
336#if (GKI_NUM_TIMERS > 3)
337        case TIMER_3:
338            gki_cb.com.OSTaskTmr3R[task_id] = 0;
339            gki_cb.com.OSTaskTmr3 [task_id] = 0;
340            break;
341#endif
342    }
343
344    if (gki_timers_is_timer_running() == FALSE)
345    {
346        if (gki_cb.com.p_tick_cb)
347        {
348#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
349            /* if inactivity delay timer is not running */
350            if ((gki_cb.com.system_tick_running)&&(gki_cb.com.OSTicksTilStop == 0))
351            {
352                /* set inactivity delay timer */
353                /* when timer expires, system tick will be stopped */
354                gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
355            }
356#else
357            gki_cb.com.system_tick_running = FALSE;
358            gki_cb.com.p_tick_cb(FALSE); /* stop system tick */
359#endif
360        }
361    }
362
363    GKI_enable();
364
365
366}
367
368
369/*******************************************************************************
370**
371** Function         GKI_timer_update
372**
373** Description      This function is called by an OS to drive the GKI's timers.
374**                  It is typically called at every system tick to
375**                  update the timers for all tasks, and check for timeouts.
376**
377**                  Note: It has been designed to also allow for variable tick updates
378**                      so that systems with strict power savings requirements can
379**                      have the update occur at variable intervals.
380**
381** Parameters:      ticks_since_last_update - (input) This is the number of TICKS that have
382**                          occurred since the last time GKI_timer_update was called.
383**
384** Returns          void
385**
386*******************************************************************************/
387void GKI_timer_update (INT32 ticks_since_last_update)
388{
389    UINT8   task_id;
390    long    next_expiration;        /* Holds the next soonest expiration time after this update */
391
392    /* Increment the number of ticks used for time stamps */
393    gki_cb.com.OSTicks += ticks_since_last_update;
394
395    /* If any timers are running in any tasks, decrement the remaining time til
396     * the timer updates need to take place (next expiration occurs)
397     */
398    gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
399
400    /* Don't allow timer interrupt nesting */
401    if (gki_cb.com.timer_nesting)
402        return;
403
404    gki_cb.com.timer_nesting = 1;
405
406#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
407    /* if inactivity delay timer is set and expired */
408    if (gki_cb.com.OSTicksTilStop)
409    {
410        if( gki_cb.com.OSTicksTilStop <= (UINT32)ticks_since_last_update )
411        {
412            if(gki_cb.com.p_tick_cb)
413            {
414                gki_cb.com.system_tick_running = FALSE;
415                (gki_cb.com.p_tick_cb) (FALSE); /* stop system tick */
416            }
417            gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
418            gki_cb.com.timer_nesting = 0;
419            return;
420        }
421        else
422            gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
423    }
424#endif
425
426    /* No need to update the ticks if no timeout has occurred */
427    if (gki_cb.com.OSTicksTilExp > 0)
428    {
429        gki_cb.com.timer_nesting = 0;
430        return;
431    }
432
433    GKI_disable();
434
435    next_expiration = GKI_NO_NEW_TMRS_STARTED;
436
437    /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase gki_cb.com.OSNumOrigTicks
438       to account for the difference so timer updates below are decremented by the full number
439       of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function so changing this
440       value only affects the timer updates below
441     */
442    gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
443
444    /* Check for OS Task Timers */
445    for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
446    {
447        if (gki_cb.com.OSRdyTbl[task_id] == TASK_DEAD)
448        {
449            // task is shutdown do not try to service timers
450            continue;
451        }
452
453        if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
454        {
455            gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
456            if (gki_cb.com.OSWaitTmr[task_id] <= 0)
457            {
458                /* Timer Expired */
459                gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
460            }
461        }
462
463#if (GKI_NUM_TIMERS > 0)
464         /* If any timer is running, decrement */
465        if (gki_cb.com.OSTaskTmr0[task_id] > 0)
466        {
467            gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
468
469            if (gki_cb.com.OSTaskTmr0[task_id] <= 0)
470            {
471                /* Set Timer 0 Expired event mask and reload timer */
472#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
473                GKI_isend_event (task_id, TIMER_0_EVT_MASK);
474#else
475                GKI_send_event (task_id, TIMER_0_EVT_MASK);
476#endif
477                gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
478            }
479        }
480
481        /* Check to see if this timer is the next one to expire */
482        if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
483            next_expiration = gki_cb.com.OSTaskTmr0[task_id];
484#endif
485
486#if (GKI_NUM_TIMERS > 1)
487         /* If any timer is running, decrement */
488        if (gki_cb.com.OSTaskTmr1[task_id] > 0)
489        {
490            gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
491
492            if (gki_cb.com.OSTaskTmr1[task_id] <= 0)
493            {
494                /* Set Timer 1 Expired event mask and reload timer */
495#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
496                GKI_isend_event (task_id, TIMER_1_EVT_MASK);
497#else
498                GKI_send_event (task_id, TIMER_1_EVT_MASK);
499#endif
500                gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
501            }
502        }
503
504        /* Check to see if this timer is the next one to expire */
505        if (gki_cb.com.OSTaskTmr1[task_id] > 0 && gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
506            next_expiration = gki_cb.com.OSTaskTmr1[task_id];
507#endif
508
509#if (GKI_NUM_TIMERS > 2)
510         /* If any timer is running, decrement */
511        if (gki_cb.com.OSTaskTmr2[task_id] > 0)
512        {
513            gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
514
515            if (gki_cb.com.OSTaskTmr2[task_id] <= 0)
516            {
517                /* Set Timer 2 Expired event mask and reload timer */
518#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
519                GKI_isend_event (task_id, TIMER_2_EVT_MASK);
520#else
521                GKI_send_event (task_id, TIMER_2_EVT_MASK);
522#endif
523                gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
524            }
525        }
526
527        /* Check to see if this timer is the next one to expire */
528        if (gki_cb.com.OSTaskTmr2[task_id] > 0 && gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
529            next_expiration = gki_cb.com.OSTaskTmr2[task_id];
530#endif
531
532#if (GKI_NUM_TIMERS > 3)
533         /* If any timer is running, decrement */
534        if (gki_cb.com.OSTaskTmr3[task_id] > 0)
535        {
536            gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
537
538            if (gki_cb.com.OSTaskTmr3[task_id] <= 0)
539            {
540                /* Set Timer 3 Expired event mask and reload timer */
541#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
542                GKI_isend_event (task_id, TIMER_3_EVT_MASK);
543#else
544                GKI_send_event (task_id, TIMER_3_EVT_MASK);
545#endif
546                gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
547            }
548        }
549
550        /* Check to see if this timer is the next one to expire */
551        if (gki_cb.com.OSTaskTmr3[task_id] > 0 && gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
552            next_expiration = gki_cb.com.OSTaskTmr3[task_id];
553#endif
554
555    }
556
557    /* Set the next timer experation value if there is one to start */
558    if (next_expiration < GKI_NO_NEW_TMRS_STARTED)
559    {
560        gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
561    }
562    else
563    {
564        gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
565    }
566
567    gki_cb.com.timer_nesting = 0;
568
569    GKI_enable();
570
571    return;
572}
573
574
575/*******************************************************************************
576**
577** Function         GKI_timer_queue_empty
578**
579** Description      This function is called by applications to see whether the timer
580**                  queue is empty
581**
582** Parameters
583**
584** Returns          BOOLEAN
585**
586*******************************************************************************/
587BOOLEAN GKI_timer_queue_empty (void)
588{
589    UINT8 tt;
590
591    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
592    {
593        if (gki_cb.com.timer_queues[tt])
594            return FALSE;
595    }
596
597    return TRUE;
598}
599
600/*******************************************************************************
601**
602** Function         GKI_timer_queue_register_callback
603**
604** Description      This function is called by applications to register system tick
605**                  start/stop callback for time queues
606**
607**
608** Parameters       p_callback - (input) pointer to the system tick callback
609**
610** Returns          BOOLEAN
611**
612*******************************************************************************/
613void GKI_timer_queue_register_callback (SYSTEM_TICK_CBACK *p_callback)
614{
615    gki_cb.com.p_tick_cb = p_callback;
616
617    return;
618}
619
620/*******************************************************************************
621**
622** Function         GKI_init_timer_list
623**
624** Description      This function is called by applications when they
625**                  want to initialize a timer list.
626**
627** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
628**
629** Returns          void
630**
631*******************************************************************************/
632void GKI_init_timer_list (TIMER_LIST_Q *p_timer_listq)
633{
634    p_timer_listq->p_first    = NULL;
635    p_timer_listq->p_last     = NULL;
636    p_timer_listq->last_ticks = 0;
637
638    return;
639}
640
641/*******************************************************************************
642**
643** Function         GKI_init_timer_list_entry
644**
645** Description      This function is called by the applications when they
646**                  want to initialize a timer list entry. This must be
647**                  done prior to first use of the entry.
648**
649** Parameters       p_tle           - (input) pointer to a timer list queue entry
650**
651** Returns          void
652**
653*******************************************************************************/
654void GKI_init_timer_list_entry (TIMER_LIST_ENT  *p_tle)
655{
656    p_tle->p_next  = NULL;
657    p_tle->p_prev  = NULL;
658    p_tle->ticks   = GKI_UNUSED_LIST_ENTRY;
659    p_tle->in_use  = FALSE;
660}
661
662
663/*******************************************************************************
664**
665** Function         GKI_update_timer_list
666**
667** Description      This function is called by the applications when they
668**                  want to update a timer list. This should be at every
669**                  timer list unit tick, e.g. once per sec, once per minute etc.
670**
671** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
672**                  num_units_since_last_update - (input) number of units since the last update
673**                                  (allows for variable unit update)
674**
675**      NOTE: The following timer list update routines should not be used for exact time
676**            critical purposes.  The timer tasks should be used when exact timing is needed.
677**
678** Returns          the number of timers that have expired
679**
680*******************************************************************************/
681UINT16 GKI_update_timer_list (TIMER_LIST_Q *p_timer_listq, INT32 num_units_since_last_update)
682{
683    TIMER_LIST_ENT  *p_tle;
684    UINT16           num_time_out = 0;
685    INT32            rem_ticks;
686    INT32            temp_ticks;
687
688    p_tle = p_timer_listq->p_first;
689
690    /* First, get the guys who have previously timed out */
691    /* Note that the tick value of the timers should always be '0' */
692    while ((p_tle) && (p_tle->ticks <= 0))
693    {
694        num_time_out++;
695        p_tle = p_tle->p_next;
696    }
697
698    /* Timer entriy tick values are relative to the preceeding entry */
699    rem_ticks = num_units_since_last_update;
700
701    /* Now, adjust remaining timer entries */
702    while ((p_tle != NULL) && (rem_ticks > 0))
703    {
704        temp_ticks = p_tle->ticks;
705        p_tle->ticks -= rem_ticks;
706
707        /* See if this timer has just timed out */
708        if (p_tle->ticks <= 0)
709        {
710            /* We set the number of ticks to '0' so that the legacy code
711             * that assumes a '0' or nonzero value will still work as coded. */
712            p_tle->ticks = 0;
713
714            num_time_out++;
715        }
716
717        rem_ticks -= temp_ticks;  /* Decrement the remaining ticks to process */
718        p_tle = p_tle->p_next;
719    }
720
721    if (p_timer_listq->last_ticks > 0)
722    {
723        p_timer_listq->last_ticks -= num_units_since_last_update;
724
725        /* If the last timer has expired set last_ticks to 0 so that other list update
726        * functions will calculate correctly
727        */
728        if (p_timer_listq->last_ticks < 0)
729            p_timer_listq->last_ticks = 0;
730    }
731
732    return (num_time_out);
733}
734
735/*******************************************************************************
736**
737** Function         GKI_get_remaining_ticks
738**
739** Description      This function is called by an application to get remaining
740**                  ticks to expire
741**
742** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
743**                  p_target_tle    - (input) pointer to a timer list queue entry
744**
745** Returns          0 if timer is not used or timer is not in the list
746**                  remaining ticks if success
747**
748*******************************************************************************/
749UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_target_tle)
750{
751    TIMER_LIST_ENT  *p_tle;
752    UINT32           rem_ticks = 0;
753
754    if (p_target_tle->in_use)
755    {
756        p_tle = p_timer_listq->p_first;
757
758        /* adding up all of ticks in previous entries */
759        while ((p_tle)&&(p_tle != p_target_tle))
760        {
761            rem_ticks += p_tle->ticks;
762            p_tle = p_tle->p_next;
763        }
764
765        /* if found target entry */
766        if (p_tle == p_target_tle)
767        {
768            rem_ticks += p_tle->ticks;
769        }
770        else
771        {
772            BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: No timer entry in the list");
773            return(0);
774        }
775    }
776    else
777    {
778        BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: timer entry is not active");
779    }
780
781    return (rem_ticks);
782}
783
784/*******************************************************************************
785**
786** Function         GKI_add_to_timer_list
787**
788** Description      This function is called by an application to add a timer
789**                  entry to a timer list.
790**
791**                  Note: A timer value of '0' will effectively insert an already
792**                      expired event.  Negative tick values will be ignored.
793**
794** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
795**                  p_tle           - (input) pointer to a timer list queue entry
796**
797** Returns          void
798**
799*******************************************************************************/
800void GKI_add_to_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
801{
802    UINT32           nr_ticks_total;
803    UINT8 tt;
804    TIMER_LIST_ENT  *p_temp;
805    if (p_tle == NULL || p_timer_listq == NULL) {
806        GKI_TRACE_3("%s: invalid argument %x, %x****************************<<", __func__, p_timer_listq, p_tle);
807        return;
808    }
809
810
811    /* Only process valid tick values */
812    if (p_tle->ticks >= 0)
813    {
814        /* If this entry is the last in the list */
815        if (p_tle->ticks >= p_timer_listq->last_ticks)
816        {
817            /* If this entry is the only entry in the list */
818            if (p_timer_listq->p_first == NULL)
819                p_timer_listq->p_first = p_tle;
820            else
821            {
822                /* Insert the entry onto the end of the list */
823                if (p_timer_listq->p_last != NULL)
824                    p_timer_listq->p_last->p_next = p_tle;
825
826                p_tle->p_prev = p_timer_listq->p_last;
827            }
828
829            p_tle->p_next = NULL;
830            p_timer_listq->p_last = p_tle;
831            nr_ticks_total = p_tle->ticks;
832            p_tle->ticks -= p_timer_listq->last_ticks;
833
834            p_timer_listq->last_ticks = nr_ticks_total;
835        }
836        else    /* This entry needs to be inserted before the last entry */
837        {
838            /* Find the entry that the new one needs to be inserted in front of */
839            p_temp = p_timer_listq->p_first;
840            while (p_tle->ticks > p_temp->ticks)
841            {
842                /* Update the tick value if looking at an unexpired entry */
843                if (p_temp->ticks > 0)
844                    p_tle->ticks -= p_temp->ticks;
845
846                p_temp = p_temp->p_next;
847            }
848
849            /* The new entry is the first in the list */
850            if (p_temp == p_timer_listq->p_first)
851            {
852                p_tle->p_next = p_timer_listq->p_first;
853                p_timer_listq->p_first->p_prev = p_tle;
854                p_timer_listq->p_first = p_tle;
855            }
856            else
857            {
858                p_temp->p_prev->p_next = p_tle;
859                p_tle->p_prev = p_temp->p_prev;
860                p_temp->p_prev = p_tle;
861                p_tle->p_next = p_temp;
862            }
863            p_temp->ticks -= p_tle->ticks;
864        }
865
866        p_tle->in_use = TRUE;
867
868        /* if we already add this timer queue to the array */
869        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
870        {
871             if (gki_cb.com.timer_queues[tt] == p_timer_listq)
872                 return;
873        }
874        /* add this timer queue to the array */
875        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
876        {
877             if (gki_cb.com.timer_queues[tt] == NULL)
878                 break;
879        }
880        if (tt < GKI_MAX_TIMER_QUEUES)
881        {
882            gki_cb.com.timer_queues[tt] = p_timer_listq;
883        }
884    }
885
886    return;
887}
888
889
890/*******************************************************************************
891**
892** Function         GKI_remove_from_timer_list
893**
894** Description      This function is called by an application to remove a timer
895**                  entry from a timer list.
896**
897** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
898**                  p_tle           - (input) pointer to a timer list queue entry
899**
900** Returns          void
901**
902*******************************************************************************/
903void GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
904{
905    UINT8 tt;
906
907    /* Verify that the entry is valid */
908    if (p_tle == NULL || p_tle->in_use == FALSE || p_timer_listq->p_first == NULL)
909    {
910        return;
911    }
912
913    /* Add the ticks remaining in this timer (if any) to the next guy in the list.
914    ** Note: Expired timers have a tick value of '0'.
915    */
916    if (p_tle->p_next != NULL)
917    {
918        p_tle->p_next->ticks += p_tle->ticks;
919    }
920    else
921    {
922        p_timer_listq->last_ticks -= p_tle->ticks;
923    }
924
925    /* Unlink timer from the list.
926    */
927    if (p_timer_listq->p_first == p_tle)
928    {
929        p_timer_listq->p_first = p_tle->p_next;
930
931        if (p_timer_listq->p_first != NULL)
932            p_timer_listq->p_first->p_prev = NULL;
933
934        if (p_timer_listq->p_last == p_tle)
935            p_timer_listq->p_last = NULL;
936    }
937    else
938    {
939        if (p_timer_listq->p_last == p_tle)
940        {
941            p_timer_listq->p_last = p_tle->p_prev;
942
943            if (p_timer_listq->p_last != NULL)
944                p_timer_listq->p_last->p_next = NULL;
945        }
946        else
947        {
948            if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
949                p_tle->p_next->p_prev = p_tle->p_prev;
950            else
951            {
952                /* Error case - chain messed up ?? */
953                return;
954            }
955
956            if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
957                p_tle->p_prev->p_next = p_tle->p_next;
958            else
959            {
960                /* Error case - chain messed up ?? */
961                return;
962            }
963        }
964    }
965
966    p_tle->p_next = p_tle->p_prev = NULL;
967    p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
968    p_tle->in_use = FALSE;
969
970    /* if timer queue is empty */
971    if (p_timer_listq->p_first == NULL && p_timer_listq->p_last == NULL)
972    {
973        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
974        {
975            if (gki_cb.com.timer_queues[tt] == p_timer_listq)
976            {
977                gki_cb.com.timer_queues[tt] = NULL;
978                break;
979            }
980        }
981    }
982
983    return;
984}
985
986
987/*******************************************************************************
988**
989** Function         gki_adjust_timer_count
990**
991** Description      This function is called whenever a new timer or GKI_wait occurs
992**                  to adjust (if necessary) the current time til the first expiration.
993**                  This only needs to make an adjustment if the new timer (in ticks) is
994**                  less than the number of ticks remaining on the current timer.
995**
996** Parameters:      ticks - (input) number of system ticks of the new timer entry
997**
998**                  NOTE:  This routine MUST be called while interrupts are disabled to
999**                          avoid updates while adjusting the timer variables.
1000**
1001** Returns          void
1002**
1003*******************************************************************************/
1004void gki_adjust_timer_count (INT32 ticks)
1005{
1006    if (ticks > 0)
1007    {
1008        /* See if the new timer expires before the current first expiration */
1009        if (gki_cb.com.OSNumOrigTicks == 0 || (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0))
1010        {
1011            gki_cb.com.OSNumOrigTicks = (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
1012            gki_cb.com.OSTicksTilExp = ticks;
1013        }
1014    }
1015
1016    return;
1017}
1018