|
|
1.1 root 1: /*
2: * VAX-11/750 console driver
3: * this is probably the simplest version
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: /*
13: * state bits
14: */
15: #define TTSTOP 01
16: #define BUSY 02
17: #define TIMEOUT 04
18:
19: char cnstate;
20: struct queue *cnrq;
21: struct queue *cnwq;
22:
23: long cnopen();
24: int cnclose(), cnoput(), nodev();
25:
26: static struct qinit cnrinit = { nodev, NULL, cnopen, cnclose, 0, 0 };
27: static struct qinit cnwinit = { cnoput, NULL, cnopen, cnclose, 200, 100 };
28: struct streamtab cnstream = { &cnrinit, &cnwinit };
29: struct cdevsw cncdev = cstrinit(&cnstream);
30:
31: long
32: cnopen(qp, dev)
33: register struct queue *qp;
34: {
35: cnrq = qp;
36: cnwq = WR(qp);
37: mtpr(RXCS, mfpr(RXCS)|RXCS_IE);
38: return(1);
39: }
40:
41: cnclose(qp)
42: struct queue *qp;
43: {
44: cnrq = NULL;
45: cnwq = NULL;
46: }
47:
48: /*
49: * Console write put routine
50: */
51: cnoput(q, bp)
52: register struct queue *q;
53: register struct block *bp;
54: {
55: register struct ttydevb *sp;
56:
57: switch(bp->type) {
58:
59: case M_IOCTL: /* just acknowledge */
60: sp = (struct ttydevb *)stiodata(bp);
61: switch (stiocom(bp)) {
62:
63: case TIOCGDEV:
64: sp->ispeed = sp->ospeed = B9600;
65: bp->wptr = bp->rptr + sizeof(struct ttydevb) + STIOCHDR;
66: bp->type = M_IOCACK;
67: qreply(q, bp);
68: return;
69: case TIOCSDEV:
70: bp->wptr = bp->rptr;
71: bp->type = M_IOCACK;
72: qreply(q, bp);
73: return;
74: default:
75: bp->type = M_IOCNAK;
76: bp->wptr = bp->rptr;
77: qreply(q, bp);
78: return;
79: }
80:
81: case M_STOP:
82: cnstate |= TTSTOP;
83: break;
84:
85: case M_START:
86: cnstate &= ~TTSTOP;
87: cnstart();
88: break;
89:
90: case M_FLUSH:
91: flushq(q, 0);
92: break;
93:
94: case M_DELAY:
95: case M_DATA:
96: if (bp->rptr >= bp->wptr)
97: break;
98: putq(q, bp);
99: cnstart();
100: return;
101:
102: default: /* not handled; just toss */
103: break;
104: }
105: freeb(bp);
106: }
107:
108: /*
109: * Console receive interrupt
110: */
111: /*ARGSUSED*/
112: cnrint(dev)
113: {
114: register int c;
115:
116: c = mfpr(RXDB);
117: if (c&RXDB_ID || cnrq==NULL)
118: return;
119: if ((cnrq->next->flag & QFULL) == 0)
120: putd(cnrq->next->qinfo->putp, cnrq->next, c);
121: }
122:
123:
124: /*
125: * Transmitter interrupt
126: */
127: /*ARGSUSED*/
128: cnxint(dev)
129: {
130: cnstate &= ~BUSY;
131: mtpr(TXCS, mfpr(TXCS)&~TXCS_IE);
132: cnstart();
133: }
134:
135: cntime()
136: {
137: cnstate &= ~TIMEOUT;
138: cnstart();
139: }
140:
141: cnstart()
142: {
143: register s;
144: register struct block *bp;
145:
146: if (cnwq==NULL)
147: return;
148: s = spl6();
149: if ((cnstate & (TIMEOUT|BUSY|TTSTOP))==0 && cnwq->count) {
150: bp = getq(cnwq);
151: switch (bp->type) {
152:
153: case M_DATA:
154: mtpr(TXDB, *bp->rptr++);
155: mtpr(TXCS, mfpr(TXCS)|TXCS_IE);
156: cnstate |= BUSY;
157: if (bp->rptr >= bp->wptr)
158: freeb(bp);
159: else
160: putbq(cnwq, bp);
161: break;
162:
163: case M_DELAY:
164: timeout(cntime, (caddr_t)NULL, (int)*bp->rptr);
165: cnstate |= TIMEOUT;
166: default: /* flow through */
167: freeb(bp);
168: break;
169: }
170: }
171: splx(s);
172: }
173:
174: /*
175: * Print a character on console.
176: * Attempts to save and restore device
177: * status.
178: */
179: cnputc(c)
180: register c;
181: {
182: register s, timo;
183:
184: timo = 30000;
185: /*
186: * Try waiting for the console tty to come ready,
187: * otherwise give up after a reasonable time.
188: */
189: while((mfpr(TXCS)&TXCS_RDY) == 0)
190: if(--timo == 0)
191: return;
192: if(c == 0)
193: return;
194: s = mfpr(TXCS);
195: mtpr(TXCS, 0);
196: mtpr(TXDB, c&0xff);
197: if(c == '\n')
198: cnputc('\r');
199: cnputc(0);
200: mtpr(TXCS, s);
201: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.