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