Annotation of researchv10dc/sys/io/okb.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * simple two-stream kmc datakit driver
                      3:  * -- assumes it is the first kmc, and only one allowed for now
                      4:  *     (the latter not severe, as 256 channels are permitted)
                      5:  */
                      6: #include "sys/param.h"
                      7: #include "sys/stream.h"
                      8: #include "sys/dkio.h"
                      9: #include "sys/ubaddr.h"
                     10: #include "sys/conf.h"
                     11: #include "sys/kb.h"
                     12: #include "sys/kmc.h"
                     13: #include "sys/dkstat.h"
                     14: #include "sys/dkmod.h"
                     15: 
                     16: /*
                     17:  * hardware stuff
                     18:  */
                     19: 
                     20: struct device {
                     21:        short   sts;    /* written by KMC */
                     22:        short   cmd;    /* command and transmit chan -- written by host */
                     23:        short   ba;     /* low bus address -- written by host */
                     24:        short   bc;     /* negative buffer size -- written by host */
                     25: };
                     26: 
                     27: /*
                     28:  * status info
                     29:  */
                     30: #define        SCOUNT  0xfff   /* receive buffer resid count */
                     31: #define        SRRDY   (020<<8)        /* receive ready */
                     32: #define        SOK     (040<<8)        /* init ok */
                     33: #define        SERROR  (0100<<8)       /* transfer or other error */
                     34: #define        SXRDY   (0200<<8)       /* transmit ready */
                     35: 
                     36: /*
                     37:  * commands
                     38:  */
                     39: #define        CGO     (01<<8)         /* turned off when command read */
                     40: #define        CRCV    (01<<8)         /* here is a receive buffer */
                     41: #define        CSEND   (03<<8)         /* send this buffer of data */
                     42: #define        CSCTL   (043<<8)        /* send this data, first char is ctl */
                     43: #define        CIE     (020<<8)        /* interrupt after this command */
                     44: #define        CXA     (014<<8)        /* high address bits */
                     45: #define        XASHIFT 10              /* shift high address bits this much */
                     46: 
                     47: #define        STALL   10000           /* max time to stall waiting for ready */
                     48: /*
                     49:  * per-channel stuff
                     50:  */
                     51: struct kb kb[];
                     52: extern int kbcnt;
                     53: char   kbstate[];
                     54: 
                     55: /*
                     56:  * kb flags
                     57:  */
                     58: #define        DKXCL   01              /* exclusive open */
                     59: #define        DKXWANT 02              /* output pending this channel */
                     60: 
                     61: /*
                     62:  * per-controller stuff;
                     63:  * always just one for now
                     64:  */
                     65: 
                     66: struct kbkmc kbkmc[1];
                     67: #define        KBNO    0       /* always this kb for now */
                     68: 
                     69: /*
                     70:  * kbkmc flags
                     71:  */
                     72: #define        INIT    01
                     73: 
                     74: /*
                     75:  * illicit linkage to other datakit code
                     76:  */
                     77: 
                     78: struct dkstat  dkstat;
                     79: 
                     80: /*
                     81:  * illicit linkage to kmc driver
                     82:  */
                     83: 
                     84: extern struct kmc kmc[];
                     85: extern struct ubaddr kmcaddr[];
                     86: extern int kmccnt;
                     87: #define        KNO     0               /* kmc0 is ours, by fiat */
                     88: 
                     89: #define        DKISIZE 1024            /* preferred input buffer size */
                     90: #define        MAXOBUF 4096            /* max allowed output buffer -- for unibus map */
                     91: 
                     92: long kbopen();
                     93: int kbclose(), kbput(), kbosrv();
                     94: 
                     95: static struct qinit kbrinit = { nodev, NULL, kbopen, kbclose, 0, 0 };
                     96:        struct qinit kbwinit = { kbput, NULL, kbopen, kbclose, 1500, 600 };
                     97: struct streamtab kbinfo = { &kbrinit, &kbwinit };
                     98: struct cdevsw kbcdev = cstrinit(&kbinfo);
                     99: 
                    100: /*
                    101:  * open DK channel
                    102:  */
                    103: long
                    104: kbopen(q, dev)
                    105: register struct queue *q;
                    106: register dev_t dev;
                    107: {
                    108:        register struct kb *dkp;
                    109:        register struct kbkmc *kk;
                    110:        register chan;
                    111: 
                    112:        chan = minor(dev);
                    113:        if (chan<=0 || chan>=kbcnt)
                    114:                return(0);
                    115:        kk = &kbkmc[KBNO];
                    116:        if ((kk->flags & INIT) == 0) {
                    117:                if ((kk->modp = dkmodall(dev, 0, kbcnt)) == NULL)
                    118:                        return (0);
                    119:                kk->modp->dkstate = kbstate;
                    120:                if (kbinit(kk) == 0)
                    121:                        return (0);
                    122:                kk->flags |= INIT;
                    123:        }
                    124:        dkp = &kb[chan];
                    125:        if (kbstate[chan] != DKCLOSED) {        /* already open */
                    126:                if (dkp->flag & DKXCL)
                    127:                        return(0);
                    128:                if (kbstate[chan] != DKOPEN)
                    129:                        return(0);      /* closing channels can't reopen */
                    130:                return(1);
                    131:        }
                    132:        dkp->dkrq = q;
                    133:        q->ptr = (caddr_t)dkp;
                    134:        WR(q)->ptr = (caddr_t)dkp;
                    135:        WR(q)->flag |= QNOENB|QBIGB;
                    136:        dkp->flag = DKXCL;
                    137:        dkp->chan = chan;
                    138:        kbstate[chan] = DKOPEN;
                    139:        return(1);
                    140: }
                    141: 
                    142: /*
                    143:  * make sure kmc is alive;
                    144:  * init data structures once
                    145:  */
                    146: kbinit(kk)
                    147: register struct kbkmc *kk;
                    148: {
                    149:        register struct kmc *kp;
                    150:        register struct device *reg;
                    151:        register int i;
                    152:        extern kbintr(), kbreset();
                    153: 
                    154:        kk->kno = KNO;
                    155:        kk->ubno = kmcaddr[KNO].ubno;   /* cheat */
                    156:        kp = &kmc[kk->kno];
                    157:        if ((reg = kp->k_addr) == 0)
                    158:                return (0);
                    159:        if ((reg->sts & SOK) == 0)
                    160:                return (0);
                    161:        if ((kk->omap = ubmalloc(kk->ubno, MAXOBUF, UBDP)) == 0)
                    162:                return (0);
                    163:        kp->k_rint = kbintr;
                    164:        kp->k_xint = kbintr;
                    165:        kp->k_reset = kbreset;
                    166:        kk->addr = reg;
                    167:        i = spl5();
                    168:        kbistart(kk);
                    169:        splx(i);
                    170:        return (1);
                    171: }
                    172: 
                    173: /*
                    174:  * called when, e.g., kmc is reloaded
                    175:  */
                    176: kbreset(kno)
                    177: int kno;
                    178: {
                    179:        register struct kbkmc *kk;
                    180:        register int s;
                    181: 
                    182:        kk = &kbkmc[KNO];
                    183:        if (kk->obuf) {
                    184:                freeb(kk->obuf);
                    185:                kk->obuf = NULL;
                    186:        }
                    187:        if (kk->imap) {
                    188:                ubmfree(kk->ubno, kk->imap);
                    189:                kk->imap = 0;
                    190:        }
                    191:        if (kk->ibuf) {
                    192:                freeb(kk->ibuf);
                    193:                kk->ibuf = NULL;
                    194:        }
                    195:        s = spl5();
                    196:        kbistart(kk);
                    197:        splx(s);
                    198: }
                    199: 
                    200: /*
                    201:  * close DK channel
                    202:  */
                    203: kbclose(q)
                    204: register struct queue *q;
                    205: {
                    206:        register struct kb *dkp;
                    207:        register struct kbkmc *kk;
                    208: 
                    209:        kk = &kbkmc[KBNO];
                    210:        dkp = (struct kb *)q->ptr;
                    211:        if (dkp == NULL)
                    212:                panic("kbclose");
                    213:        dkp->dkrq = NULL;
                    214:        dkp->flag = 0;
                    215:        if (kbstate[dkp->chan] == DKRCLOSE || kk->modp->listnrq==NULL)
                    216:                kbstate[dkp->chan] = DKCLOSED;
                    217:        else if (kbstate[dkp->chan] == DKOPEN)
                    218:                kbstate[dkp->chan] = DKLCLOSE;
                    219:        if (kk->modp->listnrq)
                    220:                putctl2(RD(kk->modp->listnrq), M_PRICTL, DKMCLOSE, dkp->chan);
                    221: }
                    222: 
                    223: /*
                    224:  * interrupt -- receiver only
                    225:  * try to short-circuit interrupts;
                    226:  * data often comes in a large piece, followed by two small ones (URP trailer)
                    227:  */
                    228: 
                    229: kbintr(dev)
                    230: {
                    231:        register struct kbkmc *kk;
                    232:        register struct block *bp;
                    233:        register struct queue *q;
                    234:        register int i;
                    235: 
                    236:        kk = &kbkmc[KBNO];
                    237:        if (kk->addr == NULL)
                    238:                return;
                    239:        i = kk->addr->sts;
                    240:        if ((bp = kk->ibuf) == NULL) {  /* shouldn't happen */
                    241:                kbistart(kk);
                    242:                return;
                    243:        }
                    244:        ubmfree(kk->ubno, kk->imap);
                    245:        kk->ibuf = NULL;
                    246:        kbistart(kk);
                    247:        i |= ~SCOUNT;   /* crypto-sign-extend */
                    248:        if ((i & SCOUNT) == 0)
                    249:                i = 0;  /* overflow just means buffer full */
                    250:        bp->wptr = bp->lim + i;         /* lim - residue */
                    251:        i = *bp->rptr;                  /* channel */
                    252:        bp->rptr++;
                    253:        if (*bp->rptr)                  /* ctl flag */
                    254:                bp->type = M_CTL;
                    255:        bp->rptr++;
                    256:        if (i == 0 || i >= kbcnt || (q = kb[i].dkrq) == NULL) {
                    257:                if (i == 0)
                    258:                        dkstat.pack0++;
                    259:                else if (i >= kbcnt)
                    260:                        dkstat.packstrange++;
                    261:                else {
                    262:                        if (kk->modp->listnrq)
                    263:                                putctl2(RD(kk->modp->listnrq), M_PRICTL, DKMCLOSE, i);
                    264:                        dkstat.closepack++;
                    265:                }
                    266:                freeb(bp);
                    267:                return;
                    268:        }
                    269:        dkstat.input += bp->wptr - bp->rptr;
                    270:        if ((q->next->flag & QFULL) == 0)
                    271:                (*q->next->qinfo->putp)(q->next, bp);
                    272:        else
                    273:                freeb(bp);
                    274: }
                    275: 
                    276: /*
                    277:  * start the next input buffer
                    278:  */
                    279: kbistart(kk)
                    280: register struct kbkmc *kk;
                    281: {
                    282:        register struct device *reg;
                    283:        register int sts;
                    284:        register struct block *bp;
                    285:        register int n;
                    286:        register uaddr_t ua;
                    287: 
                    288:        if ((reg = kk->addr) == NULL)
                    289:                return;
                    290:        if (kk->ibuf)
                    291:                return;
                    292:        for (sts = 0, n = 0; n < STALL; n++) {
                    293:                if ((reg->cmd & CGO) == 0
                    294:                &&  (sts = reg->sts) & SRRDY)
                    295:                        break;
                    296:                /* delay to free up unibus? */
                    297:        }
                    298:        if ((sts & SRRDY) == 0) {
                    299:                printf("kb rcv not ready, sts %o cmd %o\n", reg->sts, reg->cmd);
                    300:                panic("kbistart");
                    301:                return;
                    302:        }
                    303:        if (sts & SERROR)
                    304:                printf("kb err, sts %o\n", sts&0177777);
                    305:        if ((bp = allocb(DKISIZE)) == NULL
                    306:        ||  (kk->imap = ubmblk(kk->ubno, bp, 0)) == 0) {
                    307:                panic("kbistart can't alloc\n");        /* later printf */
                    308:                if (bp)
                    309:                        freeb(bp);
                    310:                return;
                    311:        }
                    312:        kk->ibuf = bp;
                    313:        if ((int)bp->rptr & 01)
                    314:                bp->rptr++;
                    315:        kk->iaddr = ua = ubadrptr(kk->ubno, bp, kk->imap);
                    316:        reg->bc = bp->rptr - bp->lim;   /* sic - negative count */
                    317:        reg->ba = ua;
                    318:        n = (ua >> 16) << XASHIFT;
                    319:        n &= CXA;
                    320:        n |= CIE|CRCV;
                    321:        reg->cmd = n;
                    322: }
                    323: 
                    324: /*
                    325:  * put procedure for output
                    326:  */
                    327: kbput(q, bp)
                    328: struct queue *q;
                    329: register struct block *bp;
                    330: {
                    331:        register struct kb *dkp;
                    332:        register struct kbkmc *kk;
                    333:        register int n;
                    334:        register struct device *reg;
                    335:        register int sts;
                    336:        int s;
                    337: 
                    338:        dkp = (struct kb *)q->ptr;
                    339:        kk = &kbkmc[KBNO];
                    340:        switch (bp->type) {
                    341: 
                    342:        case M_IOCTL:
                    343:                switch (stiocom(bp)) {
                    344:                case DIOCNXCL:
                    345:                        dkp->flag &=~ DKXCL;
                    346:                        bp->wptr = bp->rptr;
                    347:                        bp->type = M_IOCACK;
                    348:                        break;
                    349: 
                    350:                case KIOCINIT:
                    351:                        /* eventually, reset things here */
                    352: 
                    353:                default:
                    354:                        bp->type = M_IOCNAK;
                    355:                        break;
                    356:                }
                    357:                qreply(q, bp);
                    358:                return;
                    359: 
                    360:        case M_CTL:
                    361:        case M_DATA:
                    362:                if (bp->rptr == bp->wptr) {
                    363:                        freeb(bp);
                    364:                        return;
                    365:                }
                    366:                dkstat.output += bp->wptr - bp->rptr;
                    367:                s = spl5();
                    368:                reg = kk->addr;
                    369:                for (sts = 0, n = 0; n < STALL; n++) {
                    370:                        if ((reg->cmd & CGO) == 0
                    371:                        &&  (sts = reg->sts) & SXRDY)
                    372:                                break;
                    373:                        DELAY(40);      /* get off the UNIBUS */
                    374:                }
                    375:                if ((sts & SXRDY) == 0) {       /* n >= STALL */
                    376:                        printf("kb xmit not ready, sts %o, cmd %o\n", sts, reg->cmd);
                    377:                        splx(s);
                    378:                        freeb(bp);
                    379:                        return;
                    380:                }
                    381:                if (sts & SERROR)
                    382:                        printf("kb err, sts %o\n", sts&0177777);
                    383:                ubmflush(kk->ubno, ubmpath(kk->omap));
                    384:                if (kk->obuf) {
                    385:                        freeb(kk->obuf);
                    386:                        kk->obuf = NULL;
                    387:                }
                    388:                n = bp->wptr - bp->rptr;
                    389:                kk->oaddr = ubmaddr(kk->ubno, bp->rptr, n, kk->omap);
                    390:                reg->bc = -n;
                    391:                reg->ba = kk->oaddr;
                    392:                n = (kk->oaddr >> 16)<<XASHIFT;
                    393:                n &= CXA;
                    394:                n |= dkp->chan;
                    395:                if (bp->type == M_DATA)
                    396:                        n |= CSEND;
                    397:                else
                    398:                        n |= CSCTL;
                    399:                reg->cmd = n;
                    400:                kk->obuf = bp;
                    401:                splx(s);
                    402:                return;
                    403: 
                    404:        case M_PRICTL:
                    405:                switch (*bp->rptr) {
                    406:                case DKMCLOSE:
                    407:                        n = bp->rptr[1];
                    408:                        if (n < kbcnt) {
                    409:                                if (kbstate[n] == DKOPEN) {
                    410:                                        kbstate[n] = DKRCLOSE;
                    411:                                        putctl(kb[n].dkrq->next, M_HANGUP);
                    412:                                } else if (kbstate[n] == DKLCLOSE)
                    413:                                        kbstate[n] = DKCLOSED;
                    414:                        }
                    415:                        freeb(bp);
                    416:                        return;
                    417: 
                    418:                case DKMXINIT:
                    419:                        n = bp->rptr[1];
                    420:                        if (n < kbcnt && kbstate[n] == DKOPEN)
                    421:                                (*kb[n].dkrq->next->qinfo->putp)(kb[n].dkrq->next, bp);
                    422:                        else
                    423:                                freeb(bp);
                    424:                        return;                         
                    425: 
                    426:                default:
                    427:                        freeb(bp);
                    428:                        return;
                    429:                }
                    430: 
                    431:        default:
                    432:                freeb(bp);
                    433:                return;
                    434:        }
                    435: }

unix.superglobalmegacorp.com

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