Annotation of researchv10no/sys/io/ibv.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.