Annotation of researchv10no/sys/io/debna.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * first cut at NI port in DEBNA
        !             3:  * slower than it need be, because of all the copying;
        !             4:  * disallows use of the storage port
        !             5:  */
        !             6: #include "sys/param.h"
        !             7: #include "sys/biaddr.h"
        !             8: #include "sys/conf.h"
        !             9: #include "sys/user.h"
        !            10: #include "sys/buf.h"
        !            11: #include "sys/stream.h"
        !            12: #include "sys/biic.h"
        !            13: #include "sys/ethernet.h"
        !            14: #include "sys/enio.h"
        !            15: #include "sys/pte.h"
        !            16: #include "sys/bvp.h"
        !            17: #include "sys/debna.h"
        !            18: 
        !            19: caddr_t remqhi();
        !            20: 
        !            21: 
        !            22: #define        PCMDQ   0       /* just one command queue */
        !            23: #define        PFREQ   0       /* just one free queue for now */
        !            24: 
        !            25: /*
        !            26:  * internal ideas about packets
        !            27:  */
        !            28: 
        !            29: /*
        !            30:  * bounds of an Ethernet packet
        !            31:  * min is probably uninteresting
        !            32:  * max is constrained by the port, which will fuss and shut down
        !            33:  * if handed a buffer bigger than ETHERMAXTU+ETHERCKSUM
        !            34:  */
        !            35: #define        ETHERMINTU      60
        !            36: #define        ETHERMAXTU      1514
        !            37: #define        ETHERCKSUM      4
        !            38: 
        !            39: #define        NIRCVBUF        (ETHERMAXTU+ETHERCKSUM)
        !            40: 
        !            41: struct dgi {
        !            42:        struct bvpdg h;         /* header */
        !            43:        char d[NIRCVBUF];
        !            44: };
        !            45: 
        !            46: struct mst {
        !            47:        struct bvpmsg h;
        !            48:        struct stptdb p;
        !            49: };
        !            50: 
        !            51: /*
        !            52:  * config stuff
        !            53:  */
        !            54: extern struct bnactl bna[];
        !            55: extern struct bnabuf bnabuf[];
        !            56: extern struct biaddr bnaaddr[];
        !            57: extern int bnacnt;
        !            58: 
        !            59: long bnaopen();
        !            60: int bnaclose(), bnaput();
        !            61: 
        !            62: static struct qinit bnarinit = { noput, NULL, bnaopen, bnaclose, 0, 0 };
        !            63: static struct qinit bnawinit = { bnaput, NULL, bnaopen, bnaclose, 4*ETHERMAXTU, 64 };
        !            64: static struct streamtab bnasinfo = { &bnarinit, &bnawinit };
        !            65: struct cdevsw bnacdev = cstrinit(&bnasinfo);
        !            66: 
        !            67: long
        !            68: bnaopen(q, dev)
        !            69: register struct queue *q;
        !            70: dev_t dev;
        !            71: {
        !            72:        register int unit, chan;
        !            73:        register struct bnachan *bc;
        !            74: 
        !            75:        unit = minor(dev);
        !            76:        chan = unit % BNACHAN;
        !            77:        unit /= BNACHAN;
        !            78:        if (unit >= bnacnt)
        !            79:                return (0);
        !            80:        if (bnainit(unit) == 0)
        !            81:                return (0);
        !            82:        bc = &bna[unit].chan[chan];
        !            83:        if (bc->rq)
        !            84:                return (0);
        !            85:        bc->unit = unit;
        !            86:        bc->proto = 0;
        !            87:        q->ptr = (caddr_t)bc;
        !            88:        q->flag |= QDELIM;
        !            89:        WR(q)->ptr = (caddr_t)bc;
        !            90:        WR(q)->flag |= QDELIM|QBIGB;
        !            91:        bc->rq = q;
        !            92:        return (1);
        !            93: }
        !            94: 
        !            95: /*
        !            96:  * init the bvp port registers and pqb
        !            97:  * set up our list of free transmit buffers,
        !            98:  * and the free queue for the port
        !            99:  * -- only one free queue for now
        !           100:  */
        !           101: bnainit(unit)
        !           102: register int unit;
        !           103: {
        !           104:        register char *cp;
        !           105:        register struct bnactl *bn;
        !           106:        register int i;
        !           107: 
        !           108:        bn = &bna[unit];
        !           109:        if (bvpinit(&bn->bvp, &bnaaddr[unit], NIREGS) == 0) {
        !           110:                printf("debna %d: can't init\n", unit);
        !           111:                return (0);
        !           112:        }
        !           113:        if (bn->bvp.d->f[PFREQ].f_size == 0) {  /* somewhat sleazy init flag */
        !           114:                bn->bvp.d->f[PFREQ].f_size = BNABSIZE-BVPHSIZE;
        !           115:                cp = bnabuf[unit].rbuf;
        !           116:                cp = (char *)(((int)cp + 7) & ~07);     /* quad-align */
        !           117:                for (i = 0; i < BNARBUF; i++, cp += BNABSIZE) {
        !           118:                        if (((int)cp&PGOFSET) > (((int)cp+sizeof(struct bvpdg))&PGOFSET))
        !           119:                                cp = (char *)(((int)cp+PGOFSET)&~PGOFSET);
        !           120:                        bnarbuf(bn, (struct dgi *)cp);
        !           121:                }
        !           122:                cp = bnabuf[unit].xbuf;
        !           123:                cp = (char *)(((int)cp + 7) & ~07);     /* quad-align */
        !           124:                for (i = 0; i < BNAXBUF; i++, cp += BNABSIZE) {
        !           125:                        if (((int)cp&PGOFSET) > (((int)cp+sizeof(struct bvpdg))&PGOFSET))
        !           126:                                cp = (char *)(((int)cp+PGOFSET)&~PGOFSET);
        !           127:                        bnaxbuf(bn, (struct dgi *)cp);
        !           128:                }
        !           129:        }
        !           130:        bcopy(bn->bvp.r->addr, bn->myaddr, sizeof(bn->myaddr));
        !           131:        return (1);
        !           132: }
        !           133: 
        !           134: bnaclose(q)
        !           135: register struct queue *q;
        !           136: {
        !           137:        register struct bnachan *bc;
        !           138: 
        !           139:        bc = (struct bnachan *)q->ptr;
        !           140:        /* turn off PTDB? */
        !           141:        bc->rq = NULL;
        !           142:        bc->proto = 0;
        !           143: }
        !           144: 
        !           145: /*
        !           146:  * output put
        !           147:  */
        !           148: bnaput(q, bp)
        !           149: register struct queue *q;
        !           150: register struct block *bp;
        !           151: {
        !           152:        register struct bnachan *bc;
        !           153:        register int s;
        !           154: 
        !           155:        bc = (struct bnachan *)q->ptr;
        !           156:        switch (bp->type) {
        !           157:        case M_IOCTL:
        !           158:                bnaioctl(q, bp);
        !           159:                return;
        !           160: 
        !           161:        case M_DATA:
        !           162:                putq(q, bp);
        !           163:                if (bp->class & S_DELIM)
        !           164:                        break;
        !           165:                return;
        !           166: 
        !           167:        default:
        !           168:                freeb(bp);
        !           169:                return;
        !           170:        }
        !           171:        /*
        !           172:         * at least a whole packet on the queue
        !           173:         */
        !           174:        bc->dcnt++;
        !           175:        s = spl6();
        !           176:        while (bnasend(bc->unit))
        !           177:                ;
        !           178:        splx(s);
        !           179: }
        !           180: 
        !           181: bnaioctl(q, bp)
        !           182: register struct queue *q;
        !           183: register struct block *bp;
        !           184: {
        !           185:        register struct bnachan *bc;
        !           186:        register struct bnactl *bn;
        !           187: 
        !           188:        bc = (struct bnachan *)q->ptr;
        !           189:        bn = &bna[bc->unit];
        !           190:        bp->type = M_IOCACK;
        !           191:        switch (stiocom(bp)) {
        !           192:        case ENIOTYPE:          /* set proto */
        !           193:                bc->proto = *((int *)stiodata(bp));
        !           194:                bnastptdb(bn, bc);
        !           195:                freeb(bp);      /* IOCACK when the port finishes */
        !           196:                return;
        !           197: 
        !           198:        case ENIOADDR:
        !           199:                bcopy(bn->myaddr, stiodata(bp), sizeof(bn->myaddr));
        !           200:                bp->wptr = bp->rptr + sizeof(bn->myaddr) + STIOCHDR;
        !           201:                break;
        !           202: 
        !           203:        default:
        !           204:                bp->type = M_IOCNAK;
        !           205:                break;
        !           206:        }
        !           207:        qreply(q, bp);
        !           208: }
        !           209: 
        !           210: bnastptdb(bn, bc)
        !           211: register struct bnactl *bn;
        !           212: register struct bnachan *bc;
        !           213: {
        !           214:        register struct mst *dp;
        !           215:        register int s;
        !           216: 
        !           217:        s = spl6();
        !           218:        if ((dp = (struct mst *)bn->xfree) == NULL) {
        !           219:                bc->needst = 1;
        !           220:                bn->needst = 1;
        !           221:                splx(s);
        !           222:                return;
        !           223:        }
        !           224:        bn->xfree = (struct dgi *)(dp->h.q.head);
        !           225:        bc->needst = 0;
        !           226:        splx(s);
        !           227:        bzero((caddr_t)dp, sizeof(*dp));
        !           228:        dp->h.bd_opc = BVPSNDMSG;
        !           229:        dp->h.bd_flag = BVPRSP;
        !           230:        dp->h.bm_len = sizeof(*dp) - ((char *)&dp->h.bm_opc - (char *)dp);
        !           231:        dp->h.bm_opc = NISTPTDB;
        !           232:        dp->p.pt_proto = bc->proto;
        !           233:        dp->p.pt_fqi = PFREQ;
        !           234:        dp->p.pt_flag = PTABM|PTAAM;
        !           235:        dp->p.pt_id = bc - bn->chan;
        !           236:        if (insqti((caddr_t)dp, &bn->bvp.d->p.p_cmdq[PCMDQ]))
        !           237:                bvpcomm(bn->bvp.r, PCOWN|PCCMDQ|(PCMDQ<<PCDS));
        !           238: }
        !           239: 
        !           240: /*
        !           241:  * here on an interrupt
        !           242:  */
        !           243: bna0int(unit)
        !           244: int unit;
        !           245: {
        !           246:        register struct bvpdata *b;
        !           247:        register struct bnactl *bn;
        !           248:        register struct dgi *dp;
        !           249:        register struct bnabuf *bf;     /* just for safety check */
        !           250:        register int i;
        !           251: 
        !           252:        if ((unsigned)unit >= bnacnt)
        !           253:                panic("bna0int");
        !           254:        bn = &bna[unit];
        !           255:        if (bn->bvp.r == NULL) {
        !           256:                printf("debna %d stray intr\n", unit);
        !           257:                return;
        !           258:        }
        !           259:        bn->bvp.rsave = *bn->bvp.r;     /* copy all, for debugging */
        !           260:        if (bn->bvp.rsave.stat & PSOWN)
        !           261:                bn->bvp.r->stat &=~ PSOWN;      /* allow fresh status */
        !           262:        if ((bn->bvp.rsave.stat & PSSTAT) != SENAB) {
        !           263:                printf("debna %d: ps %x pe %x pd %x\n", unit,
        !           264:                        bn->bvp.rsave.stat, bn->bvp.rsave.err, bn->bvp.rsave.data);
        !           265:                return;
        !           266:        }
        !           267:        b = bn->bvp.d;
        !           268:        bf = &bnabuf[unit];
        !           269:        while ((dp = (struct dgi *)remqhi(&b->p.p_rspq)) != NULL) {
        !           270:                if (dp->h.bd_sts != BVPSUC)
        !           271:                        printf("debna %d opc %x sts %x\n", unit, dp->h.bd_opc, dp->h.bd_sts);
        !           272:                switch (dp->h.bd_opc) {
        !           273:                case BVPSNDDGI:         /* datagram sent */
        !           274:                        for (i = ETHERALEN-1; i >= 0; --i)
        !           275:                                if (((struct etherpup *)dp->d)->dhost[i] != 0xff
        !           276:                                &&  ((struct etherpup *)dp->d)->dhost[i] != bn->myaddr[i])
        !           277:                                        goto notecho;
        !           278:                        /*
        !           279:                         * packet sent to ourselves;
        !           280:                         * port won't echo it back
        !           281:                         */
        !           282:                        dp->h.bd_len += ETHERCKSUM;     /* banrdg will trim */
        !           283:                        bcopy(bn->myaddr, ((struct etherpup *)dp->d)->shost, sizeof(bn->myaddr));
        !           284:                        bnardg(bn, dp);
        !           285: notecho:
        !           286:                        /* fall through */
        !           287:                case BVPSNDMSG:         /* message sent */
        !           288:                        if ((char *)dp < bf->xbuf
        !           289:                        ||  (char *)dp >= &bf->xbuf[sizeof(bf->xbuf)])
        !           290:                                panic("bna0int sent");
        !           291:                        bnaxbuf(bn, dp);
        !           292:                        continue;
        !           293: 
        !           294:                case BVPRCVDGI:         /* datagram received */
        !           295:                        if ((char *)dp < bf->rbuf
        !           296:                        ||  (char *)dp >= &bf->rbuf[sizeof(bf->rbuf)])
        !           297:                                panic("bna0int rcv dg");
        !           298:                        bnardg(bn, dp);
        !           299:                        bnarbuf(bn, dp);
        !           300:                        continue;
        !           301: 
        !           302:                case BVPRCVMSG:         /* message received */
        !           303:                        if ((char *)dp < bf->rbuf
        !           304:                        ||  (char *)dp >= &bf->rbuf[sizeof(bf->rbuf)])
        !           305:                                panic("bna0int rcv msg");
        !           306:                        bnarmsg(bn, (struct bvpmsg *)dp);
        !           307:                        bnarbuf(bn, dp);
        !           308:                        continue;
        !           309: 
        !           310:                default:
        !           311:                        printf("debna %d: %x: opc %x\n", unit, dp, dp->h.bd_opc);
        !           312:                        continue;       /* leaving buffer tied up */
        !           313:                }
        !           314:        }
        !           315:        while (bnasend(unit))
        !           316:                ;
        !           317: }
        !           318: 
        !           319: /*
        !           320:  * here is a received datagram;
        !           321:  * find the right channel,
        !           322:  * and send it up the queue
        !           323:  */
        !           324: bnardg(bn, dp)
        !           325: register struct bnactl *bn;
        !           326: register struct dgi *dp;
        !           327: {
        !           328:        register int n;
        !           329:        register struct block *bp;
        !           330:        register char *p;
        !           331:        register struct queue *q;
        !           332:        int len;
        !           333:        short proto;
        !           334: 
        !           335:        if (dp->h.bd_dgsts != NISUC) {
        !           336:                printf("debna %d dg sts %x\n", bn - bna, dp->h.bd_dgsts);
        !           337:                return;
        !           338:        }
        !           339:        len = (dp->h.bd_len+BVPHSIZE)-sizeof(struct bvpdg)-ETHERCKSUM;
        !           340:        proto = (short)((struct etherpup *)dp->d)->type;
        !           341:        for (n = 0; n < BNACHAN; n++)
        !           342:                if (bn->chan[n].proto == proto)
        !           343:                        break;
        !           344:        if (n >= BNACHAN)
        !           345:                return;         /* unexpected proto */
        !           346:        q = bn->chan[n].rq;
        !           347:        if (q == NULL)
        !           348:                return;         /* snh */
        !           349:        if (q->next->flag & QFULL)
        !           350:                return;         /* no room */
        !           351:        p = dp->d;
        !           352:        while (len > 0) {
        !           353:                if ((bp = allocb(len)) == NULL)
        !           354:                        return;         /* wrong, but hard */
        !           355:                n = bp->lim - bp->wptr;
        !           356:                if (len < n)
        !           357:                        n = len;
        !           358:                bcopy(p, bp->wptr, n);
        !           359:                bp->wptr += n;
        !           360:                p += n;
        !           361:                len -= n;
        !           362:                if (len <= 0)
        !           363:                        bp->class |= S_DELIM;
        !           364:                (*q->next->qinfo->putp)(q->next, bp);
        !           365:        }
        !           366: }
        !           367: 
        !           368: /*
        !           369:  * here is a message
        !           370:  */
        !           371: 
        !           372: bnarmsg(bn, dp)
        !           373: register struct bnactl *bn;
        !           374: register struct bvpmsg *dp;
        !           375: {
        !           376:        register struct bnachan *bc;
        !           377:        register struct mst *sdp;
        !           378: 
        !           379:        switch (dp->bm_opc) {
        !           380:        case NISTPTDB:  /* ptdb set, sent ioctl back */
        !           381:                sdp = (struct mst *)dp;
        !           382:                if (sdp->p.pt_id < 0 || sdp->p.pt_id >= BNACHAN)
        !           383:                        panic("bnastptdb");
        !           384:                bc = &bn->chan[sdp->p.pt_id];
        !           385:                if (bc->rq == NULL || bc->proto != sdp->p.pt_proto)
        !           386:                        return; /* early close? */
        !           387:                if (sdp->h.bm_nists != NISUC)
        !           388:                        printf("debna %d %d stptdb sts %x\n", bn - bna,
        !           389:                                sdp->p.pt_id, sdp->h.bm_nists);
        !           390:                putctl(bc->rq->next, M_IOCACK);
        !           391:                return;
        !           392: 
        !           393:        default:
        !           394:                printf("debna %d msg opc %x sts %x\n", dp->bm_opc, dp->bm_nists);
        !           395:                return;
        !           396:        }
        !           397: }
        !           398: 
        !           399: /*
        !           400:  * find a channel with a packet,
        !           401:  * find a buffer,
        !           402:  * and send
        !           403:  */
        !           404: bnasend(unit)
        !           405: int unit;
        !           406: {
        !           407:        register struct bnactl *bn;
        !           408:        register struct bnachan *bc;
        !           409:        register struct dgi *dp;
        !           410:        register char *p;
        !           411:        register struct block *bp;
        !           412:        register int n;
        !           413:        char *ep;
        !           414: 
        !           415:        bn = &bna[unit];
        !           416:        n = bn->lastx;
        !           417:        while (bn->chan[n].dcnt == 0) {
        !           418:                if (++n >= BNACHAN)
        !           419:                        n = 0;
        !           420:                if (n == bn->lastx)
        !           421:                        return (0);             /* nothing to send */
        !           422:        }
        !           423:        bn->lastx = n;
        !           424:        bc = &bn->chan[n];
        !           425:        if ((dp = bn->xfree) == NULL)
        !           426:                return (0);                     /* no buffer */
        !           427:        bn->xfree = (struct dgi *)dp->h.q.head;
        !           428:        bzero((caddr_t)&dp->h, sizeof(dp->h));
        !           429:        p = dp->d;
        !           430:        ep = p + sizeof(dp->d);
        !           431:        while ((bp = getq(WR(bc->rq))) != NULL) {
        !           432:                n = bp->wptr - bp->rptr;
        !           433:                if (p + n > ep)
        !           434:                        n = ep - p;     /* quietly truncate */
        !           435:                if (n) {
        !           436:                        bcopy(bp->rptr, p, n);
        !           437:                        p += n;
        !           438:                }
        !           439:                if (bp->class & S_DELIM) {
        !           440:                        bc->dcnt--;
        !           441:                        freeb(bp);
        !           442:                        break;
        !           443:                }
        !           444:                freeb(bp);
        !           445:        }
        !           446:        if (bp == NULL) {
        !           447:                printf("debna %d no delim\n", unit);
        !           448:                bc->dcnt = 0;
        !           449:                dp->h.q.head = (quadque *)bn->xfree;
        !           450:                bn->xfree = dp;
        !           451:                return (1);     /* ok to try another channel */
        !           452:        }
        !           453:        if (p - dp->d < ETHERMINTU)
        !           454:                p = dp->d + ETHERMINTU; /* quietly extend */
        !           455:        dp->h.bd_opc = BVPSNDDGI;
        !           456:        dp->h.bd_flag = BVPRSP;         /* so it will appear on rsp queue */
        !           457:        dp->h.bd_len = p - &dp->h.bd_dgsts;
        !           458:        dp->h.bd_ptdb = unit;   /* some valid number */
        !           459:        /* probably should zero some other fields */
        !           460:        if (insqti((caddr_t)dp, &bn->bvp.d->p.p_cmdq[PCMDQ]))
        !           461:                bvpcomm(bn->bvp.r, PCOWN|PCCMDQ|(PCMDQ<<PCDS));
        !           462:        return (1);
        !           463: }
        !           464: 
        !           465: /*
        !           466:  * free a buffer for the port to fill in
        !           467:  * -- port fusses if buffer bigger than an Ethernet packet + BVP header
        !           468:  */
        !           469: bnarbuf(bn, dp)
        !           470: register struct bnactl *bn;
        !           471: register struct dgi *dp;
        !           472: {
        !           473: 
        !           474:        dp->h.bd_sts = 0;       /* just in case */
        !           475:        dp->h.bd_opc = BVPRCVDGI;
        !           476:        dp->h.bd_len = sizeof(struct bvpdg) + NIRCVBUF - BVPHSIZE;
        !           477:        if (insqti((caddr_t)dp, &bn->bvp.d->f[PFREQ].f_q))
        !           478:                bvpcomm(bn->bvp.r, PCOWN|PCFREQ|(PFREQ<<PCDS));
        !           479: }
        !           480: 
        !           481: bnaxbuf(bn, dp)
        !           482: register struct bnactl *bn;
        !           483: register struct dgi *dp;
        !           484: {
        !           485:        register int i;
        !           486: 
        !           487:        dp->h.q.head = (quadque *)bn->xfree;
        !           488:        bn->xfree = dp;
        !           489:        if (bn->needst) {
        !           490:                bn->needst = 0;
        !           491:                for (i = 0; i < BNACHAN; i++)
        !           492:                        if (bn->chan[i].needst)
        !           493:                                bnastptdb(bn, &bn->chan[i]);
        !           494:        }
        !           495: }
        !           496: 
        !           497: /*
        !           498:  * (fairly) general BVP routines
        !           499:  */
        !           500: bvpinit(bv, ap, roff)
        !           501: register struct bvp *bv;
        !           502: struct biaddr *ap;
        !           503: int roff;
        !           504: {
        !           505:        register struct bvpregs *r;
        !           506:        register struct biic *rb;
        !           507:        register long ps;       /* most recent status */
        !           508: 
        !           509:        if ((rb = bv->rb) == NULL) {
        !           510:                if ((rb = (struct biic *)biaddr(ap)) == NULL
        !           511:                ||  badaddr(rb, sizeof(long))) {
        !           512:                        printf("bvp absent\n");
        !           513:                        return (0);
        !           514:                }
        !           515:                bv->rb = rb;
        !           516:        }
        !           517:        if (bv->r == NULL) {
        !           518:                r = (struct bvpregs *)((char *)rb + roff);
        !           519:                if (badaddr(r, sizeof(long))) {
        !           520:                        printf("bvp off %x absent\n", roff);
        !           521:                        return (0);
        !           522:                }
        !           523:                bv->r = r;
        !           524:        }
        !           525:        if (bv->dbuf == NULL) {
        !           526:                bv->dbuf = geteblk();
        !           527:                if (bv->dbuf->b_bcount < sizeof(struct bvpdata)) {
        !           528:                        printf("bcount too small\n");
        !           529:                        brelse(bv->dbuf);
        !           530:                        return (0);
        !           531:                }
        !           532:                clrbuf(bv->dbuf);
        !           533:                bv->d = (struct bvpdata *)bv->dbuf->b_un.b_addr;
        !           534:        }
        !           535:        r = bv->r;
        !           536:        ps = r->stat;
        !           537:        if ((ps & PSSTAT) == SUNDEF) {
        !           538:                biinit(ap, 0);
        !           539:                bvpdatinit(bv->d);
        !           540:                bv->d->p.p_nodmsk = rb->biintr;
        !           541:                bv->d->p.p_vector = (ap->vec<<2) | 5;   /* vec, br */
        !           542:                bvpcomm(r, physadr(&bv->d->p)|PCOWN|PCINIT);
        !           543:                ps = bvpstat(r);
        !           544:        }
        !           545:        if ((ps & PSSTAT) == SINIT) {
        !           546:                bvpcomm(r, PCOWN|PCENAB);
        !           547:                ps = bvpstat(r);
        !           548:        }
        !           549:        if ((ps & PSSTAT) != SENAB) {
        !           550:                printf("ps %x pe %x pd %x\n", r->stat, r->err, r->data);
        !           551:                return (0);
        !           552:        }
        !           553:        return (1);
        !           554: }
        !           555: 
        !           556: bvpdatinit(b)
        !           557: register struct bvpdata *b;
        !           558: {
        !           559:        bzero((char *)b, sizeof(*b));
        !           560:        b->p.p_nfreeq = NFREEQ;
        !           561:        b->p.p_fqb = b->f;
        !           562:        b->p.p_bvplvl = 1;
        !           563:        b->p.p_pqb = &b->p;
        !           564:        b->p.p_bdt = b->b;
        !           565:        b->p.p_bdtlen = NBDT;   /* -1? */
        !           566:        b->p.p_spt = (struct pte *)physadr(Sysmap);
        !           567:        b->p.p_sptlen = 0x100000;       /* huge */
        !           568:        b->p.p_gpt = b->p.p_spt;
        !           569:        b->p.p_gptlen = b->p.p_sptlen;
        !           570: }
        !           571: 
        !           572: /*
        !           573:  * send a port command
        !           574:  */
        !           575: #define        COMMTIME        1000000
        !           576: 
        !           577: bvpcomm(r, c)
        !           578: register struct bvpregs *r;
        !           579: long c;
        !           580: {
        !           581:        register int i;
        !           582: 
        !           583:        i = COMMTIME;
        !           584:        while (r->ctrl & PCOWN)
        !           585:                if (--i <= 0) {
        !           586:                        printf("bvpcomm timeout c %x\n", c);
        !           587:                        return; /* what else to do? */
        !           588:                }
        !           589:        r->stat &=~ PSOWN;
        !           590:        r->ctrl = c;
        !           591: }
        !           592: 
        !           593: /*
        !           594:  * wait for status in init
        !           595:  */
        !           596: 
        !           597: #define        STATTIME        1000000
        !           598: 
        !           599: int
        !           600: bvpstat(r)
        !           601: register struct bvpregs *r;
        !           602: {
        !           603:        register long ps;
        !           604:        register int i;
        !           605: 
        !           606:        i = STATTIME;
        !           607:        while (((ps = r->stat) & PSOWN) == 0)
        !           608:                if (--i <= 0) {
        !           609:                        printf("bvpstat timeout, ps %x\n", ps);
        !           610:                        return (0);
        !           611:                }
        !           612:        return (ps);
        !           613: }
        !           614: 
        !           615: /*
        !           616:  * VAX queue primitives
        !           617:  *
        !           618:  * -- to set up empty queue, just zero both longwords
        !           619:  */
        !           620: 
        !           621: /*
        !           622:  * remove entry from head;
        !           623:  * return entry, or 0 if none
        !           624:  */
        !           625: caddr_t
        !           626: remqhi(q)
        !           627: quadque *q;
        !           628: {
        !           629:        asm("0: remqhi *4(ap),r0");
        !           630:        asm("bcs 0b");          /* couldn't interlock; try again */
        !           631:        asm("bvc 1f");          /* br if removed something */
        !           632:        asm("clrl r0");
        !           633:        asm("1:");
        !           634: }
        !           635: 
        !           636: /*
        !           637:  * insert entry to tail
        !           638:  * return 1 if this was the first entry
        !           639:  */
        !           640: insqti(e, q)
        !           641: caddr_t e;
        !           642: quadque *q;
        !           643: {
        !           644:        asm("clrl r0");
        !           645:        asm("0: insqti *4(ap),*8(ap)");
        !           646:        asm("bcs 0b");
        !           647:        asm("bneq 1f");
        !           648:        asm("incl r0");
        !           649:        asm("1:");
        !           650: }

unix.superglobalmegacorp.com

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