Annotation of researchv10no/sys/io/ibv.c, revision 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.