]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netat/adsp_Open.c
6f2f55a449ac1b7732a2649d7aebf33cc9e997fd
2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
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
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
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.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
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.
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>
44 #include <sys/filedesc.h>
45 #include <sys/fcntl.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
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>
58 extern atlock_t adspgen_lock
;
63 * Create a unique connection ID.
68 * unique connection ID
70 unsigned short NextCID()
77 ATDISABLE(s
, adspgen_lock
); /* Disable interrupts */
78 num
= ++adspGlobal
.lastCID
;
79 /* qfind_w below is in 68K assembly */
80 /* point to the first element */
81 queue
= (CCB
*)AT_ADSP_STREAMS
;
84 if (queue
->locCID
== num
)
86 queue
= queue
->ccbLink
;
88 ATENABLE(s
, adspgen_lock
);
89 if (queue
== (CCBPtr
)NULL
)
95 static 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 */
102 static 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 */
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
127 * <-- localCID connection identifier of this connection end
128 * <-- remoteCID connection id of remote connection end
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
140 int adspOpen(sp
, pb
) /* (DSPPBPtr pb) */
142 register struct adspcmd
*pb
;
144 extern int adsp_pidM
[];
150 pb
->ioResult
= errRefNum
; /* Unknown refnum */
154 if ((sp
->state
!= sClosed
) ||
155 (sp
->removing
)) { /* The CCB must be closed */
156 pb
->ioResult
= errState
;
160 ocMode
= pb
->u
.openParams
.ocMode
; /* get a local copy of open mode */
161 if (ocMode
== ocRequest
)
162 adsp_pidM
[pb
->socket
] = 0;
165 * Save parameters. Fill in defaults if zero
167 if (pb
->u
.openParams
.ocInterval
)
168 sp
->openInterval
= pb
->u
.openParams
.ocInterval
;
170 sp
->openInterval
= ocIntervalDefault
;
172 if (pb
->u
.openParams
.ocMaximum
)
173 sp
->openRetrys
= pb
->u
.openParams
.ocMaximum
;
175 sp
->openRetrys
= ocMaximumDefault
;
177 sp
->remoteAddress
= *((AddrUnionPtr
)&pb
->u
.openParams
.remoteAddress
);
178 /* Not used for passive */
180 * Clear out send/receive buffers.
182 if (sp
->sbuf_mb
) { /* clear the send queue */
183 gbuf_freel(sp
->sbuf_mb
);
187 gbuf_freem(sp
->csbuf_mb
);
190 if (sp
->rbuf_mb
) { /* clear the receive queue */
191 gbuf_freel(sp
->rbuf_mb
);
195 gbuf_freem(sp
->crbuf_mb
);
199 sp
->rData
= 0; /* Flag both buffers as empty */
201 sp
->recvQPending
= 0; /* No bytes in receive queue */
204 * Clear all of those pesky flags
209 sp
->sendAttnData
= 0;
215 * Reset round-trip timers
217 sp
->roundTrip
= sp
->rtmtInterval
;
221 * Reset stuff for retransmit advice packet
225 * Reset flow control variables
227 sp
->pktSendMax
= 1; /* Slow start says we should set this to 1 */
235 * Copy required information out of parameter block
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 */
249 if (ocMode
== ocEstablish
) { /* Only set these if establish mode */
250 sp
->recvSeq
= pb
->u
.openParams
.recvSeq
;
251 sp
->attnRecvSeq
= pb
->u
.openParams
.attnRecvSeq
;
252 UAS_ASSIGN(sp
->f
.CID
, sp
->locCID
); /* Preset the CID in the ADSP header */
253 /* This is done elsewhere for all other modes */
254 InsertTimerElem(&adspGlobal
.slowTimers
, &sp
->ProbeTimer
,
256 } else { /* establish */
257 /* All other modes need a CID assigned */
258 sp
->locCID
= NextCID();
264 * Now set the state variables for this CCB.
267 sp
->openState
= xlateOpenTbl
[ocMode
-ocRequest
];
268 sp
->state
= xlateStateTbl
[ocMode
-ocRequest
];
270 if (ocMode
== ocEstablish
) { /* For establish call, we're done */
272 adspioc_ack(0, pb
->ioc
, pb
->gref
);
276 pb
->qLink
= 0; /* Clear link field before putting on queue */
277 mp
= gbuf_copym(pb
->mp
); /* Save parameter block to match later */
280 pb
->ioResult
= errDSPQueueSize
;
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 */
290 * For request & accept, need to send a packet
292 if ((ocMode
== ocRequest
) || (ocMode
== ocAccept
)) {
293 sp
->sendCtl
|= (1 << (ocMode
== ocRequest
?
294 ADSP_CTL_OREQ
: ADSP_CTL_OREQACK
));
301 register struct adspcmd
*pb
;
303 return pb
->u
.openParams
.ocMode
;