]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
5d5c5d0d A |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. |
3 | * | |
8f6c56a5 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
8f6c56a5 A |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
8ad349bb | 24 | * limitations under the License. |
8f6c56a5 A |
25 | * |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
1c79356b A |
27 | */ |
28 | /* | |
29 | * Copyright (c) 1995-1998 Apple Computer, Inc. | |
30 | * All Rights Reserved. | |
31 | */ | |
32 | ||
33 | /* | |
34 | * 09/07/95 - Modified for performance (Tuyen Nguyen) | |
35 | * Modified for MP, 1996 by Tuyen Nguyen | |
36 | * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX. | |
37 | */ | |
38 | #include <sys/errno.h> | |
39 | #include <sys/types.h> | |
40 | #include <sys/param.h> | |
41 | #include <machine/spl.h> | |
42 | #include <sys/systm.h> | |
43 | #include <sys/kernel.h> | |
44 | #include <sys/proc.h> | |
45 | #include <sys/filedesc.h> | |
46 | #include <sys/fcntl.h> | |
47 | #include <sys/mbuf.h> | |
48 | #include <sys/socket.h> | |
49 | #include <sys/socketvar.h> | |
50 | #include <sys/time.h> | |
51 | #include <sys/ioctl.h> | |
52 | #include <sys/malloc.h> | |
53 | ||
54 | #include <net/if.h> | |
55 | ||
56 | #include <netat/sysglue.h> | |
57 | #include <netat/appletalk.h> | |
58 | #include <netat/ddp.h> | |
59 | #include <netat/at_snmp.h> | |
60 | #include <netat/at_pcb.h> | |
61 | #include <netat/debug.h> | |
62 | #include <netat/at_var.h> | |
63 | #include <netat/adsp.h> | |
64 | #include <netat/adsp_internal.h> | |
65 | ||
66 | void SndMsgUp(); | |
67 | void adsp_rput(); | |
68 | static void adsp_iocack(); | |
69 | static void adsp_iocnak(); | |
70 | void adsp_dequeue_ccb(); | |
71 | unsigned char adspAssignSocket(); | |
72 | int adspallocate(), adsprelease(); | |
73 | int adspInited = 0; | |
74 | ||
8f6c56a5 A |
75 | atlock_t adspall_lock; |
76 | atlock_t adspgen_lock; | |
1c79356b A |
77 | GLOBAL adspGlobal; |
78 | ||
79 | /**********/ | |
80 | ||
81 | int adsp_pidM[256]; | |
82 | char adsp_inputC[256]; | |
83 | CCB *adsp_inputQ[256]; | |
84 | ||
85 | extern at_ifaddr_t *ifID_home; | |
86 | ||
87 | CCB *ccb_used_list; | |
88 | ||
89 | void adsp_input(mp) | |
90 | gbuf_t *mp; | |
91 | { | |
92 | gref_t *gref; | |
93 | CCBPtr sp; | |
94 | at_ddp_t *p; | |
8f6c56a5 | 95 | int s, l; |
1c79356b A |
96 | gbuf_t *mb; |
97 | ||
98 | switch (gbuf_type(mp)) { | |
99 | case MSG_DATA: | |
100 | p = (at_ddp_t *)gbuf_rptr(mp); | |
8f6c56a5 | 101 | ATDISABLE(s, adspall_lock); |
1c79356b A |
102 | sp = adsp_inputQ[p->dst_socket]; |
103 | if ((sp == 0) || (sp->gref==0) || (sp->state==sClosed)) | |
104 | { | |
8f6c56a5 | 105 | ATENABLE(s, adspall_lock); |
1c79356b A |
106 | gbuf_freem(mp); |
107 | return; | |
108 | } | |
109 | else if (sp->otccbLink != 0) { | |
110 | do { | |
111 | if ((sp->remoteAddress.a.node == p->src_node) | |
112 | && (sp->remoteAddress.a.socket == p->src_socket) | |
113 | && (sp->remoteAddress.a.net == NET_VALUE(p->src_net))) | |
114 | break; | |
115 | } while ((sp = sp->otccbLink) != 0); | |
116 | if (sp == 0) | |
117 | { | |
8f6c56a5 | 118 | ATENABLE(s, adspall_lock); |
1c79356b A |
119 | gbuf_freem(mp); |
120 | return; | |
121 | } | |
122 | } | |
123 | if (sp->lockFlag) { | |
124 | gbuf_next(mp) = 0; | |
125 | if (sp->deferred_mb) { | |
126 | for (mb=sp->deferred_mb; gbuf_next(mb); mb=gbuf_next(mb)) ; | |
127 | gbuf_next(mb) = mp; | |
128 | } else | |
129 | sp->deferred_mb = mp; | |
8f6c56a5 | 130 | ATENABLE(s, adspall_lock); |
1c79356b A |
131 | return; |
132 | } | |
8f6c56a5 | 133 | ATDISABLE(l, sp->lockRemove); |
1c79356b | 134 | sp->lockFlag = 1; |
8f6c56a5 | 135 | ATENABLE(l, adspall_lock); |
1c79356b A |
136 | while (mp) { |
137 | adsp_rput(sp->gref, mp); | |
138 | if ((mp = sp->deferred_mb) != 0) { | |
139 | sp->deferred_mb = gbuf_next(mp); | |
140 | gbuf_next(mp) = 0; | |
141 | } | |
142 | } | |
143 | sp->lockFlag = 0; | |
8f6c56a5 | 144 | ATENABLE(s, sp->lockRemove); |
1c79356b A |
145 | return; |
146 | ||
147 | case MSG_IOCACK: | |
148 | case MSG_IOCNAK: | |
149 | gref = (gref_t *)((ioc_t *)gbuf_rptr(mp))->ioc_private; | |
150 | break; | |
151 | ||
152 | case MSG_IOCTL: | |
153 | #ifdef APPLETALK_DEBUG | |
154 | kprintf("unexpected MSG_IOCTL in adsp_input()"); | |
155 | #endif | |
156 | /* fall through */ | |
157 | ||
158 | default: | |
159 | gbuf_freem(mp); | |
160 | return; | |
161 | } | |
162 | ||
163 | adsp_rput(gref, mp); | |
164 | } | |
165 | ||
166 | /**********/ | |
167 | int adsp_readable(gref) | |
168 | gref_t *gref; | |
169 | { | |
170 | int rc; | |
171 | CCBPtr sp; | |
172 | ||
173 | if (gref->info == 0) | |
174 | /* | |
175 | * we don't have the structure we need to determine | |
176 | * if there's data available... we return readable in | |
177 | * this case to keep from hanging up in the select | |
178 | * a subsequent read will run into the same missing data | |
179 | * structure and return an error... the ATselect code does | |
180 | * this if it can't retrieve the 'gref' structure from the | |
181 | * file table for the fd specified | |
182 | */ | |
183 | return(1); | |
184 | ||
185 | sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); | |
186 | rc = sp->rData; | |
187 | ||
188 | return rc; | |
189 | } | |
190 | ||
191 | int adsp_writeable(gref) | |
192 | gref_t *gref; | |
193 | { | |
8f6c56a5 | 194 | int s, rc; |
1c79356b A |
195 | CCBPtr sp; |
196 | ||
197 | if (gref->info == 0) | |
198 | /* | |
199 | * we don't have the structure we need to determine | |
200 | * if there's room available... we return writeable in | |
201 | * this case to keep from hanging up in the select | |
202 | * a subsequent write will run into the same missing data | |
203 | * structure and return an error... the ATselect code does | |
204 | * this if it can't retrieve the 'gref' structure from the | |
205 | * file table for the fd specified | |
206 | */ | |
207 | return(1); | |
208 | ||
209 | sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); | |
8f6c56a5 | 210 | ATDISABLE(s, sp->lock); |
1c79356b | 211 | rc = CalcSendQFree(sp); |
8f6c56a5 | 212 | ATENABLE(s, sp->lock); |
1c79356b A |
213 | |
214 | return rc; | |
215 | } | |
216 | ||
217 | static void adsp_init() | |
218 | { | |
219 | adspInited++; | |
220 | InitGlobals(); | |
221 | ccb_used_list = 0; | |
222 | bzero(adsp_pidM, sizeof(adsp_pidM)); | |
223 | bzero(adsp_inputC, sizeof(adsp_inputC)); | |
224 | bzero(adsp_inputQ, sizeof(adsp_inputQ)); | |
225 | } | |
226 | ||
227 | /* | |
228 | * Description: | |
229 | * ADSP open and close routines. These routines | |
230 | * initalize and release the ADSP structures. They do not | |
231 | * have anything to do with "connections" | |
232 | */ | |
233 | ||
234 | int adsp_open(gref) | |
235 | gref_t *gref; | |
236 | { | |
237 | register CCBPtr sp; | |
8f6c56a5 | 238 | int s; |
1c79356b A |
239 | |
240 | if (!adspInited) | |
241 | adsp_init(); | |
242 | ||
243 | if (!adspAllocateCCB(gref)) | |
244 | return(ENOBUFS); /* can't get buffers */ | |
245 | ||
246 | sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); | |
247 | gref->readable = adsp_readable; | |
248 | gref->writeable = adsp_writeable; | |
8f6c56a5 | 249 | ATDISABLE(s, adspall_lock); |
1c79356b A |
250 | if ((sp->otccbLink = ccb_used_list) != 0) |
251 | sp->otccbLink->ccbLink = sp; | |
252 | ccb_used_list = sp; | |
8f6c56a5 | 253 | ATENABLE(s, adspall_lock); |
1c79356b A |
254 | return 0; |
255 | } | |
256 | ||
257 | int adsp_close(gref) | |
258 | gref_t *gref; | |
259 | { | |
8f6c56a5 | 260 | int s, l; |
1c79356b A |
261 | unsigned char localSocket; |
262 | ||
263 | /* make sure we've not yet removed the CCB (e.g., due to TrashSession) */ | |
8f6c56a5 | 264 | ATDISABLE(l, adspgen_lock); |
1c79356b A |
265 | if (gref->info) { |
266 | CCBPtr sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); | |
8f6c56a5 A |
267 | ATDISABLE(s, sp->lock); |
268 | ATENABLE(s, adspgen_lock); | |
1c79356b | 269 | localSocket = sp->localSocket; |
8f6c56a5 | 270 | ATENABLE(l, sp->lock); |
1c79356b A |
271 | if (localSocket) |
272 | adspRelease(gref); | |
273 | else | |
274 | { | |
275 | adsp_dequeue_ccb(sp); | |
276 | gbuf_freeb((gbuf_t *)gref->info); | |
277 | } | |
278 | } else | |
8f6c56a5 | 279 | ATENABLE(l, adspgen_lock); |
1c79356b A |
280 | return 0; |
281 | } | |
282 | ||
283 | ||
284 | /* | |
285 | * Name: | |
286 | * adsp_rput | |
287 | * | |
288 | * Description: | |
289 | * ADSP streams read put and service routines. | |
290 | */ | |
291 | ||
292 | void adsp_rput(gref, mp) | |
293 | gref_t *gref; /* READ queue */ | |
294 | gbuf_t *mp; | |
295 | { | |
296 | switch (gbuf_type(mp)) { | |
297 | case MSG_HANGUP: | |
298 | case MSG_IOCACK: | |
299 | case MSG_IOCNAK: | |
300 | switch (adspReadHandler(gref, mp)) { | |
301 | case STR_PUTNEXT: | |
302 | atalk_putnext(gref, mp); | |
303 | break; | |
304 | case STR_IGNORE: | |
305 | break; | |
306 | } | |
307 | break; | |
308 | case MSG_ERROR: | |
309 | #ifdef APPLETALK_DEBUG | |
310 | kprintf("adsp_rput received MSG_ERROR"); | |
311 | #endif | |
312 | /* fall through */ | |
313 | default: | |
314 | CheckReadQueue(gbuf_rptr(((gbuf_t *)gref->info))); | |
315 | CheckSend(gbuf_rptr(((gbuf_t *)gref->info))); | |
316 | ||
317 | switch (gbuf_type(mp)) { | |
318 | case MSG_IOCTL: | |
319 | case MSG_DATA: | |
320 | case MSG_PROTO: | |
321 | if (adspReadHandler(gref, mp) == STR_PUTNEXT) | |
322 | atalk_putnext(gref, mp); | |
323 | break; | |
324 | default: | |
325 | atalk_putnext(gref, mp); | |
326 | break; | |
327 | } | |
328 | } | |
329 | } | |
330 | ||
331 | /* | |
332 | * Name: | |
333 | * adsp_wput | |
334 | * | |
335 | * Description: | |
336 | * ADSP streams write put and service routines. | |
337 | * | |
338 | */ | |
339 | ||
340 | int adsp_wput(gref, mp) | |
341 | gref_t *gref; /* WRITE queue */ | |
342 | gbuf_t *mp; | |
343 | { | |
344 | int rc; | |
8f6c56a5 | 345 | int s; |
1c79356b A |
346 | gbuf_t *xm; |
347 | ioc_t *iocbp; | |
fa4905b1 A |
348 | CCBPtr sp; |
349 | ||
350 | if (gref->info) | |
351 | sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); | |
352 | else | |
353 | sp = 0; | |
1c79356b A |
354 | |
355 | if (gbuf_type(mp) == MSG_IOCTL) { | |
356 | iocbp = (ioc_t *)gbuf_rptr(mp); | |
357 | switch (iocbp->ioc_cmd) { | |
358 | case ADSPBINDREQ: | |
359 | { | |
360 | unsigned char v; | |
361 | ||
362 | if (gbuf_cont(mp) == NULL) { | |
363 | iocbp->ioc_rval = -1; | |
364 | adsp_iocnak(gref, mp, EINVAL); | |
365 | } | |
366 | v = *(unsigned char *)gbuf_rptr(gbuf_cont(mp)); | |
8f6c56a5 | 367 | ATDISABLE(s, adspall_lock); |
1c79356b A |
368 | if ( (v != 0) |
369 | && ((v > DDP_SOCKET_LAST) || (v < 2) | |
370 | || ddp_socket_inuse(v, DDP_ADSP))) { | |
8f6c56a5 | 371 | ATENABLE(s, adspall_lock); |
1c79356b A |
372 | iocbp->ioc_rval = -1; |
373 | adsp_iocnak(gref, mp, EINVAL); | |
374 | } | |
375 | else { | |
376 | if (v == 0) { | |
8f6c56a5 | 377 | ATENABLE(s, adspall_lock); |
1c79356b A |
378 | if ((v = adspAssignSocket(gref, 0)) == 0) { |
379 | iocbp->ioc_rval = -1; | |
380 | adsp_iocnak(gref, mp, EINVAL); | |
381 | return 0; | |
382 | } | |
383 | } else { | |
384 | adsp_inputC[v] = 1; | |
385 | adsp_inputQ[v] = sp; | |
386 | adsp_pidM[v] = sp->pid; | |
8f6c56a5 | 387 | ATENABLE(s, adspall_lock); |
1c79356b A |
388 | adsp_dequeue_ccb(sp); |
389 | } | |
390 | *(unsigned char *)gbuf_rptr(gbuf_cont(mp)) = v; | |
391 | sp->localSocket = v; | |
392 | iocbp->ioc_rval = 0; | |
393 | adsp_iocack(gref, mp); | |
394 | } | |
395 | return 0; | |
396 | } | |
397 | ||
398 | case ADSPGETSOCK: | |
399 | case ADSPGETPEER: | |
400 | { | |
401 | at_inet_t *addr; | |
402 | ||
403 | if (((xm = gbuf_cont(mp)) == NULL) | |
404 | && ((xm = gbuf_alloc(sizeof(at_inet_t), PRI_MED)) == NULL)) { | |
405 | iocbp->ioc_rval = -1; | |
406 | adsp_iocnak(gref, mp, ENOBUFS); | |
407 | return 0; | |
408 | } | |
409 | gbuf_cont(mp) = xm; | |
410 | gbuf_wset(xm,sizeof(at_inet_t)); | |
411 | addr = (at_inet_t *)gbuf_rptr(xm); | |
412 | if (iocbp->ioc_cmd == ADSPGETSOCK) { | |
413 | /* Obtain Network and Node Id's from DDP */ | |
414 | /* *** was ddp_get_cfg() *** */ | |
415 | addr->net = ifID_home->ifThisNode.s_net; | |
416 | addr->node = ifID_home->ifThisNode.s_node; | |
417 | addr->socket = (sp)? sp->localSocket: 0; | |
418 | } else | |
419 | if (sp) | |
420 | *addr = sp->remoteAddress.a; | |
421 | else { | |
422 | addr->net = 0; | |
423 | addr->node = 0; | |
424 | addr->socket = 0; | |
425 | } | |
426 | iocbp->ioc_rval = 0; | |
427 | adsp_iocack(gref, mp); | |
428 | return 0; | |
429 | } | |
430 | case DDP_IOC_GET_CFG: | |
431 | /* respond to an DDP_IOC_GET_CFG sent on an adsp fd */ | |
432 | if (((xm = gbuf_cont(mp)) == NULL) && | |
9bccf70c | 433 | (xm = gbuf_alloc(sizeof(ddp_addr_t), PRI_MED)) == NULL) { |
1c79356b A |
434 | iocbp->ioc_rval = -1; |
435 | adsp_iocnak(gref, mp, ENOBUFS); | |
436 | return 0; | |
437 | } | |
438 | gbuf_cont(mp) = xm; | |
439 | gbuf_wset(xm, sizeof(ddp_addr_t)); | |
440 | /* Obtain Network and Node Id's from DDP */ | |
441 | { | |
442 | /* *** was ddp_get_cfg() *** */ | |
443 | ddp_addr_t *cfgp = | |
444 | (ddp_addr_t *)gbuf_rptr(gbuf_cont(mp)); | |
445 | cfgp->inet.net = ifID_home->ifThisNode.s_net; | |
446 | cfgp->inet.node = ifID_home->ifThisNode.s_node; | |
447 | cfgp->inet.socket = (sp)? sp->localSocket: 0; | |
448 | cfgp->ddptype = DDP_ADSP; | |
449 | } | |
450 | iocbp->ioc_rval = 0; | |
451 | adsp_iocack(gref, mp); | |
452 | return 0; | |
453 | } /* switch */ | |
454 | } | |
455 | ||
456 | if (!gref->info) | |
457 | gbuf_freem(mp); | |
458 | else { | |
8f6c56a5 | 459 | ATDISABLE(s, sp->lockClose); |
1c79356b | 460 | rc = adspWriteHandler(gref, mp); |
8f6c56a5 | 461 | ATENABLE(s, sp->lockClose); |
1c79356b A |
462 | |
463 | switch (rc) { | |
464 | case STR_PUTNEXT: | |
465 | if (gbuf_type(mp) == MSG_IOCTL) { | |
466 | iocbp = (ioc_t *)gbuf_rptr(mp); | |
467 | iocbp->ioc_private = (void *)gref; | |
468 | } | |
469 | DDP_OUTPUT(mp); | |
470 | break; | |
471 | case STR_IGNORE: | |
472 | case STR_IGNORE+99: | |
473 | break; | |
474 | default: | |
475 | gbuf_freem(mp); | |
476 | break; | |
477 | } | |
478 | } | |
479 | ||
480 | return 0; | |
481 | } /* adsp_wput */ | |
482 | ||
483 | void adspioc_ack(errno, m, gref) | |
484 | int errno; | |
485 | gbuf_t *m; | |
486 | gref_t *gref; | |
487 | { | |
488 | ioc_t *iocbp; | |
489 | ||
490 | if (m == NULL) | |
491 | return; | |
492 | iocbp = (ioc_t *) gbuf_rptr(m); | |
493 | ||
494 | iocbp->ioc_error = errno; /* set the errno */ | |
495 | iocbp->ioc_count = gbuf_msgsize(gbuf_cont(m)); | |
496 | if (gbuf_type(m) == MSG_IOCTL) /* if an ioctl, this is an ack */ | |
497 | gbuf_set_type(m, MSG_IOCACK); /* and ALWAYS update the user */ | |
498 | /* ioctl structure */ | |
499 | trace_mbufs(D_M_ADSP,"A ", m); | |
500 | SndMsgUp(gref, m); | |
501 | } | |
502 | ||
503 | static void adsp_iocack(gref, m) | |
504 | gref_t *gref; | |
505 | register gbuf_t *m; | |
506 | { | |
507 | if (gbuf_type(m) == MSG_IOCTL) | |
508 | gbuf_set_type(m, MSG_IOCACK); | |
509 | ||
510 | if (gbuf_cont(m)) | |
511 | ((ioc_t *)gbuf_rptr(m))->ioc_count = gbuf_msgsize(gbuf_cont(m)); | |
512 | else | |
513 | ((ioc_t *)gbuf_rptr(m))->ioc_count = 0; | |
514 | ||
515 | SndMsgUp(gref, m); | |
516 | } | |
517 | ||
518 | ||
519 | static void adsp_iocnak(gref, m, err) | |
520 | gref_t *gref; | |
521 | register gbuf_t *m; | |
522 | register int err; | |
523 | { | |
524 | if (gbuf_type(m) == MSG_IOCTL) | |
525 | gbuf_set_type(m, MSG_IOCNAK); | |
526 | ((ioc_t *)gbuf_rptr(m))->ioc_count = 0; | |
527 | ||
528 | if (err == 0) | |
529 | err = ENXIO; | |
530 | ((ioc_t *)gbuf_rptr(m))->ioc_error = err; | |
531 | ||
532 | if (gbuf_cont(m)) { | |
533 | gbuf_freem(gbuf_cont(m)); | |
534 | gbuf_cont(m) = NULL; | |
535 | } | |
536 | SndMsgUp(gref, m); | |
537 | } | |
538 | ||
539 | unsigned char | |
540 | adspAssignSocket(gref, flag) | |
541 | gref_t *gref; | |
542 | int flag; | |
543 | { | |
544 | unsigned char sVal, sMax, sMin, sSav, inputC; | |
545 | CCBPtr sp; | |
8f6c56a5 | 546 | int s; |
1c79356b A |
547 | |
548 | sMax = flag ? DDP_SOCKET_LAST-46 : DDP_SOCKET_LAST-6; | |
14353aa8 | 549 | sMin = DDP_SOCKET_1st_DYNAMIC; |
1c79356b | 550 | |
8f6c56a5 | 551 | ATDISABLE(s, adspall_lock); |
1c79356b A |
552 | for (inputC=255, sVal=sMax; sVal >= sMin; sVal--) { |
553 | if (!ddp_socket_inuse(sVal, DDP_ADSP)) | |
554 | break; | |
555 | else if (flag) { | |
556 | if (adsp_inputC[sVal] && | |
557 | /* meaning that raw DDP doesn't have it */ | |
558 | (adsp_inputC[sVal] < inputC) | |
559 | && (adsp_inputQ[sVal]->state == sOpen)) { | |
560 | inputC = adsp_inputC[sVal]; | |
561 | sSav = sVal; | |
562 | } | |
563 | } | |
564 | } | |
565 | if (sVal < sMin) { | |
8f6c56a5 A |
566 | if (!flag || (inputC == 255)) { |
567 | ATENABLE(s, adspall_lock); | |
1c79356b | 568 | return 0; |
8f6c56a5 | 569 | } |
1c79356b A |
570 | sVal = sSav; |
571 | } | |
572 | sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); | |
8f6c56a5 | 573 | ATENABLE(s, adspall_lock); |
1c79356b | 574 | adsp_dequeue_ccb(sp); |
8f6c56a5 | 575 | ATDISABLE(s, adspall_lock); |
1c79356b A |
576 | adsp_inputC[sVal]++; |
577 | sp->otccbLink = adsp_inputQ[sVal]; | |
578 | adsp_inputQ[sVal] = sp; | |
579 | if (!flag) | |
580 | adsp_pidM[sVal] = sp->pid; | |
8f6c56a5 | 581 | ATENABLE(s, adspall_lock); |
1c79356b A |
582 | return sVal; |
583 | } | |
584 | ||
585 | int | |
586 | adspDeassignSocket(sp) | |
587 | CCBPtr sp; | |
588 | { | |
589 | unsigned char sVal; | |
590 | CCBPtr curr_sp; | |
591 | CCBPtr prev_sp; | |
592 | int pid = 0; | |
8f6c56a5 | 593 | int s, l; |
1c79356b A |
594 | |
595 | dPrintf(D_M_ADSP, D_L_TRACE, ("adspDeassignSocket: pid=%d,s=%d\n", | |
596 | sp->pid, sp->localSocket)); | |
8f6c56a5 | 597 | ATDISABLE(s, adspall_lock); |
1c79356b A |
598 | sVal = sp->localSocket; |
599 | if ((curr_sp = adsp_inputQ[sVal]) != 0) { | |
600 | prev_sp = 0; | |
601 | while (curr_sp != sp) { | |
602 | prev_sp = curr_sp; | |
603 | curr_sp = curr_sp->otccbLink; | |
604 | } | |
605 | if (curr_sp) { | |
8f6c56a5 | 606 | ATDISABLE(l, sp->lockRemove); |
1c79356b A |
607 | if (prev_sp) |
608 | prev_sp->otccbLink = sp->otccbLink; | |
609 | else | |
610 | adsp_inputQ[sVal] = sp->otccbLink; | |
8f6c56a5 | 611 | ATENABLE(l, sp->lockRemove); |
1c79356b A |
612 | if (adsp_inputQ[sVal]) |
613 | adsp_inputC[sVal]--; | |
614 | else { | |
615 | pid = adsp_pidM[sVal]; | |
616 | adsp_inputC[sVal] = 0; | |
617 | adsp_pidM[sVal] = 0; | |
618 | } | |
619 | sp->ccbLink = 0; | |
620 | sp->otccbLink = 0; | |
621 | sp->localSocket = 0; | |
8f6c56a5 | 622 | ATENABLE(s, adspall_lock); |
1c79356b A |
623 | return pid ? 0 : 1; |
624 | } | |
625 | } | |
8f6c56a5 | 626 | ATENABLE(s, adspall_lock); |
1c79356b A |
627 | |
628 | dPrintf(D_M_ADSP, D_L_ERROR, | |
629 | ("adspDeassignSocket: closing, no CCB block, trouble ahead\n")); | |
630 | return -1; | |
631 | } /* adspDeassignSocket */ | |
632 | ||
633 | /* | |
634 | * remove CCB from the use list | |
635 | */ | |
636 | void | |
637 | adsp_dequeue_ccb(sp) | |
638 | CCB *sp; | |
639 | { | |
8f6c56a5 | 640 | int s; |
1c79356b | 641 | |
8f6c56a5 | 642 | ATDISABLE(s, adspall_lock); |
1c79356b A |
643 | if (sp == ccb_used_list) { |
644 | if ((ccb_used_list = sp->otccbLink) != 0) | |
645 | sp->otccbLink->ccbLink = 0; | |
646 | } else if (sp->ccbLink) { | |
647 | if ((sp->ccbLink->otccbLink = sp->otccbLink) != 0) | |
648 | sp->otccbLink->ccbLink = sp->ccbLink; | |
649 | } | |
650 | ||
651 | sp->otccbLink = 0; | |
652 | sp->ccbLink = 0; | |
8f6c56a5 | 653 | ATENABLE(s, adspall_lock); |
1c79356b A |
654 | } |
655 | ||
656 | void SndMsgUp(gref, mp) | |
657 | gref_t *gref; /* WRITE queue */ | |
658 | gbuf_t *mp; | |
659 | { | |
660 | /* | |
661 | dPrintf(D_M_ADSP, D_L_TRACE, | |
662 | ("SndMsgUp: gref=0x%x, mbuf=0x%x\n", (unsigned)gref, (unsigned)mp)); | |
663 | trace_mbufs(D_M_ADSP, " m", mp); | |
664 | */ | |
665 | atalk_putnext(gref, mp); | |
666 | } |