Annotation of researchv10dc/sys/md/consstar.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * VAX 11/780 console driver
                      3:  * multiple ID stuff is mostly to aid floppy
                      4:  */
                      5: #include "sys/param.h"
                      6: #include "sys/stream.h"
                      7: #include "sys/ttyio.h"
                      8: #include "sys/cons.h"
                      9: #include "sys/mtpr.h"
                     10: #include "sys/conf.h"
                     11: 
                     12: #define        NCONS   16      /* possible console IDs */
                     13: 
                     14: #define        DATA    0xff
                     15: #define        IDMASK  0xff
                     16: #define        IDSHIFT 8
                     17: 
                     18: #define        CONPRI  (PZERO+5)       /* something interruptible */
                     19: 
                     20: /*
                     21:  * state bits
                     22:  */
                     23: #define        TTSTOP  01
                     24: #define        TIMEOUT 04
                     25: 
                     26: /*
                     27:  * cnbusy bits
                     28:  */
                     29: #define        TXBUSY  01
                     30: #define        IOBUSY  02      /* cninc/cnoutc busy */
                     31: 
                     32: static char cnbusy;
                     33: static char cnonext;
                     34: static char cnstate[NCONS];
                     35: static struct queue *cnrq[NCONS];
                     36: static struct queue *cnwq[NCONS];
                     37: 
                     38: /*
                     39:  * for internal io without device open
                     40:  */
                     41: struct cnbuf {
                     42:        int count;
                     43:        char *buf;
                     44: };
                     45: static struct cnbuf cnibuf[NCONS];
                     46: static struct cnbuf cnobuf[NCONS];
                     47: static short cnlastin;         /* debugging */
                     48: 
                     49: long   cnopen();
                     50: int    cnclose(), cnoput();
                     51: 
                     52: static struct qinit cnrinit = { nulldev, NULL, cnopen, cnclose, 0, 0 };
                     53: static struct qinit cnwinit = { cnoput, NULL, cnopen, cnclose, 200, 100 };
                     54: struct streamtab cnstream = { &cnrinit, &cnwinit };
                     55: struct cdevsw cncdev = cstrinit(&cnstream);
                     56: 
                     57: long
                     58: cnopen(qp, dev)
                     59: struct queue *qp;
                     60: dev_t dev;
                     61: {
                     62:        register int i;
                     63: 
                     64:        i = minor(dev);
                     65:        if (i >= NCONS)
                     66:                return (1);
                     67:        cnrq[i] = qp;
                     68:        cnwq[i] = WR(qp);
                     69:        qp->ptr = (caddr_t)i;
                     70:        mtpr(RXCS, mfpr(RXCS)|RXCS_IE);
                     71:        return(1);
                     72: }
                     73: 
                     74: cnclose(qp)
                     75: struct queue *qp;
                     76: {
                     77:        register int i;
                     78: 
                     79:        i = (int)qp->ptr;
                     80:        cnrq[i] = NULL;
                     81:        cnwq[i] = NULL;
                     82: }
                     83: 
                     84: /*
                     85:  * Console write put routine
                     86:  */
                     87: cnoput(q, bp)
                     88: register struct queue *q;
                     89: register struct block *bp;
                     90: {
                     91:        register struct ttydevb *sp;
                     92:        register int dev;
                     93: 
                     94:        dev = (int)OTHERQ(q)->ptr;
                     95:        switch(bp->type) {
                     96:        case M_IOCTL:           /* just acknowledge */
                     97:                sp = (struct ttydevb *)stiodata(bp);
                     98:                switch (stiocom(bp)) {
                     99:                case TIOCGDEV:
                    100:                        sp->ispeed = sp->ospeed = B9600;
                    101:                        bp->wptr = bp->rptr + sizeof(struct ttydevb) + STIOCHDR;
                    102:                        bp->type = M_IOCACK;
                    103:                        qreply(q, bp);
                    104:                        return;
                    105: 
                    106:                case TIOCSDEV:
                    107:                        bp->wptr = bp->rptr;
                    108:                        bp->type = M_IOCACK;
                    109:                        qreply(q, bp);
                    110:                        return;
                    111: 
                    112:                default:
                    113:                        bp->type = M_IOCNAK;
                    114:                        bp->wptr = bp->rptr;
                    115:                        qreply(q, bp);
                    116:                        return;
                    117:                }
                    118: 
                    119:        case M_STOP:
                    120:                cnstate[dev] |= TTSTOP;
                    121:                break;
                    122: 
                    123:        case M_START:
                    124:                cnstate[dev] &= ~TTSTOP;
                    125:                cnstart();
                    126:                break;
                    127: 
                    128:        case M_FLUSH:
                    129:                flushq(q, 0);
                    130:                break;
                    131: 
                    132:        case M_DELAY:
                    133:        case M_DATA:
                    134:                if (bp->rptr >= bp->wptr)
                    135:                        break;
                    136:                putq(q, bp);
                    137:                cnstart();
                    138:                return;
                    139:        
                    140:        default:                /* not handled; just toss */
                    141:                break;
                    142:        }
                    143:        freeb(bp);
                    144: }
                    145: 
                    146: /*
                    147:  * Console receive interrupt
                    148:  */
                    149: 
                    150: cnrint()
                    151: {
                    152:        register int c, dev;
                    153:        register struct queue *qp;
                    154:        register struct cnbuf *cp;
                    155: 
                    156:        c = mfpr(RXDB);
                    157:        dev = (c >> IDSHIFT) & IDMASK;
                    158:        cp = &cnibuf[dev];
                    159:        if (cp->count) {
                    160:                *cp->buf++ = c;
                    161:                if (--cp->count == 0)
                    162:                        wakeup((caddr_t)&cp->count);
                    163:                return;
                    164:        }
                    165:        if ((qp = cnrq[dev])!=NULL) {
                    166:                if ((qp->next->flag & QFULL) == 0)
                    167:                        putd(qp->next->qinfo->putp, qp->next, c);
                    168:                return;
                    169:        }
                    170:        cnlastin = c;           /* for debugging */
                    171: }
                    172: 
                    173: /*
                    174:  * Transmitter interrupt
                    175:  */
                    176: cnxint()
                    177: {
                    178:        cnbusy &=~ TXBUSY;
                    179:        mtpr(TXCS, mfpr(TXCS)&~TXCS_IE);
                    180:        cnstart();
                    181: }
                    182: 
                    183: cntime(dev)
                    184: caddr_t dev;
                    185: {
                    186:        cnstate[(int)dev] &= ~TIMEOUT;
                    187:        cnstart();
                    188: }
                    189: 
                    190: #define        NEXT(i) (((i)+1)%NCONS)
                    191: 
                    192: cnstart()
                    193: {
                    194:        register struct block *bp;
                    195:        register int i;
                    196:        register struct queue *q;
                    197:        register struct cnbuf *cp;
                    198:        register s, j;
                    199: 
                    200:        s = spl6();
                    201:        if (cnbusy & TXBUSY) {
                    202:                splx(s);
                    203:                return;
                    204:        }
                    205:        i = cnonext;
                    206:        for (j = 0; j < NCONS && (cnbusy & TXBUSY) == 0; i = NEXT(i), j++) {
                    207:                cp = &cnobuf[i];
                    208:                if (cp->count) {
                    209:                        mtpr(TXDB, (*cp->buf++&0377) | (i<<IDSHIFT));
                    210:                        mtpr(TXCS, mfpr(TXCS)|TXCS_IE);
                    211:                        cnbusy |= TXBUSY;
                    212:                        if (--cp->count == 0)
                    213:                                wakeup((caddr_t)&cp->count);
                    214:                        continue;
                    215:                }
                    216:                if ((q = cnwq[i]) == NULL)
                    217:                        continue;
                    218:                if ((cnstate[i] & (TIMEOUT|TTSTOP)) || q->count == 0)
                    219:                        continue;
                    220:                bp = getq(q);
                    221:                switch (bp->type) {
                    222:                case M_DATA:
                    223:                        mtpr(TXDB, (i<<IDSHIFT)|*bp->rptr++);
                    224:                        mtpr(TXCS, mfpr(TXCS)|TXCS_IE);
                    225:                        cnbusy |= TXBUSY;
                    226:                        if (bp->rptr >= bp->wptr)
                    227:                                freeb(bp);
                    228:                        else
                    229:                                putbq(q, bp);
                    230:                        break;
                    231: 
                    232:                case M_DELAY:
                    233:                        timeout(cntime, (caddr_t)i, (int)*bp->rptr);
                    234:                        cnstate[i] |= TIMEOUT;
                    235:                default:        /* flow through */
                    236:                        freeb(bp);
                    237:                        break;
                    238:                }
                    239:        }
                    240:        cnonext = i;
                    241:        splx(s);
                    242: }
                    243: 
                    244: /*
                    245:  * Print a character on console; for printf.
                    246:  * try to preserve things; wait a bit for console to come ready.
                    247:  * all fairly hopeless.
                    248:  */
                    249: cnputc(c)
                    250: register c;
                    251: {
                    252:        register s, timo;
                    253: 
                    254:        timo = 3000000;
                    255:        while((mfpr(TXCS)&TXCS_RDY) == 0)
                    256:                if(--timo == 0)
                    257:                        return;
                    258:        if(c == 0)
                    259:                return;
                    260:        s = mfpr(TXCS);
                    261:        mtpr(TXCS, 0);
                    262:        mtpr(TXDB, c&DATA);
                    263:        if(c == '\n')
                    264:                cnputc('\r');
                    265:        cnputc(0);
                    266:        mtpr(TXCS, s);
                    267: }
                    268: 
                    269: /*
                    270:  * primitives for internal console I/O
                    271:  * p = cniwrite(id, buf, count)
                    272:  * p = cniread(id, buf, count)
                    273:  * p is a pointer to an integer.
                    274:  * when the count is satisfied, *p will be zero and p will be awakened
                    275:  * *p = 0 aborts the I/O
                    276:  * cniwait(p, s) waits for at most s seconds, then aborts
                    277:  *
                    278:  * only one I/O may be outstanding per id;
                    279:  * a new one aborts the previous one, quietly
                    280:  *
                    281:  * buf had best be static; stacks move, and the process waiting for io
                    282:  * will almost certainly go out of context.
                    283:  * hence the KSTART checks.
                    284:  */
                    285: 
                    286: int *
                    287: cniread(id, buf, count)
                    288: int id, count;
                    289: char *buf;
                    290: {
                    291:        register struct cnbuf *cp;
                    292: 
                    293:        if (id < 0 || id >= NCONS || (int)buf < KSTART)
                    294:                panic("cniread");
                    295:        cp = &cnibuf[id];
                    296:        cp->buf = buf;
                    297:        cp->count = count;
                    298:        mtpr(RXCS, mfpr(RXCS)|RXCS_IE);
                    299:        return (&cp->count);
                    300: }
                    301: 
                    302: int *
                    303: cniwrite(id, buf, count)
                    304: int id, count;
                    305: char *buf;
                    306: {
                    307:        register struct cnbuf *cp;
                    308: 
                    309:        if (id < 0 || id >= NCONS || (int)buf < KSTART)
                    310:                panic("cniwrite");
                    311:        cp = &cnobuf[id];
                    312:        cp->buf = buf;
                    313:        cp->count = count;
                    314:        cnstart();
                    315:        return (&cp->count);
                    316: }
                    317: 
                    318: cniwait(p, t)
                    319: register int *p;
                    320: int t;
                    321: {
                    322:        register int s;
                    323:        register int sh;
                    324: 
                    325:        s = spl6();
                    326:        while (*p)
                    327:                if (tsleep((caddr_t)p, CONPRI, t) != TS_OK) {
                    328:                        sh = *p;
                    329:                        *p = 0;
                    330:                        splx(s);
                    331:                        return (sh);
                    332:                }
                    333:        splx(s);
                    334:        return (0);
                    335: }

unix.superglobalmegacorp.com

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