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