Annotation of researchv10no/sys/md/consnaut.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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