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