|
|
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.