]> git.saurik.com Git - apple/xnu.git/blame - bsd/netat/atp_open.c
xnu-201.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;
0b4e3aa0
A
110 atp_trans_abort.head = NULL;
111 atp_trans_abort.tail = NULL;
112
1c79356b
A
113 for (i = 0; i < NATP_RCB; i++) {
114 atp_rcb_data[i].rc_list.next = atp_rcb_free_list;
115 atp_rcb_free_list = &atp_rcb_data[i];
116 }
117 for (i = 0; i < NATP_STATE; i++) {
118 atp_state_data[i].atp_trans_waiting = atp_free_list;
119 atp_free_list = &atp_state_data[i];
120 }
121 atp_need_rel.head = NULL;
122 atp_need_rel.tail = NULL;
123
124 bzero(atp_inputQ, sizeof(atp_inputQ));
125 bzero(atp_pidM, sizeof(atp_pidM));
126 asp_init();
127 }
128}
129
130/*
131 * The open routine allocates a state structure
132 */
133
134/*ARGSUSED*/
135int atp_open(gref, flag)
136 gref_t *gref;
137 int flag;
138{
139 register struct atp_state *atp;
140 register int s;
141
142 /*
143 * If no atp structure available return failure
144 */
145
146 ATDISABLE(s, atpall_lock);
147 if ((atp = atp_free_list) == NULL) {
148 ATENABLE(s, atpall_lock);
149 return(EAGAIN);
150 }
151
152 /*
153 * Update free list
154 */
155
156 atp_free_list = atp->atp_trans_waiting;
157 ATENABLE(s, atpall_lock);
158
159 /*
160 * Initialize the data structure
161 */
162
163 atp->dflag = 0;
164 atp->atp_trans_wait.head = NULL;
165 atp->atp_trans_waiting = NULL;
166 atp->atp_gref = gref;
167 atp->atp_retry = 10;
168 atp->atp_timeout = HZ/8;
169 atp->atp_rcb_waiting = NULL;
170 atp->atp_rcb.head = NULL;
171 atp->atp_flags = T_MPSAFE;
172 atp->atp_socket_no = -1;
173 atp->atp_pid = gref->pid;
174 atp->atp_msgq = 0;
175 ATLOCKINIT(atp->atp_lock);
176 ATLOCKINIT(atp->atp_delay_lock);
177 ATEVENTINIT(atp->atp_event);
178 ATEVENTINIT(atp->atp_delay_event);
179 gref->info = (void *)atp;
180
181 /*
182 * Return success
183 */
184
185 if (flag) {
186 ATDISABLE(s, atpall_lock);
187 if ((atp->atp_trans_waiting = atp_used_list) != 0)
188 atp->atp_trans_waiting->atp_rcb_waiting = atp;
189 atp_used_list = atp;
190 ATENABLE(s, atpall_lock);
191 }
192 return(0);
193}
194
195/*
196 * The close routine frees all the data structures
197 */
198
199/*ARGSUSED*/
200int atp_close(gref, flag)
201 gref_t *gref;
202 int flag;
203{
204 extern void atp_req_timeout();
205 register struct atp_state *atp;
206 register struct atp_trans *trp;
207 register struct atp_rcb *rcbp;
208 register int s;
209 int socket;
210 pid_t pid;
211
212 atp = (struct atp_state *)gref->info;
213 if (atp->dflag)
214 atp = (struct atp_state *)atp->atp_msgq;
215 if (atp->atp_msgq) {
216 gbuf_freem(atp->atp_msgq);
217 atp->atp_msgq = 0;
218 }
219
220 ATDISABLE(s, atp->atp_lock);
221 atp->atp_flags |= ATP_CLOSING;
222 socket = atp->atp_socket_no;
223 if (socket != -1)
224 atp_inputQ[socket] = (gref_t *)1;
225
226 /*
227 * blow away all pending timers
228 */
229 for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next)
230 atp_untimout(atp_req_timeout, trp);
231
232 /*
233 * Release pending transactions + rcbs
234 */
235 while ((trp = atp->atp_trans_wait.head))
236 atp_free(trp);
237 while ((rcbp = atp->atp_rcb.head))
238 atp_rcb_free(rcbp);
239 while ((rcbp = atp->atp_attached.head))
240 atp_rcb_free(rcbp);
241 ATENABLE(s, atp->atp_lock);
242
243 if (flag && (socket == -1))
244 atp_dequeue_atp(atp);
245
246 /*
247 * free the state variable
248 */
249 ATDISABLE(s, atpall_lock);
250 atp->atp_socket_no = -1;
251 atp->atp_trans_waiting = atp_free_list;
252 atp_free_list = atp;
253 ATENABLE(s, atpall_lock);
254
255 if (socket != -1) {
256 pid = (pid_t)atp_pidM[socket];
257 atp_pidM[socket] = 0;
258 atp_inputQ[socket] = NULL;
259 if (pid)
260 ddp_notify_nbp(socket, pid, DDP_ATP);
261 }
262
263 return 0;
264}