1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * Copyright (c) 1990, 1996-1998 Apple Computer, Inc. 30 * All Rights Reserved. 31 */ 32 33/* 34 * Timer.c 35 * 36 * From v01.12 06/22/90 mbs 37 * Modified for MP, 1996 by Tuyen Nguyen 38 * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX. 39 */ 40 41#include <sys/errno.h> 42#include <sys/types.h> 43#include <sys/param.h> 44#include <machine/spl.h> 45#include <sys/systm.h> 46#include <sys/kernel.h> 47#include <sys/proc.h> 48#include <sys/filedesc.h> 49#include <sys/fcntl.h> 50#include <sys/mbuf.h> 51#include <sys/socket.h> 52#include <sys/time.h> 53 54#include <net/if.h> 55 56#include <netat/sysglue.h> 57#include <netat/appletalk.h> 58#include <netat/at_pcb.h> 59#include <netat/at_var.h> 60#include <netat/debug.h> 61#include <netat/adsp.h> 62#include <netat/adsp_internal.h> 63 64 65/* 66 * TrashSession 67 * 68 * Cleanly abort a session that might be open. Called if probe timer expires, 69 * or from AppleTalk event handler (close or network gone away) 70 * 71 * Only call if the session is active (I.e. not for closed or listeners) 72 * 73 * INPUTS: 74 * session pointer 75 * OUTPUTS: 76 * none 77 */ 78void TrashSession(CCBPtr); 79 80void TrashSession(sp) /* (CCBPtr sp) */ 81 CCBPtr sp; 82{ 83 84 sp->userFlags |= eTearDown; 85 sp->removing = 1; 86 sp->state = sClosed; 87 88 DoClose(sp, errAborted, 1); 89} 90 91 92/* 93 * DoTimerElem 94 * 95 * INPUTS: 96 * 97 * OUTPUTS: 98 * 99 */ 100void DoTimerElem(TimerElemPtr); 101 102void DoTimerElem(t) /* (TimerElemPtr t) */ 103 TimerElemPtr t; 104{ 105 CCBPtr sp; 106 107 sp = (CCBPtr)((Ptr)t - t->type); /* Recover stream pointer for this guy */ 108 109 if (t->type == kFlushTimerType) { /* flush write data time just fired */ 110 if (sp->sData) { /* If there's any data, flush it. */ 111 sp->writeFlush = 1; 112 goto send; 113 } 114 } else if (t->type == kRetryTimerType) { 115 if (sp->waitingAck) { 116 117 sp->waitingAck = 0; 118 sp->sendSeq = sp->firstRtmtSeq; 119 sp->pktSendCnt = 0; 120 sp->resentData = 1; /* Had to resend data */ 121 sp->noXmitFlow = 1; /* Don't incr. max packets. */ 122 123 if ((sp->pktSendMax /= 2) == 0) /* Back off on max # packets 124 * sent */ 125 sp->pktSendMax = 1; 126 127 if ((sp->roundTrip *= 2) > sp->probeInterval) 128 sp->roundTrip = sp->probeInterval; 129 sp->rtmtInterval = sp->roundTrip + ((short)2 * 130 (short)sp->deviation); 131 goto send; 132 } 133 } else if (t->type == kAttnTimerType) { 134 if (sp->sapb) { /* Unacknowledged attn pkt */ 135 sp->sendAttnData = 1; 136 goto send; 137 } 138 } else if (t->type == kResetTimerType) { 139 if (sp->frpb) { /* Unacknowledged forward reset */ 140 sp->sendCtl |= B_CTL_FRESET; 141 goto send; 142 } 143 } else if (t->type == kProbeTimerType) { 144 if (sp->state == sOpen || sp->state == sClosing) { 145 if (--sp->probeCntr == 0) { /* Connection died */ 146 TrashSession(sp); 147 return; 148 } else { 149 InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, 150 sp->probeInterval); 151 sp->sendCtl |= B_CTL_PROBE; 152 goto send; 153 } 154 } else if (sp->state == sOpening) { 155 if ((sp->openState == O_STATE_OPENWAIT) || 156 (sp->openState == O_STATE_ESTABLISHED)) 157 { 158 if (--sp->openRetrys == 0) { /* Oops, didn't open */ 159 sp->state = sClosed; 160 DoClose(sp, errOpening, 1); 161 return; 162 } /* open failed */ 163 else /* Send packet again */ 164 { 165 sp->sendCtl |= (sp->openState == O_STATE_OPENWAIT) ? 166 B_CTL_OREQ : B_CTL_OREQACK; 167 goto send; 168 } 169 } /* we're opening */ 170 } 171 } 172 173 else { 174 dPrintf(D_M_ADSP, D_L_ERROR, ("DoTimerElem:Unknown timer type!\n")); 175 } 176 177 return; 178 179send: 180 CheckSend(sp); 181} 182 183void TimerTick_funnel(void *arg); 184 185void TimerTick_funnel(__unused void *arg) 186{ 187 atalk_lock(); 188 TimerTick(); 189 atalk_unlock(); 190} 191 192static int StopTimer; 193 194/* 195 * TimerTick 196 * 197 * Called 6 times per second 198 * INPUTS: 199 * 200 * OUTPUTS: 201 * 202 */ 203void TimerTick() /* (void) */ 204{ 205 206 if (StopTimer) { 207 return; 208 } 209 TimerQueueTick(&adspGlobal.slowTimers); 210 TimerQueueTick(&adspGlobal.fastTimers); 211 timeout(TimerTick_funnel, (caddr_t)0, HZ/6); 212} 213 214void TimerStop() 215{ 216 StopTimer = 1; 217 untimeout(TimerTick_funnel, (caddr_t) 0); 218} 219