Annotation of researchv10no/sys/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: /* printf("DK XCL chan %d state %o flag %o\n", chan, dkstate[chan], dkp->flag); */
                    116:                        return(0);
                    117:                }
                    118:                if (dkstate[chan] != DKOPEN) {
                    119: /* printf("DK XCL chan %d state %o flag %o\n", chan, dkstate[chan], dkp->flag); */
                    120:                        return(0);      /* closing channels can't reopen */
                    121:                }
                    122:                return(1);
                    123:        }
                    124:        dkp->dkrq = q;
                    125:        q->ptr = (caddr_t)dkp;
                    126:        WR(q)->ptr = (caddr_t)dkp;
                    127:        dkp->flag = DKXCL;
                    128:        dkp->icnt = 0;
                    129:        dkp->isize = 0;
                    130:        dkp->ibuf = 0;
                    131:        dkp->ialloc = DKISML;
                    132:        dkstate[chan] = DKOPEN;
                    133:        return(1);
                    134: }
                    135: 
                    136: /*
                    137:  * Timer to recover from lost interrupt condition.
                    138:  */
                    139: dkrecover(dev)
                    140: dev_t  dev;
                    141: {
                    142:        register int    ps = spl5();
                    143: 
                    144:        if (DKADDR->csr & DKRDONE)
                    145:                dk1int(dev);
                    146:        splx(ps);
                    147: 
                    148:        timeout(dkrecover, (caddr_t)dev, HZ/2);
                    149: }
                    150: 
                    151: /*
                    152:  * close DK channel
                    153:  */
                    154: dkclose(q)
                    155: register struct queue *q;
                    156: {
                    157:        register struct dk *dkp;
                    158:        register struct block *bp;
                    159: 
                    160:        dkp = (struct dk *)q->ptr;
                    161:        dkp->dkrq = NULL;
                    162:        dkp->flag = 0;
                    163:        if (dkstate[dkp->chan] == DKRCLOSE || dkmodp->listnrq==NULL)
                    164:                dkstate[dkp->chan] = DKCLOSED;
                    165:        else if (dkstate[dkp->chan] == DKOPEN)
                    166:                dkstate[dkp->chan] = DKLCLOSE;
                    167:        if (dkmodp->listnrq)
                    168:                putctl2(RD(dkmodp->listnrq), M_PRICTL, DKMCLOSE, dkp->chan);
                    169:        if (dkp->ibuf)
                    170:                freeb(dkp->ibuf);
                    171:        while ((bp = dkp->ofirst) != NULL) {
                    172:                dkp->ofirst = bp->next;
                    173:                freeb(bp);
                    174:        }
                    175:        dkp->ibuf = 0;
                    176: }
                    177: 
                    178: /*
                    179:  * DK receiver interrupt.
                    180:  */
                    181: 
                    182: #define        PUTIN(bp, q)    {\
                    183:        dkstat.input += (bp)->wptr - (bp)->rptr;\
                    184:        if (((q)->next->flag & QFULL) == 0)\
                    185:                (*(q)->next->qinfo->putp)(q->next, bp);\
                    186:        else\
                    187:                freeb(bp);\
                    188: }
                    189: 
                    190: #define        DKSIZUP(dkp)    {\
                    191:        if (dkp->isize > DKITHRES) {\
                    192:                dkp->ialloc = dkp->isize;\
                    193:                dkp->icnt = 3;\
                    194:        } else if (--dkp->icnt <= 0) {\
                    195:                dkp->icnt = 0;\
                    196:                dkp->ialloc = DKISML;\
                    197:        }\
                    198:        dkp->isize = 0;\
                    199: }
                    200: 
                    201: dk1int(dev)
                    202: {
                    203:        register struct queue *q;
                    204:        register struct block *bp;
                    205:        register struct dk *dkp;
                    206:        register struct device *reg;
                    207:        register c, nbytes;
                    208:        register sane, chan;
                    209:        register struct block **bpp;
                    210:        struct block *blist[DKIPKT+2];
                    211: 
                    212:        if ((reg = DKADDR) == NULL)
                    213:                return;
                    214:        c = 0;
                    215:        dkp = NULL;
                    216:        while (reg->csr & DKRDONE) {
                    217:                reg->csr = D_READ|ENABS;
                    218:                if ((c & DKMARK) == 0) {
                    219:                        /* Search for channel number */
                    220:                        sane = 256;
                    221:                        do {
                    222:                                c = reg->dki;
                    223:                                if (c & DKMARK || --sane==0)
                    224:                                        break;
                    225:                        } while (reg->csr & DKRDONE);
                    226:                }
                    227:                if ((c & DKMARK) == 0) {
                    228:                        dkstat.markflt++;
                    229:                        continue;
                    230:                }
                    231:                if ((c & DKPARITY) == 0) {
                    232:                        dkstat.markparity++;
                    233:                        c = 0;
                    234:                        continue;
                    235:                }
                    236:                /* check channel */
                    237:                chan = c & 0777;
                    238:                if (dkp && dkp->chan != chan) {
                    239:                        if ((bp = dkp->ibuf) != NULL)
                    240:                                PUTIN(bp, q);
                    241:                        DKSIZUP(dkp);
                    242:                        dkp->ibuf = NULL;
                    243:                }
                    244:                if (chan == 0 || chan >= dkcnt || (q = dk[chan].dkrq)==NULL) {
                    245:                        if (chan>0 && chan<dkcnt)
                    246:                                dkstat.closepack++;
                    247:                        else if (chan == 0)
                    248:                                dkstat.pack0++;
                    249:                        else
                    250:                                dkstat.packstrange++;
                    251:                        for (nbytes=0; nbytes<DKIPKT; nbytes++) {
                    252:                                c = reg->dki;
                    253:                                if (c & DKMARK)
                    254:                                        break;
                    255:                        }
                    256:                        continue;
                    257:                }
                    258:                dkp = (struct dk *)q->ptr;
                    259:                if ((bp = dkp->ibuf) == NULL
                    260:                &&  (bp = allocb(dkp->ialloc)) == NULL)
                    261:                        return;
                    262:                bpp = blist;
                    263:                for (nbytes=0; nbytes<DKIPKT; nbytes++) {
                    264: #ifdef SAFETY
                    265:                        if ((reg->csr&DKRDONE) == 0)
                    266:                                break;
                    267: #endif
                    268:                        c = reg->dki;
                    269:                        if ((c&(DKPARITY|DKMARK|DKDATA)) == (DKPARITY|DKDATA)) {
                    270:                                if (bp->wptr >= bp->lim) {
                    271:                                        *bpp++ = bp;
                    272:                                        if ((bp = allocb(DKISML)) == NULL)
                    273:                                                break;
                    274:                                }
                    275:                                *bp->wptr++ = c;
                    276:                                dkp->isize++;
                    277:                                continue;
                    278:                        }
                    279:                        /*
                    280:                         * control or error
                    281:                         */
                    282:                        if (c & DKMARK) {
                    283:                                dkstat.shortpack++;
                    284:                                break;
                    285:                        }
                    286:                        if ((c & DKPARITY) == 0) {
                    287:                                dkstat.parity++;
                    288:                                break;
                    289:                        }
                    290:                        if ((c & 0377) == 0)    /* control-null */
                    291:                                continue;
                    292:                        if (bp->wptr > bp->rptr) {
                    293:                                *bpp++ = bp;
                    294:                                if ((bp = allocb(DKISML)) == NULL)
                    295:                                        break;
                    296:                        }
                    297:                        bp->type = M_CTL;
                    298:                        *bp->wptr++ = c;
                    299:                }
                    300:                if (bpp == blist && bp->type == M_DATA) {
                    301:                        dkp->ibuf = bp;
                    302:                        continue;
                    303:                }
                    304:                *bpp++ = bp;
                    305:                *bpp = NULL;
                    306:                bpp = blist;
                    307:                while ((bp = *bpp++) != NULL)
                    308:                        PUTIN(bp, q);
                    309:                DKSIZUP(dkp);
                    310:                dkp->ibuf = NULL;
                    311:        }
                    312:        if (dkp && (bp = dkp->ibuf) != NULL) {
                    313:                PUTIN(bp, q);
                    314:                DKSIZUP(dkp);
                    315:                dkp->ibuf = NULL;
                    316:        }
                    317: }
                    318: 
                    319: /*
                    320:  * DK put procedure
                    321:  */
                    322: dkput(q, bp)
                    323: register struct queue *q;
                    324: register struct block *bp;
                    325: {
                    326:        register n;
                    327:        register bn;
                    328:        int s;
                    329:        register struct device *reg = DKADDR;
                    330:        register struct dk *dkp;
                    331: 
                    332:        dkp = (struct dk *)q->ptr;
                    333:        if (dkp == NULL) {
                    334:                freeb(bp);
                    335:                return;
                    336:        }
                    337:        switch (bp->type) {
                    338: 
                    339:        case M_IOCTL:
                    340:                bp->type = M_IOCACK;
                    341:                switch (stiocom(bp)) {
                    342:                case DIOCNXCL:
                    343:                        dkp->flag &=~ DKXCL;
                    344:                        bp->wptr = bp->rptr;
                    345:                        bp->type = M_IOCACK;
                    346:                        break;
                    347: 
                    348:                default:
                    349:                        bp->type = M_IOCNAK;
                    350:                        break;
                    351:                }
                    352:                qreply(q, bp);
                    353:                return;
                    354: 
                    355:        case M_CTL:
                    356:        case M_DATA:
                    357:                s = spl6();
                    358:                bp->next = NULL;
                    359:                if (dkp->ofirst == NULL)
                    360:                        dkp->ofirst = bp;
                    361:                else
                    362:                        dkp->olast->next = bp;
                    363:                dkp->olast = bp;
                    364:                if ((bp->class&S_DELIM)==0 || dkalive == 0) {
                    365:                        splx(s);
                    366:                        return;
                    367:                }
                    368:                /*
                    369:                 * S_DELIM:
                    370:                 * push out data
                    371:                 */
                    372:                n = DKOPKT;
                    373:                reg->csr = D_WRITE + ENABS;
                    374:                reg->dko = DKMARK + dkp->chan;
                    375:                while ((bp = dkp->ofirst) != NULL) {
                    376:                        dkp->ofirst = bp->next;
                    377:                        if (bp->wptr == bp->rptr) {
                    378:                                freeb(bp);
                    379:                                continue;
                    380:                        }
                    381:                        dkstat.output += bp->wptr - bp->rptr;
                    382:                        if (n <= 0) {
                    383:                                reg->csr = D_XPACK + ENABS;
                    384:                                reg->dko = 0;
                    385:                                n = DKOPKT;
                    386:                                reg->csr = D_WRITE + ENABS;
                    387:                                reg->dko = DKMARK + dkp->chan;
                    388:                        }
                    389:                        --n;
                    390:                        reg->dko = *bp->rptr++ | ((bp->type==M_DATA)?DKDATA:0);
                    391:                        while ((bn = bp->wptr - bp->rptr) > 0) {
                    392:                                if (bn > n)
                    393:                                        bn = n;
                    394:                                n -= bn;
                    395:                                while (--bn >= 0)
                    396:                                        reg->dko = *bp->rptr++ | DKDATA;
                    397:                                if (n <= 0) {
                    398:                                        reg->csr = D_XPACK + ENABS;
                    399:                                        reg->dko = 0;
                    400:                                        n = DKOPKT;
                    401:                                        reg->csr = D_WRITE + ENABS;
                    402:                                        reg->dko = DKMARK + dkp->chan;
                    403:                                }
                    404:                        }
                    405:                        freeb(bp);
                    406:                }
                    407:                reg->csr = D_XPACK + ENABS;
                    408:                reg->dko = 0;
                    409:                splx(s);
                    410:                return;
                    411: 
                    412:        case M_PRICTL:
                    413:                switch (*bp->rptr) {
                    414:                case DKMCLOSE:
                    415:                        n = bp->rptr[1];
                    416:                        if (n < dkcnt) {
                    417:                                if (dkstate[n] == DKOPEN) {
                    418:                                        dkstate[n] = DKRCLOSE;
                    419:                                        putctl(dk[n].dkrq->next, M_HANGUP);
                    420:                                } else if (dkstate[n] == DKLCLOSE)
                    421:                                        dkstate[n] = DKCLOSED;
                    422:                        }
                    423:                        freeb(bp);
                    424:                        return;
                    425: 
                    426:                case DKMXINIT:
                    427:                        n = bp->rptr[1];
                    428:                        if (n < dkcnt && dkstate[n] == DKOPEN)
                    429:                                (*dk[n].dkrq->next->qinfo->putp)(dk[n].dkrq->next, bp);
                    430:                        else
                    431:                                freeb(bp);
                    432:                        return;                         
                    433: 
                    434:                default:
                    435:                        freeb(bp);
                    436:                        return;
                    437:                }
                    438: 
                    439:        default:
                    440:                freeb(bp);
                    441:                return;
                    442:        }
                    443: }
                    444: 
                    445: /*
                    446:  * transmit interrupt
                    447:  */
                    448: 
                    449: dk0int(dev)
                    450: int dev;
                    451: {
                    452:        printf("dk%d xmit stray\n", dev);
                    453: }
                    454: 
                    455: /*
                    456:  * unibus reset
                    457:  */
                    458: dkreset()
                    459: {
                    460:        if (DKADDR)
                    461:                DKADDR->csr = ENABS;
                    462: }

unix.superglobalmegacorp.com

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