Annotation of researchv8dc/sys/dev/dk.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  Datakit driver
                      3:  */
                      4: #include "dk.h"
                      5: #if NDK
                      6: #include "../h/param.h"
                      7: #include "../h/systm.h"
                      8: #include "../h/stream.h"
                      9: #include "../h/ioctl.h"
                     10: #include "../h/pte.h"
                     11: #include "../h/map.h"
                     12: #include "../h/buf.h"
                     13: #include "../h/ubavar.h"
                     14: #include "../h/conf.h"
                     15: #include "../h/dkstat.h"
                     16: #include "../h/dkmod.h"
                     17: #include "sparam.h"
                     18: 
                     19: struct device {
                     20:        unsigned short csr;
                     21:        unsigned short dko;
                     22:        unsigned short dki;
                     23: };
                     24: 
                     25: struct device  *DKADDR;
                     26: #ifndef        NDKLINE
                     27: #define        NDKLINE 64
                     28: #endif NDKLINE
                     29: 
                     30: struct dk {
                     31:        struct  queue *dkrq;
                     32:        u_char  chan;
                     33: } dk[NDKLINE];
                     34: 
                     35: int    dkalive;
                     36: struct dkstat  dkstat;
                     37: extern struct  dkmodule dkmod[];
                     38: struct dkmodule *dkmodp;
                     39: char   dkstate[NDKLINE];
                     40: 
                     41: /*
                     42:  * channel states
                     43:  */
                     44: #define        CLOSED  0
                     45: #define        RCLOSE  1               /* remote hung up, local still around */
                     46: #define        LCLOSE  2               /* closed locally, CMC hasn't acked yet */
                     47: #define        OPEN    3               /* in use */
                     48: 
                     49: /*
                     50:  * Hardware control bits
                     51:  */
                     52: #define        DKTENAB 0100
                     53: #define        DKRENAB 040
                     54: #define        ENABS   (DKRENAB)
                     55: #define        DKTDONE 0200
                     56: #define        DKRDONE 0100000
                     57: #define        D_OSEQ  0
                     58: #define        D_READ  01
                     59: #define        D_WRITE 02
                     60: #define        D_XPACK 03
                     61: #define        DKMARK  01000
                     62: #define        DKDATA  0400
                     63: #define        DKPARITY 0100000
                     64: 
                     65: #define        DKISIZ  16
                     66: 
                     67: int    nodev(), dkopen(), dkclose(), dkput();
                     68: 
                     69: static struct qinit dkrinit = { nodev, NULL, dkopen, dkclose, 0, 0 };
                     70:        struct qinit dkwinit = { dkput, NULL, dkopen, dkclose, 0, 0 };
                     71: struct streamtab dkinfo = { &dkrinit, &dkwinit };
                     72: 
                     73: int    dkattach(), dkprobe();
                     74: struct uba_device *dkstuff[NDK];
                     75: u_short        dkstd[] = { 0 };
                     76: struct uba_driver dkdriver =
                     77:        { dkprobe, 0, dkattach, 0, dkstd, "dk", dkstuff };
                     78: 
                     79: dkprobe(reg)
                     80: caddr_t reg;
                     81: {
                     82:        register int br, cvec;
                     83:        register struct device *dkaddr = (struct device *)reg;
                     84: 
                     85:        dkaddr->csr = D_OSEQ;
                     86:        dkaddr->dko = 0;        /* this clears fifos */
                     87:        DELAY(1000);            /* wait for board to reset */
                     88:        dkaddr->csr = D_WRITE;
                     89:        dkaddr->dko = DKMARK + 511;     /* pack on 511 */
                     90:        dkaddr->csr = D_XPACK+DKTENAB;
                     91:        dkaddr->dko = 0;
                     92:        DELAY(10000);
                     93:        dkaddr->csr = 0;
                     94:        DKADDR = dkaddr;
                     95:        return(1);
                     96: }
                     97: 
                     98: dkattach()
                     99: {
                    100: }
                    101: 
                    102: /*
                    103:  * open DK channel
                    104:  */
                    105: dkopen(q, dev)
                    106: register struct queue *q;
                    107: register dev_t dev;
                    108: {
                    109:        register struct dk *dkp;
                    110:        static opened, badtime;
                    111:        register maj = major(dev);
                    112: 
                    113:        dev = minor(dev);
                    114:        if (dev<=0 || dev>=NDKLINE)
                    115:                return(0);
                    116:        if (!opened) {
                    117:                register sane;
                    118: 
                    119:                if (DKADDR == NULL)
                    120:                        return(0);
                    121:                DKADDR->csr = D_OSEQ;
                    122:                DKADDR->dko = 0;        /* Clear fifo's */
                    123:                sane = 256;
                    124:                do {
                    125:                        if (DKADDR->csr & DKTDONE) {
                    126:                                dkalive = 0;
                    127:                                if (time > badtime + 300) {
                    128:                                        badtime = time;
                    129:                                        printf("DK interface bad\n");
                    130:                                }
                    131:                                return(0);
                    132:                        }
                    133:                } while (--sane);
                    134:                for (dkmodp=dkmod; ; dkmodp++) {
                    135:                        if (dkmodp->dev==0 || dkmodp->dev==maj) {
                    136:                                dkmodp->dev = maj;
                    137:                                dkmodp->dkstate = dkstate;
                    138:                                dkmodp->nchan = NDKLINE;
                    139:                                break;
                    140:                        }
                    141:                }
                    142:                dkalive = 1;
                    143:                for (dkp = &dk[0]; dkp < &dk[NDKLINE]; dkp++)
                    144:                        dkp->chan = dkp - &dk[0];
                    145:                DKADDR->csr = ENABS;
                    146:                opened++;
                    147:                dkrecover(dev);
                    148:        }
                    149:        dkp = &dk[dev];
                    150:        if (dkmodp->dkstate[dev] != CLOSED) {   /* already open */
                    151:                if (dev&01 && dev>1)    /* outgoing channels can't reopen */
                    152:                        return(0);
                    153:                if (dkmodp->dkstate[dev] != OPEN)
                    154:                        return(0);      /* closing channels can't reopen */
                    155:                return(1);
                    156:        }
                    157:        dkp->dkrq = q;
                    158:        q->ptr = (caddr_t)dkp;
                    159:        WR(q)->ptr = (caddr_t)dkp;
                    160:        dkmodp->dkstate[dev] = OPEN;
                    161:        return(1);
                    162: }
                    163: 
                    164: /*
                    165:  * Timer to recover from lost interrupt condition.
                    166:  */
                    167: dkrecover(dev)
                    168: dev_t  dev;
                    169: {
                    170:        register int    ps = spl5();
                    171: 
                    172:        if (DKADDR->csr & DKRDONE)
                    173:                dkrint(dev);
                    174:        splx(ps);
                    175: 
                    176:        timeout(dkrecover, dev, hz/2);
                    177: }
                    178: 
                    179: /*
                    180:  * close DK channel
                    181:  */
                    182: dkclose(q)
                    183: register struct queue *q;
                    184: {
                    185:        register struct dk *dkp;
                    186: 
                    187:        dkp = (struct dk *)q->ptr;
                    188:        dkp->dkrq = NULL;
                    189:        if (dkmodp->dkstate[dkp->chan] == RCLOSE || dkmodp->listnrq==NULL)
                    190:                dkmodp->dkstate[dkp->chan] = CLOSED;
                    191:        else if (dkmodp->dkstate[dkp->chan] == OPEN)
                    192:                dkmodp->dkstate[dkp->chan] = LCLOSE;
                    193:        if (dkmodp->listnrq)
                    194:                putctl1(RD(dkmodp->listnrq), M_CLOSE, dkp->chan);
                    195: }
                    196: 
                    197: /*
                    198:  * DK receiver interrupt.
                    199:  */
                    200: dkrint(dev)
                    201: {
                    202:        register struct queue *q;
                    203:        register struct block *bp, **bpp;
                    204:        register c, nbytes, sts, sane, chan;
                    205:        struct block *blist[DKISIZ+1];
                    206: 
                    207:        sts = DKADDR->csr;
                    208:        c = 0;
                    209:        while (DKADDR->csr & DKRDONE) {
                    210:                DKADDR->csr = D_READ|ENABS;
                    211:                if ((c & DKMARK) == 0) {
                    212:                        /* Search for channel number */
                    213:                        sane = 256;
                    214:                        do {
                    215:                                c = DKADDR->dki;
                    216:                                if (c & DKMARK || --sane==0)
                    217:                                        break;
                    218:                        } while (DKADDR->csr & DKRDONE);
                    219:                }
                    220:                if ((c & DKMARK) == 0) {
                    221:                        dkstat.markflt++;
                    222:                        continue;
                    223:                }
                    224:                if ((c & DKPARITY) == 0) {
                    225:                        dkstat.markparity++;
                    226:                        c = 0;
                    227:                        continue;
                    228:                }
                    229:                /* check channel */
                    230:                chan = c & 0777;
                    231:                if (chan == 0 || chan >= NDKLINE || (q = dk[chan].dkrq)==NULL) {
                    232:                        if (chan>0 && chan<NDKLINE) {
                    233:                                if (dkmodp->listnrq)
                    234:                                        putctl1(RD(dkmodp->listnrq),
                    235:                                                M_CLOSE, chan);
                    236:                                dkstat.closepack++;
                    237:                        } else if (chan == 0)
                    238:                                dkstat.pack0++;
                    239:                        else
                    240:                                dkstat.packstrange++;
                    241:                        for (nbytes=0; nbytes<DKISIZ; nbytes++) {
                    242:                                c = DKADDR->dki;
                    243:                                if (c & DKMARK)
                    244:                                        break;
                    245:                        }
                    246:                        continue;
                    247:                }
                    248:                bp = allocb(DKISIZ);
                    249:                if (bp == NULL)
                    250:                        return;
                    251:                bpp = blist;
                    252:                for (nbytes=0; nbytes<DKISIZ; nbytes++) {
                    253:                        if ((DKADDR->csr&DKRDONE) == 0)
                    254:                                break;
                    255:                        c = DKADDR->dki;
                    256:                        if ((c & (DKPARITY|DKDATA|DKMARK))!=(DKPARITY|DKDATA)) {
                    257:                                if (c & DKMARK) {
                    258:                                        dkstat.shortpack++;
                    259:                                        break;
                    260:                                }
                    261:                                if ((c & DKPARITY) == 0) {
                    262:                                        dkstat.parity++;
                    263:                                        break;
                    264:                                } else { /* it's control */
                    265:                                        if ((c & 0377) == 0)
                    266:                                                continue;
                    267:                                        if (bp->wptr > bp->rptr) {
                    268:                                                *bpp++ = bp;
                    269:                                                bp = allocb(DKISIZ);
                    270:                                                if (bp == NULL)
                    271:                                                        break;
                    272:                                        }
                    273:                                }
                    274:                                bp->type = M_CTL;
                    275:                        }
                    276:                        *bp->wptr++ = c;
                    277:                }
                    278:                *bpp++ = bp;
                    279:                *bpp++ = NULL;
                    280:                bpp = blist;
                    281:                if (nbytes!=DKISIZ) {
                    282:                        while (*bpp)
                    283:                                freeb(*bpp++);
                    284:                        continue;
                    285:                }
                    286:                while (*bpp) {
                    287:                        dkstat.input += bp->wptr - bp->rptr;
                    288:                        if ((q->next->flag & QFULL) == 0)
                    289:                                (*q->next->qinfo->putp)(q->next, *bpp++);
                    290:                        else
                    291:                                freeb(*bpp++);
                    292:                }
                    293:        }
                    294:        DKADDR->csr = sts;
                    295: }
                    296: 
                    297: /*
                    298:  * DK put procedure
                    299:  */
                    300: dkput(q, bp)
                    301: register struct queue *q;
                    302: register struct block *bp;
                    303: {
                    304:        register n, isdata = DKDATA;
                    305:        struct dk *dp;
                    306:        int chan, s;
                    307:        struct ioctl1 {
                    308:                int     com;
                    309:                int     lhn;
                    310:        } *iop;
                    311: 
                    312:        dp = (struct dk *)q->ptr;
                    313:        chan = dp->chan;
                    314:        switch (bp->type) {
                    315: 
                    316:        case M_IOCTL:
                    317:                bp->type = M_IOCACK;
                    318:                iop = (struct ioctl1 *)bp->rptr;
                    319:                switch (iop->com) {
                    320: 
                    321:                default:
                    322:                        bp->type = M_IOCNAK;
                    323:                        break;
                    324:                }
                    325:                qreply(q, bp);
                    326:                return;
                    327: 
                    328:        case M_CTL:
                    329:                isdata = 0;
                    330:        case M_DATA:
                    331:                break;
                    332: 
                    333:        case M_CLOSE:
                    334:                n = *bp->rptr;
                    335:                if (n < NDKLINE) {
                    336:                        if (dkmodp->dkstate[n] == OPEN) {
                    337:                                dkmodp->dkstate[n] = RCLOSE;
                    338:                                putctl(dk[n].dkrq->next, M_HANGUP);
                    339:                        } else if (dkmodp->dkstate[n] == LCLOSE)
                    340:                                dkmodp->dkstate[n] = CLOSED;
                    341:                }
                    342:                freeb(bp);
                    343:                return;
                    344: 
                    345:        default:
                    346:                freeb(bp);
                    347:                return;
                    348:        }
                    349:        dkstat.output += bp->wptr - bp->rptr;
                    350:        s = spl6();
                    351:        if (dkalive) {
                    352:                register struct device *dkaddr = DKADDR;
                    353:                int r = dkaddr->csr;
                    354:                while ((n = bp->wptr - bp->rptr) > 0) {
                    355:                        if (n > DKISIZ)
                    356:                                n = DKISIZ;
                    357:                        dkaddr->csr = D_WRITE + ENABS;
                    358:                        dkaddr->dko = DKMARK + chan;
                    359:                        dkaddr->dko = *bp->rptr++ | isdata;
                    360:                        while (--n)
                    361:                                dkaddr->dko = *bp->rptr++ | DKDATA;
                    362:                        dkaddr->csr = D_XPACK + ENABS;
                    363:                        dkaddr->dko = 0;
                    364:                }
                    365:                dkaddr->csr = r;
                    366:        }
                    367:        splx(s);
                    368:        freeb(bp);
                    369: }
                    370: 
                    371: /*
                    372:  * unibus reset
                    373:  */
                    374: dkreset()
                    375: {
                    376:        if (DKADDR)
                    377:                DKADDR->csr = ENABS;
                    378: }

unix.superglobalmegacorp.com

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