|
|
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: /*
26: * Copyright (c) 1996-1998 Apple Computer, Inc.
27: * All Rights Reserved.
28: *
29: * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC.
30: * The copyright notice above does not evidence any actual or
31: * intended publication of such source code.
32: */
33:
34: #include <appletalk.h>
35: #include <atp.h>
36: #include <ddp.h>
37: #include <at_atp.h>
38: #include <atp_inc.h>
39:
40: static void atp_trans_complete();
41:
42: /*
43: * Decide what to do about received messages
44: * Version 1.7 of atp_read.c on 89/02/09 17:53:16
45: */
46:
47: int atp_treq_event(gref)
48: register gref_t *gref;
49: {
50: register gbuf_t *m;
51: register struct atp_state *atp;
52:
53: atp = (struct atp_state *)gref->info;
54: if (atp->dflag)
55: atp = (struct atp_state *)atp->atp_msgq;
56:
57: if (atp->dflag) {
58: if ((m = gbuf_alloc(sizeof(ioc_t), PRI_HI)) != NULL) {
59: gbuf_set_type(m, MSG_IOCTL);
60: gbuf_wset(m,sizeof(ioc_t));
61: ((ioc_t *)gbuf_rptr(m))->ioc_cmd = AT_ATP_GET_POLL;
62: atp_wput(gref, m);
63: }
64: }
65: else if ((m = gbuf_alloc(1, PRI_HI)) != NULL) {
66: *gbuf_rptr(m) = 0;
67: gbuf_wset(m,1);
68: atalk_putnext(gref, m);
69: }
70:
71: if (m == 0)
72: atalk_timeout(atp_treq_event, gref, 10);
73: }
74:
75: void atp_rput(gref, m)
76: gref_t *gref;
77: gbuf_t *m;
78: {
79: register at_atp_t *athp;
80: register struct atp_state *atp;
81: register int s, s_gen;
82: gbuf_t *m_asp = NULL;
83:
84: atp = (struct atp_state *)gref->info;
85: if (atp->dflag)
86: atp = (struct atp_state *)atp->atp_msgq;
87:
88: switch(gbuf_type(m)) {
89: case MSG_DATA:
90: /*
91: * Decode the message, make sure it is an atp
92: * message
93: */
94: if (((AT_DDP_HDR(m))->type != ATP_DDP_TYPE) ||
95: (atp->atp_flags & ATP_CLOSING)) {
96: gbuf_freem(m);
97: dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR),
98: ("atp_rput: dropping MSG, not atp\n"));
99: break;
100: }
101:
102: athp = AT_ATP_HDR(m);
103: dPrintf(D_M_ATP_LOW, D_L_INPUT,
104: ("atp_rput MSG_DATA: %s (%d)\n",
105: (athp->cmd == ATP_CMD_TRESP)? "TRESP":
106: (athp->cmd == ATP_CMD_TREL)? "TREL":
107: (athp->cmd == ATP_CMD_TREQ)? "TREQ": "unknown",
108: athp->cmd));
109:
110: switch (athp->cmd) {
111:
112: case ATP_CMD_TRESP:
113: {
114: register struct atp_trans *trp;
115: register int seqno;
116: register at_ddp_t *ddp;
117:
118: /*
119: * we just got a response, find the trans record
120: */
121:
122: ATDISABLE(s, atp->atp_lock);
123: for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) {
124: if (trp->tr_tid == UAS_VALUE(athp->tid))
125: break;
126: }
127:
128: /*
129: * If we can't find one then ignore the message
130: */
131: seqno = athp->bitmap;
132: if (trp == NULL) {
133: ATENABLE(s, atp->atp_lock);
134: ddp = AT_DDP_HDR(m);
135: dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR),
136: ("atp_rput: dropping TRESP, no trp,tid=%d,loc=%d,rem=%d.%d,seqno=%d\n",
137: UAS_VALUE(athp->tid),
138: ddp->dst_socket,ddp->src_node,ddp->src_socket,seqno));
139: gbuf_freem(m);
140: return;
141: }
142:
143: /*
144: * If no longer valid, drop it
145: */
146: if (trp->tr_state == TRANS_FAILED) {
147: ATENABLE(s, atp->atp_lock);
148: ddp = AT_DDP_HDR(m);
149: dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR),
150: ("atp_rput: dropping TRESP, failed trp,tid=%d,loc=%d,rem=%d.%d\n",
151: UAS_VALUE(athp->tid),
152: ddp->dst_socket, ddp->src_node, ddp->src_socket));
153: gbuf_freem(m);
154: return;
155: }
156:
157: /*
158: * If we have already received it, ignore it
159: */
160: if (!(trp->tr_bitmap&atp_mask[seqno]) || trp->tr_rcv[seqno]) {
161: ATENABLE(s, atp->atp_lock);
162: ddp = AT_DDP_HDR(m);
163: dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR),
164: ("atp_rput: dropping TRESP, duplicate,tid=%d,loc=%d,rem=%d.%d,seqno=%d\n",
165: UAS_VALUE(athp->tid),
166: ddp->dst_socket, ddp->src_node, ddp->src_socket, seqno));
167: gbuf_freem(m);
168: return;
169: }
170:
171: /*
172: * Update the received packet bitmap
173: */
174: if (athp->eom)
175: trp->tr_bitmap &= atp_lomask[seqno];
176: else
177: trp->tr_bitmap &= ~atp_mask[seqno];
178:
179: /*
180: * Save the message in the trans record
181: */
182: trp->tr_rcv[seqno] = m;
183:
184: /*
185: * If it isn't the first message then
186: * can the header
187: */
188: if (seqno)
189: gbuf_rinc(m,DDP_X_HDR_SIZE);
190:
191: /*
192: * If we now have all the responses then return
193: * the message to the user
194: */
195: if (trp->tr_bitmap == 0) {
196: ATENABLE(s, atp->atp_lock);
197:
198: /*
199: * Cancel the request timer and any
200: * pending transmits
201: */
202: atp_untimout(atp_req_timeout, trp);
203:
204: /*
205: * Send the results back to the user
206: */
207: atp_x_done(trp);
208: return;
209: }
210: if (athp->sts) {
211: /*
212: * If they want treq again, send them
213: */
214: ATENABLE(s, atp->atp_lock);
215: atp_untimout(atp_req_timeout, trp);
216: atp_send(trp);
217: return;
218: }
219: ATENABLE(s, atp->atp_lock);
220: return;
221: }
222:
223: case ATP_CMD_TREL:
224: { register struct atp_rcb *rcbp;
225: register at_ddp_t *ddp;
226:
227: /*
228: * Search for a matching transaction
229: */
230: ddp = AT_DDP_HDR(m);
231:
232: ATDISABLE(s, atp->atp_lock);
233: for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) {
234: if (rcbp->rc_tid == UAS_VALUE(athp->tid) &&
235: rcbp->rc_socket.node == ddp->src_node &&
236: rcbp->rc_socket.net == NET_VALUE(ddp->src_net) &&
237: rcbp->rc_socket.socket == ddp->src_socket) {
238: /*
239: * Mark the rcb released
240: */
241: rcbp->rc_not_sent_bitmap = 0;
242: if (rcbp->rc_state == RCB_SENDING)
243: rcbp->rc_state = RCB_RELEASED;
244: else
245: {
246: ddp = 0;
247: atp_rcb_free(rcbp);
248: ATENABLE(s, atp->atp_lock);
249: }
250: break;
251: }
252: }
253:
254: if (ddp)
255: ATENABLE(s, atp->atp_lock);
256: gbuf_freem(m);
257: return;
258: }
259:
260:
261: case ATP_CMD_TREQ:
262: { register struct atp_rcb *rcbp;
263: register at_ddp_t *ddp;
264: gbuf_t *m2;
265:
266: /*
267: * If it is a request message, first
268: * check to see
269: * if matches something in our active
270: * request queue
271: */
272: ddp = AT_DDP_HDR(m);
273:
274: ATDISABLE(s, atp->atp_lock);
275: for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) {
276: if (rcbp->rc_tid == UAS_VALUE(athp->tid) &&
277: rcbp->rc_socket.node == ddp->src_node &&
278: rcbp->rc_socket.net == NET_VALUE(ddp->src_net) &&
279: rcbp->rc_socket.socket == ddp->src_socket)
280: break;
281: }
282: /*
283: * If this is a new req then do
284: * something with it
285: */
286: if (rcbp == NULL) {
287: /*
288: * see if it matches something in the
289: * attached request queue
290: * if it does, just release the message
291: * and go on about our buisness
292: */
293: /* we just did this, why do again? -jjs 4-10-95 */
294: for (rcbp = atp->atp_attached.head; rcbp; rcbp = rcbp->rc_list.next) {
295: if (rcbp->rc_tid == UAS_VALUE(athp->tid) &&
296: rcbp->rc_socket.node == ddp->src_node &&
297: rcbp->rc_socket.net == NET_VALUE(ddp->src_net) &&
298: rcbp->rc_socket.socket == ddp->src_socket) {
299: ATENABLE(s, atp->atp_lock);
300: gbuf_freem(m);
301: dPrintf(D_M_ATP_LOW, D_L_INPUT,
302: ("atp_rput: dropping TREQ, matches req queue\n"));
303: return;
304: }
305: }
306:
307: /*
308: * assume someone is interested in
309: * in an asynchronous incoming request
310: */
311: ATENABLE(s, atp->atp_lock);
312: if ((rcbp = atp_rcb_alloc(atp)) == NULL) {
313: gbuf_freem(m);
314: return;
315: }
316: rcbp->rc_state = RCB_UNQUEUED;
317: ATDISABLE(s, atp->atp_lock);
318:
319: rcbp->rc_local_node = ddp->dst_node;
320: NET_NET(rcbp->rc_local_net, ddp->dst_net);
321: rcbp->rc_socket.socket = ddp->src_socket;
322: rcbp->rc_socket.node = ddp->src_node;
323: rcbp->rc_socket.net = NET_VALUE(ddp->src_net);
324: rcbp->rc_tid = UAS_VALUE(athp->tid);
325: rcbp->rc_bitmap = athp->bitmap;
326: rcbp->rc_not_sent_bitmap = athp->bitmap;
327: rcbp->rc_xo = athp->xo;
328: /*
329: * if async then send it as
330: * data
331: * otherwise, it is a synchronous ioctl so
332: * complete it
333: */
334: if (atp->dflag) { /* for ASP? */
335: if (m2 = gbuf_alloc(sizeof(ioc_t), PRI_HI)) {
336: gbuf_set_type(m2, MSG_DATA);
337: gbuf_wset(m2,sizeof(ioc_t));
338: ((ioc_t *)gbuf_rptr(m2))->ioc_cmd = AT_ATP_GET_POLL;
339: m_asp = m2;
340: }
341: } else if (m2 = gbuf_alloc(1, PRI_HI)) {
342: *gbuf_rptr(m2) = 0;
343: gbuf_wset(m2,1);
344: atalk_putnext(gref, m2);
345: }
346: if (m2 == 0) {
347: dPrintf(D_M_ATP,D_L_WARNING,
348: ("atp_rput: out of buffer for TREQ\n"));
349: atalk_timeout(atp_treq_event, gref, 10);
350: }
351: rcbp->rc_ioctl = m;
352:
353: /*
354: * move it to the attached list
355: */
356: dPrintf(D_M_ATP_LOW, D_L_INPUT,
357: ("atp_rput: moving to attached list\n"));
358: rcbp->rc_state = RCB_PENDING;
359: ATP_Q_APPEND(atp->atp_attached, rcbp, rc_list);
360: if (m_asp != NULL) {
361: ATENABLE(s, atp->atp_lock);
362: atp_req_ind(atp, m_asp);
363: return;
364: }
365: } else {
366: dPrintf(D_M_ATP_LOW, D_L_INPUT,
367: ("atp_rput: found match, state:%d\n",
368: rcbp->rc_state));
369:
370: /*
371: * Otherwise we have found a matching request
372: * look for what to do
373: */
374: switch (rcbp->rc_state) {
375: case RCB_RESPONDING:
376: case RCB_RESPONSE_FULL:
377: /*
378: * If it is one we have in progress
379: * (either have all the responses
380: * or are waiting for them)
381: * update the bitmap and resend
382: * the replies
383: */
384: ATDISABLE(s_gen, atpgen_lock);
385: if (rcbp->rc_timestamp) {
386: rcbp->rc_timestamp = time.tv_sec;
387: if (rcbp->rc_timestamp == 0)
388: rcbp->rc_timestamp = 1;
389: }
390: ATENABLE(s_gen, atpgen_lock);
391: rcbp->rc_bitmap = athp->bitmap;
392: rcbp->rc_not_sent_bitmap = athp->bitmap;
393: ATENABLE(s, atp->atp_lock);
394: gbuf_freem(m);
395: atp_reply(rcbp);
396: return;
397:
398: case RCB_RELEASED:
399: default:
400: /*
401: * If we have a release or
402: * we haven't sent any data yet
403: * ignore the request
404: */
405: ATENABLE(s, atp->atp_lock);
406: gbuf_freem(m);
407: return;
408: }
409: }
410: ATENABLE(s, atp->atp_lock);
411: return;
412: }
413:
414: default:
415: gbuf_freem(m);
416: break;
417: }
418: break;
419:
420: case MSG_IOCACK:
421: if (atp->dflag)
422: asp_ack_reply(gref, m);
423: else
424: atalk_putnext(gref, m);
425: break;
426:
427: case MSG_IOCNAK:
428: if (atp->dflag)
429: asp_nak_reply(gref, m);
430: else
431: atalk_putnext(gref, m);
432: break;
433:
434: default:
435: gbuf_freem(m);
436: }
437: } /* atp_rput */
438:
439: void
440: atp_x_done(trp)
441: register struct atp_trans *trp;
442: {
443: struct atp_state *atp;
444: gbuf_t *m;
445:
446: if ( !trp->tr_xo)
447: atp_trans_complete(trp);
448: else {
449: /*
450: * If execute once send a release
451: */
452: if ((m = (gbuf_t *)atp_build_release(trp)) != NULL) {
453: AT_DDP_HDR(m)->src_socket = ((struct atp_state *)
454: trp->tr_queue)->atp_socket_no;
455: DDP_OUTPUT(m);
456: /*
457: * Now send back the transaction reply to the process
458: * or notify the process if required
459: */
460: atp_trans_complete(trp);
461: } else {
462:
463: atp = trp->tr_queue;
464: trp->tr_state = TRANS_RELEASE;
465: atalk_timeout(atp_x_done, trp, 10);
466: }
467: }
468: }
469:
470: static void
471: atp_trans_complete(trp)
472: register struct atp_trans *trp;
473: { register gbuf_t *m;
474: register int type;
475: struct atp_state *atp;
476:
477: /* we could gbuf_freem(trp->tr_xmt) here if were not planning to
478: re-use the mbuf later */
479: m = trp->tr_xmt;
480: trp->tr_xmt = NULL;
481: trp->tr_state = TRANS_DONE;
482:
483: if (gbuf_cont(m) == NULL) /* issued via the new interface */
484: type = AT_ATP_ISSUE_REQUEST_NOTE;
485: else {
486: type = ((ioc_t *)(gbuf_rptr(m)))->ioc_cmd;
487: /*
488: * free any data following the ioctl blk
489: */
490: gbuf_freem(gbuf_cont(m));
491: gbuf_cont(m) = NULL;
492: }
493: dPrintf(D_M_ATP_LOW, D_L_INPUT, ("atp_trans_comp: trp=0x%x type = %s\n",
494: (u_int) trp,
495: (type==AT_ATP_ISSUE_REQUEST)? "AT_ATP_ISSUE_REQUEST":
496: (type==AT_ATP_ISSUE_REQUEST_NOTE)? "AT_ATP_ISSUE_REQUEST_NOTE" :
497: "unknown"));
498:
499: switch(type) {
500: case AT_ATP_ISSUE_REQUEST:
501: atp = trp->tr_queue;
502: if (atp->dflag) {
503: ((ioc_t *)gbuf_rptr(m))->ioc_count = 0;
504: ((ioc_t *)gbuf_rptr(m))->ioc_error = 0;
505: ((ioc_t *)gbuf_rptr(m))->ioc_rval = trp->tr_tid;
506: ((ioc_t *)gbuf_rptr(m))->ioc_cmd = AT_ATP_REQUEST_COMPLETE;
507: gbuf_set_type(m, MSG_IOCTL);
508: atp_rsp_ind(trp, m);
509: } else {
510: if (trp->tr_bdsp == NULL) {
511: gbuf_freem(m);
512: if (trp->tr_rsp_wait)
513: #ifdef _AIX
514: e_wakeup(&trp->tr_event);
515: #else
516: thread_wakeup(&trp->tr_event);
517: #endif
518: } else {
519: gbuf_set_type(m, MSG_IOCACK);
520: ((ioc_t *)gbuf_rptr(m))->ioc_count = 0;
521: ((ioc_t *)gbuf_rptr(m))->ioc_error = 0;
522: ((ioc_t *)gbuf_rptr(m))->ioc_rval = 0;
523: atalk_putnext(trp->tr_queue->atp_gref, m);
524: }
525: }
526: break;
527:
528: case AT_ATP_ISSUE_REQUEST_NOTE:
529: gbuf_wset(m,1);
530: *gbuf_rptr(m) = 1;
531: gbuf_set_type(m, MSG_DATA);
532: atalk_putnext(trp->tr_queue->atp_gref, m);
533: break;
534: }
535: } /* atp_trans_complete */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.