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 *******************************************************************************/
gki_timers_init(void)44 void 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 *******************************************************************************/
gki_timers_is_timer_running(void)100 BOOLEAN 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 *******************************************************************************/
GKI_get_tick_count(void)148 UINT32 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 *******************************************************************************/
GKI_ready_to_sleep(void)171 INT32 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 *******************************************************************************/
GKI_start_timer(UINT8 tnum,INT32 ticks,BOOLEAN is_continuous)196 void 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 *******************************************************************************/
GKI_stop_timer(UINT8 tnum)307 void 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 *******************************************************************************/
GKI_timer_update(INT32 ticks_since_last_update)387 void 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 *******************************************************************************/
GKI_timer_queue_empty(void)587 BOOLEAN 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 *******************************************************************************/
GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK * p_callback)613 void 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 *******************************************************************************/
GKI_init_timer_list(TIMER_LIST_Q * p_timer_listq)632 void 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 *******************************************************************************/
GKI_init_timer_list_entry(TIMER_LIST_ENT * p_tle)654 void 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 *******************************************************************************/
GKI_update_timer_list(TIMER_LIST_Q * p_timer_listq,INT32 num_units_since_last_update)681 UINT16 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 *******************************************************************************/
GKI_get_remaining_ticks(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_target_tle)749 UINT32 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 *******************************************************************************/
GKI_add_to_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)800 void 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 *******************************************************************************/
GKI_remove_from_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)903 void 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 *******************************************************************************/
gki_adjust_timer_count(INT32 ticks)1004 void 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