|
|
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: * Copyright (c) 1996-1998 Apple Computer, Inc.
24: * All Rights Reserved.
25: */
26:
27: /* Modified for MP, 1996 by Tuyen Nguyen
28: * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
29: */
30: #define ATP_DECLARE
31:
32: #include <sys/errno.h>
33: #include <sys/types.h>
34: #include <sys/param.h>
35: #include <machine/spl.h>
36: #include <sys/systm.h>
37: #include <sys/kernel.h>
38: #include <sys/proc.h>
39: #include <sys/filedesc.h>
40: #include <sys/fcntl.h>
41: #include <sys/mbuf.h>
42: #include <sys/ioctl.h>
43: #include <sys/malloc.h>
44: #include <sys/socket.h>
45:
46: #include <netat/sysglue.h>
47: #include <netat/appletalk.h>
48: #include <netat/ddp.h>
49: #include <netat/at_pcb.h>
50: #include <netat/atp.h>
51: #include <netat/debug.h>
52:
53: /*
54: * The init routine creates all the free lists
55: * Version 1.4 of atp_open.c on 89/02/09 17:53:11
56: */
57:
58: int atp_inited = 0;
59: struct atp_rcb_qhead atp_need_rel;
60: atlock_t atpall_lock;
61: atlock_t atptmo_lock;
62: atlock_t atpgen_lock;
63:
64: /**********/
65: int atp_pidM[256];
66: gref_t *atp_inputQ[256];
67: struct atp_state *atp_used_list;
68:
69: int atp_input(mp)
70: gbuf_t *mp;
71: {
72: register gref_t *gref;
73:
74: switch (gbuf_type(mp)) {
75: case MSG_DATA:
76: gref = atp_inputQ[((at_ddp_t *)gbuf_rptr(mp))->dst_socket];
77: if ((gref == 0) || (gref == (gref_t *)1)) {
78: dPrintf(D_M_ATP, D_L_WARNING, ("atp_input: no socket, skt=%d\n",
79: ((at_ddp_t *)gbuf_rptr(mp))->dst_socket));
80: gbuf_freem(mp);
81: return 0;
82: }
83: break;
84:
85: case MSG_IOCACK:
86: case MSG_IOCNAK:
87: gref = (gref_t *)((ioc_t *)gbuf_rptr(mp))->ioc_private;
88: break;
89:
90: case MSG_IOCTL:
91: default:
92: dPrintf(D_M_ATP, D_L_WARNING, ("atp_input: unknown msg, type=%d\n",
93: gbuf_type(mp)));
94: gbuf_freem(mp);
95: return 0;
96: }
97:
98: atp_rput(gref, mp);
99: return 0;
100: }
101:
102: /**********/
103: void atp_init()
104: {
105: int i;
106:
107: if (!atp_inited) {
108: atp_inited = 1;
109: atp_used_list = 0;
110: for (i = 0; i < NATP_RCB; i++) {
111: atp_rcb_data[i].rc_list.next = atp_rcb_free_list;
112: atp_rcb_free_list = &atp_rcb_data[i];
113: }
114: for (i = 0; i < NATP_STATE; i++) {
115: atp_state_data[i].atp_trans_waiting = atp_free_list;
116: atp_free_list = &atp_state_data[i];
117: }
118: atp_need_rel.head = NULL;
119: atp_need_rel.tail = NULL;
120:
121: bzero(atp_inputQ, sizeof(atp_inputQ));
122: bzero(atp_pidM, sizeof(atp_pidM));
123: asp_init();
124: }
125: }
126:
127: /*
128: * The open routine allocates a state structure
129: */
130:
131: /*ARGSUSED*/
132: int atp_open(gref, flag)
133: gref_t *gref;
134: int flag;
135: {
136: register struct atp_state *atp;
137: register int s;
138:
139: /*
140: * If no atp structure available return failure
141: */
142:
143: ATDISABLE(s, atpall_lock);
144: if ((atp = atp_free_list) == NULL) {
145: ATENABLE(s, atpall_lock);
146: return(EAGAIN);
147: }
148:
149: /*
150: * Update free list
151: */
152:
153: atp_free_list = atp->atp_trans_waiting;
154: ATENABLE(s, atpall_lock);
155:
156: /*
157: * Initialize the data structure
158: */
159:
160: atp->dflag = 0;
161: atp->atp_trans_wait.head = NULL;
162: atp->atp_trans_waiting = NULL;
163: atp->atp_gref = gref;
164: atp->atp_retry = 10;
165: atp->atp_timeout = HZ/8;
166: atp->atp_rcb_waiting = NULL;
167: atp->atp_rcb.head = NULL;
168: atp->atp_flags = T_MPSAFE;
169: atp->atp_socket_no = -1;
170: atp->atp_pid = gref->pid;
171: atp->atp_msgq = 0;
172: ATLOCKINIT(atp->atp_lock);
173: ATLOCKINIT(atp->atp_delay_lock);
174: ATEVENTINIT(atp->atp_event);
175: ATEVENTINIT(atp->atp_delay_event);
176: gref->info = (void *)atp;
177:
178: /*
179: * Return success
180: */
181:
182: if (flag) {
183: ATDISABLE(s, atpall_lock);
184: if ((atp->atp_trans_waiting = atp_used_list) != 0)
185: atp->atp_trans_waiting->atp_rcb_waiting = atp;
186: atp_used_list = atp;
187: ATENABLE(s, atpall_lock);
188: }
189: return(0);
190: }
191:
192: /*
193: * The close routine frees all the data structures
194: */
195:
196: /*ARGSUSED*/
197: int atp_close(gref, flag)
198: gref_t *gref;
199: int flag;
200: {
201: extern void atp_req_timeout();
202: register struct atp_state *atp;
203: register struct atp_trans *trp;
204: register struct atp_rcb *rcbp;
205: register int s;
206: int socket;
207: pid_t pid;
208:
209: atp = (struct atp_state *)gref->info;
210: if (atp->dflag)
211: atp = (struct atp_state *)atp->atp_msgq;
212: if (atp->atp_msgq) {
213: gbuf_freem(atp->atp_msgq);
214: atp->atp_msgq = 0;
215: }
216:
217: ATDISABLE(s, atp->atp_lock);
218: atp->atp_flags |= ATP_CLOSING;
219: socket = atp->atp_socket_no;
220: if (socket != -1)
221: atp_inputQ[socket] = (gref_t *)1;
222:
223: /*
224: * blow away all pending timers
225: */
226: for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next)
227: atp_untimout(atp_req_timeout, trp);
228:
229: /*
230: * Release pending transactions + rcbs
231: */
232: while ((trp = atp->atp_trans_wait.head))
233: atp_free(trp);
234: while ((rcbp = atp->atp_rcb.head))
235: atp_rcb_free(rcbp);
236: while ((rcbp = atp->atp_attached.head))
237: atp_rcb_free(rcbp);
238: ATENABLE(s, atp->atp_lock);
239:
240: if (flag && (socket == -1))
241: atp_dequeue_atp(atp);
242:
243: /*
244: * free the state variable
245: */
246: ATDISABLE(s, atpall_lock);
247: atp->atp_socket_no = -1;
248: atp->atp_trans_waiting = atp_free_list;
249: atp_free_list = atp;
250: ATENABLE(s, atpall_lock);
251:
252: if (socket != -1) {
253: pid = (pid_t)atp_pidM[socket];
254: atp_pidM[socket] = 0;
255: atp_inputQ[socket] = NULL;
256: if (pid)
257: ddp_notify_nbp(socket, pid, DDP_ATP);
258: }
259:
260: return 0;
261: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.