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