|
|
1.1 root 1: /*
2: * DR11C for Mergenthaler 202
3: */
4: #include "mg.h"
5: #if NMG
6: #include "../h/param.h"
7: #include "../h/systm.h"
8: #include "../h/stream.h"
9: #include "../h/ioctl.h"
10: #include "../h/pte.h"
11: #include "../h/map.h"
12: #include "../h/buf.h"
13: #include "../h/ubavar.h"
14: #include "../h/conf.h"
15:
16: struct device {
17: unsigned short csr;
18: unsigned short wbuf;
19: unsigned short rbuf;
20: };
21:
22: struct device *MGADDR;
23:
24: struct {
25: char busy;
26: struct queue *rq;
27: struct queue *wq;
28: } mg;
29:
30:
31: /*
32: * Hardware control bits
33: */
34: #define CSR0 1
35: #define CSR1 2
36: #define REQA 0200
37: #define REQB 0100000
38: #define INTA 0100
39: #define INTB 040
40:
41:
42: int nodev(), mgopen(), mgclose(), mgoput();
43:
44: static struct qinit mgrinit = { nodev, NULL, mgopen, mgclose, 0, 0 };
45: struct qinit mgwinit = { mgoput, NULL, mgopen, mgclose, 200, 100 };
46: struct streamtab mginfo = { &mgrinit, &mgwinit };
47:
48: int mgattach(), mgprobe();
49: struct uba_device *mgstuff[NMG];
50: u_short mgstd[] = { 0 };
51: struct uba_driver mgdriver =
52: { mgprobe, 0, mgattach, 0, mgstd, "mg", mgstuff };
53:
54: mgprobe(reg)
55: caddr_t reg;
56: {
57: register int br, cvec;
58: register struct device *mgaddr = (struct device *)reg;
59:
60: mg.busy = 0;
61: mg.rq = mg.wq = NULL;
62: MGADDR = mgaddr;
63: mgaddr->csr = INTA;
64: DELAY(10000);
65: mgaddr->csr = 0;
66: return(1);
67: }
68:
69: mgattach()
70: {
71: }
72:
73: /*
74: * comment
75: */
76: mgopen(q, dev)
77: register struct queue *q;
78: register dev_t dev;
79: {
80: register d, c;
81:
82: d = minor(dev);
83: MGADDR->csr |= CSR0 | CSR1;
84: if(d == 0){
85: if(mg.rq != NULL) goto bad;
86: c = MGADDR->rbuf;
87: MGADDR->csr |= INTB;
88: mg.rq = q;
89: } else if(d == 1){
90: if(mg.wq != NULL) goto bad;
91: MGADDR->csr |= INTA;
92: mg.wq = WR(q);
93: } else {
94: goto bad;
95: }
96: q->ptr = (caddr_t) minor(dev);
97: WR(q)->ptr = (caddr_t) minor(dev);
98: return(1);
99: bad:
100: return(0);
101: }
102:
103: /*
104: * close MG
105: */
106: mgclose(q)
107: register struct queue *q;
108: {
109: int dev;
110:
111: dev = (int) q->ptr;
112: if(dev){
113: mg.wq = NULL;
114: } else {
115: MGADDR->csr &= (~INTB);
116: /* flush output */;
117: flushq(WR(q), 1);
118: mg.rq = NULL;
119: }
120: }
121:
122: /*
123: * DK receiver interrupt.
124: */
125: mgrint(dev)
126: {
127: register struct queue *q;
128: register struct block *bp;
129: register c;
130:
131: q = mg.rq;
132:
133: c = MGADDR->rbuf;
134: if(q == NULL) return;
135: if((q->flag & QFULL) == 0){
136: putd(q->next->qinfo->putp, q->next, c);
137: }
138: }
139:
140: /*
141: * MG put procedure
142: */
143: mgoput(q, bp)
144: register struct queue *q;
145: register struct block *bp;
146: {
147: int s, r, n;
148:
149: switch(bp->type){
150: case M_IOCTL:
151: bp->type = M_IOCNAK;
152: bp->wptr = bp->rptr;
153: qreply(q, bp);
154: return;
155: case M_FLUSH:
156: flushq(q, 0);
157: break;
158: case M_DATA:
159: putq(q, bp);
160: mgstart();
161: return;
162: default:
163: break;
164: }
165: freeb(bp);
166: }
167:
168: mgtint(dev)
169: {
170: mg.busy = 0;
171: mgstart();
172: }
173:
174: mgstart()
175: {
176: register c, s;
177: register struct block *bp;
178:
179: if(mg.wq == NULL) return;
180:
181: s = spl6();
182: if((mg.busy == 0) && mg.wq->count){
183: bp = getq(mg.wq);
184: switch(bp->type){
185: case M_DATA:
186: MGADDR->wbuf = *bp->rptr++;
187: mg.busy = 1;
188: if(bp->rptr >= bp->wptr)
189: freeb(bp);
190: else
191: putbq(mg.wq, bp);
192: break;
193: default:
194: freeb(bp);
195: break;
196: }
197: }
198: splx(s);
199: }
200: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.