|
|
1.1 root 1: /*
2: * DR11C for Mergenthaler 202
3: */
4: #include "sys/param.h"
5: #include "sys/conf.h"
6: #include "sys/stream.h"
7: #include "sys/ubaddr.h"
8: #include "sys/mg.h"
9:
10: /*
11: * hardware
12: */
13: struct device {
14: u_short csr;
15: u_short wbuf;
16: u_short rbuf;
17: };
18:
19: #define CSR0 1
20: #define CSR1 2
21: #define REQA 0200
22: #define REQB 0100000
23: #define INTA 0100
24: #define INTB 040
25:
26: /*
27: * stream glue
28: */
29: long mgopen();
30: int nodev(), mgclose(), mgoput();
31:
32: static struct qinit mgrinit = {
33: nodev, NULL, mgopen, mgclose, 0, 0
34: };
35: static struct qinit mgwinit = {
36: mgoput, NULL, mgopen, mgclose, 200, 100
37: };
38: struct streamtab mginfo = {
39: &mgrinit, &mgwinit
40: };
41:
42: /*
43: * config glue
44: */
45: extern struct mg mg[]; /* one per device */
46: extern struct ubaddr mgaddr[]; /* one per device */
47: extern int mgcnt; /* one per device or what? */
48: struct cdevsw mgcdev = cstrinit(&mginfo);
49:
50: long
51: mgopen(q, d)
52: register struct queue *q;
53: {
54: register struct mg *mp;
55: register dev, s;
56:
57: if((dev = (minor(d) >> 1)) >= mgcnt)
58: return 0;
59: mp = &mg[dev];
60: if((mp->addr = (struct device *)ubaddr(&mgaddr[dev])) == 0
61: || ubbadaddr(mgaddr[dev].ubno, mp->addr, sizeof(u_short))) {
62: printf("mg%d absent\n", d);
63: return 0;
64: }
65: mp->addr->csr |= CSR0 | CSR1;
66: if(d & 01) {
67: if(mp->wq != NULL)
68: return 0;
69: mp->addr->csr |= INTA;
70: mp->wq = WR(q);
71: }
72: else {
73: if(mp->rq != NULL)
74: return 0;
75: s = mp->addr->rbuf;
76: mp->addr->csr |= INTB;
77: mp->rq = q;
78: }
79: WR(q)->ptr = q->ptr = (caddr_t) minor(d);
80: return 1;
81: }
82:
83: mgclose(q)
84: register struct queue *q;
85: {
86: register struct mg *mp = &mg[((int)q->ptr) >> 1];
87:
88: if(((int)q->ptr) & 01) {
89: mp->wq = NULL;
90: }
91: else {
92: mp->addr->csr &= (~INTB);
93: flushq(WR(q), 1);
94: mp->rq = NULL;
95: }
96: }
97:
98: mg1int(dev)
99: {
100: register struct mg *mp = &mg[dev];
101: register c;
102:
103: c = mp->addr->rbuf;
104: if(mp->rq && (mp->rq->flag & QFULL) == 0)
105: putd(mp->rq->next->qinfo->putp, mp->rq->next, c);
106: }
107:
108: mg0int(dev)
109: {
110: register struct mg *mp = &mg[dev];
111:
112: mp->busy = 0;
113: mgstart(mp);
114: }
115:
116: mgoput(q, bp)
117: register struct queue *q;
118: register struct block *bp;
119: {
120: switch(bp->type) {
121:
122: case M_IOCTL:
123: bp->type = M_IOCNAK;
124: bp->wptr = bp->rptr;
125: qreply(q, bp);
126: return;
127:
128: case M_FLUSH:
129: flushq(q, 0);
130: break;
131:
132: case M_DATA:
133: putq(q, bp);
134: mgstart(&mg[((int)q->ptr) >> 1]);
135: return;
136:
137: default:
138: break;
139: }
140: freeb(bp);
141: }
142:
143: mgstart(mp)
144: register struct mg *mp;
145: {
146: register struct block *bp;
147: register s;
148:
149: if(mp->wq == NULL)
150: return;
151: s = spl6();
152: if((mp->busy == 0) && mp->wq->count) {
153: bp = getq(mp->wq);
154: switch(bp->type) {
155:
156: case M_DATA:
157: mp->addr->wbuf = *bp->rptr++;
158: mp->busy = 1;
159: if(bp->rptr >= bp->wptr)
160: freeb(bp);
161: else
162: putbq(mp->wq, bp);
163: break;
164:
165: default:
166: freeb(bp);
167: break;
168: }
169: }
170: splx(s);
171: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.