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 <linux/delay.h> 28 29#include <net/irda/timer.h> 30#include <net/irda/irda.h> 31#include <net/irda/irda_device.h> 32#include <net/irda/irlap.h> 33#include <net/irda/irlmp.h> 34 35extern int sysctl_slot_timeout; 36 37static void irlap_slot_timer_expired(void* data); 38static void irlap_query_timer_expired(void* data); 39static void irlap_final_timer_expired(void* data); 40static void irlap_wd_timer_expired(void* data); 41static void irlap_backoff_timer_expired(void* data); 42static void irlap_media_busy_expired(void* data); 43 44void irlap_start_slot_timer(struct irlap_cb *self, int timeout) 45{ 46 irda_start_timer(&self->slot_timer, timeout, (void *) self, 47 irlap_slot_timer_expired); 48} 49 50void irlap_start_query_timer(struct irlap_cb *self, int S, int s) 51{ 52 int timeout; 53 54 /* Calculate when the peer discovery should end. Normally, we 55 * get the end-of-discovery frame, so this is just in case 56 * we miss it. 57 * Basically, we multiply the number of remaining slots by our 58 * slot time, plus add some extra time to properly receive the last 59 * discovery packet (which is longer due to extra discovery info), 60 * to avoid messing with for incoming connections requests and 61 * to accommodate devices that perform discovery slower than us. 62 * Jean II */ 63 timeout = ((sysctl_slot_timeout * HZ / 1000) * (S - s) 64 + XIDEXTRA_TIMEOUT + SMALLBUSY_TIMEOUT); 65 66 /* Set or re-set the timer. We reset the timer for each received 67 * discovery query, which allow us to automatically adjust to 68 * the speed of the peer discovery (faster or slower). Jean II */ 69 irda_start_timer( &self->query_timer, timeout, (void *) self, 70 irlap_query_timer_expired); 71} 72 73void irlap_start_final_timer(struct irlap_cb *self, int timeout) 74{ 75 irda_start_timer(&self->final_timer, timeout, (void *) self, 76 irlap_final_timer_expired); 77} 78 79void irlap_start_wd_timer(struct irlap_cb *self, int timeout) 80{ 81 irda_start_timer(&self->wd_timer, timeout, (void *) self, 82 irlap_wd_timer_expired); 83} 84 85void irlap_start_backoff_timer(struct irlap_cb *self, int timeout) 86{ 87 irda_start_timer(&self->backoff_timer, timeout, (void *) self, 88 irlap_backoff_timer_expired); 89} 90 91void irlap_start_mbusy_timer(struct irlap_cb *self, int timeout) 92{ 93 irda_start_timer(&self->media_busy_timer, timeout, 94 (void *) self, irlap_media_busy_expired); 95} 96 97void irlap_stop_mbusy_timer(struct irlap_cb *self) 98{ 99 /* If timer is activated, kill it! */ 100 del_timer(&self->media_busy_timer); 101 102 /* If we are in NDM, there is a bunch of events in LAP that 103 * that be pending due to the media_busy condition, such as 104 * CONNECT_REQUEST and SEND_UI_FRAME. If we don't generate 105 * an event, they will wait forever... 106 * Jean II */ 107 if (self->state == LAP_NDM) 108 irlap_do_event(self, MEDIA_BUSY_TIMER_EXPIRED, NULL, NULL); 109} 110 111void irlmp_start_watchdog_timer(struct lsap_cb *self, int timeout) 112{ 113 irda_start_timer(&self->watchdog_timer, timeout, (void *) self, 114 irlmp_watchdog_timer_expired); 115} 116 117void irlmp_start_discovery_timer(struct irlmp_cb *self, int timeout) 118{ 119 irda_start_timer(&self->discovery_timer, timeout, (void *) self, 120 irlmp_discovery_timer_expired); 121} 122 123void irlmp_start_idle_timer(struct lap_cb *self, int timeout) 124{ 125 irda_start_timer(&self->idle_timer, timeout, (void *) self, 126 irlmp_idle_timer_expired); 127} 128 129void irlmp_stop_idle_timer(struct lap_cb *self) 130{ 131 /* If timer is activated, kill it! */ 132 del_timer(&self->idle_timer); 133} 134 135/* 136 * Function irlap_slot_timer_expired (data) 137 * 138 * IrLAP slot timer has expired 139 * 140 */ 141static void irlap_slot_timer_expired(void *data) 142{ 143 struct irlap_cb *self = (struct irlap_cb *) data; 144 145 IRDA_ASSERT(self != NULL, return;); 146 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 147 148 irlap_do_event(self, SLOT_TIMER_EXPIRED, NULL, NULL); 149} 150 151/* 152 * Function irlap_query_timer_expired (data) 153 * 154 * IrLAP query timer has expired 155 * 156 */ 157static void irlap_query_timer_expired(void *data) 158{ 159 struct irlap_cb *self = (struct irlap_cb *) data; 160 161 IRDA_ASSERT(self != NULL, return;); 162 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 163 164 irlap_do_event(self, QUERY_TIMER_EXPIRED, NULL, NULL); 165} 166 167/* 168 * Function irda_final_timer_expired (data) 169 * 170 * 171 * 172 */ 173static void irlap_final_timer_expired(void *data) 174{ 175 struct irlap_cb *self = (struct irlap_cb *) data; 176 177 IRDA_ASSERT(self != NULL, return;); 178 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 179 180 irlap_do_event(self, FINAL_TIMER_EXPIRED, NULL, NULL); 181} 182 183/* 184 * Function irda_wd_timer_expired (data) 185 * 186 * 187 * 188 */ 189static void irlap_wd_timer_expired(void *data) 190{ 191 struct irlap_cb *self = (struct irlap_cb *) data; 192 193 IRDA_ASSERT(self != NULL, return;); 194 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 195 196 irlap_do_event(self, WD_TIMER_EXPIRED, NULL, NULL); 197} 198 199/* 200 * Function irda_backoff_timer_expired (data) 201 * 202 * 203 * 204 */ 205static void irlap_backoff_timer_expired(void *data) 206{ 207 struct irlap_cb *self = (struct irlap_cb *) data; 208 209 IRDA_ASSERT(self != NULL, return;); 210 IRDA_ASSERT(self->magic == LAP_MAGIC, return;); 211 212 irlap_do_event(self, BACKOFF_TIMER_EXPIRED, NULL, NULL); 213} 214 215 216/* 217 * Function irtty_media_busy_expired (data) 218 * 219 * 220 */ 221static void irlap_media_busy_expired(void *data) 222{ 223 struct irlap_cb *self = (struct irlap_cb *) data; 224 225 IRDA_ASSERT(self != NULL, return;); 226 227 irda_device_set_media_busy(self->netdev, FALSE); 228 /* Note : the LAP event will be send in irlap_stop_mbusy_timer(), 229 * to catch other cases where the flag is cleared (for example 230 * after a discovery) - Jean II */ 231} 232