|
|
1.1 root 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: * Change log:
24: * 06/29/95 - Modified to handle flow control for writing (Tuyen Nguyen)
25: * Modified for MP, 1996 by Tuyen Nguyen
26: * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX.
27: */
28: #define RESOLVE_DBG
29: #include <sys/errno.h>
30: #include <sys/types.h>
31: #include <sys/param.h>
32: #include <machine/spl.h>
33: #include <sys/systm.h>
34: #include <sys/kernel.h>
35: #include <sys/proc.h>
36: #include <sys/filedesc.h>
37: #include <sys/fcntl.h>
38: #include <sys/mbuf.h>
39: #include <sys/socket.h>
40:
41: #include <netat/sysglue.h>
42: #include <netat/appletalk.h>
43: #include <netat/at_pcb.h>
44: #include <netat/ddp.h>
45: #include <netat/adsp.h>
46: #include <netat/adsp_internal.h>
47:
48: #ifdef notdefn
49: struct adsp_debug adsp_dtable[1025];
50: int ad_entry = 0;
51: #endif
52:
53: extern atlock_t adspgen_lock;
54:
55: adspAllocateCCB(gref)
56: register gref_t *gref; /* READ queue */
57: {
58: gbuf_t *ccb_mp;
59: register CCBPtr sp;
60:
61: if (!(ccb_mp = gbuf_alloc(sizeof(CCB), PRI_LO))) {
62: return (0);
63: }
64: bzero((caddr_t) gbuf_rptr(ccb_mp), sizeof(CCB));
65: gbuf_wset(ccb_mp,sizeof(CCB));
66: gref->info = (caddr_t) ccb_mp;
67: sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info));
68:
69: sp->pid = gref->pid; /* save the caller process pointer */
70: sp->gref = gref; /* save a back pointer to the WRITE queue */
71: sp->sp_mp = ccb_mp; /* and its message block */
72: ATLOCKINIT(sp->lock);
73: ATLOCKINIT(sp->lockClose);
74: ATLOCKINIT(sp->lockRemove);
75: return 1;
76: }
77:
78: adspRelease(gref)
79: register gref_t *gref; /* READ queue */
80: {
81: register CCBPtr sp;
82: int s, l;
83:
84: ATDISABLE(l, adspgen_lock);
85: if (gref->info) {
86: sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info));
87: ATDISABLE(s, sp->lock);
88: ATENABLE(s, adspgen_lock);
89: /* Tells completion routine of close */
90: /* packet to remove us. */
91:
92: if (sp->state == sPassive || sp->state == sClosed ||
93: sp->state == sOpening || sp->state == sListening) {
94: ATENABLE(l, sp->lock);
95: if (sp->state == sListening)
96: CompleteQueue(&sp->opb, errAborted);
97: sp->removing = 1; /* Prevent allowing another dspClose. */
98: DoClose(sp, errAborted, 0); /* will remove CCB */
99: return 0;
100: } else { /* sClosing & sOpen */
101: sp->state = sClosing;
102: }
103: ATENABLE(l, sp->lock);
104:
105: if (CheckOkToClose(sp)) { /* going to close */
106: sp->sendCtl = B_CTL_CLOSE; /* Send close advice */
107: } else {
108: CheckSend(sp); /* try one more time to send out data */
109: if (sp->state != sClosed)
110: sp->sendCtl = B_CTL_CLOSE; /* Setup to send close advice */
111: }
112: CheckSend(sp); /* and force out the close */
113: ATDISABLE(s, sp->lock);
114: sp->removing = 1; /* Prevent allowing another dspClose. */
115: sp->state = sClosed;
116: ATENABLE(s, sp->lock);
117: DoClose(sp, errAborted, 0); /* to closed and remove CCB */
118: } else
119: ATENABLE(l, adspgen_lock);
120: }
121:
122:
123:
124:
125: adspWriteHandler(gref, mp)
126: gref_t *gref; /* WRITE queue */
127: gbuf_t *mp;
128: {
129:
130: register ioc_t *iocbp;
131: register struct adspcmd *ap;
132: int error, flag;
133: void *sp;
134:
135: switch(gbuf_type(mp)) {
136: case MSG_DATA:
137: if (gref->info == 0) {
138: gbuf_freem(mp);
139: return(STR_IGNORE);
140: }
141: /*
142: * Fill in the global stuff
143: */
144: ap = (struct adspcmd *)gbuf_rptr(mp);
145: ap->gref = gref;
146: ap->ioc = 0;
147: ap->mp = mp;
148: sp = (void *)gbuf_rptr(((gbuf_t *)gref->info));
149: switch(ap->csCode) {
150: case dspWrite:
151: if ((error = adspWrite(sp, ap)))
152: gbuf_freem(mp);
153: return(STR_IGNORE);
154: case dspAttention:
155: if ((error = adspAttention(sp, ap)))
156: gbuf_freem(mp);
157: return(STR_IGNORE);
158: }
159: case MSG_IOCTL:
160: if (gref->info == 0) {
161: adspioc_ack(EPROTO, mp, gref);
162: return(STR_IGNORE);
163: }
164: iocbp = (ioc_t *) gbuf_rptr(mp);
165: if (ADSP_IOCTL(iocbp->ioc_cmd)) {
166: iocbp->ioc_count = sizeof(*ap) - 1;
167: if (gbuf_cont(mp) == 0) {
168: adspioc_ack(EINVAL, mp, gref);
169: return(STR_IGNORE);
170: }
171: ap = (struct adspcmd *) gbuf_rptr(gbuf_cont(mp));
172: ap->gref = gref;
173: ap->ioc = (caddr_t) mp;
174: ap->mp = gbuf_cont(mp); /* request head */
175: ap->ioResult = 0;
176:
177: if ((gref->info == 0) && ((iocbp->ioc_cmd != ADSPOPEN) &&
178: (iocbp->ioc_cmd != ADSPCLLISTEN))) {
179: ap->ioResult = errState;
180:
181: adspioc_ack(EINVAL, mp, gref);
182: return(STR_IGNORE);
183: }
184: }
185: sp = (void *)gbuf_rptr(((gbuf_t *)gref->info));
186: switch(iocbp->ioc_cmd) {
187: case ADSPOPEN:
188: case ADSPCLLISTEN:
189: ap->socket = ((CCBPtr)sp)->localSocket;
190: flag = (adspMode(ap) == ocAccept) ? 1 : 0;
191: if (flag && ap->socket) {
192: if (adspDeassignSocket((CCBPtr)sp) >= 0)
193: ap->socket = 0;
194: }
195: if ((ap->socket == 0) &&
196: ((ap->socket = (at_socket)adspAssignSocket(gref, flag)) == 0)) {
197: adspioc_ack(EADDRNOTAVAIL, mp, gref);
198: return(STR_IGNORE);
199: }
200: ap->csCode = iocbp->ioc_cmd == ADSPOPEN ? dspInit : dspCLInit;
201: if ((error = adspInit(sp, ap)) == 0) {
202: switch(ap->csCode) {
203: case dspInit:
204: /* and open the connection */
205: ap->csCode = dspOpen;
206: error = adspOpen(sp, ap);
207: break;
208: case dspCLInit:
209: /* ADSPCLLISTEN */
210: ap->csCode = dspCLListen;
211: error = adspCLListen(sp, ap);
212: break;
213: }
214: }
215: if (error)
216: adspioc_ack(error, mp, gref); /* if this failed req complete */
217: return(STR_IGNORE);
218: case ADSPCLOSE:
219: ap->csCode = dspClose;
220: if ((error = adspClose(sp, ap))) {
221: adspioc_ack(error, mp, gref);
222: break;
223: }
224: break;
225: case ADSPCLREMOVE:
226: ap->csCode = dspCLRemove;
227: error = adspClose(sp, ap);
228: adspioc_ack(error, mp, gref);
229: return(STR_IGNORE);
230: case ADSPCLDENY:
231: ap->csCode = dspCLDeny;
232: if ((error = adspCLDeny(sp, ap))) {
233: adspioc_ack(error, mp, gref);
234: }
235: return(STR_IGNORE);
236: case ADSPSTATUS:
237: ap->csCode = dspStatus;
238: if ((error = adspStatus(sp, ap))) {
239: adspioc_ack(error, mp, gref);
240: }
241: return(STR_IGNORE);
242: case ADSPREAD:
243: ap->csCode = dspRead;
244: if ((error = adspRead(sp, ap))) {
245: adspioc_ack(error, mp, gref);
246: }
247: return(STR_IGNORE);
248: case ADSPATTENTION:
249: ap->csCode = dspAttention;
250: if ((error = adspReadAttention(sp, ap))) {
251: adspioc_ack(error, mp, gref);
252: }
253: return(STR_IGNORE);
254: case ADSPOPTIONS:
255: ap->csCode = dspOptions;
256: if ((error = adspOptions(sp, ap))) {
257: adspioc_ack(error, mp, gref);
258: }
259: return(STR_IGNORE);
260: case ADSPRESET:
261: ap->csCode = dspReset;
262: if ((error = adspReset(sp, ap))) {
263: adspioc_ack(error, mp, gref);
264: }
265: return(STR_IGNORE);
266: case ADSPNEWCID:
267: ap->csCode = dspNewCID;
268: if ((error = adspNewCID(sp, ap))) {
269: adspioc_ack(error, mp, gref);
270: }
271: return(STR_IGNORE);
272: default:
273: return(STR_PUTNEXT); /* pass it on down */
274: }
275: return(STR_IGNORE);
276: case MSG_PROTO:
277: default:
278: gbuf_freem(mp);
279: }
280: }
281:
282:
283: adspReadHandler(gref, mp)
284: gref_t *gref;
285: gbuf_t *mp;
286: {
287: int error;
288:
289: switch(gbuf_type(mp)) {
290: case MSG_DATA:
291: if ((error = adspPacket(gref, mp))) {
292: gbuf_freem(mp);
293: }
294: break;
295:
296: case MSG_IOCTL:
297: default:
298: return(STR_PUTNEXT);
299: break;
300: }
301: return(STR_IGNORE);
302: }
303:
304: /*
305: * adsp_sendddp()
306: *
307: * Description:
308: * This procedure a formats a DDP datagram header and calls the
309: * DDP module to queue it for routing and transmission according to
310: * the DDP parameters. We always take control of the datagram;
311: * if there is an error we free it, otherwise we pass it to the next
312: * layer. We don't need to set the src address fileds because the
313: * DDP layer fills these in for us.
314: *
315: * Calling Sequence:
316: * ret_status = adsp_sendddp(q, sp, mp, length, dstnetaddr, ddptype);
317: *
318: * Formal Parameters:
319: * sp Caller stream pointer
320: * mp gbuf_t chain containing the datagram to transmit
321: * The first mblk contains the ADSP header and space
322: * for the DDP header.
323: * length size of data portion of datagram
324: * dstnetaddr address of 4-byte destination internet address
325: * ddptype DDP protocol to assign to the datagram
326: *
327: * Completion Status:
328: * 0 Procedure successful completed.
329: * EMSGSIZE Specified datagram length is too big.
330: *
331: * Side Effects:
332: * NONE
333: */
334:
335: adsp_sendddp(sp, mp, length, dstnetaddr, ddptype)
336: CCBPtr sp;
337: gbuf_t *mp;
338: int length;
339: AddrUnion *dstnetaddr;
340: int ddptype;
341: {
342: DDPX_FRAME *ddp;
343: gbuf_t *mlist = mp;
344:
345: if (mp == 0)
346: return EINVAL;
347:
348: if (length > DDP_DATA_SIZE) {
349: gbuf_freel(mlist);
350: return EMSGSIZE;
351: }
352:
353: while (mp) {
354:
355: if (length == 0)
356: length = gbuf_msgsize(mp) - DDPL_FRAME_LEN;
357: /* Set up the DDP header */
358:
359: ddp = (DDPX_FRAME *) gbuf_rptr(mp);
360: UAS_ASSIGN(ddp->ddpx_length, (length + DDPL_FRAME_LEN));
361: UAS_ASSIGN(ddp->ddpx_cksm, 0);
362: if (sp) {
363: if (sp->useCheckSum)
364: UAS_ASSIGN(ddp->ddpx_cksm, 1);
365: }
366:
367: NET_ASSIGN(ddp->ddpx_dnet, dstnetaddr->a.net);
368: ddp->ddpx_dnode = dstnetaddr->a.node;
369: ddp->ddpx_source = sp ? sp->localSocket : ddp->ddpx_dest;
370: ddp->ddpx_dest = dstnetaddr->a.socket;
371:
372: ddp->ddpx_type = ddptype;
373: length = 0;
374: mp = gbuf_next(mp);
375:
376: }
377:
378: DDP_OUTPUT(mlist);
379: return 0;
380: }
381:
382: void NotifyUser(sp)
383: register CCBPtr sp;
384:
385: {
386: /*
387: pidsig(sp->pid, SIGIO);
388: */
389: }
390:
391: void UrgentUser(sp)
392: register CCBPtr sp;
393: {
394: /*
395: pidsig(sp->pid, SIGURG);
396: */
397: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.