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