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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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