]> git.saurik.com Git - apple/xnu.git/blame - bsd/netat/atp_open.c
xnu-123.5.tar.gz
[apple/xnu.git] / bsd / netat / atp_open.c
CommitLineData
1c79356b
A
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
58int atp_inited = 0;
59struct atp_rcb_qhead atp_need_rel;
60atlock_t atpall_lock;
61atlock_t atptmo_lock;
62atlock_t atpgen_lock;
63
64/**********/
65int atp_pidM[256];
66gref_t *atp_inputQ[256];
67struct atp_state *atp_used_list;
68
69int 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/**********/
103void 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*/
132int 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*/
197int 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}