Annotation of researchv10dc/lsys/io/dk.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  Datakit driver
                      3:  */
                      4: #include "sys/param.h"
                      5: #include "sys/systm.h"
                      6: #include "sys/stream.h"
                      7: #include "sys/dkio.h"
                      8: #include "sys/ubaddr.h"
                      9: #include "sys/conf.h"
                     10: #include "sys/dk.h"
                     11: #include "sys/dkstat.h"
                     12: #include "sys/dkmod.h"
                     13: 
                     14: #define        SAFETY  1               /* turn off doubtful speed hack */
                     15: 
                     16: struct device {
                     17:        unsigned short csr;
                     18:        unsigned short dko;
                     19:        unsigned short dki;
                     20: };
                     21: 
                     22: struct device  *DKADDR;        /* assume one addr for now */
                     23: 
                     24: extern struct dk dk[];
                     25: extern int dkcnt;
                     26: extern char dkstate[];
                     27: 
                     28: #define        DKXCL   01
                     29: 
                     30: int    dkalive;
                     31: struct dkstat  dkstat;
                     32: extern struct  dkmodule dkmod[];
                     33: struct dkmodule *dkmodp;
                     34: 
                     35: /*
                     36:  * Hardware control bits
                     37:  */
                     38: #define        DKTENAB 0100
                     39: #define        DKRENAB 040
                     40: #define        ENABS   (DKRENAB)
                     41: #define        DKTDONE 0200
                     42: #define        DKRDONE 0100000
                     43: #define        D_OSEQ  0
                     44: #define        D_READ  01
                     45: #define        D_WRITE 02
                     46: #define        D_XPACK 03
                     47: #define        DKMARK  01000
                     48: #define        DKDATA  0400
                     49: #define        DKPARITY 0100000
                     50: 
                     51: #define        DKOPKT  16      /* biggest output packet */
                     52: #define        DKIPKT  16      /* biggest input packet */
                     53: #define        DKISML  16      /* smallest interesting allocation */
                     54: #define        DKITHRES 200
                     55: 
                     56: int    dkclose(), dkput();
                     57: long   dkopen();
                     58: 
                     59: static struct qinit dkrinit = { noput, NULL, dkopen, dkclose, 0, 0 };
                     60:        struct qinit dkwinit = { dkput, NULL, dkopen, dkclose, 0, 0 };
                     61: struct streamtab dkinfo = { &dkrinit, &dkwinit };
                     62: struct cdevsw dkcdev = cstrinit(&dkinfo);
                     63: extern struct ubaddr dkaddr[];
                     64: 
                     65: /*
                     66:  * open DK channel
                     67:  */
                     68: long
                     69: dkopen(q, dev)
                     70: register struct queue *q;
                     71: register dev_t dev;
                     72: {
                     73:        register struct dk *dkp;
                     74:        static opened, badtime;
                     75:        register chan;
                     76: 
                     77:        chan = minor(dev);
                     78:        if (chan<=0 || chan>=dkcnt)
                     79:                return(0);
                     80:        if (!opened) {
                     81:                register i;
                     82: 
                     83:                if ((DKADDR = (struct device *)ubaddr(&dkaddr[0])) == NULL
                     84:                ||  badaddr(DKADDR, 2)) {
                     85:                        printf("dk0 absent\n");
                     86:                        return (0);
                     87:                }
                     88:                DKADDR->csr = D_OSEQ;
                     89:                DKADDR->dko = 0;        /* Clear fifo's */
                     90:                i = 256;                /* sanity count */
                     91:                DELAY(1000);            /* wait for board to reset */
                     92:                do {
                     93:                        if (DKADDR->csr & DKTDONE) {
                     94:                                dkalive = 0;
                     95:                                if (time > badtime + 300) {
                     96:                                        badtime = time;
                     97:                                        printf("DK interface bad\n");
                     98:                                }
                     99:                                return(0);
                    100:                        }
                    101:                } while (--i);
                    102:                if ((dkmodp = dkmodall(dev, 0, dkcnt)) == NULL)
                    103:                        return (0);
                    104:                dkmodp->dkstate = dkstate;
                    105:                dkalive = 1;
                    106:                for (dkp = dk, i = 0; i < dkcnt; dkp++, i++)
                    107:                        dkp->chan = i;
                    108:                DKADDR->csr = ENABS;
                    109:                opened++;
                    110:                dkrecover(chan);
                    111:        }
                    112:        dkp = &dk[chan];
                    113:        if (dkstate[chan] != DKCLOSED) {        /* already open */
                    114:                if (dkp->flag & DKXCL)
                    115:                        return(0);
                    116:                if (dkstate[chan] != DKOPEN)
                    117:                        return(0);      /* closing channels can't reopen */
                    118:                return(1);
                    119:        }
                    120:        dkp->dkrq = q;
                    121:        q->ptr = (caddr_t)dkp;
                    122:        WR(q)->ptr = (caddr_t)dkp;
                    123:        dkp->flag = DKXCL;
                    124:        dkp->icnt = 0;
                    125:        dkp->isize = 0;
                    126:        dkp->ibuf = 0;
                    127:        dkp->ialloc = DKISML;
                    128:        dkstate[chan] = DKOPEN;
                    129:        return(1);
                    130: }
                    131: 
                    132: /*
                    133:  * Timer to recover from lost interrupt condition.
                    134:  */
                    135: dkrecover(dev)
                    136: dev_t  dev;
                    137: {
                    138:        register int    ps = spl5();
                    139: 
                    140:        if (DKADDR->csr & DKRDONE)
                    141:                dk1int(dev);
                    142:        splx(ps);
                    143: 
                    144:        timeout(dkrecover, (caddr_t)dev, HZ/2);
                    145: }
                    146: 
                    147: /*
                    148:  * close DK channel
                    149:  */
                    150: dkclose(q)
                    151: register struct queue *q;
                    152: {
                    153:        register struct dk *dkp;
                    154:        register struct block *bp;
                    155: 
                    156:        dkp = (struct dk *)q->ptr;
                    157:        dkp->dkrq = NULL;
                    158:        dkp->flag = 0;
                    159:        if (dkstate[dkp->chan] == DKRCLOSE || dkmodp->listnrq==NULL)
                    160:                dkstate[dkp->chan] = DKCLOSED;
                    161:        else if (dkstate[dkp->chan] == DKOPEN)
                    162:                dkstate[dkp->chan] = DKLCLOSE;
                    163:        if (dkmodp->listnrq)
                    164:                putctl2(RD(dkmodp->listnrq), M_PRICTL, DKMCLOSE, dkp->chan);
                    165:        if (dkp->ibuf)
                    166:                freeb(dkp->ibuf);
                    167:        while ((bp = dkp->ofirst) != NULL) {
                    168:                dkp->ofirst = bp->next;
                    169:                freeb(bp);
                    170:        }
                    171:        dkp->ibuf = 0;
                    172: }
                    173: 
                    174: /*
                    175:  * DK receiver interrupt.
                    176:  */
                    177: 
                    178: #define        PUTIN(bp, q)    {\
                    179:        dkstat.input += (bp)->wptr - (bp)->rptr;\
                    180:        if (((q)->next->flag & QFULL) == 0)\
                    181:                (*(q)->next->qinfo->putp)(q->next, bp);\
                    182:        else\
                    183:                freeb(bp);\
                    184: }
                    185: 
                    186: #define        DKSIZUP(dkp)    {\
                    187:        if (dkp->isize > DKITHRES) {\
                    188:                dkp->ialloc = dkp->isize;\
                    189:                dkp->icnt = 3;\
                    190:        } else if (--dkp->icnt <= 0) {\
                    191:                dkp->icnt = 0;\
                    192:                dkp->ialloc = DKISML;\
                    193:        }\
                    194:        dkp->isize = 0;\
                    195: }
                    196: 
                    197: dk1int(dev)
                    198: {
                    199:        register struct queue *q;
                    200:        register struct block *bp;
                    201:        register struct dk *dkp;
                    202:        register struct device *reg;
                    203:        register c, nbytes;
                    204:        register sane, chan;
                    205:        register struct block **bpp;
                    206:        struct block *blist[DKIPKT+2];
                    207: 
                    208:        if ((reg = DKADDR) == NULL)
                    209:                return;
                    210:        c = 0;
                    211:        dkp = NULL;
                    212:        while (reg->csr & DKRDONE) {
                    213:                reg->csr = D_READ|ENABS;
                    214:                if ((c & DKMARK) == 0) {
                    215:                        /* Search for channel number */
                    216:                        sane = 256;
                    217:                        do {
                    218:                                c = reg->dki;
                    219:                                if (c & DKMARK || --sane==0)
                    220:                                        break;
                    221:                        } while (reg->csr & DKRDONE);
                    222:                }
                    223:                if ((c & DKMARK) == 0) {
                    224:                        dkstat.markflt++;
                    225:                        continue;
                    226:                }
                    227:                if ((c & DKPARITY) == 0) {
                    228:                        dkstat.markparity++;
                    229:                        c = 0;
                    230:                        continue;
                    231:                }
                    232:                /* check channel */
                    233:                chan = c & 0777;
                    234:                if (dkp && dkp->chan != chan) {
                    235:                        if ((bp = dkp->ibuf) != NULL)
                    236:                                PUTIN(bp, q);
                    237:                        DKSIZUP(dkp);
                    238:                        dkp->ibuf = NULL;
                    239:                }
                    240:                if (chan == 0 || chan >= dkcnt || (q = dk[chan].dkrq)==NULL) {
                    241:                        if (chan>0 && chan<dkcnt) {
                    242:                                if (dkmodp->listnrq)
                    243:                                        putctl2(RD(dkmodp->listnrq),
                    244:                                                M_PRICTL, DKMCLOSE, chan);
                    245:                                dkstat.closepack++;
                    246:                        } else if (chan == 0)
                    247:                                dkstat.pack0++;
                    248:                        else
                    249:                                dkstat.packstrange++;
                    250:                        for (nbytes=0; nbytes<DKIPKT; nbytes++) {
                    251:                                c = reg->dki;
                    252:                                if (c & DKMARK)
                    253:                                        break;
                    254:                        }
                    255:                        continue;
                    256:                }
                    257:                dkp = (struct dk *)q->ptr;
                    258:                if ((bp = dkp->ibuf) == NULL
                    259:                &&  (bp = allocb(dkp->ialloc)) == NULL)
                    260:                        return;
                    261:                bpp = blist;
                    262:                for (nbytes=0; nbytes<DKIPKT; nbytes++) {
                    263: #ifdef SAFETY
                    264:                        if ((reg->csr&DKRDONE) == 0)
                    265:                                break;
                    266: #endif
                    267:                        c = reg->dki;
                    268:                        if ((c&(DKPARITY|DKMARK|DKDATA)) == (DKPARITY|DKDATA)) {
                    269:                                if (bp->wptr >= bp->lim) {
                    270:                                        *bpp++ = bp;
                    271:                                        if ((bp = allocb(DKISML)) == NULL)
                    272:                                                break;
                    273:                                }
                    274:                                *bp->wptr++ = c;
                    275:                                dkp->isize++;
                    276:                                continue;
                    277:                        }
                    278:                        /*
                    279:                         * control or error
                    280:                         */
                    281:                        if (c & DKMARK) {
                    282:                                dkstat.shortpack++;
                    283:                                break;
                    284:                        }
                    285:                        if ((c & DKPARITY) == 0) {
                    286:                                dkstat.parity++;
                    287:                                break;
                    288:                        }
                    289:                        if ((c & 0377) == 0)    /* control-null */
                    290:                                continue;
                    291:                        if (bp->wptr > bp->rptr) {
                    292:                                *bpp++ = bp;
                    293:                                if ((bp = allocb(DKISML)) == NULL)
                    294:                                        break;
                    295:                        }
                    296:                        bp->type = M_CTL;
                    297:                        *bp->wptr++ = c;
                    298:                }
                    299:                if (bpp == blist && bp->type == M_DATA) {
                    300:                        dkp->ibuf = bp;
                    301:                        continue;
                    302:                }
                    303:                *bpp++ = bp;
                    304:                *bpp = NULL;
                    305:                bpp = blist;
                    306:                while ((bp = *bpp++) != NULL)
                    307:                        PUTIN(bp, q);
                    308:                DKSIZUP(dkp);
                    309:                dkp->ibuf = NULL;
                    310:        }
                    311:        if (dkp && (bp = dkp->ibuf) != NULL) {
                    312:                PUTIN(bp, q);
                    313:                DKSIZUP(dkp);
                    314:                dkp->ibuf = NULL;
                    315:        }
                    316: }
                    317: 
                    318: /*
                    319:  * DK put procedure
                    320:  */
                    321: dkput(q, bp)
                    322: register struct queue *q;
                    323: register struct block *bp;
                    324: {
                    325:        register n;
                    326:        register bn;
                    327:        int s;
                    328:        register struct device *reg = DKADDR;
                    329:        register struct dk *dkp;
                    330: 
                    331:        dkp = (struct dk *)q->ptr;
                    332:        if (dkp == NULL) {
                    333:                freeb(bp);
                    334:                return;
                    335:        }
                    336:        switch (bp->type) {
                    337: 
                    338:        case M_IOCTL:
                    339:                bp->type = M_IOCACK;
                    340:                switch (stiocom(bp)) {
                    341:                case DIOCNXCL:
                    342:                        dkp->flag &=~ DKXCL;
                    343:                        bp->wptr = bp->rptr;
                    344:                        bp->type = M_IOCACK;
                    345:                        break;
                    346: 
                    347:                default:
                    348:                        bp->type = M_IOCNAK;
                    349:                        break;
                    350:                }
                    351:                qreply(q, bp);
                    352:                return;
                    353: 
                    354:        case M_CTL:
                    355:        case M_DATA:
                    356:                s = spl6();
                    357:                bp->next = NULL;
                    358:                if (dkp->ofirst == NULL)
                    359:                        dkp->ofirst = bp;
                    360:                else
                    361:                        dkp->olast->next = bp;
                    362:                dkp->olast = bp;
                    363:                if ((bp->class&S_DELIM)==0 || dkalive == 0) {
                    364:                        splx(s);
                    365:                        return;
                    366:                }
                    367:                /*
                    368:                 * S_DELIM:
                    369:                 * push out data
                    370:                 */
                    371:                n = DKOPKT;
                    372:                reg->csr = D_WRITE + ENABS;
                    373:                reg->dko = DKMARK + dkp->chan;
                    374:                while ((bp = dkp->ofirst) != NULL) {
                    375:                        dkp->ofirst = bp->next;
                    376:                        if (bp->wptr == bp->rptr) {
                    377:                                freeb(bp);
                    378:                                continue;
                    379:                        }
                    380:                        dkstat.output += bp->wptr - bp->rptr;
                    381:                        if (n <= 0) {
                    382:                                reg->csr = D_XPACK + ENABS;
                    383:                                reg->dko = 0;
                    384:                                n = DKOPKT;
                    385:                                reg->csr = D_WRITE + ENABS;
                    386:                                reg->dko = DKMARK + dkp->chan;
                    387:                        }
                    388:                        --n;
                    389:                        reg->dko = *bp->rptr++ | ((bp->type==M_DATA)?DKDATA:0);
                    390:                        while ((bn = bp->wptr - bp->rptr) > 0) {
                    391:                                if (bn > n)
                    392:                                        bn = n;
                    393:                                n -= bn;
                    394:                                while (--bn >= 0)
                    395:                                        reg->dko = *bp->rptr++ | DKDATA;
                    396:                                if (n <= 0) {
                    397:                                        reg->csr = D_XPACK + ENABS;
                    398:                                        reg->dko = 0;
                    399:                                        n = DKOPKT;
                    400:                                        reg->csr = D_WRITE + ENABS;
                    401:                                        reg->dko = DKMARK + dkp->chan;
                    402:                                }
                    403:                        }
                    404:                        freeb(bp);
                    405:                }
                    406:                reg->csr = D_XPACK + ENABS;
                    407:                reg->dko = 0;
                    408:                splx(s);
                    409:                return;
                    410: 
                    411:        case M_PRICTL:
                    412:                switch (*bp->rptr) {
                    413:                case DKMCLOSE:
                    414:                        n = bp->rptr[1];
                    415:                        if (n < dkcnt) {
                    416:                                if (dkstate[n] == DKOPEN) {
                    417:                                        dkstate[n] = DKRCLOSE;
                    418:                                        putctl(dk[n].dkrq->next, M_HANGUP);
                    419:                                } else if (dkstate[n] == DKLCLOSE)
                    420:                                        dkstate[n] = DKCLOSED;
                    421:                        }
                    422:                        freeb(bp);
                    423:                        return;
                    424: 
                    425:                case DKMXINIT:
                    426:                        n = bp->rptr[1];
                    427:                        if (n < dkcnt && dkstate[n] == DKOPEN)
                    428:                                (*dk[n].dkrq->next->qinfo->putp)(dk[n].dkrq->next, bp);
                    429:                        else
                    430:                                freeb(bp);
                    431:                        return;                         
                    432: 
                    433:                default:
                    434:                        freeb(bp);
                    435:                        return;
                    436:                }
                    437: 
                    438:        default:
                    439:                freeb(bp);
                    440:                return;
                    441:        }
                    442: }
                    443: 
                    444: /*
                    445:  * transmit interrupt
                    446:  */
                    447: 
                    448: dk0int(dev)
                    449: int dev;
                    450: {
                    451:        printf("dk%d xmit stray\n", dev);
                    452: }
                    453: 
                    454: /*
                    455:  * unibus reset
                    456:  */
                    457: dkreset()
                    458: {
                    459:        if (DKADDR)
                    460:                DKADDR->csr = ENABS;
                    461: }

unix.superglobalmegacorp.com

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