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

unix.superglobalmegacorp.com

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