]> git.saurik.com Git - apple/xnu.git/blob - bsd/netat/adsp_Timer.c
9f551fd0eda0eef8f75a0c343f448242a6f5b074
[apple/xnu.git] / bsd / netat / adsp_Timer.c
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 <netat/sysglue.h>
55 #include <netat/appletalk.h>
56 #include <netat/at_pcb.h>
57 #include <netat/debug.h>
58 #include <netat/adsp.h>
59 #include <netat/adsp_internal.h>
60
61 void TimerTick();
62
63 /*
64 * TrashSession
65 *
66 * Cleanly abort a session that might be open. Called if probe timer expires,
67 * or from AppleTalk event handler (close or network gone away)
68 *
69 * Only call if the session is active (I.e. not for closed or listeners)
70 *
71 * INPUTS:
72 * session pointer
73 * OUTPUTS:
74 * none
75 */
76 void TrashSession(sp) /* (CCBPtr sp) */
77 CCBPtr sp;
78 {
79
80 sp->userFlags |= eTearDown;
81 sp->removing = 1;
82 sp->state = sClosed;
83
84 DoClose(sp, errAborted, 1);
85 }
86
87
88 /*
89 * DoTimerElem
90 *
91 * INPUTS:
92 *
93 * OUTPUTS:
94 *
95 */
96 void DoTimerElem(t) /* (TimerElemPtr t) */
97 TimerElemPtr t;
98 {
99 CCBPtr sp;
100
101 sp = (CCBPtr)((Ptr)t - t->type); /* Recover stream pointer for this guy */
102
103 if (t->type == kFlushTimerType) { /* flush write data time just fired */
104 if (sp->sData) { /* If there's any data, flush it. */
105 sp->writeFlush = 1;
106 goto send;
107 }
108 } else if (t->type == kRetryTimerType) {
109 if (sp->waitingAck) {
110
111 sp->waitingAck = 0;
112 sp->sendSeq = sp->firstRtmtSeq;
113 sp->pktSendCnt = 0;
114 sp->resentData = 1; /* Had to resend data */
115 sp->noXmitFlow = 1; /* Don't incr. max packets. */
116
117 if ((sp->pktSendMax /= 2) == 0) /* Back off on max # packets
118 * sent */
119 sp->pktSendMax = 1;
120
121 if ((sp->roundTrip *= 2) > sp->probeInterval)
122 sp->roundTrip = sp->probeInterval;
123 sp->rtmtInterval = sp->roundTrip + ((short)2 *
124 (short)sp->deviation);
125 goto send;
126 }
127 } else if (t->type == kAttnTimerType) {
128 if (sp->sapb) { /* Unacknowledged attn pkt */
129 sp->sendAttnData = 1;
130 goto send;
131 }
132 } else if (t->type == kResetTimerType) {
133 if (sp->frpb) { /* Unacknowledged forward reset */
134 sp->sendCtl |= B_CTL_FRESET;
135 goto send;
136 }
137 } else if (t->type == kProbeTimerType) {
138 if (sp->state == sOpen || sp->state == sClosing) {
139 if (--sp->probeCntr == 0) { /* Connection died */
140 TrashSession(sp);
141 return;
142 } else {
143 InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer,
144 sp->probeInterval);
145 sp->sendCtl |= B_CTL_PROBE;
146 goto send;
147 }
148 } else if (sp->state == sOpening) {
149 if ((sp->openState == O_STATE_OPENWAIT) ||
150 (sp->openState == O_STATE_ESTABLISHED))
151 {
152 if (--sp->openRetrys == 0) { /* Oops, didn't open */
153 sp->state = sClosed;
154 DoClose(sp, errOpening, 1);
155 return;
156 } /* open failed */
157 else /* Send packet again */
158 {
159 sp->sendCtl |= (sp->openState == O_STATE_OPENWAIT) ?
160 B_CTL_OREQ : B_CTL_OREQACK;
161 goto send;
162 }
163 } /* we're opening */
164 }
165 }
166
167 else {
168 dPrintf(D_M_ADSP, D_L_ERROR, ("DoTimerElem:Unknown timer type!\n"));
169 }
170
171 return;
172
173 send:
174 CheckSend(sp);
175 }
176
177 void TimerTick_funnel(void *arg)
178 {
179 atalk_lock();
180 TimerTick();
181 atalk_unlock();
182 }
183
184 static StopTimer;
185
186 /*
187 * TimerTick
188 *
189 * Called 6 times per second
190 * INPUTS:
191 *
192 * OUTPUTS:
193 *
194 */
195 void TimerTick() /* (void) */
196 {
197
198 if (StopTimer) {
199 return;
200 }
201 TimerQueueTick(&adspGlobal.slowTimers);
202 TimerQueueTick(&adspGlobal.fastTimers);
203 timeout(TimerTick_funnel, (caddr_t)0, HZ/6);
204 }
205
206 void TimerStop()
207 {
208 StopTimer = 1;
209 untimeout(TimerTick_funnel, (caddr_t) 0);
210 }