Annotation of researchv8dc/sys/dev/dk.c, revision 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.