|
|
1.1 ! root 1: /* ! 2: * ibv.c - DEC IBV-11A IEEE INTERFACE DRIVER ! 3: * Version III (modified for portability, burst reads, ! 4: * and easier secondary addressing) ! 5: * DLA 8/1/85 ! 6: * ! 7: * ! 8: changed for the Qbus VAX under ! 9: unix 10e T. Siegrist 19-Nov-94 ! 10: ! 11: the base address is needed for two registers, the csr and ibs ! 12: ! 13: the board generates 4 interrupts: ! 14: - err error 420 ! 15: - srq service request 424 ! 16: - tlr talker 430 ! 17: - lnr listener 434 ! 18: ! 19: To Install: ! 20: ! 21: low core section: ! 22: . = ZERO + 420 ! 23: ! 24: ibverr; br5 ! 25: ibvsrq; br5 ! 26: ibvtlr; br5 ! 27: ibvlnr; br5 ! 28: ! 29: ! 30: .globl _iberr ! 31: ibverr: jsr r0,call; jmp _iberr ! 32: ! 33: .globl _ibsrq ! 34: ibvsrq: jsr r0,call; jmp _ibsrq ! 35: ! 36: .globl _ibwint ! 37: ibvtlr: jsr r0,call; jmp _ibwint ! 38: ! 39: .globl _ibrint ! 40: ibvlnr: jsr r0,call; jmp _ibrint ! 41: ! 42: c.c section: ! 43: int ibopen(), ibclose(), ibread(), ibwrite(), ibioctl(); ! 44: in cdevsw, add: ! 45: ibopen, ibclose, ibread, ibwrite, ibioctl, nulldev, 0, ! 46: then add other code ! 47: ! 48: Install ibv.h in /usr/include for user access to regular IEEE commands ! 49: */ ! 50: ! 51: ! 52: /* define NOSDC for no SDC command sent with device open. ! 53: * allows full use of Shell - level I/O without resetting device ! 54: * each time. "friendly" systems only! ! 55: */ ! 56: #define NOSDC ! 57: ! 58: /* ! 59: #include "../h/param.h" ! 60: #include "../h/dir.h" ! 61: #include "../h/user.h" ! 62: #include "../h/proc.h" ! 63: #include "../h/var.h" ! 64: */ ! 65: ! 66: #include <sys/param.h> ! 67: #include <sys/dir.h> ! 68: #include <sys/user.h> ! 69: #include <sys/ubaddr.h> ! 70: #include <sys/proc.h> ! 71: #include <sys/systm.h> ! 72: #include <sys/ibv.h> ! 73: ! 74: #define IB_ADDR 0775000 /* IBV-11 base address */ ! 75: #define IB_VEC 420 /* Interrupt vector */ ! 76: #define NIBDEV 31 /* max devices on IEEE bus */ ! 77: /* (Note the IBV-11 is limited to 15 devs online at a time, but ! 78: * minors for these may range 1-30. 0 will be for the raw bus. ! 79: * Attempting an open on any minor >= NIBDEV sends kill to all bus ! 80: * processes and unconditionally resets bus.) ! 81: */ ! 82: ! 83: #define QMAX 75 /* max queue characters */ ! 84: #define TTIME 1800 /* ibtimer return interval in system Hz */ ! 85: #define IQLOOP 750 /* max untimed inqueue wait loop */ ! 86: #define OQLOOP 750 /* max untimed outqueue wait loop */ ! 87: /* Pri range while awaiting IEEE bus, > PZERO allows proc to be signaled. ! 88: * Range is reset to IBSPRI when IBHPRI is reached. ! 89: */ ! 90: #define IBLPRI PZERO+5 /* multi-user low value */ ! 91: #define IBSPRI PZERO+15 /* multi-user start value */ ! 92: #define IBHPRI PZERO+25 /* multi-user high value */ ! 93: #define IBXPRI IBLPRI+5 /* exclusive-use wait value */ ! 94: ! 95: ! 96: /* IB STATUS FLAGS */ ! 97: #define IBLOCK 001 /* locked */ ! 98: #define IBATEOF 002 /* at EOF */ ! 99: #define IBERR 010 /* bus error */ ! 100: #define IBULOCK 070 /* unlocking mask - LOCK and EOF bits only! */ ! 101: ! 102: /* HARDWARE CONTROL */ ! 103: #define IBSRQ (1<<15) /* csr definitions: */ ! 104: #define IBER2 (1<<14) ! 105: #define IBER1 (1<<13) ! 106: #define IBCMD (1<<10) ! 107: #define IBTKR (1<<9) ! 108: #define IBLNR (1<<8) ! 109: #define IBACC (1<<7) ! 110: #define IBIEN (1<<6) ! 111: #define IBTON (1<<5) ! 112: #define IBLON (1<<4) ! 113: #define IBIBC (1<<3) ! 114: #define IBREM (1<<2) ! 115: #define IBEOP (1<<1) ! 116: #define IBTCS (1<<0) ! 117: ! 118: #define BEOI (1<<15) /* ibs definitions: */ ! 119: #define BATN (1<<14) ! 120: #define BIFC (1<<13) ! 121: #define BREN (1<<12) ! 122: #define BSRQ (1<<11) ! 123: #define BRFD (1<<10) ! 124: #define BDAV (1<<9) ! 125: #define BDAC (1<<8) ! 126: ! 127: #define IBATT (IBREM | IBIEN | IBTCS) /* IB11 take control */ ! 128: #define IBTALK (IBREM | IBIEN | IBTON) /* IB11 talker */ ! 129: #define IBLISTEN (IBREM | IBIEN | IBLON | IBACC) /* IB11 listener */ ! 130: #define IBIFC (IBREM | IBIEN | IBIBC) /* IB11 send IFC */ ! 131: #define IBWAIT (IBREM | IBIEN) /* IB11 standby */ ! 132: ! 133: ! 134: /* structure definitions */ ! 135: struct clist { /* standard character queue */ ! 136: int c_cc; /* character count */ ! 137: char *c_cf; /* pointer to first char */ ! 138: char *c_cl; /* pointer to last char */ ! 139: }; ! 140: ! 141: struct ibdevs { /* bus devices */ ! 142: short pid; /* proc id controlling dev */ ! 143: short signo; /* sig no. to be sent on SRQ */ ! 144: char sbyte; /* SRQ status return byte (returned as int) */ ! 145: char pri; /* bus use priority penalty */ ! 146: } bdev[NIBDEV]; ! 147: ! 148: struct device { /* the IBV-11 hardware itself */ ! 149: unsigned short csr; /* control & status register */ ! 150: unsigned short ibs; /* instrument bus status register */ ! 151: /* these are 16-bit registers */ ! 152: }; ! 153: ! 154: struct ib { /* IBV-11 driver */ ! 155: unsigned state; /* current status flags */ ! 156: int count; /* number of currently open devices */ ! 157: struct clist iq; /* char in queue */ ! 158: struct clist oq; /* char out queue */ ! 159: } ib; ! 160: ! 161: ! 162: /* this is the absolute addressing scheme of the PDP/11 ! 163: it is now replaced by a relative addressing scheme, where ! 164: the address is fetched from the address array ubaddr ! 165: ! 166: #define ibc ((struct device *)IB_ADDR) /* the IBV-11 card */ ! 167: */ ! 168: ! 169: #define TEST(flag) (ib.state & flag) /* shorthand */ ! 170: ! 171: short ibrcount; /* read count */ ! 172: short mtq; /* queue activity test flags */ ! 173: short omtq; ! 174: short timer; /* timer active flag */ ! 175: extern int ibtimer(); /* ib timeout routine */ ! 176: ! 177: ! 178: ! 179: ibopen(dev,flag) ! 180: { register struct ibdevs *pbdev; ! 181: register s; ! 182: ! 183: if( minor(dev) >= NIBDEV ) /* unconditional bus reset */ ! 184: { for( pbdev = bdev; pbdev < &bdev[NIBDEV]; pbdev++ ) ! 185: { ibpsig( pbdev->pid, 9 ); /* SIGKILL all procs */ ! 186: pbdev->pid = 0; ! 187: } ! 188: ib.state = 0; ! 189: ib.count = 0; ! 190: ibc->csr = 0; ! 191: wakeup((caddr_t)&ib.state); ! 192: err: u.u_error = ENXIO; ! 193: return; ! 194: } ! 195: ! 196: /* Check this bus dev not inuse. Note bdev[0] is interface itself, ! 197: * with a nonzero pid if exclusive use. Since ibpsig returns 0 ! 198: * for a pid = 0, the double test is ok. ! 199: */ ! 200: pbdev = &bdev[minor(dev)]; ! 201: if( ibpsig(pbdev->pid, 0) || ibpsig(bdev[0].pid, 0) ) ! 202: { u.u_error = EBUSY; ! 203: return; ! 204: } ! 205: ! 206: /* ! 207: * Since polling of IEEE devices is so device dependent, there is ! 208: * no general way to tell if a particular one is online. Send cmds ! 209: * to clear. If interrupt has set error, there are NONE active. ! 210: */ ! 211: ! 212: pbdev->pri = IBLPRI; /* open gets highest priority */ ! 213: if( minor(dev) ) /* address device for clear */ ! 214: { bdev[0].pid = 0; /* should be! */ ! 215: ibsetup(dev, 1); /* await free bus, setup to listen */ ! 216: #ifndef NOSDC /* send SDC to dev, else just address & unaddress */ ! 217: putc(SDC, &ib.oq); ! 218: #endif ! 219: } else /* exclusive: await bus empty */ ! 220: { s = spl5(); /* allow to sleep before wakeup call */ ! 221: while( ib.count || TEST(IBLOCK) ) ! 222: sleep((caddr_t)&ib.state,IBXPRI); ! 223: ib.state = IBLOCK; ! 224: splx(s); ! 225: ibqdrain(); ! 226: putc(UNTALK, &ib.oq); ! 227: } ! 228: ! 229: ib.state |= IBATEOF; /* flag to free after last output */ ! 230: ! 231: if( ib.count ) s = IBATT; /* start command output */ ! 232: else s = IBIFC; /* open with IFC */ ! 233: ! 234: if( ibstart(s) ) /* iberr or timeout */ ! 235: { printf("\nNo active IEEE devices"); ! 236: return; ! 237: } ! 238: ! 239: pbdev->pid = u.u_procp->p_pid; /* this pid now owns dev */ ! 240: pbdev->signo = 0; /* clear SRQ returned signal */ ! 241: pbdev->sbyte = 0; /* clear SRQ status byte */ ! 242: pbdev->pri = IBSPRI; /* set starting I/O priority */ ! 243: ib.count++; /* update open count */ ! 244: } ! 245: ! 246: ! 247: ibclose(dev) ! 248: { bdev[minor(dev)].pid = 0; ! 249: if( --ib.count == 0 ) wakeup((caddr_t)&ib.state); ! 250: } ! 251: ! 252: ! 253: ibread(dev) ! 254: { register c; ! 255: ! 256: ibsetup(dev, 0); /* steal and setup bus */ ! 257: if( minor(dev) ) ! 258: if( ibstart(IBATT) ) return; /* addressing sequence */ ! 259: ! 260: /* ibrint() keeps track of count via ibrcount. If EOI observed ! 261: * on bus, ibrcount set to 0 to flag transaction complete. ! 262: */ ! 263: ibrcount = u.u_count; ! 264: ! 265: do{ /* break if usr read filled or EOI on bus: */ ! 266: if(ib.iq.c_cc == 0) ! 267: { if( ibrcount == 0 ) break; ! 268: if( ibstart(IBLISTEN) ) return; ! 269: } ! 270: } while( passc(getc(&ib.iq)) == 0 ); ! 271: ! 272: if( minor(dev) ) ! 273: { ib.state |= IBATEOF; ! 274: putc(UNTALK,&ib.oq); ! 275: ibstart(IBATT); ! 276: } else ibfree(); /* exclusive-use mode - no unaddressing */ ! 277: } ! 278: ! 279: ! 280: ibwrite(dev) ! 281: { register c; ! 282: register s; ! 283: ! 284: ibsetup(dev, 1); ! 285: if( minor(dev) ) ! 286: if( ibstart(IBATT) ) return; ! 287: ! 288: /* get chars from user buf. try at least once since u.u_count = 0 ! 289: * is not necessarily EOF at start . cpass will set u.u_error if ! 290: * bad buffer read occurs. ! 291: */ ! 292: ! 293: if( (c = cpass()) < 0 ) ! 294: { putc(UNLISTEN, &ib.oq); ! 295: s = IBATT; ! 296: goto out; ! 297: } ! 298: s = IBTALK; ! 299: putc(c, &ib.oq); ! 300: ! 301: do { if( (c = cpass()) < 0 ) break; ! 302: if( ib.oq.c_cc > QMAX ) /* restart ints and sleep */ ! 303: if( ibstart(IBTALK) ) return; ! 304: ! 305: putc(c, &ib.oq); ! 306: } while( u.u_count ) ; ! 307: ! 308: out: ib.state |= IBATEOF; ! 309: ibstart(s); ! 310: } ! 311: ! 312: ! 313: ! 314: ibioctl(dev, mode, arg, flag) ! 315: dev_t dev; ! 316: int mode; ! 317: caddr_t arg; ! 318: { register struct ibdevs *pbdev; ! 319: register s; ! 320: int cmd; ! 321: ! 322: pbdev = &bdev[minor(dev)]; ! 323: ! 324: switch( mode ) ! 325: { case IBSETPID: /* set new controlling pid */ ! 326: if( copyin( arg, (caddr_t)&pbdev->pid, ! 327: sizeof(pbdev->pid)) ) ! 328: { ! 329: err1: u.u_error = EFAULT; ! 330: return; ! 331: } ! 332: break; ! 333: case IBSETSIG: /* set SRQ return signal */ ! 334: if( copyin( arg, (caddr_t)&pbdev->signo, ! 335: sizeof(pbdev->signo)) ) goto err1; ! 336: break; ! 337: case IBGETSTAT: /* return SRQ status byte */ ! 338: /* insure no SRQ int while current byte is being ! 339: * cleared. sbyte is int for copyout() portability ! 340: */ ! 341: s = spl5(); ! 342: cmd = pbdev->sbyte; ! 343: if( copyout( (caddr_t)&cmd, arg, sizeof(cmd)) ) ! 344: u.u_error = EFAULT; ! 345: else pbdev->sbyte = 0; /* clear status byte */ ! 346: splx(s); ! 347: break; ! 348: case IBSENDC: /* send command */ ! 349: ibsetup(dev, 1); ! 350: if( copyin( arg, (caddr_t)&cmd, sizeof(cmd)) ) ! 351: { ibfree(); ! 352: goto err1; ! 353: } ! 354: putc(cmd, &ib.oq); ! 355: ! 356: if( minor(dev) ) /* addr cmds (less TCT) only: */ ! 357: { if( cmd & 020 || cmd == TCT ) ! 358: { ibfree(); ! 359: goto err2; ! 360: } ! 361: putc(UNLISTEN, &ib.oq); ! 362: } else /* "raw" bus mode: */ ! 363: { if( cmd == TCT ) ! 364: { /* release bus until EOI or signaled */ ! 365: if( ibstart(IBATT) ) return; ! 366: ibc->csr = IBREM; ! 367: mtq++; /* allow timeout wakeups */ ! 368: while( !(ibc->ibs & BEOI) && !issig() ) ! 369: sleep((caddr_t)&mtq, IBLPRI); ! 370: } else ! 371: { /* if extended (2byte) cmd, add to queue: */ ! 372: cmd >>= 8; ! 373: if( cmd ) putc(cmd,&ib.oq); ! 374: } ! 375: } ! 376: ib.state |= IBATEOF; ! 377: ibstart(IBATT); ! 378: break; ! 379: default: ! 380: err2: u.u_error = EINVAL; ! 381: } ! 382: } ! 383: ! 384: ! 385: ! 386: ibrint() ! 387: { ! 388: putc(ibc->ibs, &ib.iq); ! 389: ! 390: /* if not last char or buffer overflow, complete handshake ! 391: * and return. Otherwise, stop I/O by not completing handshake: ! 392: * ibstart() will complete and restart if more chars expected. ! 393: */ ! 394: ! 395: if( ibc->ibs & BEOI ) ibrcount = 0; /* last byte from sender */ ! 396: else ibrcount--; ! 397: ! 398: if( ibrcount && ib.iq.c_cc < QMAX ) ! 399: { ibc->ibs = 0; /* complete DAC handshake */ ! 400: mtq++; /* show activity to preclude timeout */ ! 401: } else ! 402: { omtq = mtq = 0; /* invalidate timer */ ! 403: wakeup((caddr_t)&mtq); ! 404: } ! 405: ! 406: } ! 407: ! 408: ! 409: ! 410: ibwint() ! 411: { if( ib.oq.c_cc == 0 ) /* empty queue - alert process */ ! 412: { omtq = mtq = 0; /* invalidate timer */ ! 413: wakeup((caddr_t)&mtq); ! 414: if( TEST(IBATEOF) ) ibfree(); ! 415: return; ! 416: } ! 417: ! 418: mtq++; /* show activity */ ! 419: ! 420: /* if last char on queue, set EOI and add UNLISTEN if reqd: */ ! 421: if( (ib.oq.c_cc == 1) && TEST(IBATEOF) && !(ibc->ibs & BATN) ) ! 422: { if( ibc->ibs & BEOI ) ! 423: { /* previous was last data in normal-use mode, ! 424: * and UNLISTEN is char on queue. ! 425: * remove EOI, set ATT for UNLISTEN cmd ! 426: * and output next loop ! 427: */ ! 428: ibc->csr = IBATT; ! 429: return; ! 430: } else ! 431: { /* last data: add EOI to output and queue ! 432: * UNLISTEN if normal use mode. ! 433: * Since ATEOF, bus will be freed afterwards ! 434: */ ! 435: ibc->csr |= IBEOP; ! 436: if( !bdev[0].pid ) putc(UNLISTEN, &ib.oq); ! 437: } ! 438: } ! 439: ! 440: ibc->ibs = getc(&ib.oq) & 0377; ! 441: } ! 442: ! 443: ! 444: ! 445: iberr() ! 446: { if( ibc->csr & IBER1 ) printf("\nIEEE hardw error"); ! 447: ibterror(); ! 448: } ! 449: ! 450: ! 451: ibsrq() ! 452: { /* If bus locked, SRQ poll will be done during ibfree(). ! 453: * Otherwise, if bus open call ibfree to do poll now. ! 454: * ibpollsrq will show bus locked when running. ! 455: */ ! 456: if( !TEST(IBLOCK) && ib.count ) ! 457: { ib.state |= IBLOCK; ! 458: ibfree(); /* run srq, etc */ ! 459: } ! 460: } ! 461: ! 462: ! 463: ! 464: ibpollsrq() /* called from ibfree() to do SRQ serial poll */ ! 465: { register struct ibdevs *pbdev; ! 466: register i, flag; ! 467: int s, twice; ! 468: char c; ! 469: ! 470: /* if exclusive-use, signal and return */ ! 471: if( ibpsig( bdev[0].pid, bdev[0].signo) ) return; ! 472: ! 473: /* Serial poll active devices first. If SRQ, record status byte and ! 474: * signal process. If SRQ uncleared, try all devices. Timeouts are ! 475: * loops and spl is reset since poll might be called from interrupt. ! 476: */ ! 477: ibc->csr = IBWAIT; ! 478: ib.state &= ~IBATEOF; ! 479: s = spl1(); ! 480: ibqdrain(); ! 481: ibunq(); ! 482: putc(SPE, &ib.oq); ! 483: flag = 1; ! 484: twice = 0; ! 485: ! 486: loop: while( ibc->ibs & BSRQ ) ! 487: { for(pbdev = &bdev[1], i = 1; i < NIBDEV; pbdev++, i++) ! 488: { if( flag ) ! 489: { if( pbdev->pid == 0 ) continue; ! 490: } else if( pbdev->pid ) continue; ! 491: putc((i | TALK), &ib.oq); ! 492: mtq++; ! 493: ibc->csr = IBWAIT; ! 494: ibc->csr = IBATT; ! 495: if( iboqloop() ) break; ! 496: ibrcount = 1; /* 1 byte anticipated */ ! 497: ibc->csr = IBLISTEN; ! 498: if( ibiqloop() ) continue; /* LISTEN timeout */ ! 499: ! 500: if( (c = getc(&ib.iq)) & 0100 ) /* set bit = SRQ */ ! 501: { if( twice == i ) /* bad device: */ ! 502: { printf("\nIEEE bad dev %d",i); ! 503: flag = 0; ! 504: break; ! 505: } ! 506: ! 507: twice = i; ! 508: pbdev->sbyte = c; /* store status */ ! 509: if( pbdev->signo ) /* send sig if wanted */ ! 510: ibpsig(pbdev->pid, pbdev->signo); ! 511: goto loop; /* search for more SRQ's */ ! 512: } ! 513: } ! 514: if(flag) flag = 0; ! 515: else ! 516: { printf("\nIEEE uncleared SRQ"); ! 517: break; ! 518: } ! 519: } ! 520: ! 521: /* end poll. Note if SRQ has not been cleared, bus ops can ! 522: * continue, but runsrq will occur again at every ibfree(). ! 523: */ ! 524: putc(SPD, &ib.oq); ! 525: ibunq(); ! 526: mtq++; ! 527: ibc->csr = IBWAIT; ! 528: ibc->csr = IBATT; ! 529: if( iboqloop() ) printf("\nIEEE bad SRQ poll"); ! 530: splx(s); ! 531: } ! 532: ! 533: ! 534: ibsetup(dev, flag) /* await bus, setup, queue dev address */ ! 535: dev_t dev; ! 536: int flag; ! 537: { register struct ibdevs *pbdev; ! 538: register s; ! 539: ! 540: pbdev = &bdev[minor(dev)]; ! 541: if( pbdev->pri < IBHPRI ) pbdev->pri++; /* use penalty */ ! 542: else pbdev->pri = IBSPRI; /* reset */ ! 543: ! 544: s = spl5(); /* hold off intrs until test and sleep */ ! 545: while( TEST(IBLOCK) ) ! 546: { if( pbdev->pri > IBLPRI ) pbdev->pri--; ! 547: sleep((caddr_t)&ib.state, pbdev->pri); ! 548: } ! 549: ! 550: ib.state = IBLOCK; /* show now inuse */ ! 551: splx(s); ! 552: ibqdrain(); ! 553: if( minor(dev) ) /* not exclusive-use: q dev addr for I/O */ ! 554: { ibunq(); /* queue bus UN- commands */ ! 555: if(flag) putc((minor(dev) | LISTEN),&ib.oq); ! 556: else putc((minor(dev) | TALK),&ib.oq); ! 557: } ! 558: } ! 559: ! 560: ! 561: ! 562: ibstart(csr) /* start interrupts, sleep on mtq & test error */ ! 563: int csr; ! 564: { register s; ! 565: ! 566: s = spl5(); /* disable ints until reallowed as part of sleep() */ ! 567: if( timer == 0 ) /* start ibtimer if not running */ ! 568: { timer++; ! 569: timeout( ibtimer, (caddr_t)0, TTIME); ! 570: } ! 571: omtq = mtq = 0; /* guarantee fresh timeout */ ! 572: mtq++; ! 573: ib.state &= ~IBERR; /* clear ERR flag */ ! 574: /* csr bits should not be toggled for LISTEN. toggling is ! 575: * required for TALK and ATT to trigger first interrupt. ! 576: * write 0 to ibc->ibs to complete a LISTEN handshake - reqd ! 577: * if listening interrupted due to buffer fill. ! 578: */ ! 579: if( csr == IBLISTEN ) ibc->ibs = 0; ! 580: else ibc->csr = IBWAIT; ! 581: ! 582: ibc->csr = csr; ! 583: sleep((caddr_t)&mtq, PZERO); /* not awakened by signal */ ! 584: ! 585: splx(s); ! 586: if( TEST(IBERR) ) /* timeout or iberr */ ! 587: { u.u_error = ENXIO; /* default error */ ! 588: return(1); ! 589: } ! 590: ! 591: return(0); ! 592: } ! 593: ! 594: ! 595: ! 596: ibtimer() /* timeout routine */ ! 597: { if( TEST(IBLOCK) ) ! 598: { if( mtq && (mtq == omtq) ) ! 599: { printf("\nIEEE timeout "); ! 600: ibterror(); ! 601: } else /* continue timer */ ! 602: { omtq = mtq; ! 603: timeout( ibtimer, (caddr_t)0, TTIME); ! 604: return; ! 605: } ! 606: } ! 607: timer = 0; /* turn timer off */ ! 608: } ! 609: ! 610: ! 611: ! 612: ibterror() /* bus or timeout error close routine */ ! 613: { ib.state |= IBERR; ! 614: omtq = mtq = 0; ! 615: wakeup((caddr_t)&mtq); ! 616: if( TEST(IBLOCK) ) ibfree(); ! 617: } ! 618: ! 619: ! 620: ! 621: ibqdrain() /* flush I/O queues */ ! 622: { while( getc(&ib.iq) >= 0 ) ; ! 623: while( getc(&ib.oq) >= 0 ) ; ! 624: } ! 625: ! 626: ! 627: ibunq() /* add UN- bus commands to output queue */ ! 628: { putc(UNTALK, &ib.oq); ! 629: putc(UNLISTEN, &ib.oq); ! 630: } ! 631: ! 632: ! 633: ! 634: iboqloop() /* loop timeout on outqueue activity */ ! 635: { int i = 0; ! 636: ! 637: while( mtq ) ! 638: if( i++ > OQLOOP ) return(1); ! 639: return(0); ! 640: } ! 641: ! 642: ibiqloop() /* loop timeout on inqueue activity */ ! 643: { int i = 0; ! 644: ! 645: while( ib.iq.c_cc == 0 ) ! 646: if( i++ > IQLOOP ) return(1); ! 647: return(0); ! 648: } ! 649: ! 650: ! 651: ibfree() ! 652: { if( ibc->ibs & BSRQ ) ibpollsrq(); /* service any SRQ request */ ! 653: ib.state &= IBULOCK; /* clear EOF & LOCK flags */ ! 654: ibc->csr = IBWAIT; /* leave csr in standby */ ! 655: wakeup((caddr_t)&ib.state); /* alert any sleepers */ ! 656: } ! 657: ! 658: ! 659: /* ibpsig() - checks pid active in sys proc table, sends sig if nonzero. ! 660: * returns 1 if process was found, 0 if not ! 661: */ ! 662: ibpsig(pid, sig) ! 663: short pid; ! 664: short sig; ! 665: { register struct proc *pp; ! 666: ! 667: if( pid == 0 ) return(0); ! 668: ! 669: for(pp = &proc[0]; pp < u.u_procp; pp++) /* changed TSI*/ ! 670: /* for(pp = &proc[0]; pp < maxproc; pp++) */ ! 671: if( pp->p_pid == pid ) ! 672: { if( sig ) psignal(pp, sig); ! 673: return(1); ! 674: } ! 675: ! 676: return(0); ! 677: } ! 678: ! 679:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.