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

1.1       root        1: /*
                      2:  * This software is provided solely for use with
                      3:  * the National Instruments GPIB11-2.
                      4:  *
                      5:  * Copyright 1980, 1983 National Instruments
                      6:  *
                      7:  * Jeffrey Kodosky
                      8:  * REV D:  10/30/83
                      9:  * (4.1bsd mods)
                     10:  *
                     11:  * utterly hopeless
                     12:  */
                     13: #include "sys/param.h"
                     14: #include "sys/conf.h"
                     15: #include "sys/user.h"
                     16: #include "sys/buf.h"
                     17: #include "sys/ubaddr.h"
                     18: #include "sys/ttyio.h"
                     19: 
                     20: #include "sys/callout.h"
                     21: 
                     22: static init(), irload(), lun(), wsetup(), rsetup(), ibdone(), gts(), tcs();
                     23: static unhold(), xfer(), ldaux(), wait100us();
                     24: 
                     25: #define TRI    0       /* 4 for Three-state highspeed timing; 0 for Normal timing */
                     26: #define EXT    1       /* 2 for Extended; 1 for Normal GPIB addressing */
                     27: #define MSA    0140    /* Msa&037 for Extended; 0140 for Normal GPIB addressing */
                     28: #define MA     025     /* GPIB address */
                     29: #define        DONE    0x0080  /* this is what they wanted */
                     30: 
                     31: 
                     32: #define SIGSRQ SIGINT
                     33: 
                     34: 
                     35: #define INACTIVE   0           /* Software controller states */
                     36: #define IDLE      1
                     37: #define INCHARGE   2
                     38: #define STANDBY           3
                     39: 
                     40: #define GO     1               /* Control/status register bits */
                     41: #define OUT    2
                     42: #define SEL    4
                     43: #define ECC    010
                     44: #define XBA    060
                     45: #define IE     0100
                     46: #define LMR    0200
                     47: #define CIC    0400
                     48: #define ATN    01000
                     49: #define EOI    02000
                     50: #define OCSW   02000
                     51: #define TCS    04000
                     52: #define DAV    04000
                     53: #define SRQ_IE 010000
                     54: #define SRQ    010000
                     55: #define INT    020000
                     56: #define DMA_ENAB 020000
                     57: #define NEX    040000
                     58: #define REN    040000
                     59: #define IFC    0100000
                     60: 
                     61: #define DIR    0               /* Internal register addresses */
                     62: #define DOR    0
                     63: #define ISR1   1
                     64: #define IMR1   1
                     65: #define ISR2   2
                     66: #define IMR2   2
                     67: #define SPS    3
                     68: #define SPM    3
                     69: #define ADS    4
                     70: #define ADM    4
                     71: #define CPT    5
                     72: #define AUX    5
                     73: #define AD0    6
                     74: #define ADR    6
                     75: #define AD1    7
                     76: #define EOS    7
                     77: 
                     78: #define ERR_IE     4           /* Internal register bits */
                     79: #define END_IE   020
                     80: #define CPT_IE  0200
                     81: #define DMAI_ENAB 020
                     82: #define DMAO_ENAB 040
                     83: #define SRQS    0100
                     84: #define RSV     0100
                     85: #define TA         2
                     86: #define LA         4
                     87: #define LON     0100
                     88: #define TON     0200
                     89: #define DL       040
                     90: #define DT      0100
                     91: #define ARS     0200
                     92: 
                     93: #define _CLKR    040           /* Hidden register addresses & offsets */
                     94: #define _PPR    0140
                     95: #define _AUXA   0200
                     96: #define _AUXB   0240
                     97: #define CLKR       0
                     98: #define PPR        1
                     99: #define AUXA       2
                    100: #define AUXB       3
                    101: 
                    102: #define U        020           /* Hidden register bits */
                    103: #define BIN      020
                    104: #define S        010
                    105: #define REOS       4
                    106: #define HLDE       2
                    107: #define HLDA       1
                    108: #define CPT_ENAB    1
                    109: #define PACS       1           /* Software status bits */
                    110: #define MON        2
                    111: 
                    112: #define IST    011             /* Special interface functions */
                    113: #define NIST     1
                    114: #define VSC    017
                    115: #define NVSC     7
                    116: #define SEOI     6
                    117: #define FH       3
                    118: #define IR       2
                    119: #define PON      0
                    120: 
                    121: #define OK        1    /* Error codes */
                    122: #define ENONE    -1    /* No command byte available (READCOMMAND) */
                    123: #define ECACFLT          -2    /* ATN not unasserted after IFC sent (bus problem) */
                    124: #define ENOTCAC          -3    /* Not Active Controller for operation requiring CAC (software problem) */
                    125: #define ENOTSAC          -4    /* Not System Controller for operation requiring SAC (software problem) */
                    126: #define EIFCLR   -5    /* IFC caused operation to abort (bus problem) */
                    127: #define ETIMO    -6    /* Operation did not complete within allotted time (bus problem) */
                    128: #define ENOFUN   -7    /* Non-existent function code (software problem) */
                    129: #define ETCTIMO          -8    /* Take control not completed within allotted time (bus problem) */
                    130: #define ENOIBDEV  -9   /* No Listeners addressed or no devices connected (bus problem) */
                    131: #define EIDMACNT -10   /* Internal DMA completed without bcr going to 0 (hardware problem) */
                    132: #define ENOPP   -11    /* PP operation attempted on three-state GPIB (software problem) */
                    133: #define EITIMO  -12    /* Internal DMA did not complete within allotted time (hardware problem) */
                    134: #define EINEXM  -13    /* Internal DMA aborted due to non-existent memory (software/hardware problem) */
                    135: #define ENEXMEM         -14    /* GPIB DMA aborted due to non-existent memory (software/hardware problem) */
                    136: #define ECNTRS  -15    /* Bar and bcr are inconsistent following GPIB DMA (hardware problem) */
                    137: 
                    138: #define RQC_STB         (RSV | 1)      /* Service request status bytes */
                    139: #define RQT_STB         (RSV | 2)
                    140: #define RQL_STB         (RSV | 4)
                    141: 
                    142: #define RQC    1               /* Asynchronous op codes */
                    143: #define CAC    2
                    144: #define TAC    3
                    145: #define LAC    4
                    146: #define CWT    5
                    147: #define WSRQ   6
                    148: 
                    149: #define TCT    011             /* GPIB multiline messages */
                    150: #define PPC    5
                    151: #define PPU    025
                    152: #define SCG    0140
                    153: 
                    154: #define IN     0
                    155: #define ITIMO  25              /* Internal loopcount timeout */
                    156: #define GTIMO  10              /* Default GPIB timeout in seconds */
                    157: #define TCTIMO 100
                    158: #define MONHWAT 32
                    159: 
                    160: #define RD     (DMA_ENAB|TCS|IN|GO)
                    161: #define WT     (DMA_ENAB|TCS|OUT|GO)
                    162: #define RDIR   (DMA_ENAB|IN|SEL|GO)
                    163: #define WTIR   (DMA_ENAB|OUT|SEL|GO)
                    164: 
                    165: static struct buf ibbuf;
                    166: static short iboddc, ibodda;
                    167: 
                    168: #define in(a)          ib.addr->a
                    169: #define out(a,v)       ib.addr->a=(v)
                    170: #define Exclude                sps=spl5()
                    171: #define Unexclude      splx(sps)
                    172: #define Try(f)         if((x=(f))<0) return x
                    173: 
                    174: struct ib {
                    175:        short unsigned  bcr, bar, csr, ccf;     /* Unibus device registers */
                    176:        char    internal[8];            /* Internal registers */
                    177:        char    hidden[4];              /* Hidden registers */
                    178:        char    cstate, istr, op;
                    179:        int     ans;
                    180:        int     timo;                   /* Watchdog timer */
                    181:        struct proc *owner;             /* GPIB owning process */
                    182:        short unsigned  rdbcr, rdbar, rdcsr;
                    183:        char    rdinternal[8];
                    184:        int     arg[3];
                    185: 
                    186:        struct ib *addr;
                    187:        int ubno;
                    188:        ubm_t ubm, ioubm;
                    189:        uaddr_t uaddr, iouaddr;
                    190: } ib;
                    191: 
                    192: static int status(), spbyte();
                    193: static int command(), transfer(), clear(), remote(), local(), ppoll();
                    194: static int passctrl(), setstat(), monitor(), readcmd(), setparam(), testsrq();
                    195: 
                    196: int (*ibfn[])() =
                    197: {
                    198:        command, transfer, clear, remote, local, ppoll,
                    199:        passctrl, setstat, monitor, readcmd, setparam, testsrq,
                    200:        status, spbyte
                    201: };
                    202: 
                    203: #define NFNS   ((sizeof ibfn)/(sizeof ibfn[0]))
                    204: 
                    205: /*
                    206:  * config glue
                    207:  */
                    208: int gpibopen(), gpibclose(), gpibread(), gpibwrite(), gpibioctl();
                    209: 
                    210: extern struct ubaddr gpibaddr[];
                    211: extern int gpibcnt;
                    212: struct cdevsw gpibcdev =
                    213:        cdinit(gpibopen, gpibclose, gpibread, gpibwrite, gpibioctl);
                    214: 
                    215: 
                    216: gpibopen(d, f)
                    217: {
                    218:        register int dev, s;
                    219:        register struct ib *p;
                    220: 
                    221:        if((dev = minor(d)) >= gpibcnt || gpibcnt > 1) {
                    222:                u.u_error = ENODEV;
                    223:                return;
                    224:        }
                    225:        if((p = &ib)->owner) {
                    226:                u.u_error = EBUSY;
                    227:                return;
                    228:        }
                    229:        if((p->addr = (struct ib *)ubaddr(&gpibaddr[dev])) == 0
                    230:          || ubbadaddr(gpibaddr[dev].ubno, (caddr_t)p->addr, sizeof(u_short))) {
                    231:                printf("gpib%d absent\n", dev);
                    232:                u.u_error = ENODEV;
                    233:                return;
                    234:        }
                    235:        p->ubno = gpibaddr[dev].ubno;
                    236:        p->ubm = ubmalloc(p->ubno, sizeof(struct ib), USLP);
                    237:        p->uaddr = ubmaddr(p->ubno, p, sizeof(struct ib), p->ubm);
                    238:        s = spl5();
                    239:        if((ib.ans=init())<0){
                    240:                ubmfree(p->ubno, p->ubm);
                    241:                u.u_error= EIO;
                    242:        }
                    243:        else ib.owner= u.u_procp;
                    244:        splx(s);
                    245: }
                    246: 
                    247: gpibclose(dev)
                    248: {
                    249:        register int sps, x;
                    250: 
                    251:        Exclude;
                    252:        ubmfree(ib.ubno, ib.ubm);
                    253:        ib.cstate= INACTIVE;
                    254:        ib.csr= 0;
                    255:        out(csr,LMR);
                    256:        ib.owner= 0;
                    257:        Unexclude;
                    258: }
                    259: 
                    260: gpibioctl(dev,cmd,addr)
                    261:        caddr_t addr;
                    262: {
                    263:        register int sps, x;
                    264: 
                    265:        Exclude;
                    266:        switch(cmd){
                    267:        case TIOCGETP:
                    268:                ib.arg[0]= ib.ans;
                    269:                ib.arg[1]= in(csr);
                    270:                ib.arg[2]= in(bcr);
                    271:                if(copyout(ib.arg,addr,sizeof ib.arg)) u.u_error= EFAULT;
                    272:                break;
                    273:        case TIOCSETP:
                    274:                if(copyin(addr,ib.arg,sizeof ib.arg)){
                    275:                        u.u_error= EFAULT;
                    276:                        break;
                    277:                }
                    278:                if((x=ib.arg[0])<0 || x>=NFNS){
                    279:                        ib.ans= ENOFUN; 
                    280:                        u.u_error= EIO;
                    281:                }
                    282:                else if((ib.ans= (*ibfn[x])())<0) u.u_error= EIO;
                    283:                break;
                    284:        default: 
                    285:                u.u_error= ENOTTY;
                    286:                break;
                    287:        }
                    288:        Unexclude;
                    289: }
                    290: 
                    291: static
                    292: command()
                    293: {
                    294:        ib.op= CWT;
                    295:        return OK;
                    296: }
                    297: 
                    298: static
                    299: transfer()
                    300: {
                    301:        return gts(EXT);
                    302: }
                    303: 
                    304: static
                    305: clear()
                    306: {
                    307:        register int x;
                    308: 
                    309:        Try(unhold());
                    310:        out(csr, ib.csr | IFC);
                    311:        wait100us();
                    312:        if(in(csr)&ATN) return ECACFLT;
                    313:        ib.cstate= INCHARGE;
                    314:        out(csr, (ib.csr |= ATN | SRQ_IE | CIC));
                    315:        return lun(TON);
                    316: }
                    317: 
                    318: static
                    319: remote()
                    320: {
                    321:        out(csr, (ib.csr |= REN));
                    322:        return OK;
                    323: }
                    324: 
                    325: static
                    326: local()
                    327: {
                    328:        out(csr, (ib.csr &= ~REN));
                    329:        return OK;
                    330: }
                    331: 
                    332: static
                    333: ppoll()
                    334: {
                    335:        register int x;
                    336: 
                    337:        Try(tcs());
                    338:        Try(lun(LON));
                    339:        out(csr, (ib.csr |= EOI));
                    340:        Try(xfer(RDIR, &ib.rdinternal[CPT], 1, CPT));
                    341:        out(csr, (ib.csr &= ~EOI));
                    342:        return (ib.rdinternal[CPT]&0377|0400);
                    343: }
                    344: 
                    345: static
                    346: passctrl()
                    347: {
                    348:        return ENOIBDEV;
                    349: }
                    350: 
                    351: static
                    352: setstat()
                    353: {
                    354:        return OK;
                    355: }
                    356: 
                    357: static
                    358: monitor()
                    359: {
                    360:        return OK;
                    361: }
                    362: 
                    363: static
                    364: readcmd()
                    365: {
                    366:        return ENONE;
                    367: }
                    368: 
                    369: static
                    370: setparam()
                    371: {
                    372:        ib.timo= ib.arg[1];
                    373:        ib.internal[0]= ib.arg[2];
                    374:        ib.internal[EOS]= ib.arg[2]>>8;
                    375:        return OK;
                    376: }
                    377: 
                    378: static
                    379: testsrq()
                    380: {
                    381:        int ibtimer();
                    382: 
                    383:        if(in(csr)&SRQ) return OK;
                    384:        if(ib.csr&CIC) out(csr, (ib.csr |= SRQ_IE));
                    385:        if(ib.arg[1]){
                    386:                ib.op= WSRQ;
                    387:                if(ib.timo)
                    388:                        timeout(ibtimer,0,ib.timo*HZ);
                    389:                sleep(&ibbuf,10);
                    390:                return ib.ans;
                    391:        }
                    392:        return ENONE;
                    393: }
                    394: 
                    395: static
                    396: status()
                    397: {
                    398:        register char *c;
                    399:        register int ct;
                    400: 
                    401:        c= (caddr_t)&ib;
                    402:        u.u_base= (caddr_t)ib.arg[1];
                    403:        if((u.u_count=ib.arg[2]) > sizeof ib)
                    404:                u.u_count= sizeof ib;
                    405:        ct= u.u_count;
                    406:        while(passc(*c++)>=0) ;
                    407:        return ct;
                    408: }
                    409: 
                    410: static
                    411: spbyte()
                    412: {
                    413:        register int x;
                    414: 
                    415:        return OK;
                    416: }
                    417: 
                    418: static
                    419: init()
                    420: {
                    421:        register char *cp;
                    422:        register int x;
                    423: 
                    424:        out(csr, LMR);
                    425:        ib.csr= 0;
                    426:        cp= &ib.hidden[0];
                    427:        *cp++= _CLKR | 6;
                    428:        *cp++= _PPR | U;
                    429:        *cp++= _AUXA;
                    430:        *cp++= _AUXB | TRI | CPT_ENAB;
                    431: 
                    432:        cp= &ib.internal[0];
                    433:        *cp++= 0;
                    434:        *cp++= CPT_IE | ERR_IE;
                    435:        *cp++= 0;
                    436:        *cp++= 0;
                    437:        *cp++= EXT;
                    438:        *cp++= ib.hidden[CLKR];
                    439:        *cp++= ARS | MSA;
                    440:        *cp++= 0;
                    441: 
                    442:        ib.istr= 0;
                    443:        ib.op= 0;
                    444:        ib.ans= 0;
                    445:        ib.timo= GTIMO;
                    446:        Try(irload());
                    447:        ib.cstate= IDLE;
                    448:        out(csr, ib.csr= IE);
                    449:        return 0;
                    450: }
                    451: 
                    452: static
                    453: ibstop()
                    454: {
                    455:        register int x;
                    456: 
                    457:        out(csr, (ib.csr &= ~(DMA_ENAB|GO)));
                    458:        ib.op= 0;
                    459:        ibdone(&ibbuf);
                    460:        return ETIMO;
                    461: }
                    462: 
                    463: static
                    464: irload()
                    465: {
                    466:        register int x;
                    467: 
                    468:        Try(xfer(WTIR,&ib.internal[ISR1],7,ISR1));
                    469:        ib.internal[AUX]= ib.hidden[AUXA];
                    470:        ib.internal[ADR]= MA;
                    471:        Try(xfer(WTIR,&ib.internal[AUX],2,AUX));
                    472:        Try(xfer(WTIR,&ib.hidden[AUXB],1,AUX));
                    473:        x= ib.internal[ADM];
                    474:        ib.internal[ADM]= 0;
                    475:        return lun(x);
                    476: }
                    477: 
                    478: static
                    479: lun(newadm)
                    480:        char newadm;
                    481: {      /* Note: rsv is cleared and not restored*/
                    482:        register int x;
                    483: 
                    484:        if(ib.internal[ADM]==newadm) return OK;
                    485:        ib.internal[ADM]= newadm;
                    486:        ib.internal[AUX]= PON;
                    487:        Try(xfer(WTIR,&ib.internal[ADM],2,ADM));
                    488:        Try(xfer(WTIR,&ib.hidden[PPR],1,AUX));
                    489:        return (ib.istr&S)? ldaux(IST): OK;
                    490: }
                    491: 
                    492: gpibwrite(dev)
                    493: {
                    494:        register int sps;
                    495:        int ibstrategy();
                    496: 
                    497:        Exclude;
                    498:        if((ib.ans=wsetup())>=0)
                    499:                physio(ibstrategy, &ibbuf, dev, B_WRITE, minphys);
                    500:        ib.op= 0;
                    501:        if(ib.ans<0) u.u_error= EIO;
                    502:        Unexclude;
                    503: }
                    504: 
                    505: static
                    506: wsetup()
                    507: {
                    508:        register x;
                    509: 
                    510:        ib.ccf= 0;
                    511:        ib.csr &= ~ECC;
                    512:        if(ib.op==CWT)
                    513:                if((x=tcs())<0){
                    514:                        return x;
                    515:                }
                    516:                else {  
                    517:                        Try(lun(TON));
                    518:                        ib.op= CAC;
                    519:                }
                    520:        else {  
                    521:                if((x=gts(TON))<0){
                    522:                        return x;
                    523:                }
                    524:                if(ib.internal[0]&2){
                    525:                        ib.ccf= SEOI; 
                    526:                        ib.csr |= ECC;
                    527:                }
                    528:                ib.op= TAC;
                    529:        }
                    530:        ibodda= (int)u.u_base&1;
                    531:        u.u_base -= ibodda;
                    532:        iboddc= ((ibodda + u.u_count + 1)&~1) - u.u_count;
                    533:        u.u_count += iboddc;
                    534:        return OK;
                    535: }
                    536: 
                    537: gpibread(dev)
                    538: {
                    539:        register int sps;
                    540:        int ibstrategy();
                    541: 
                    542:        Exclude;
                    543:        if((ib.ans=rsetup())>=0)
                    544:                physio(ibstrategy, &ibbuf, dev, B_READ, minphys);
                    545:        ib.op= 0;
                    546:        if(ib.ans<0) u.u_error= EIO;
                    547:        Unexclude;
                    548: }
                    549: 
                    550: static
                    551: rsetup()
                    552: {
                    553:        register int x;
                    554: 
                    555:        ib.ccf= 0;
                    556:        ib.csr &= ~ECC;
                    557:        if((x=gts(LON))<0){
                    558:                return x;
                    559:        }
                    560:        ib.hidden[AUXA] |= (ib.internal[0]&(2<<4)? REOS:0) | (ib.internal[0]&(1<<4)? BIN:0);
                    561:        if(ib.internal[0]&(4<<4)) ib.internal[IMR1] &= ~END_IE;
                    562:        else {  
                    563:                ib.internal[IMR1] |= END_IE;
                    564:                if(ib.cstate==STANDBY) ib.hidden[AUXA] |= HLDE;
                    565:        }
                    566:        ib.internal[AUX]= ib.hidden[AUXA];
                    567:        Try(xfer(WTIR, &ib.internal[IMR1], 7, IMR1));
                    568:        if(ib.cstate==STANDBY){
                    569:                ib.ccf= ib.hidden[AUXA]= ib.hidden[AUXA]&~HLDE|HLDA;
                    570:                ib.csr |= ECC;
                    571:        }
                    572:        ib.op= LAC;
                    573:        ibodda= (int)u.u_base&1;
                    574:        u.u_base -= ibodda;
                    575:        iboddc= ((ibodda + u.u_count + 1)&~1) - u.u_count;
                    576:        u.u_count += iboddc;
                    577:        return OK;
                    578: }
                    579: 
                    580: ibstrategy(bp)
                    581:        register struct buf *bp;
                    582: {
                    583:        register int x, rw;
                    584: 
                    585:        ib.ioubm = ubmbuf(ib.ubno, bp, USLP);
                    586:        ib.iouaddr = ubadbuf(ib.ubno, bp, ib.ioubm);
                    587:        rw= bp->b_flags&B_READ? RD:(ib.op==RQC? OUT:WT);
                    588:        if((x=xfer(rw, ib.iouaddr+ibodda, bp->b_bcount-iboddc, 0))<0){
                    589:                ib.ans= x;
                    590:                ibdone(bp);
                    591:        }       
                    592: }
                    593: 
                    594: static
                    595: ibdone(bp)
                    596:        register struct buf *bp;
                    597: {
                    598:        register int x;
                    599: 
                    600:        iodone(bp);
                    601:        ubmfree(ib.ubno, ib.ioubm);
                    602: }
                    603: 
                    604: 
                    605: static
                    606: gts(newadm)
                    607:        char newadm;
                    608: {
                    609:        register int x;
                    610: 
                    611:        Try(unhold());
                    612:        if(ib.cstate==STANDBY)
                    613:                return (ib.internal[ADM]==newadm)? OK : ENOIBDEV;
                    614:        if(ib.cstate==IDLE) return ENOTCAC;
                    615:        Try(lun(newadm));
                    616:        out(csr, (ib.csr &= ~ATN));
                    617:        ib.cstate= STANDBY;
                    618:        return OK;
                    619: }
                    620: 
                    621: static
                    622: tcs()
                    623: {
                    624:        if(ib.cstate==INCHARGE) return OK;
                    625:        if(ib.cstate==IDLE) return ENOTCAC;
                    626:        out(csr, (ib.csr |= ATN));
                    627:        ib.cstate= INCHARGE;
                    628:        return unhold();
                    629: }
                    630: 
                    631: static
                    632: unhold()
                    633: {
                    634:        register int x;
                    635: 
                    636:        if(ib.hidden[AUXA]&(HLDE|HLDA)){
                    637:                ib.hidden[AUXA]= _AUXA;
                    638:                Try(ldaux(FH));
                    639:                return xfer(WTIR, &ib.hidden[AUXA], 1, AUX);
                    640:        }
                    641:        return OK;
                    642: }
                    643: 
                    644: static
                    645: xfer(rw,bp,n,fr)
                    646: {      /* fr is internal reg addr  */
                    647:        register int i, x;
                    648:        int ibtimer();
                    649: 
                    650:        if(n<=0) return OK;
                    651:        if(rw&SEL){
                    652:                out(bcr, (-n<<8) | fr & 7);
                    653:                bp += ib.uaddr - (int)&ib;
                    654:                out(bar, bp);
                    655:                out(csr, ib.csr & (REN|SRQ_IE|EOI|ATN|CIC) | (bp>>12) & XBA | rw);
                    656:                for(i=ITIMO; !((x=in(csr))&DONE); )
                    657:                        if(--i<=0) return EITIMO;
                    658:                if(x&NEX) return EINEXM;
                    659:                if(in(bcr)&0177400) return EIDMACNT;
                    660:                out(csr, ib.csr & (REN|SRQ_IE|ATN|CIC|IE));
                    661:                return n;
                    662:        }
                    663:        ib.internal[IMR2]= rw&OUT? DMAO_ENAB:DMAI_ENAB;
                    664:        Try(xfer(WTIR,&ib.internal[IMR2],1,IMR2));
                    665:        out(bcr, ib.bcr= -n);
                    666:        out(bar, ib.bar= bp);
                    667:        out(ccf, ib.ccf);
                    668:        out(csr, (ib.csr= ib.csr & (REN|SRQ_IE|TCS|ATN|CIC|ECC) | (bp>>12) & XBA | IE | rw));
                    669:        ib.ans= 0;
                    670:        if(ib.timo) timeout(ibtimer,0,ib.timo*HZ);
                    671:        return OK;
                    672: }
                    673: 
                    674: static
                    675: ldaux(a)
                    676: {
                    677:        ib.internal[AUX]= a;
                    678:        return xfer(WTIR, &ib.internal[AUX], 1, AUX);
                    679: }
                    680: 
                    681: ibtimer(id)
                    682: {
                    683:        int sps;
                    684: 
                    685:        Exclude;
                    686:        printf("timer (%o)\n",ibtimer);
                    687:        ib.ans= ibstop();
                    688:        Unexclude;
                    689: }
                    690: 
                    691: gpib0int()
                    692: {
                    693:        register int x, i;
                    694:        register short unsigned y, z;
                    695: 
                    696:        ib.rdcsr= in(csr);
                    697:        ib.rdbcr= in(bcr);
                    698:        ib.rdbar= in(bar);
                    699:        if((ib.rdcsr&SRQ) && (ib.csr&SRQ_IE)){
                    700:                out(csr, (ib.csr &= ~SRQ_IE) & ~GO);
                    701:                if(ib.op==WSRQ){
                    702:                        ib.op= 0;
                    703:                        ib.ans= OK;
                    704:                        untimeout(ibtimer,0);
                    705:                        wakeup(&ibbuf);
                    706:                }
                    707:                else if(ib.owner) psignal(ib.owner,SIGSRQ);
                    708:        }
                    709:        if(ib.rdcsr&INT){
                    710:                out(csr, ib.csr & ~(DMA_ENAB|GO));
                    711:                ib.rdcsr= in(csr);
                    712:                ib.rdbcr= in(bcr);
                    713:                ib.rdbar= in(bar);
                    714:                if((x=xfer(RDIR, &ib.rdinternal[ISR1], 5, ISR1))<0) goto quit;
                    715:                if(ib.rdinternal[ISR1]&ERR_IE) ib.ans= ENOIBDEV;
                    716:                if(ib.internal[IMR1]&END_IE){
                    717:                        ib.internal[IMR1] &= ~END_IE;
                    718:                        if((x=xfer(WTIR,&ib.internal[IMR1],1,IMR1))<0) goto quit;
                    719:                }       
                    720:        }
                    721:        if((ib.rdcsr&DONE) && (ib.csr&GO)){
                    722:                ib.csr &= ~GO;
                    723:                if(ib.timo) untimeout(ibtimer,0);
                    724:                if(ib.rdcsr&NEX) ib.ans= ENEXMEM;
                    725:                x = y = ib.rdbcr - ib.bcr;
                    726:                z = ib.rdbar - ib.bar;  /* complete batshit */
                    727:                if(z != y){
                    728:                        x= ECNTRS;
                    729:                        printf("\trdbcr,rdbar,rdcsr= %o %o %o\n",ib.rdbcr,ib.rdbar,ib.rdcsr);
                    730:                        printf("\tbcr,bar,csr= %o %o %o\n",ib.bcr,ib.bar,ib.csr);
                    731:                }
                    732:                ibbuf.b_resid= -ib.rdbcr;
                    733:                if(ib.ans==0)
                    734: quit:                  
                    735:                        ib.ans= x;
                    736:                ib.op= 0;
                    737:                ibdone(&ibbuf);
                    738:        }
                    739: }
                    740: 
                    741: static
                    742: wait100us()
                    743: {
                    744:        register int i;
                    745: 
                    746:        for(i=100; i-->0; ) ;
                    747: }
                    748: 
                    749: untimeout(fn,arg)
                    750:        register int (*fn)();
                    751:        caddr_t arg;
                    752: {
                    753:        register struct callout *p, *q;
                    754:        int s;
                    755: 
                    756:        s= spl7();
                    757:        for(p= &calltodo; q=p->c_next; p=q)
                    758:                if(q->c_func==fn && q->c_arg==arg){
                    759:                        p->c_next= q->c_next;
                    760:                        q->c_next= callfree;
                    761:                        callfree= q;
                    762:                        if(p=p->c_next)
                    763:                                p->c_time += q->c_time;
                    764:                        break;
                    765:                }
                    766:        splx(s);
                    767: }

unix.superglobalmegacorp.com

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