]> git.saurik.com Git - apple/xnu.git/blob - bsd/netat/adsp_Timer.c
xnu-344.49.tar.gz
[apple/xnu.git] / bsd / netat / adsp_Timer.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * Copyright (c) 1990, 1996-1998 Apple Computer, Inc.
27 * All Rights Reserved.
28 */
29
30 /*
31 * Timer.c
32 *
33 * From v01.12 06/22/90 mbs
34 * Modified for MP, 1996 by Tuyen Nguyen
35 * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX.
36 */
37
38 #include <sys/errno.h>
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <machine/spl.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/proc.h>
45 #include <sys/filedesc.h>
46 #include <sys/fcntl.h>
47 #include <sys/mbuf.h>
48 #include <sys/socket.h>
49 #include <sys/time.h>
50
51 #include <netat/sysglue.h>
52 #include <netat/appletalk.h>
53 #include <netat/at_pcb.h>
54 #include <netat/debug.h>
55 #include <netat/adsp.h>
56 #include <netat/adsp_internal.h>
57
58 /*
59 * TrashSession
60 *
61 * Cleanly abort a session that might be open. Called if probe timer expires,
62 * or from AppleTalk event handler (close or network gone away)
63 *
64 * Only call if the session is active (I.e. not for closed or listeners)
65 *
66 * INPUTS:
67 * session pointer
68 * OUTPUTS:
69 * none
70 */
71 void TrashSession(sp) /* (CCBPtr sp) */
72 CCBPtr sp;
73 {
74 int s;
75
76 ATDISABLE(s, sp->lock);
77 sp->userFlags |= eTearDown;
78 sp->removing = 1;
79 sp->state = sClosed;
80 ATENABLE(s, sp->lock);
81
82 DoClose(sp, errAborted, 1);
83 }
84
85
86 /*
87 * DoTimerElem
88 *
89 * INPUTS:
90 *
91 * OUTPUTS:
92 *
93 */
94 void DoTimerElem(t) /* (TimerElemPtr t) */
95 TimerElemPtr t;
96 {
97 CCBPtr sp;
98 int s;
99
100 sp = (CCBPtr)((Ptr)t - t->type); /* Recover stream pointer for this guy */
101 ATDISABLE(s, sp->lock);
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 ATENABLE(s, sp->lock);
141 TrashSession(sp);
142 return;
143 } else {
144 InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer,
145 sp->probeInterval);
146 sp->sendCtl |= B_CTL_PROBE;
147 goto send;
148 }
149 } else if (sp->state == sOpening) {
150 if ((sp->openState == O_STATE_OPENWAIT) ||
151 (sp->openState == O_STATE_ESTABLISHED))
152 {
153 if (--sp->openRetrys == 0) { /* Oops, didn't open */
154 sp->state = sClosed;
155 ATENABLE(s, sp->lock);
156 DoClose(sp, errOpening, 1);
157 return;
158 } /* open failed */
159 else /* Send packet again */
160 {
161 sp->sendCtl |= (sp->openState == O_STATE_OPENWAIT) ?
162 B_CTL_OREQ : B_CTL_OREQACK;
163 goto send;
164 }
165 } /* we're opening */
166 }
167 }
168
169 else {
170 dPrintf(D_M_ADSP, D_L_ERROR, ("DoTimerElem:Unknown timer type!\n"));
171 }
172
173 ATENABLE(s, sp->lock);
174 return;
175
176 send:
177 ATENABLE(s, sp->lock);
178 CheckSend(sp);
179 }
180
181 void TimerTick_funnel()
182 {
183 thread_funnel_set(network_flock, TRUE);
184 TimerTick();
185 thread_funnel_set(network_flock, FALSE);
186 }
187
188 static StopTimer;
189
190 /*
191 * TimerTick
192 *
193 * Called 6 times per second
194 * INPUTS:
195 *
196 * OUTPUTS:
197 *
198 */
199 void TimerTick() /* (void) */
200 {
201
202 if (StopTimer) {
203 return;
204 }
205 TimerQueueTick(&adspGlobal.slowTimers);
206 TimerQueueTick(&adspGlobal.fastTimers);
207 timeout(TimerTick_funnel, (caddr_t)0, HZ/6);
208 }
209
210 void TimerStop()
211 {
212 StopTimer = 1;
213 untimeout(TimerTick_funnel, (caddr_t) 0);
214 }