]> git.saurik.com Git - apple/xnu.git/blame - bsd/netat/adsp_Open.c
xnu-792.12.6.tar.gz
[apple/xnu.git] / bsd / netat / adsp_Open.c
CommitLineData
1c79356b 1/*
8ad349bb 2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
1c79356b 3 *
8ad349bb 4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
1c79356b 5 *
8ad349bb
A
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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
1c79356b
A
29 */
30/* adspOpen.c v01.20
31 *
32 * From v01.20 08/23/90 Mike Shoemaker for MacOS
33 * Modified for MP, 1996 by Tuyen Nguyen
34 * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX.
35 */
36
37#include <sys/errno.h>
38#include <sys/types.h>
39#include <sys/param.h>
40#include <machine/spl.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>
43#include <sys/proc.h>
44#include <sys/filedesc.h>
45#include <sys/fcntl.h>
46#include <sys/mbuf.h>
47#include <sys/socket.h>
48#include <sys/socketvar.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
8ad349bb 58extern atlock_t adspgen_lock;
1c79356b
A
59
60/*
61 * NextCID
62 *
63 * Create a unique connection ID.
64 *
65 * INPUTS:
66 * none
67 * OUTPUTS:
68 * unique connection ID
69 */
70unsigned short NextCID()
71{
8ad349bb 72 int s;
1c79356b
A
73 unsigned short num;
74 register CCB *queue;
75
76 while (1) {
8ad349bb 77 ATDISABLE(s, adspgen_lock); /* Disable interrupts */
1c79356b
A
78 num = ++adspGlobal.lastCID;
79 /* qfind_w below is in 68K assembly */
80 /* point to the first element */
81 queue = (CCB *)AT_ADSP_STREAMS;
82 while (queue) {
83 /* and scan .. */
84 if (queue->locCID == num)
85 break;
86 queue = queue->ccbLink;
87 }
8ad349bb 88 ATENABLE(s, adspgen_lock);
1c79356b
A
89 if (queue == (CCBPtr)NULL)
90 break;
91 }
92 return num;
93}
94
95static byte xlateStateTbl[4] = /* The value to be given to the CCB's state. */
96{ /* indexed by ocMode */
97 sOpening, /* ocRequest */
98 sPassive, /* ocPassive */
99 sOpening, /* ocAccept */
100 sOpen /* ocEstablish */
101};
102static byte xlateOpenTbl[4] = /* Value to use for open state. */
103{ /* indexed by ocMode */
104 O_STATE_OPENWAIT, /* ocRequest */
105 O_STATE_LISTEN, /* ocPassive */
106 O_STATE_ESTABLISHED, /* ocAccept */
107 O_STATE_OPEN /* ocEstablish */
108};
109
110/*
111 * adspOpen
112 *
113 * INPUTS:
114 * --> ccbRefNum refnum of connection end
115 * --> remoteCID connection id of remote connection end
116 * --> remoteAddress internet address of remote connection end
117 * --> filterAddress filter for incoming open connection requests
118 * --> sendSeq initial send sequence number to use
119 * --> sendWindow initial size of remote end's receive buffer
120 * --> recvSeq initial receive sequence number to use
121 * --> attnSendSeq initial attention send sequence number
122 * --> attnRecvSeq initial receive sequence number
123 * --> ocMode connection opening mode
124 * --> ocMaximum maximum retries of open connection request
125 *
126 * OUTPUTS:
127 * <-- localCID connection identifier of this connection end
128 * <-- remoteCID connection id of remote connection end
129 * <-- remoteAddress
130 * <-- sendSeq
131 * <-- sendWindow
132 * <-- attnSendSeq
133 *
134 * ERRORS:
135 * errRefNum bad connection refnum
136 * errState connection end must be closed
137 * errOpening open connection attempt failed
138 * errAborted request aborted by a remove or close call
139 */
140int adspOpen(sp, pb) /* (DSPPBPtr pb) */
141 register CCBPtr sp;
142 register struct adspcmd *pb;
143{
144 extern int adsp_pidM[];
145
146 int ocMode;
147 register gbuf_t *mp;
148
149 if (sp == 0) {
150 pb->ioResult = errRefNum; /* Unknown refnum */
151 return EINVAL;
152 }
153
154 if ((sp->state != sClosed) ||
155 (sp->removing)) { /* The CCB must be closed */
156 pb->ioResult = errState;
157 return EALREADY;
158 }
159
160 ocMode = pb->u.openParams.ocMode; /* get a local copy of open mode */
161 if (ocMode == ocRequest)
162 adsp_pidM[pb->socket] = 0;
163
164 /*
165 * Save parameters. Fill in defaults if zero
166 */
167 if (pb->u.openParams.ocInterval)
168 sp->openInterval = pb->u.openParams.ocInterval;
169 else
170 sp->openInterval = ocIntervalDefault;
171
172 if (pb->u.openParams.ocMaximum)
173 sp->openRetrys = pb->u.openParams.ocMaximum;
174 else
175 sp->openRetrys = ocMaximumDefault;
176
177 sp->remoteAddress = *((AddrUnionPtr)&pb->u.openParams.remoteAddress);
178 /* Not used for passive */
179 /*
180 * Clear out send/receive buffers.
181 */
182 if (sp->sbuf_mb) { /* clear the send queue */
183 gbuf_freel(sp->sbuf_mb);
184 sp->sbuf_mb = 0;
185 }
186 if (sp->csbuf_mb) {
187 gbuf_freem(sp->csbuf_mb);
188 sp->csbuf_mb = 0;
189 }
190 if (sp->rbuf_mb) { /* clear the receive queue */
191 gbuf_freel(sp->rbuf_mb);
192 sp->rbuf_mb = 0;
193 }
194 if (sp->crbuf_mb) {
195 gbuf_freem(sp->crbuf_mb);
196 sp->crbuf_mb = 0;
197 }
198
199 sp->rData = 0; /* Flag both buffers as empty */
200 sp->sData = 0;
201 sp->recvQPending = 0; /* No bytes in receive queue */
202
203 /*
204 * Clear all of those pesky flags
205 */
206 sp->userFlags = 0;
207 sp->sendDataAck = 0;
208 sp->sendAttnAck = 0;
209 sp->sendAttnData = 0;
210 sp->callSend = 0;
211 sp->removing = 0;
212 sp->writeFlush = 0;
213
214 /*
215 * Reset round-trip timers
216 */
217 sp->roundTrip = sp->rtmtInterval;
218 sp->deviation = 0;
219
220 /*
221 * Reset stuff for retransmit advice packet
222 */
223 sp->badSeqCnt = 0;
224 /*
225 * Reset flow control variables
226 */
227 sp->pktSendMax = 1; /* Slow start says we should set this to 1 */
228 sp->pktSendCnt = 0;
229 sp->rbufFull = 0;
230 sp->resentData = 0;
231 sp->noXmitFlow = 0;
232 sp->waitingAck = 0;
233
234 /*
235 * Copy required information out of parameter block
236 */
237 if (ocMode == ocAccept || ocMode == ocEstablish) {
238 sp->remCID = pb->u.openParams.remoteCID;
239 sp->sendSeq = sp->firstRtmtSeq = pb->u.openParams.sendSeq;
240 sp->sendWdwSeq = sp->sendSeq + pb->u.openParams.sendWindow;
241 sp->attnSendSeq = pb->u.openParams.attnSendSeq;
242 } else { /* accept or establish */
243 sp->remCID = 0;
244 sp->sendSeq = 0;
245 sp->sendWdwSeq = 0;
246 sp->attnSendSeq = 0;
247 }
248
249 if (ocMode == ocEstablish) { /* Only set these if establish mode */
250 sp->recvSeq = pb->u.openParams.recvSeq;
251 sp->attnRecvSeq = pb->u.openParams.attnRecvSeq;
8ad349bb 252 UAS_ASSIGN(sp->f.CID, sp->locCID); /* Preset the CID in the ADSP header */
1c79356b
A
253 /* This is done elsewhere for all other modes */
254 InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer,
255 sp->probeInterval);
256 } else { /* establish */
257 /* All other modes need a CID assigned */
258 sp->locCID = NextCID();
259 sp->recvSeq = 0;
260 sp->attnRecvSeq = 0;
261 }
262
263 /*
264 * Now set the state variables for this CCB.
265 */
266
267 sp->openState = xlateOpenTbl[ocMode-ocRequest];
268 sp->state = xlateStateTbl[ocMode-ocRequest];
269
270 if (ocMode == ocEstablish) { /* For establish call, we're done */
271 pb->ioResult = 0;
272 adspioc_ack(0, pb->ioc, pb->gref);
273 return 0;
274 }
275
276 pb->qLink = 0; /* Clear link field before putting on queue */
277 mp = gbuf_copym(pb->mp); /* Save parameter block to match later */
278
279 if (mp == 0) {
280 pb->ioResult = errDSPQueueSize;
281 return ENOBUFS;
282 }
283 pb->ioResult = 1; /* not open -> not done */
284 adspioc_ack(0, pb->ioc, pb->gref); /* release user */
285 sp->opb = (struct adspcmd *)gbuf_rptr(mp);
286 sp->opb->ioc = 0; /* unlink saved pb from ioctl block */
287 sp->opb->mp = mp;
288
289 /*
290 * For request & accept, need to send a packet
291 */
292 if ((ocMode == ocRequest) || (ocMode == ocAccept)) {
293 sp->sendCtl |= (1 << (ocMode == ocRequest ?
294 ADSP_CTL_OREQ : ADSP_CTL_OREQACK));
295 CheckSend(sp);
296 }
297 return 0;
298}
299
300int adspMode(pb)
301 register struct adspcmd *pb;
302{
303 return pb->u.openParams.ocMode;
304}