1/********************************************************************* 2 * 3 * Filename: timer.c 4 * Version: 5 * Description: 6 * Status: Experimental. 7 * Author: Dag Brattli <dagb@cs.uit.no> 8 * Created at: Sat Aug 16 00:59:29 1997 9 * Modified at: Wed Dec 8 12:50:34 1999 10 * Modified by: Dag Brattli <dagb@cs.uit.no> 11 * 12 * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 13 * All Rights Reserved. 14 * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> 15 * 16 * This program is free software; you can redistribute it and/or 17 * modify it under the terms of the GNU General Public License as 18 * published by the Free Software Foundation; either version 2 of 19 * the License, or (at your option) any later version. 20 * 21 * Neither Dag Brattli nor University of Troms�� admit liability nor 22 * provide warranty for any of this software. This material is 23 * provided "AS-IS" and at no charge. 24 * 25 ********************************************************************/ 26 27#include <asm/system.h> 28#include <linux/delay.h> 29 30#include <net/irda/timer.h> 31#include <net/irda/irda.h> 32#include <net/irda/irda_device.h> 33#include <net/irda/irlap.h> 34#include <net/irda/irlmp.h> 35 36extern int sysctl_slot_timeout; 37 38static void irlap_slot_timer_expired(void* data); 39static void irlap_query_timer_expired(void* data); 40static void irlap_final_timer_expired(void* data); 41static void irlap_wd_timer_expired(void* data); 42static void irlap_backoff_timer_expired(void* data); 43static void irlap_media_busy_expired(void* data); 44 45void irlap_start_slot_timer(struct irlap_cb *self, int timeout) 46{ 47 irda_start_timer(&self->slot_timer, timeout, (void *) self, 48 irlap_slot_timer_expired); 49} 50 51void irlap_start_query_timer(struct irlap_cb *self, int S, int s) 52{ 53 int timeout; 54 55 /* Calculate when the peer discovery should end. Normally, we 56 * get the end-of-discovery frame, so this is just in case 57 * we miss it. 58 * Basically, we multiply the number of remaining slots by our 59 * slot time, plus add some extra time to properly receive the last 60 * discovery packet (which is longer due to extra discovery info), 61 * to avoid messing with for incomming connections requests and 62 * to accomodate devices that perform discovery slower than us. 63 * Jean II */ 64 timeout = ((sysctl_slot_timeout * HZ / 1000) * (S - s) 65 + XIDEXTRA_TIMEOUT + SMALLBUSY_TIMEOUT); 66 67 /* Set or re-set the timer. We reset the timer for each received 68 * discovery query, which allow us to automatically adjust to 69 * the speed of the peer discovery (faster or slower). Jean II */ 70 irda_start_timer( &self->query_timer, timeout, (void *) self, 71 irlap_query_timer_expired); 72} 73 74void irlap_start_final_timer(struct irlap_cb *self, int timeout) 75{ 76 irda_start_timer(&self->final_timer, timeout, (void *) self, 77 irlap_final_timer_expired); 78} 79 80void irlap_start_wd_timer(struct irlap_cb *self, int timeout) 81{ 82 irda_start_timer(&self->wd_timer, timeout, (void *) self, 83 irlap_wd_timer_expired); 84} 85 86void irlap_start_backoff_timer(struct irlap_cb *self, int timeout) 87{ 88 irda_start_timer(&self->backoff_timer, timeout, (void *) self, 89 irlap_backoff_timer_expired); 90} 91 92void irlap_start_mbusy_timer(struct irlap_cb *self, int timeout) 93{ 94 irda_start_timer(&self->media_busy_timer, timeout, 95 (void *) self, irlap_media_busy_expired); 96} 97 98void irlap_stop_mbusy_timer(struct irlap_cb *self) 99{ 100 /* If timer is activated, kill it! */ 101 del_timer(&self->media_busy_timer); 102 103 /* If we are in NDM, there is a bunch of events in LAP that 104 * that be pending due to the media_busy condition, such as 105 * CONNECT_REQUEST and SEND_UI_FRAME. If we don't generate 106 * an event, they will wait forever... 107 * Jean II */ 108 if (self->state == LAP_NDM) 109 irlap_do_event(self, MEDIA_BUSY_TIMER_EXPIRED, NULL, NULL); 110} 111 112void irlmp_start_watchdog_timer(struct lsap_cb *self, int timeout) 113{ 114 irda_start_timer(&self->watchdog_timer, timeout, (void *) self, 115 irlmp_watchdog_timer_expired); 116} 117 118void irlmp_start_discovery_timer(struct irlmp_cb *self, int timeout) 119{ 120 irda_start_timer(&self->discovery_timer, timeout, (void *) self, 121 irlmp_discovery_timer_expired); 122} 123 124void irlmp_start_idle_timer(struct lap_cb *self, int timeout) 125{ 126 irda_start_timer(&self->idle_timer, timeout, (void *) self, 127 irlmp_idle_timer_expired); 128} 129 130void irlmp_stop_idle_timer(struct lap_cb *self) 131{ 132 /* If timer is activated, kill it! */ 133 del_timer(&self->idle_timer); 134} 135 136/* 137 * Function irlap_slot_timer_expired (data) 138 * 139 * IrLAP slot timer has expired 140 * 141 */ 142static void irlap_slot_timer_expired(void *data) 143{ 144 struct irlap_cb *self = (struct irlap_cb *) data; 145 146 IRDA_ASSERT(self != NULL, return;); 147 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 148 149 irlap_do_event(self, SLOT_TIMER_EXPIRED, NULL, NULL); 150} 151 152/* 153 * Function irlap_query_timer_expired (data) 154 * 155 * IrLAP query timer has expired 156 * 157 */ 158static void irlap_query_timer_expired(void *data) 159{ 160 struct irlap_cb *self = (struct irlap_cb *) data; 161 162 IRDA_ASSERT(self != NULL, return;); 163 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 164 165 irlap_do_event(self, QUERY_TIMER_EXPIRED, NULL, NULL); 166} 167 168/* 169 * Function irda_final_timer_expired (data) 170 * 171 * 172 * 173 */ 174static void irlap_final_timer_expired(void *data) 175{ 176 struct irlap_cb *self = (struct irlap_cb *) data; 177 178 IRDA_ASSERT(self != NULL, return;); 179 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 180 181 irlap_do_event(self, FINAL_TIMER_EXPIRED, NULL, NULL); 182} 183 184/* 185 * Function irda_wd_timer_expired (data) 186 * 187 * 188 * 189 */ 190static void irlap_wd_timer_expired(void *data) 191{ 192 struct irlap_cb *self = (struct irlap_cb *) data; 193 194 IRDA_ASSERT(self != NULL, return;); 195 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 196 197 irlap_do_event(self, WD_TIMER_EXPIRED, NULL, NULL); 198} 199 200/* 201 * Function irda_backoff_timer_expired (data) 202 * 203 * 204 * 205 */ 206static void irlap_backoff_timer_expired(void *data) 207{ 208 struct irlap_cb *self = (struct irlap_cb *) data; 209 210 IRDA_ASSERT(self != NULL, return;); 211 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 212 213 irlap_do_event(self, BACKOFF_TIMER_EXPIRED, NULL, NULL); 214} 215 216 217/* 218 * Function irtty_media_busy_expired (data) 219 * 220 * 221 */ 222static void irlap_media_busy_expired(void *data) 223{ 224 struct irlap_cb *self = (struct irlap_cb *) data; 225 226 IRDA_ASSERT(self != NULL, return;); 227 228 irda_device_set_media_busy(self->netdev, FALSE); 229 /* Note : the LAP event will be send in irlap_stop_mbusy_timer(), 230 * to catch other cases where the flag is cleared (for example 231 * after a discovery) - Jean II */ 232} 233