|
|
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) 1995-1998 Apple Computer, Inc.
27: *
28: * The information contained herein is subject to change without
29: * notice and should not be construed as a commitment by Apple
30: * Computer, Inc. Apple Computer, Inc. assumes no responsibility
31: * for any errors that may appear.
32: *
33: * Confidential and Proprietary to Apple Computer, Inc.
34: *
35: */
36: #include <h/sysglue.h>
37: #include <h/debug.h>
38: #include <sys/malloc.h>
39: #ifdef _AIX
40: #include <sys/device.h>
41: #else
42: #include <sys/file.h>
43: #endif
44:
45: int (*sys_ATsocket)() = 0;
46: int (*sys_ATgetmsg)() = 0;
47: int (*sys_ATputmsg)() = 0;
48: int (*sys_ATPsndreq)() = 0;
49: int (*sys_ATPsndrsp)() = 0;
50: int (*sys_ATPgetreq)() = 0;
51: int (*sys_ATPgetrsp)() = 0;
52:
53: #ifndef _AIX
54:
55: int ATsocket(proc, uap, retval)
56: void *proc;
57: struct {
58: int proto;
59: } *uap;
60: int *retval;
61: {
62: int err;
63:
64: if (sys_ATsocket)
65: *retval = (*sys_ATsocket)(uap->proto, &err, proc);
66: else {
67: *retval = -1;
68: err = ENXIO;
69: }
70: return err;
71: }
72:
73: int ATgetmsg(proc, uap, retval)
74: void *proc;
75: struct {
76: int fd;
77: void *ctlptr;
78: void *datptr;
79: int *flags;
80: } *uap;
81: int *retval;
82: {
83: int err;
84:
85: if (sys_ATgetmsg)
86: *retval = (*sys_ATgetmsg)(uap->fd,
87: uap->ctlptr, uap->datptr, uap->flags, &err, proc);
88: else {
89: *retval = -1;
90: err = ENXIO;
91: }
92: return err;
93: }
94:
95: int ATputmsg(proc, uap, retval)
96: void *proc;
97: struct {
98: int fd;
99: void *ctlptr;
100: void *datptr;
101: int flags;
102: } *uap;
103: int *retval;
104: {
105: int err;
106:
107: if (sys_ATputmsg)
108: *retval = (*sys_ATputmsg)(uap->fd,
109: uap->ctlptr, uap->datptr, uap->flags, &err, proc);
110: else {
111: *retval = -1;
112: err = ENXIO;
113: }
114: return err;
115: }
116:
117: int ATPsndreq(proc, uap, retval)
118: void *proc;
119: struct {
120: int fd;
121: unsigned char *buf;
122: int len;
123: int nowait;
124: } *uap;
125: int *retval;
126: {
127: int err;
128:
129: if (sys_ATPsndreq)
130: *retval = (*sys_ATPsndreq)(uap->fd,
131: uap->buf, uap->len, uap->nowait, &err, proc);
132: else {
133: *retval = -1;
134: err= ENXIO;
135: }
136: return err;
137: }
138:
139: int ATPsndrsp(proc, uap, retval)
140: void *proc;
141: struct {
142: int fd;
143: unsigned char *respbuff;
144: int resplen;
145: int datalen;
146: } *uap;
147: int *retval;
148: {
149: int err;
150:
151: if (sys_ATPsndrsp)
152: *retval = (*sys_ATPsndrsp)(uap->fd,
153: uap->respbuff, uap->resplen, uap->datalen, &err, proc);
154: else {
155: *retval = -1;
156: err = ENXIO;
157: }
158: return err;
159: }
160:
161: int ATPgetreq(proc, uap, retval)
162: void *proc;
163: struct {
164: int fd;
165: unsigned char *buf;
166: int buflen;
167: } *uap;
168: int *retval;
169: {
170: int err;
171:
172: if (sys_ATPgetreq)
173: *retval = (*sys_ATPgetreq)(uap->fd,
174: uap->buf, uap->buflen, &err, proc);
175: else {
176: *retval = -1;
177: err = ENXIO;
178: }
179: return err;
180: }
181:
182: int ATPgetrsp(proc, uap, retval)
183: void *proc;
184: struct {
185: int fd;
186: unsigned char *bdsp;
187: } *uap;
188: int *retval;
189: {
190: int err;
191:
192: if (sys_ATPgetrsp)
193: *retval = (*sys_ATPgetrsp)(uap->fd, uap->bdsp, &err, proc);
194: else {
195: *retval = -1;
196: err = ENXIO;
197: }
198: return err;
199: }
200:
201: void *at_cl_alloc(size, wait)
202: int size; /* in bytes */
203: int wait;
204: {
205: return((void *)_MALLOC(size, M_MCLUST, (wait)? M_WAITOK: M_NOWAIT));
206: }
207:
208: void at_cl_free(buf)
209: void *buf;
210: {
211: FREE(buf, M_MCLUST);
212: }
213:
214: int atalk_closeref(fp, grefp)
215: struct file *fp;
216: gref_t **grefp;
217: {
218: *grefp = (gref_t *)fp->f_data;
219: fp->f_data = 0;
220: return 0;
221: }
222:
223: int atalk_openref(gref, retfd, proc)
224: gref_t *gref;
225: int *retfd;
226: struct proc *proc;
227: {
228: extern int _ATread(), _ATwrite(),_ATioctl(), _ATselect(), _ATclose();
229: static struct fileops fileops = {_ATread, _ATwrite, _ATioctl, _ATselect, _ATclose};
230: int err, fd;
231: struct file *fp;
232:
233: if ((err = falloc(proc, &fp, &fd)) != 0)
234: return err;
235: fp->f_flag = FREAD|FWRITE;
236: /*##### LD 5/7/96 Warning: we don't have a "DTYPE_OTHER" for
237: * Rhapsody, so defines DTYPE_ATALK as DTYPE_SOCKET...
238: */
239: fp->f_type = DTYPE_ATALK+1;
240: fp->f_ops = &fileops;
241: *fdflags(proc, fd) &= ~UF_RESERVED;
242: *retfd = fd;
243: fp->f_data = (void *)gref;
244: gref->next = (void *)fp;
245: return 0;
246: }
247:
248: int atalk_getref(fp, fd, grefp, proc)
249: struct file *fp;
250: int fd;
251: gref_t **grefp;
252: struct proc *proc;
253: {
254: if (fp == 0) {
255: int error = fdgetf(proc, fd, &fp);
256:
257: if (error) {
258:
259: *grefp = (gref_t *)0;
260: return EBADF;
261: }
262: }
263: if ((*grefp = (gref_t *)fp->f_data) == 0)
264: return EBADF;
265: return 0;
266: }
267:
268: gbuf_t *gbuf_alloc_wait(size, wait)
269: int size;
270: int wait;
271: {
272: gbuf_t *m;
273: /*
274: * ### LD 5/12/97 Allocate only a mbuf if size is ok,
275: * otherwise add a cluster.
276: */
277: if (size > MCLBYTES) {
278: void *buf;
279: if ((buf = at_cl_alloc(size, wait)) == 0) {
280: #ifdef APPLETALK_DEBUG
281: kprintf("gbuf_alloc: size =%d at_cl_alloc failed\n",
282: size);
283: #endif
284: return NULL;
285: }
286: if ((m = (gbuf_t *)gbuf_attach( buf, at_cl_free, size, 0)) == 0) {
287: #ifdef APPLETALK_DEBUG
288: kprintf("gbuf_alloc: size =%d gbuf_attach failed\n",
289: size);
290: #endif
291: at_cl_free(buf);
292: return NULL;
293: }
294: /*
295: kprintf("gbuf_alloc: allocated with MALLOC m=%x size =%d \n",
296: m, size);
297: */
298: }
299: else {
300: if (!(m =
301: (gbuf_t *)m_gethdr((wait)? M_WAIT: M_DONTWAIT, MSG_DATA)))
302: return(NULL);
303: if (size > MHLEN) {
304: MCLGET(m, (wait)? M_WAIT: M_DONTWAIT);
305: if (!(m->m_flags & M_EXT)) {
306: (void)m_free(m);
307: return(NULL);
308: }
309: }
310: }
311: gbuf_next(m) = 0;
312: gbuf_cont(m) = 0;
313: gbuf_wset(m,0);
314: return m;
315: } /* gbuf_alloc_wait */
316:
317: gbuf_t *gbuf_alloc(size, pri)
318: int size;
319: int pri;
320: {
321: return(gbuf_alloc_wait(size, FALSE));
322: }
323:
324: void gbuf_set_type(m, mtype)
325: gbuf_t *m;
326: short mtype;
327: {
328: MBUF_LOCK();
329: mbstat.m_mtypes[m->m_type]--;
330: m->m_type = mtype;
331: mbstat.m_mtypes[mtype]++;
332: MBUF_UNLOCK();
333: }
334:
335: void gbuf_freeb(m)
336: gbuf_t *m;
337: {
338: if (m) {
339: /*
340: kprintf("gbuf_freeb: calling m_free for m=%x\n", m);
341: */
342: (void)m_free((struct mbuf *)m);
343: }
344: }
345:
346: /*
347: * LD 5/12/97 Added for Rhapsody, defines a m_clattach function that:
348: * "Allocates an mbuf structure and attaches an external cluster."
349: */
350:
351: struct mbuf *m_clattach(extbuf, extfree, extsize, extarg, wait)
352: caddr_t extbuf;
353: int (*extfree)();
354: int extsize;
355: int extarg;
356: int wait;
357: {
358: struct mbuf *m;
359:
360: m = m_gethdr(wait, MSG_DATA);
361: /*
362: kprintf("m_clattach: for mbuf = %x of extbuf =%x extsize=%d extfree=%x\n",
363: m, extbuf, extsize, extfree);
364: */
365: if (m == NULL)
366: return (NULL);
367: m->m_ext.ext_buf = extbuf;
368: m->m_ext.ext_free = extfree;
369: m->m_ext.ext_size = extsize;
370: m->m_ext.ext_arg = extarg;
371: m->m_ext.ext_refs.forward = m->m_ext.ext_refs.backward =
372: &m->m_ext.ext_refs;
373: m->m_data = extbuf;
374: m->m_flags |= M_EXT;
375: m->m_pkthdr.len = extsize;
376: m->m_len = extsize;
377:
378: return (m);
379:
380: }
381: void *atalk_timeout(func, arg, ticks)
382: void (*func)();
383: void *arg;
384: int ticks;
385: {
386: /*
387: dPrintf(D_M_ATP,D_L_VERBOSE,
388: "atalk_timeout: func=%x,arg=%x,time=%d\n", func,arg,ticks, 0, 0);
389: */
390: timeout(func, arg, ticks);
391: return arg;
392: }
393:
394: void atalk_untimeout(func, arg, trb)
395: void (*func)();
396: void *arg;
397: void *trb;
398: {
399: /*
400: dPrintf(D_M_ATP,D_L_VERBOSE,
401: "atalk_untimeout: func=%x,arg=%x, trb=%d\n", func,arg,trb, 0, 0);
402: */
403: untimeout(func, arg);
404: }
405:
406: #else /* This AIX code (to the end of this file) is no longer supported. */
407:
408: int ATsocket(proto) /* AIX version */
409: int proto;
410: {
411: int err, rc = -1;
412:
413: if (sys_ATsocket)
414: rc = (*sys_ATsocket)(proto, &err, 0);
415: else
416: err = ENXIO;
417: if (err)
418: setuerror(err);
419: return rc;
420: }
421:
422: int ATgetmsg(fd, ctlptr, datptr, flags) /* AIX version */
423: int fd;
424: void *ctlptr;
425: void *datptr;
426: int *flags;
427: {
428: int err, rc = -1;
429:
430: if (sys_ATgetmsg)
431: rc = (*sys_ATgetmsg)(fd, ctlptr, datptr, flags, &err, 0);
432: else
433: err = ENXIO;
434: if (err)
435: setuerror(err);
436: return rc;
437: }
438:
439: int ATputmsg(fd, ctlptr, datptr, flags) /* AIX version */
440: int fd;
441: void *ctlptr;
442: void *datptr;
443: int flags;
444: {
445: int err, rc = -1;
446:
447: if (sys_ATputmsg)
448: rc = (*sys_ATputmsg)(fd, ctlptr, datptr, flags, &err, 0);
449: else
450: err = ENXIO;
451: if (err)
452: setuerror(err);
453: return rc;
454: }
455:
456: int ATPsndreq(fd, buf, len, nowait) /* AIX version */
457: int fd;
458: unsigned char *buf;
459: int len;
460: int nowait;
461: {
462: int err, rc = -1;
463:
464: if (sys_ATPsndreq)
465: rc = (*sys_ATPsndreq)(fd, buf, len, nowait, &err, 0);
466: else
467: err = ENXIO;
468: if (err)
469: setuerror(err);
470: return rc;
471: }
472:
473: int ATPsndrsp(fd, respbuff, resplen, datalen) /* AIX version */
474: int fd;
475: unsigned char *respbuff;
476: int resplen;
477: int datalen;
478: {
479: int err, rc = -1;
480:
481: if (sys_ATPsndrsp)
482: rc = (*sys_ATPsndrsp)(fd, respbuff, resplen, datalen, &err, 0);
483: else
484: err = ENXIO;
485: if (err)
486: setuerror(err);
487: return rc;
488: }
489:
490: int ATPgetreq(fd, buf, buflen) /* AIX version */
491: int fd;
492: unsigned char *buf;
493: int buflen;
494: {
495: int err, rc = -1;
496:
497: if (sys_ATPgetreq)
498: rc = (*sys_ATPgetreq)(fd, buf, buflen, &err, 0);
499: else
500: err = ENXIO;
501: if (err)
502: setuerror(err);
503: return rc;
504: }
505:
506: int ATPgetrsp(fd, bdsp) /* AIX version */
507: int fd;
508: unsigned char *bdsp;
509: {
510: int err, rc = -1;
511:
512: if (sys_ATPgetrsp)
513: rc = (*sys_ATPgetrsp)(fd, bdsp, &err, 0);
514: else
515: err = ENXIO;
516: if (err)
517: setuerror(err);
518: return rc;
519: }
520:
521: void *atalk_kalloc(size) /* AIX version */
522: int size;
523: {
524: return (void *)xmalloc(size, 2, pinned_heap);
525: }
526:
527: void atalk_kfree(buf) /* AIX version */
528: void *buf;
529: {
530: xmfree(buf, pinned_heap);
531: }
532:
533: int atalk_closeref(fp, grefp) /* AIX version */
534: struct file *fp;
535: gref_t **grefp;
536: {
537: *grefp = (gref_t *)fp->f_data;
538: fp->f_data = 0;
539: return 0;
540: }
541:
542: int atalk_openref(gref, retfd, proc) /* AIX version */
543: gref_t *gref;
544: int *retfd;
545: void *proc;
546: {
547: extern int _ATrw(), _ATioctl(), _ATselect(), _ATclose(), _ATstat();
548: static struct fileops fileops = {_ATrw, _ATioctl, _ATselect, _ATclose, _ATstat};
549: int err, fd;
550: struct file *fp;
551: void *crp;
552:
553: crp = (void *)crref();
554: #ifdef _AIX
555: if ((err = ufdcreate(FREAD|FWRITE,
556: &fileops, 0, DTYPE_OTHER, &fd, crp)) != 0)
557: #else
558: if ((err = ufdcreate(FREAD|FWRITE,
559: &fileops, 0, DTYPE_ATALK, &fd, crp)) != 0)
560: #endif
561: return err;
562: *retfd = fd;
563: fp = U.U_ufd[fd].fp;
564: fp->f_data = (void *)gref;
565: gref->next = (void *)fp;
566: return 0;
567: }
568:
569: int atalk_getref(fp, fd, grefp, proc) /* AIX version */
570: struct file *fp;
571: int fd;
572: gref_t **grefp;
573: struct proc *proc;
574: {
575: if (fp == 0) {
576: if ((fd < 0) || (fd > U.U_maxofile) || ((fp = U.U_ufd[fd].fp) == 0)) {
577: *grefp = (gref_t *)0;
578: return EBADF;
579: }
580: }
581: if ((*grefp = (gref_t *)fp->f_data) == 0)
582: return EBADF;
583: return 0;
584: }
585:
586: gbuf_t *gbuf_alloc(size, pri) /* AIX version */
587: int size;
588: int pri;
589: {
590: gbuf_t *m;
591:
592: m = (size > MHLEN) ? (gbuf_t *)m_getclustm(M_DONTWAIT, MSG_DATA, size)
593: : (gbuf_t *)m_gethdr(M_DONTWAIT, MSG_DATA);
594: #ifdef APPLETALK_DEBUG
595: kprintf("gbuf_alloc: for size = %d m=%x\n", size, m);
596: #endif
597: gbuf_next(m) = 0;
598: gbuf_cont(m) = 0;
599: gbuf_wset(m,0);
600: return m;
601: }
602:
603: void gbuf_freeb(m) /* AIX version */
604: gbuf_t *m;
605: {
606: if (m)
607: m_free(m);
608: }
609:
610: static struct trb *trb_freehead = 0;
611: static struct trb *trb_freetail = 0;
612: static struct trb *trb_pendhead = 0;
613: static int trb_cnt = 0;
614: static atlock_t trb_lock;
615:
616: static void atalk_rem_timeoutcf() /* AIX version */
617: {
618: register int s;
619: register struct trb *trb;
620: register struct trb *tmp_freehead, *tmp_pendhead;
621:
622: ATDISABLE(s, trb_lock);
623: tmp_freehead = trb_freehead;
624: trb_freehead = 0;
625: tmp_pendhead = trb_pendhead;
626: trb_pendhead = 0;
627: trb_cnt = 0;
628: ATENABLE(s, trb_lock);
629: while ((trb = tmp_pendhead) != 0) {
630: tmp_pendhead = trb->to_next;
631: while (tstop(trb));
632: tfree(trb);
633: }
634: while ((trb = tmp_freehead) != 0) {
635: tmp_freehead = trb->to_next;
636: tfree(trb);
637: }
638: dPrintf(D_M_ATP,D_L_ERROR, "atalk: timer stopped!\n",0,0,0,0,0);
639: }
640:
641: static void atalk_timeoutcf(cnt) /* AIX version */
642: int cnt;
643: {
644: register int i;
645: register struct trb *trb;
646:
647: if (trb_freehead == 0) {
648: for (i=0; i < cnt-1; i++) {
649: trb = (struct trb *)talloc();
650: trb->to_next = trb_freehead;
651: trb_freehead = trb;
652: if (!i) trb_freetail = trb;
653: trb_cnt++;
654: }
655: }
656: ATLOCKINIT(trb_lock);
657: }
658:
659: static void atalk_clock(trb) /* AIX version */
660: register struct trb *trb;
661: {
662: register int s;
663: register struct trb *next;
664: void (*tof)();
665: void *arg;
666:
667: ATDISABLE(s, trb_lock);
668: if (trb_pendhead && trb->func) {
669: /*
670: * remove the timeout from the pending queue
671: */
672: if (trb_pendhead == trb)
673: trb_pendhead = trb->to_next;
674: else {
675: for (next=trb_pendhead; next->to_next; next=next->to_next) {
676: if (next->to_next == trb) {
677: next->to_next = trb->to_next;
678: trb->func = 0;
679: break;
680: }
681: }
682: if (trb->func) {
683: dPrintf(D_M_ATP,D_L_WARNING,
684: "atalk_clock: %d,%x,%x\n", trb_cnt,trb,trb_pendhead,0,0);
685: /*
686: * we have not found the trb in the pending list - something
687: * has gone wrong here. maybe the trb has been returned to
688: * the free list; in which case, we should simply ignore
689: * this timeout event!
690: */
691: for (next=trb_freehead; next; next=next->to_next) {
692: if (next == trb)
693: {
694: ATENABLE(s, trb_lock);
695: return;
696: }
697: }
698: /*
699: * the trb is not in the free list either - something has
700: * really gone wacky here! all we can do now is put the
701: * trb back into the free list and hope that it will be ok.
702: */
703: trb->to_next = 0;
704: if (trb_freehead)
705: trb_freetail->to_next = trb;
706: else
707: trb_freehead = trb;
708: trb_freetail = trb;
709: trb_cnt++;
710: ATENABLE(s, trb_lock);
711: return;
712: }
713: }
714:
715: /*
716: * process the timeout
717: */
718: trb->func = 0;
719: trb->to_next = 0;
720: tof = trb->tof;
721: trb->tof = 0;
722: arg = (void *)trb->func_data;
723: trb->func_data = 999;
724: if (trb_freehead)
725: trb_freetail->to_next = trb;
726: else
727: trb_freehead = trb;
728: trb_freetail = trb;
729: trb_cnt++;
730: ATENABLE(s, trb_lock);
731: if (tof) {
732: dPrintf(D_M_ATP,D_L_VERBOSE, "atalk_clock: func=%x, arg=%x, %d\n",
733: tof,arg,trb_cnt,0,0);
734: (*tof)(arg);
735: } else {
736: dPrintf(D_M_ATP,D_L_ERROR, "atalk_clock: func=%x, arg=%x, %d\n",
737: tof,arg,trb_cnt,0,0);
738: }
739: } else
740: ATENABLE(s, trb_lock);
741: }
742:
743: void *atalk_timeout(func, arg, ticks) /* AIX version */
744: void (*func)();
745: void *arg;
746: int ticks;
747: {
748: register int s;
749: register struct trb *trb;
750:
751: dPrintf(D_M_ATP,D_L_VERBOSE,
752: "atalk_timeout: func=%x,arg=%x,time=%d, %d,%x\n", func,arg,ticks,trb_cnt,trb_pendhead);
753: /*
754: * set up the timeout request
755: */
756: ATDISABLE(s, trb_lock);
757: if ((trb = trb_freehead) == 0) {
758: ATENABLE(s, trb_lock);
759: dPrintf(D_M_ATP,D_L_WARNING,
760: "atalk_timeout: NO TRB! time=%d, %d\n", ticks,trb_cnt,0,0,0);
761: return 0;
762: }
763: trb_freehead = trb->to_next;
764: trb->to_next = trb_pendhead;
765: trb_pendhead = trb;
766: trb_cnt--;
767: trb->timeout.it_value.tv_sec = ticks / HZ;
768: trb->timeout.it_value.tv_nsec = (ticks % HZ) * (NS_PER_SEC / HZ);
769: trb->knext = 0;
770: trb->kprev = 0;
771: trb->flags = 0;
772: trb->tof = func;
773: trb->func = (void (*)())atalk_clock;
774: trb->func_data = (ulong)arg;
775: trb->ipri = PL_IMP;
776: trb->id = -1;
777:
778: /*
779: * start the timeout
780: */
781: ATENABLE(s, trb_lock);
782: tstart(trb);
783: return (void *)trb;
784: }
785:
786: void atalk_untimeout(func, arg, trb) /* AIX version */
787: void (*func)();
788: void *arg;
789: register struct trb *trb;
790: {
791: register int s;
792: register struct trb *next;
793:
794: dPrintf(D_M_ATP,D_L_VERBOSE,
795: "atalk_untimeout: func=%x,arg=%x, %d\n", func,arg,trb_cnt,0,0);
796:
797: ATDISABLE(s, trb_lock);
798: if (trb == 0) {
799: for (trb=trb_pendhead; trb; trb=trb->to_next) {
800: if ((func == trb->tof) && (arg == (void *)trb->func_data))
801: break;
802: }
803: }
804: if (trb && (trb->func == (void (*)())atalk_clock)
805: && (func == trb->tof) && (arg == (void *)trb->func_data)) {
806: trb->func_data = 999;
807: if (!(trb->flags & T_PENDING))
808: {
809: trb->tof = 0;
810: ATENABLE(s, trb_lock);
811: return;
812: }
813: trb->func = 0;
814: while (tstop(trb));
815: if (trb_pendhead == trb)
816: trb_pendhead = trb->to_next;
817: else {
818: for (next=trb_pendhead; next->to_next != trb; next=next->to_next) {
819: if (next->to_next == 0) {
820: ATENABLE(s, trb_lock);
821: dPrintf(D_M_ATP,D_L_WARNING,
822: "atalk_untimeout: UNKNOWN TRB %x...\n",trb,0,0,0,0);
823: return;
824: }
825: }
826: next->to_next = trb->to_next;
827: }
828: trb->to_next = 0;
829: trb_freetail->to_next = trb;
830: trb_freetail = trb;
831: trb_cnt++;
832: }
833: ATENABLE(s, trb_lock);
834: }
835:
836: int config_atalk(dev, cmd, uiop) /* AIX only */
837: dev_t dev;
838: int cmd;
839: void *uiop;
840: {
841: static int loaded = 0;
842: int err, nest;
843:
844: err = 0;
845: nest = lockl(&kernel_lock, LOCK_SHORT);
846:
847: if (cmd == CFG_INIT) {
848: if (loaded)
849: goto out;
850: vm_protect(0, 4096, 3);
851: atalk_timeoutcf(256);
852: atalk_load();
853: loaded = 1;
854:
855: } else if (cmd == CFG_TERM) {
856: if (!loaded)
857: goto out;
858: atalk_rem_timeoutcf();
859: atalk_unload();
860: loaded = 0;
861:
862: } else
863: err = EINVAL;
864:
865: out:
866: if (nest != LOCK_NEST)
867: unlockl(&kernel_lock);
868: return(err);
869: }
870:
871: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.