]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netat/adsp.c
622b7845448de31f000a0bf6a86e6cf774f00dd4
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 * 06/29/95 - Modified to handle flow control for writing (Tuyen Nguyen)
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>
49 #include <netat/sysglue.h>
50 #include <netat/appletalk.h>
51 #include <netat/at_pcb.h>
52 #include <netat/ddp.h>
53 #include <netat/adsp.h>
54 #include <netat/adsp_internal.h>
57 struct adsp_debug adsp_dtable
[1025];
61 extern atlock_t adspgen_lock
;
64 register gref_t
*gref
; /* READ queue */
69 if (!(ccb_mp
= gbuf_alloc(sizeof(CCB
), PRI_LO
))) {
72 bzero((caddr_t
) gbuf_rptr(ccb_mp
), sizeof(CCB
));
73 gbuf_wset(ccb_mp
,sizeof(CCB
));
74 gref
->info
= (caddr_t
) ccb_mp
;
75 sp
= (CCBPtr
)gbuf_rptr(((gbuf_t
*)gref
->info
));
77 sp
->pid
= gref
->pid
; /* save the caller process pointer */
78 sp
->gref
= gref
; /* save a back pointer to the WRITE queue */
79 sp
->sp_mp
= ccb_mp
; /* and its message block */
81 ATLOCKINIT(sp
->lockClose
);
82 ATLOCKINIT(sp
->lockRemove
);
87 register gref_t
*gref
; /* READ queue */
92 ATDISABLE(l
, adspgen_lock
);
94 sp
= (CCBPtr
)gbuf_rptr(((gbuf_t
*)gref
->info
));
95 ATDISABLE(s
, sp
->lock
);
96 ATENABLE(s
, adspgen_lock
);
97 /* Tells completion routine of close */
98 /* packet to remove us. */
100 if (sp
->state
== sPassive
|| sp
->state
== sClosed
||
101 sp
->state
== sOpening
|| sp
->state
== sListening
) {
102 ATENABLE(l
, sp
->lock
);
103 if (sp
->state
== sListening
)
104 CompleteQueue(&sp
->opb
, errAborted
);
105 sp
->removing
= 1; /* Prevent allowing another dspClose. */
106 DoClose(sp
, errAborted
, 0); /* will remove CCB */
108 } else { /* sClosing & sOpen */
109 sp
->state
= sClosing
;
111 ATENABLE(l
, sp
->lock
);
113 if (CheckOkToClose(sp
)) { /* going to close */
114 sp
->sendCtl
= B_CTL_CLOSE
; /* Send close advice */
116 CheckSend(sp
); /* try one more time to send out data */
117 if (sp
->state
!= sClosed
)
118 sp
->sendCtl
= B_CTL_CLOSE
; /* Setup to send close advice */
120 CheckSend(sp
); /* and force out the close */
121 ATDISABLE(s
, sp
->lock
);
122 sp
->removing
= 1; /* Prevent allowing another dspClose. */
124 ATENABLE(s
, sp
->lock
);
125 DoClose(sp
, errAborted
, 0); /* to closed and remove CCB */
127 ATENABLE(l
, adspgen_lock
);
133 adspWriteHandler(gref
, mp
)
134 gref_t
*gref
; /* WRITE queue */
138 register ioc_t
*iocbp
;
139 register struct adspcmd
*ap
;
143 switch(gbuf_type(mp
)) {
145 if (gref
->info
== 0) {
150 * Fill in the global stuff
152 ap
= (struct adspcmd
*)gbuf_rptr(mp
);
156 sp
= (void *)gbuf_rptr(((gbuf_t
*)gref
->info
));
159 if ((error
= adspWrite(sp
, ap
)))
163 if ((error
= adspAttention(sp
, ap
)))
168 if (gref
->info
== 0) {
169 adspioc_ack(EPROTOTYPE
, mp
, gref
);
172 iocbp
= (ioc_t
*) gbuf_rptr(mp
);
173 if (ADSP_IOCTL(iocbp
->ioc_cmd
)) {
174 iocbp
->ioc_count
= sizeof(*ap
) - 1;
175 if (gbuf_cont(mp
) == 0) {
176 adspioc_ack(EINVAL
, mp
, gref
);
179 ap
= (struct adspcmd
*) gbuf_rptr(gbuf_cont(mp
));
181 ap
->ioc
= (caddr_t
) mp
;
182 ap
->mp
= gbuf_cont(mp
); /* request head */
185 if ((gref
->info
== 0) && ((iocbp
->ioc_cmd
!= ADSPOPEN
) &&
186 (iocbp
->ioc_cmd
!= ADSPCLLISTEN
))) {
187 ap
->ioResult
= errState
;
189 adspioc_ack(EINVAL
, mp
, gref
);
193 return(STR_PUTNEXT
); /* pass it on down */
194 sp
= (void *)gbuf_rptr(((gbuf_t
*)gref
->info
));
195 switch(iocbp
->ioc_cmd
) {
198 ap
->socket
= ((CCBPtr
)sp
)->localSocket
;
199 flag
= (adspMode(ap
) == ocAccept
) ? 1 : 0;
200 if (flag
&& ap
->socket
) {
201 if (adspDeassignSocket((CCBPtr
)sp
) >= 0)
204 if ((ap
->socket
== 0) &&
206 (at_socket
)adspAssignSocket(gref
, flag
)) == 0)) {
207 adspioc_ack(EADDRNOTAVAIL
, mp
, gref
);
210 ap
->csCode
= iocbp
->ioc_cmd
== ADSPOPEN
? dspInit
: dspCLInit
;
211 if ((error
= adspInit(sp
, ap
)) == 0) {
214 /* and open the connection */
215 ap
->csCode
= dspOpen
;
216 error
= adspOpen(sp
, ap
);
220 ap
->csCode
= dspCLListen
;
221 error
= adspCLListen(sp
, ap
);
226 adspioc_ack(error
, mp
, gref
); /* if this failed req complete */
229 ap
->csCode
= dspClose
;
230 if ((error
= adspClose(sp
, ap
))) {
231 adspioc_ack(error
, mp
, gref
);
236 ap
->csCode
= dspCLRemove
;
237 error
= adspClose(sp
, ap
);
238 adspioc_ack(error
, mp
, gref
);
241 ap
->csCode
= dspCLDeny
;
242 if ((error
= adspCLDeny(sp
, ap
))) {
243 adspioc_ack(error
, mp
, gref
);
247 ap
->csCode
= dspStatus
;
248 if ((error
= adspStatus(sp
, ap
))) {
249 adspioc_ack(error
, mp
, gref
);
253 ap
->csCode
= dspRead
;
254 if ((error
= adspRead(sp
, ap
))) {
255 adspioc_ack(error
, mp
, gref
);
259 ap
->csCode
= dspAttention
;
260 if ((error
= adspReadAttention(sp
, ap
))) {
261 adspioc_ack(error
, mp
, gref
);
265 ap
->csCode
= dspOptions
;
266 if ((error
= adspOptions(sp
, ap
))) {
267 adspioc_ack(error
, mp
, gref
);
271 ap
->csCode
= dspReset
;
272 if ((error
= adspReset(sp
, ap
))) {
273 adspioc_ack(error
, mp
, gref
);
277 ap
->csCode
= dspNewCID
;
278 if ((error
= adspNewCID(sp
, ap
))) {
279 adspioc_ack(error
, mp
, gref
);
283 return(STR_PUTNEXT
); /* pass it on down */
293 adspReadHandler(gref
, mp
)
299 switch(gbuf_type(mp
)) {
301 if ((error
= adspPacket(gref
, mp
))) {
318 * This procedure a formats a DDP datagram header and calls the
319 * DDP module to queue it for routing and transmission according to
320 * the DDP parameters. We always take control of the datagram;
321 * if there is an error we free it, otherwise we pass it to the next
322 * layer. We don't need to set the src address fileds because the
323 * DDP layer fills these in for us.
326 * ret_status = adsp_sendddp(q, sp, mp, length, dstnetaddr, ddptype);
329 * sp Caller stream pointer
330 * mp gbuf_t chain containing the datagram to transmit
331 * The first mblk contains the ADSP header and space
332 * for the DDP header.
333 * length size of data portion of datagram
334 * dstnetaddr address of 4-byte destination internet address
335 * ddptype DDP protocol to assign to the datagram
338 * 0 Procedure successful completed.
339 * EMSGSIZE Specified datagram length is too big.
345 adsp_sendddp(sp
, mp
, length
, dstnetaddr
, ddptype
)
349 AddrUnion
*dstnetaddr
;
358 if (length
> DDP_DATA_SIZE
) {
366 length
= gbuf_msgsize(mp
) - DDPL_FRAME_LEN
;
367 /* Set up the DDP header */
369 ddp
= (DDPX_FRAME
*) gbuf_rptr(mp
);
370 UAS_ASSIGN(ddp
->ddpx_length
, (length
+ DDPL_FRAME_LEN
));
371 UAS_ASSIGN(ddp
->ddpx_cksm
, 0);
374 UAS_ASSIGN(ddp
->ddpx_cksm
, 1);
377 NET_ASSIGN(ddp
->ddpx_dnet
, dstnetaddr
->a
.net
);
378 ddp
->ddpx_dnode
= dstnetaddr
->a
.node
;
379 ddp
->ddpx_source
= sp
? sp
->localSocket
: ddp
->ddpx_dest
;
380 ddp
->ddpx_dest
= dstnetaddr
->a
.socket
;
382 ddp
->ddpx_type
= ddptype
;
397 pidsig(sp->pid, SIGIO);
405 pidsig(sp->pid, SIGURG);