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