Annotation of researchv8dc/sys/dev/kdi.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * stream driver for DK via KMC-11/KDI board
        !             3:  */
        !             4: #include "kdi.h"
        !             5: #include "kmc.h"
        !             6: #if NKDI && NKMC
        !             7: 
        !             8: #include "../h/param.h"
        !             9: #include "../h/systm.h"
        !            10: #include "../h/stream.h"
        !            11: #include "../h/ioctl.h"
        !            12: #include "../h/pte.h"
        !            13: #include "../h/map.h"
        !            14: #include "../h/buf.h"
        !            15: #include "../h/ubavar.h"
        !            16: #include "../h/conf.h"
        !            17: #include "../h/ttyld.h"
        !            18: #include "../h/dkstat.h"
        !            19: #include "../h/dkmod.h"
        !            20: 
        !            21: #define        NKMB    10              /* size of cmd/status buffers */
        !            22: #define        KDIPRI  28
        !            23: 
        !            24: /* channel states */
        !            25: #define        CLOSED  0
        !            26: #define        RCLOSE  1               /* remote gone, local still around */
        !            27: #define        LCLOSE  2               /* closed locally, not acked yet */
        !            28: #define        OPEN    3               /* in use */
        !            29: 
        !            30: /*
        !            31:  * format of UB addresses sent to KMC
        !            32:  */
        !            33: struct kmaddr {
        !            34:        u_short hi;
        !            35:        u_short lo;
        !            36: };
        !            37: 
        !            38: /*
        !            39:  * KMC init packet
        !            40:  */
        !            41: struct kinit {
        !            42:        struct  kmaddr  cmdaddr;        /* UB addr of cmd buf */
        !            43:        struct  kmaddr  stataddr;       /* UB addr of statbuf */
        !            44:        struct  kmaddr  bufaddr;        /* UB addr of KMC workspace */
        !            45:        struct  kmaddr  csraddr;        /* for DR11C - unused */
        !            46: };
        !            47: 
        !            48: /*
        !            49:  * command/status packets
        !            50:  */
        !            51: struct kin {                           /* KMC command buffer */
        !            52:        u_char  type;                   /* command type */
        !            53:        u_char  serno;                  /* probably seq number */
        !            54:        u_char  chan;                   /* channel number */
        !            55:        u_char  fill2;                  /* probably seq number */
        !            56:        u_short len;                    /* byte count */
        !            57:        char    ctl;                    /* possible control byte */
        !            58:        char    mode;                   /* command variant */
        !            59:        struct  kmaddr addr;            /* UB location of buffer */
        !            60: };
        !            61: 
        !            62: /*
        !            63:  * Big structure with stuff that needs to be accessible on the unibus
        !            64:  */
        !            65: struct kmcdk {
        !            66:        struct  kinit   kinit;                  /* the init packet */
        !            67:        struct  kin     cmd[NKMB];              /* KMC command buffer */
        !            68:        struct  kin     stat[NKMB];             /* KMC status buffer */
        !            69:        char    kmcbuf[16*1024];                /* temp space for KMC */
        !            70: } k;
        !            71: 
        !            72: struct kdi {
        !            73:        struct  queue *dkrq;
        !            74:        struct  block *ibp;
        !            75:        struct  block *obp;
        !            76:        u_short rsize;                  /* # bytes in last read */
        !            77:        char    chan;
        !            78:        char    ostate;
        !            79: } kdi[NKDI];
        !            80: 
        !            81: 
        !            82: #define        KMBUSY  01
        !            83: #define        KMSTOP  02
        !            84: #define        KMBIG   04              /* rcvd lots last time, use big buffer */
        !            85: 
        !            86: /*
        !            87:  * device structure
        !            88:  */
        !            89: struct device {
        !            90:        char    sts;
        !            91:        char    x1;
        !            92:        union {
        !            93:                struct {
        !            94:                        u_short lo;
        !            95:                        u_char  hi;
        !            96:                } a;
        !            97:                struct {
        !            98:                        u_char  x2;
        !            99:                        u_char  x3;
        !           100:                        u_char  ch;
        !           101:                        u_char  ct;
        !           102:                        u_char  sh;
        !           103:                        u_char  st;
        !           104:                } q;
        !           105:        } u;
        !           106: };
        !           107: 
        !           108: /*
        !           109:  * KMC commands
        !           110:  */
        !           111: #define        KC_INIT         1
        !           112: #define        KC_SEND         2
        !           113: #define        KC_RCVB         3
        !           114: #define        KC_CLOSE        4
        !           115: #define        KC_XINIT        5
        !           116: #define        KC_CMD          6
        !           117: #define        KC_FLAG         7
        !           118: #define        KC_SOI          8
        !           119: 
        !           120: /*
        !           121:  * subcommands of KC_CMD or KC_SEND
        !           122:  */
        !           123: #define        OFLUSH          02      /* flush output */
        !           124: #define        OSPND           04      /* suspend output */
        !           125: #define        ORSME           010     /* resume output */
        !           126: #define        OBOTM           0200    /* send BOTM trailer, not BOT */
        !           127: 
        !           128: /*
        !           129:  * KMC reports
        !           130:  */
        !           131: #define        KS_SEND         024
        !           132: #define        KS_RDB          025
        !           133: #define        KS_EOI          026
        !           134: #define        KS_CNTL         027
        !           135: #define        KS_ERR          030
        !           136: 
        !           137: /*
        !           138:  * KC_RCV modes
        !           139:  */
        !           140: #define        CBLOCK          0040    /* return on block boundary */
        !           141: #define        CTIME           0100    /* return when time expires */
        !           142: 
        !           143: /*
        !           144:  * KS_RDB mode
        !           145:  */
        !           146: #define        SFULL           0001    /* buffer full */
        !           147: #define        SCNTL           0002    /* cntl char recv */
        !           148: #define        SABORT          0010    /* rcv aborted */
        !           149: #define        SBLOCK          0040    /* block boundary */
        !           150: #define        STIME           0100    /* time limit expired */
        !           151: 
        !           152: /*
        !           153:  * URP control characters
        !           154:  */
        !           155: #define        D_DELAY 0100
        !           156: #define        D_BREAK 0110
        !           157: 
        !           158: /*
        !           159:  *  KMC errors
        !           160:  */
        !           161: #define        E_NOQB  4               /* internal buffer runout */
        !           162: #define        E_UMETA 7               /* unknown control character */
        !           163: 
        !           164: /*
        !           165:  * tracing
        !           166:  */
        !           167: #define DEBUG
        !           168: #ifdef DEBUG
        !           169: struct kin ktrbuf[256];
        !           170: struct kin *ktrp = ktrbuf;
        !           171: #define        TRACE(x) *ktrp++ = x; if (ktrp >= &ktrbuf[256]) ktrp = ktrbuf;
        !           172: #else
        !           173: #define        TRACE(x)        ;
        !           174: #endif
        !           175: 
        !           176: int    nodev(), kdiopen(), kdiclose(), kdiput(), kdiisrv();
        !           177: struct qinit kdirinit = { nodev, kdiisrv, kdiopen, kdiclose, 0, 0 };
        !           178: struct qinit kdiwinit = { kdiput, NULL, kdiopen, kdiclose, 512, 128 };
        !           179: struct streamtab kdiinfo = { &kdirinit, &kdiwinit };
        !           180: 
        !           181: extern u_char  blkdata[];      /* stream IO blocks */
        !           182: extern long    blkubad;        /* unibus address of IO blocks */
        !           183: long   kdiubad;                /* unibus address of device data */
        !           184: struct kmaddr kmcaddr();
        !           185: int    kdiopened;
        !           186: int    kmcbad;
        !           187: char   kdistate[NKDI];
        !           188: struct dkmodule *kdmodp;
        !           189: extern struct dkmodule dkmod[];
        !           190: extern struct  uba_device *kmcdinfo[NKMC];
        !           191: extern struct  uba_driver kmcdriver;
        !           192: extern (*kdirint)();
        !           193: extern (*kdixint)();
        !           194: struct dkstat  dkstat;
        !           195: 
        !           196: /*
        !           197:  * open channel
        !           198:  */
        !           199: kdiopen(q, dev)
        !           200: register struct queue *q;
        !           201: register dev_t dev;
        !           202: {
        !           203:        register struct kdi *kp;
        !           204:        register struct block *bp;
        !           205:        register mindev = minor(dev);
        !           206: 
        !           207:        if (mindev <= 0 || mindev >= NKDI || kmcbad)
        !           208:                return(0);
        !           209:        if (!kdiopened) {
        !           210:                if (mindev > 1)
        !           211:                        return(0);
        !           212:                for (kp = &kdi[0]; kp < &kdi[NKDI]; kp++)
        !           213:                        kp->chan = kp - &kdi[0];
        !           214:                if (kdiinit() == 0)
        !           215:                        return(0);
        !           216:                for (kdmodp = dkmod; ;kdmodp++) {
        !           217:                        if (kdmodp->dev==(dev_t)0 || kdmodp->dev==major(dev)) {
        !           218:                                kdmodp->dev = major(dev);
        !           219:                                kdmodp->dkstate = kdistate;
        !           220:                                kdmodp->nchan = NKDI;
        !           221:                                break;
        !           222:                        }
        !           223:                }
        !           224:                kdiopened++;
        !           225:        }
        !           226:        kp = &kdi[mindev];
        !           227:        if (kdmodp->dkstate[mindev] != CLOSED) {
        !           228:                if (mindev&01 && mindev>1) /* outgoing channels cannot reopen */
        !           229:                        return(0);
        !           230:                if (kdmodp->dkstate[mindev] != OPEN)
        !           231:                        return(0);      /* closing channels cannot reopen */
        !           232:                return(1);
        !           233:        }
        !           234:        kp->dkrq = q;
        !           235:        q->ptr = (caddr_t)kp;
        !           236:        WR(q)->flag |= QDELIM|QBIGB;
        !           237:        q->flag |= QDELIM;
        !           238:        WR(q)->ptr = (caddr_t)kp;
        !           239:        kdmodp->dkstate[mindev] = OPEN;
        !           240:        kp->ostate = 0;
        !           241:        kcmd(KC_INIT, kp->chan, 0, 0, 0, (caddr_t)0);
        !           242:        if ((bp = allocb(64)) == NULL) {
        !           243:                kdmodp->dkstate[mindev] = 0;
        !           244:                return(0);
        !           245:        }
        !           246:        kp->ibp = bp;
        !           247:        kcmd(KC_RCVB, mindev, bp->lim-bp->wptr, 50,
        !           248:             CBLOCK|CTIME, (caddr_t)bp->wptr);
        !           249:        return(1);
        !           250: }
        !           251: 
        !           252: kdiclose(q)
        !           253: register struct queue *q;
        !           254: {
        !           255:        register struct kdi *kp = (struct kdi *)q->ptr;
        !           256:        register s, i;
        !           257:        register struct block *bp;
        !           258: 
        !           259:        if (kdmodp->dkstate[kp->chan]==RCLOSE || kdmodp->listnrq==NULL)
        !           260:                kdmodp->dkstate[kp->chan] = CLOSED;
        !           261:        else if (kdmodp->dkstate[kp->chan] == OPEN) {
        !           262:                kdmodp->dkstate[kp->chan] = LCLOSE;
        !           263:                for (i=0; i<30 && (WR(q)->count || kp->obp); i++)
        !           264:                        tsleep((caddr_t)kp, KDIPRI, 1);
        !           265:        }
        !           266:        kp->dkrq = NULL;
        !           267:        if (kdmodp->listnrq)
        !           268:                putctl1(RD(kdmodp->listnrq), M_CLOSE, kp->chan);
        !           269:        s = spl6();
        !           270:        if (kp->obp) {
        !           271:                freeb(kp->obp);
        !           272:                kp->obp = NULL;
        !           273:        }
        !           274:        splx(s);
        !           275:        kcmd(KC_CLOSE, kp->chan, 0, 0, 0, (caddr_t)NULL);
        !           276: }
        !           277: 
        !           278: kdiput(q, bp)
        !           279: register struct queue *q;
        !           280: register struct block *bp;
        !           281: {
        !           282:        register struct kdi *kdp = (struct kdi *)q->ptr;
        !           283:        register union stmsg *sp;
        !           284:        register s;
        !           285: 
        !           286:        switch(bp->type) {
        !           287: 
        !           288:        case M_DATA:
        !           289:        case M_DELIM:
        !           290:        case M_DELAY:
        !           291:        case M_BREAK:
        !           292:                if (kdmodp->dkstate[kdp->chan] < LCLOSE) {
        !           293:                        freeb(bp);
        !           294:                        return;
        !           295:                }
        !           296:                putq(q, bp);
        !           297:                if ((kdp->ostate&KMBUSY)==0)
        !           298:                        kmstart(kdp);
        !           299:                return;
        !           300: 
        !           301:        case M_CLOSE:
        !           302:                s = *bp->rptr;
        !           303:                if (s < NKDI) {
        !           304:                        flushq(q, 1);
        !           305:                        if (kdmodp->dkstate[s] == OPEN) {
        !           306:                                kdmodp->dkstate[s] = RCLOSE;
        !           307:                                putctl(kdi[s].dkrq->next, M_HANGUP);
        !           308:                        } else if (kdmodp->dkstate[s] == LCLOSE)
        !           309:                                kdmodp->dkstate[s] = CLOSED;
        !           310:                        kcmd(KC_CLOSE, s, 0, 0, 0, (caddr_t)NULL);
        !           311:                }
        !           312:                freeb(bp);
        !           313:                return;
        !           314: 
        !           315:        case M_IOCTL:
        !           316:                sp = (union stmsg *)bp->rptr;
        !           317:                bp->type = M_IOCACK;
        !           318:                switch (sp->ioc0.com) {
        !           319: 
        !           320:                case TIOCSETP:
        !           321:                case TIOCSETN:
        !           322:                        if (sp->ioc1.sb.sg_ispeed == 0)
        !           323:                                putctl1(q, M_CLOSE, kdp->chan);
        !           324:                case KIOCISURP:
        !           325:                        bp->wptr = bp->rptr;
        !           326:                        break;
        !           327: 
        !           328:                case TIOCGETP:
        !           329:                        sp->ioc1.sb.sg_ispeed =
        !           330:                          sp->ioc1.sb.sg_ospeed = B9600;
        !           331:                        break;
        !           332: 
        !           333:                case KIOCINIT:
        !           334:                        kcmd(KC_XINIT, kdp->chan, 0, 0, 0, (caddr_t)NULL);
        !           335:                        bp->rptr = bp->wptr;
        !           336:                        break;
        !           337: 
        !           338:                case KIOCSHUT:
        !           339:                        if (kdp->chan > 1) {
        !           340:                                bp->type = M_IOCNAK;
        !           341:                                break;
        !           342:                        }
        !           343:                        kdireset();
        !           344:                        bp->rptr = bp->wptr;
        !           345:                        break;
        !           346: 
        !           347:                case DIOCSTREAM:
        !           348:                        RD(q)->flag &= ~QDELIM;
        !           349:                        bp->rptr = bp->wptr;
        !           350:                        break;
        !           351: 
        !           352:                case DIOCRECORD:
        !           353:                        RD(q)->flag |= QDELIM;
        !           354:                        bp->rptr = bp->wptr;
        !           355:                        break;
        !           356: 
        !           357:                default:
        !           358:                        bp->wptr = bp->rptr;
        !           359:                        bp->type = M_IOCNAK;
        !           360:                        break;
        !           361:                }
        !           362:                qreply(q, bp);
        !           363:                return;
        !           364: 
        !           365:        case M_STOP:
        !           366:                s = OSPND;
        !           367:                kdp->ostate |= KMSTOP;
        !           368:                goto dontcmd;
        !           369: 
        !           370:        case M_FLUSH:
        !           371:                flushq(q, 0);
        !           372:                s = spl6();
        !           373:                if (kdp->obp) {
        !           374:                        freeb(kdp->obp);
        !           375:                        kdp->obp = 0;
        !           376:                }
        !           377:                kdp->ostate &= ~(KMSTOP|KMBUSY);
        !           378:                splx(s);
        !           379:                s = OFLUSH|ORSME;
        !           380:                goto docmd;
        !           381: 
        !           382:        case M_START:
        !           383:        case M_HANGUP:
        !           384:                s = ORSME;
        !           385:                kdp->ostate &= ~KMSTOP;
        !           386:                goto dontcmd;
        !           387:        docmd:
        !           388:                kcmd(KC_CMD, kdp->chan, 0, s, 0, (caddr_t)NULL);
        !           389:        dontcmd:
        !           390:                kmstart(kdp);
        !           391:                break;
        !           392: 
        !           393:        default:                /* not handled; just toss */
        !           394:                break;
        !           395:        }
        !           396:        freeb(bp);
        !           397: }
        !           398: 
        !           399: kdiisrv(q)
        !           400: register struct queue *q;
        !           401: {
        !           402:        register struct kdi *kp = (struct kdi *)q->ptr;
        !           403: 
        !           404:        if ((q->next->flag&QFULL)==0 && kp->ibp==NULL) {
        !           405:                register struct block *bp = allocb(kp->ostate&KMBIG? 1024:64);
        !           406:                if (bp == NULL)
        !           407:                        panic("kdi: can't alloc");
        !           408:                kp->ibp = bp;
        !           409:                kcmd(KC_RCVB, kp->chan, bp->lim - bp->wptr,
        !           410:                     50, CBLOCK|CTIME, (caddr_t)bp->wptr);
        !           411:        }
        !           412: }
        !           413: 
        !           414: kmstart(kdp)
        !           415: register struct kdi *kdp;
        !           416: {
        !           417:        register s = spl5();
        !           418:        register struct block *bp;
        !           419:        register struct queue *qp;
        !           420:        register c;
        !           421:        register struct block *xbp;
        !           422: 
        !           423:        if (kdp->ostate&(KMBUSY|KMSTOP)) {
        !           424:                splx(s);
        !           425:                return;
        !           426:        }
        !           427:        if ((qp = kdp->dkrq)==NULL || (qp = WR(qp))==NULL) {
        !           428:                splx(s);
        !           429:                return;
        !           430:        }
        !           431:        if (bp = getq(qp)) switch (bp->type) {
        !           432: 
        !           433:        case M_DELIM:
        !           434:                kcmd(KC_SEND, kdp->chan, 0,
        !           435:                     D_DELAY, 0, (caddr_t)bp->rptr);
        !           436:                kdp->ostate |= KMBUSY;
        !           437:                kdp->obp = bp;
        !           438:                break;
        !           439: 
        !           440:        case M_DATA:
        !           441:                c = OBOTM;
        !           442:                if (xbp = qp->first) {
        !           443:                        if (xbp->type==M_DELIM) {
        !           444:                                if (xbp = getq(qp))
        !           445:                                        freeb(xbp);
        !           446:                                c = 0;
        !           447:                        } 
        !           448:                } else {        /* wait for delim or data */
        !           449:                        putbq(qp, bp);
        !           450:                        splx(s);
        !           451:                        return;
        !           452:                }
        !           453:                kcmd(KC_SEND, kdp->chan, bp->wptr-bp->rptr,
        !           454:                     0, c, (caddr_t)bp->rptr);
        !           455:                kdp->ostate |= KMBUSY;
        !           456:                dkstat.output += bp->wptr - bp->rptr;
        !           457:                kdp->obp = bp;
        !           458:                break;
        !           459: 
        !           460:        case M_DELAY:
        !           461:                c = D_DELAY;
        !           462:                while (*bp->rptr>0) {
        !           463:                        c++;
        !           464:                        *bp->rptr >>= 1;
        !           465:                }
        !           466:                kcmd(KC_SEND, kdp->chan, 1, c, 0, (caddr_t)bp->rptr);
        !           467:                kdp->ostate |= KMBUSY;
        !           468:                kdp->obp = bp;
        !           469:                break;
        !           470: 
        !           471:        case M_BREAK:
        !           472:                kcmd(KC_SEND, kdp->chan, 0, D_BREAK, 0, (caddr_t)bp->rptr);
        !           473:                kdp->ostate |= KMBUSY;
        !           474:                kdp->obp = bp;
        !           475:                break;
        !           476: 
        !           477:        default:
        !           478:                printf("mesg %o in kdi\n", bp->type);
        !           479:                freeb(bp);
        !           480:                break;
        !           481:        }
        !           482:        splx(s);
        !           483: }
        !           484: 
        !           485: kcmd(type, chan, len, ctl, mode, addr)
        !           486: caddr_t addr;
        !           487: {
        !           488:        register i;
        !           489:        register struct device *dp = (struct device *)kmcdinfo[0]->ui_addr;
        !           490:        register struct kin *kp;
        !           491:        register s = spl5();
        !           492:        static struct kmaddr nulladr = {0, 0};
        !           493:        static serno;
        !           494: 
        !           495:        i = dp->u.q.ch;
        !           496:        if (i >= NKMB)
        !           497:                panic("cmd hd %d in kcmd\n", i);
        !           498:        kp = &k.cmd[i];
        !           499:        kp->type = type;
        !           500:        kp->serno = ++serno;
        !           501:        kp->chan = chan;
        !           502:        kp->len = len;
        !           503:        kp->ctl = ctl;
        !           504:        kp->mode = mode;
        !           505:        if (addr)
        !           506:                kp->addr = kmcaddr(addr, (caddr_t)blkdata, blkubad);
        !           507:        else
        !           508:                kp->addr = nulladr;
        !           509:        i++;
        !           510:        if (i >= NKMB)
        !           511:                i = 0;
        !           512:        dp->u.q.ch = i;
        !           513:        TRACE(*kp);
        !           514:        splx(s);
        !           515: }
        !           516: 
        !           517: /*
        !           518:  * Interrupt routine-- unload status buffer:
        !           519:  * release write blocks, collect input
        !           520:  */
        !           521: kdiintr()
        !           522: {
        !           523:        register struct device *dp = (struct device *)(kmcdinfo[0]->ui_addr);
        !           524:        register struct kin *sp;
        !           525:        register struct kdi *kp;
        !           526:        register struct block *bp;
        !           527:        register c;
        !           528: 
        !           529:        for ( ; (c = dp->u.q.st) != dp->u.q.sh; dp->u.q.st = c) {
        !           530:                if (c >= NKMB)
        !           531:                        panic("kdi stat buf is %d\n", c);
        !           532:                sp = &k.stat[c];
        !           533:                TRACE(*sp);
        !           534:                c++;
        !           535:                if (c >= NKMB)
        !           536:                        c = 0;
        !           537:                if (sp->chan >= NKDI) {
        !           538:                        printf("kdi stat chan is 0%o\n", sp->chan);
        !           539:                        printf("type: %o len: 0%o mode: 0%o\n");
        !           540:                        continue;
        !           541:                }
        !           542:                kp = &kdi[sp->chan];
        !           543:                switch (sp->type) {
        !           544: 
        !           545:                case KS_SEND:
        !           546:                        if (kp->obp) {
        !           547:                                freeb(kp->obp);
        !           548:                                kp->obp = NULL;
        !           549:                        }
        !           550:                        kp->ostate &= ~KMBUSY;
        !           551:                        if (kp->dkrq && WR(kp->dkrq)->first)
        !           552:                                kmstart(kp);
        !           553:                        break;
        !           554: 
        !           555:                case KS_RDB:
        !           556:                        bp = kp->ibp;
        !           557:                        kp->ibp = NULL;
        !           558:                        if (kp->dkrq==NULL || kdmodp->dkstate[kp->chan]!=OPEN) {
        !           559:                                if (bp)
        !           560:                                        freeb(bp);
        !           561:                                break;
        !           562:                        }
        !           563:                        if (sp->mode & SABORT) {
        !           564:                                printf("kdi rcv abort chan %d mode %o bp %x\n",
        !           565:                                  kp->chan, sp->mode, bp);
        !           566:                                if (bp)
        !           567:                                        kp->ibp = bp;
        !           568:                                kp->rsize = 0;
        !           569:                                kp->ostate &= ~KMBIG;
        !           570:                                break;
        !           571:                        }
        !           572:                        if (bp == NULL) {
        !           573:                                printf("kdi intr: no ibp\n");
        !           574:                                break;;
        !           575:                        }
        !           576:                        /* special hacks */
        !           577:                        if (sp->mode&020
        !           578:                          || sp->mode==0100 && bp->wptr+sp->len == bp->lim) {
        !           579:                                printf("I");
        !           580:                                freeb(bp);
        !           581:                        } else {
        !           582:                                bp->wptr = bp->lim - sp->len;
        !           583:                                kp->rsize += bp->wptr - bp->rptr;
        !           584:                                dkstat.input += bp->wptr - bp->rptr;
        !           585:                                (*kp->dkrq->next->qinfo->putp)
        !           586:                                       (kp->dkrq->next, bp);
        !           587:                                kp->ibp = NULL;
        !           588:                                if(sp->mode&(SBLOCK|STIME)) {
        !           589:                                        putctl(kp->dkrq->next, M_DELIM);
        !           590:                                        kp->ostate &= ~KMBIG;
        !           591:                                        if (kp->rsize >= 512)
        !           592:                                                kp->ostate |= KMBIG;
        !           593:                                        kp->rsize = 0;
        !           594:                                }
        !           595:                                if (sp->mode&SCNTL) {
        !           596:                                        switch (sp->ctl) {
        !           597: 
        !           598:                                        case D_BREAK:
        !           599:                                                putctl(kp->dkrq->next, M_BREAK);
        !           600:                                                break;
        !           601: 
        !           602:                                        }
        !           603:                                }
        !           604:                        }
        !           605:                        if ((kp->dkrq->next->flag&QFULL) == 0) {
        !           606:                                bp = allocb(kp->ostate&KMBIG? 1024:64);
        !           607:                                if (bp == NULL)
        !           608:                                        panic("kdi: can't alloc");
        !           609:                                kp->ibp = bp;
        !           610:                                kcmd(KC_RCVB, kp->chan, bp->lim - bp->wptr,
        !           611:                                     50, CBLOCK|CTIME, (caddr_t)bp->wptr);
        !           612:                        }
        !           613:                        break;
        !           614:                
        !           615:                case KS_EOI:
        !           616:                        printf("kdi chan %d rcv EOI %x\n", sp->chan, sp->len);
        !           617:                        break;
        !           618: 
        !           619:                case KS_CNTL:
        !           620:                        /*
        !           621:                        printf("kdi chan %d rcv ctl %x\n", sp->chan, sp->len);
        !           622:                        */
        !           623:                        break;
        !           624: 
        !           625:                case KS_ERR:
        !           626:                        printf("kdi chan %d error %d\n", sp->chan, sp->len);
        !           627:                        if (sp->len==E_NOQB || sp->len==E_UMETA) {
        !           628:                                printf("ignored\n");
        !           629:                                break;
        !           630:                        }
        !           631:                        kdireset();
        !           632:                        break;
        !           633: 
        !           634:                }
        !           635:        }
        !           636: }
        !           637: 
        !           638: kdiinit()
        !           639: {
        !           640:        register struct device *kp = (struct device *)kmcdinfo[0]->ui_addr;
        !           641:        register i;
        !           642:        struct kmaddr ka;
        !           643:        static time_t kditime;
        !           644:        extern time_t time;
        !           645: 
        !           646:        /* close all open channels? */
        !           647:        if (kditime+30 > time)
        !           648:                return(0);
        !           649:        kp->sts = 0;                    /* initialize KMC */
        !           650:        if (kdiubad == 0) {
        !           651:                kdiubad = uballoc(kmcdinfo[0]->ui_ubanum,
        !           652:                                   (caddr_t)&k, sizeof(k), 0);
        !           653:                if (kdiubad == 0)
        !           654:                        panic("UB AD 0 in kdiinit");
        !           655:        }
        !           656:        k.kinit.cmdaddr = kmcaddr((caddr_t)k.cmd, (caddr_t)&k, kdiubad);
        !           657:        k.kinit.stataddr = kmcaddr((caddr_t)k.stat, (caddr_t)&k, kdiubad);
        !           658:        k.kinit.bufaddr = kmcaddr((caddr_t)k.kmcbuf, (caddr_t)&k, kdiubad);
        !           659:        ka = kmcaddr((caddr_t)&k.kinit, (caddr_t)&k, kdiubad);
        !           660:        kp->u.a.lo = ka.lo;
        !           661:        kp->u.a.hi = ka.hi;
        !           662:        kditime = time;
        !           663:        kp->sts = 1;                    /* start handshake */
        !           664:        for (i = 0; i<100000; i++) {
        !           665:                if (kp->sts == 2) {
        !           666:                        kdirint = kdiintr;
        !           667:                        kdixint = kdiintr;
        !           668:                        return(1);                      /* KMC is running OK */
        !           669:                }
        !           670:                if (kp->sts == 3) {
        !           671:                        printf("KMC entered state 3\n");
        !           672:                        return(0);
        !           673:                }
        !           674:        }
        !           675:        printf("KMC did not come ready\n");
        !           676:        return(0);
        !           677: }
        !           678: 
        !           679: struct kmaddr
        !           680: kmcaddr(memaddr, membase, ubbase)
        !           681: caddr_t memaddr, membase, ubbase;
        !           682: {
        !           683:        register struct kmaddr r;
        !           684:        register long a;
        !           685: 
        !           686:        a = (long)memaddr - (long)membase + ((long)ubbase & 0x03ffff);
        !           687:        r.hi = a >> 16;
        !           688:        r.lo = (u_short)a;
        !           689:        return(r);
        !           690: }
        !           691: 
        !           692: /*
        !           693:  * kmc reload
        !           694:  */
        !           695: kdireload()
        !           696: {
        !           697:        kdiopened = 0;
        !           698:        kdmodp = 0;
        !           699:        kmcbad = 0;
        !           700: }
        !           701: 
        !           702: /*
        !           703:  * zap all open channels
        !           704:  */
        !           705: kdireset()
        !           706: {
        !           707:        register struct kdi *kp;
        !           708: 
        !           709:        if (kdmodp==0)
        !           710:                return;
        !           711:        for (kp = kdi; kp < &kdi[NKDI]; kp++) {
        !           712:                register state = kdmodp->dkstate[kp->chan];
        !           713:                if ((state==OPEN || state==LCLOSE) && kp->dkrq) {
        !           714:                        flushq(WR(kp->dkrq), 1);
        !           715:                        kdmodp->dkstate[kp->chan] = state==OPEN? RCLOSE: CLOSED;
        !           716:                        putctl(kp->dkrq->next, M_HANGUP);
        !           717:                }
        !           718:        }
        !           719:        kmcbad = 1;
        !           720: }

unix.superglobalmegacorp.com

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