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