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