|
|
1.1 root 1: /* dr.c 4.10 82/05/18 */
2:
3: #include "ekx.h"
4: #if NEKX > 0
5: /*
6: * UNIBUS DR11-B driver for various graphical systems,.
7: * TS
8: */
9:
10: #include "../h/param.h"
11: #include "../h/systm.h"
12: #include "../h/cpu.h"
13: #include "../h/nexus.h"
14: #include "../h/dk.h"
15: #include "../h/buf.h"
16: #include "../h/conf.h"
17: #include "../h/dir.h"
18: #include "../h/user.h"
19: #include "../h/map.h"
20: #include "../h/pte.h"
21: #include "../h/mtpr.h"
22: #include "../h/vm.h"
23: #include "../h/ubavar.h"
24: #include "../h/ubareg.h"
25: #include "../h/cmap.h"
26:
27: #include "../h/ekcmd.h"
28:
29: struct ekdevice{
30: u_short ekgc;
31: u_short ekdc;
32: u_short ekgs;
33: u_short ekds;
34: short ekwc;
35: u_short ekba;
36: u_short ekcs;
37: u_short ekdata;
38: };
39: struct ekctl {
40: u_short mode;
41: u_short dma_device;
42: u_short device;
43: u_short state;
44: } ek[NEKX];
45: #define EK_GO 01
46: #define EK_FCTN 016
47: #define EK_12BIT 0
48: #define EK_12BITST 04
49: #define EK_8BIT 02
50: #define EK_8BITST 06
51: #define EK_DARK 0
52: #define EK_GAIN 02
53: #define EK_HTST 010
54: #define EK_GTST 012
55: #define EK_X1617 060
56: #define EK_IE 0100
57: #define EK_READY 0200
58: #define EK_DIR 0400
59: #define EK_ODEV 01000
60: #define EK_OVER 02000
61: #define EK_ATTN 020000
62: #define EK_NEX 040000
63: #define EK_ERROR 0100000
64:
65: int ekxprobe(),ekxattach(),ekxdgo(),ekxintr();
66: int ekstrategy(),ekstart();
67: struct uba_ctlr *ekxminfo[NEKX];
68: struct uba_device *ekxdinfo[NEKX];
69: struct uba_ctlr ekctlr[NEKX]; /* ekxminfo points to this */
70: u_short ekxstd[] = { 0163700, 0};
71: struct uba_driver ekxdriver =
72: { ekxprobe,0,ekxattach,ekxdgo,ekxstd,"ekx",ekxdinfo,"ekx",ekxminfo };
73:
74: #define ui_open ui_type
75: struct buf ekbuf[NEKX];
76: struct buf ekutab[NEKX];
77: int ct1, ct2, ct3, ct4, ct5, ct6, ct7, ct8, ct9, ct10, ct11;
78: short sekgs, sekds, sekcs;
79: unsigned short sekwc;
80:
81: /*ARGSUSED*/
82: ekxprobe(reg)
83: caddr_t reg;
84: {
85: register int br,cvec;
86:
87: #ifdef LINT
88: br = 0; cvec = br; br = cvec;
89: #endif
90:
91: /* There seems to be no way to make this vile animal
92: interrupt, so we cheat... */
93:
94: br = 0x15;
95: cvec = 0270;
96: }
97:
98: ekxattach(ui)
99: register struct uba_device *ui;
100: {
101: register struct uba_ctlr *um;
102: register int unit;
103:
104: unit = ui->ui_unit;
105:
106: um = &ekctlr[unit];
107: ekxminfo[unit] = um;
108: ui->ui_ctlr = unit;
109: ui->ui_mi = um;
110: um->um_driver = ui->ui_driver;
111: um->um_ctlr = unit;
112: um->um_ubanum = ui->ui_ubanum;
113: um->um_alive = 1;
114: um->um_intr = ui->ui_intr;
115: um->um_addr = ui->ui_addr;
116: um->um_hd = ui->ui_hd;
117: }
118:
119: ekxopen(dev)
120: dev_t dev;
121: {
122: register int unit;
123:
124: ct1 = ct2 = ct3 = ct4 = ct5 = 0;
125: ct6 = ct7 = ct8 = ct9 = 0;
126: ct10 = ct11 = 0;
127: unit = minor(dev);
128: if((unit >= NEKX) || (ekxdinfo[unit]->ui_open)) {
129: u.u_error = ENXIO;
130: return;
131: }
132: ekxdinfo[unit]->ui_open++;
133: }
134:
135: ekxclose(dev)
136: dev_t dev;
137: {
138: register int unit;
139:
140: ekxdinfo[minor(dev)]->ui_open = 0;
141: }
142:
143: ekxread(dev)
144: dev_t dev;
145: {
146: register int unit = minor(dev);
147:
148: ct1++;
149: physio(ekstrategy,&ekbuf[unit],dev,B_READ,minphys);
150: ct2++;
151: }
152:
153: ekxwrite(dev)
154: dev_t dev;
155: {
156: register int unit = minor(dev);
157:
158: physio(ekstrategy,&ekbuf[unit],dev,B_WRITE,minphys);
159: }
160:
161: /*
162: * Due to the fact the ekstrategy routine is called only by ekxread
163: * and ekxwrite via physio, there will only be one transaction in each
164: * DR11-B's queue at any time. Therefore, one can just tack the given
165: * buffer header pointer on at the end of the queue, and call ekstart.
166: */
167: ekstrategy(bp)
168: register struct buf *bp;
169: {
170: register struct uba_device *ui;
171: register struct uba_ctlr *um;
172: register struct buf *dp;
173: register int s;
174: struct ekdevice *draddr;
175: dev_t unit;
176:
177: ct3++;
178: unit = minor(bp->b_dev); /* chose a DR11-B */
179: ui = ekxdinfo[unit];
180: um = ui->ui_mi; /* get ctlr ptr */
181: dp = &ekutab[unit];
182: s = spl5();
183: dp->b_actf = bp;
184: dp->b_actl = bp;
185: bp->av_forw = NULL;
186: um->um_tab.b_actf = dp;
187: um->um_tab.b_actl = dp;
188:
189: ekstart(um);
190: splx(s);
191: switch(tsleep((caddr_t)bp, PRIBIO+1, 20)) {
192: case TS_OK:
193: break;
194: case TS_SIG: /* not supposed to happen*/
195: case TS_TIME:
196: draddr = (struct ekdevice *)um->um_addr;
197: sekgs = draddr->ekgs;
198: sekds = draddr->ekds;
199: sekwc = draddr->ekwc;
200: sekcs = draddr->ekcs;
201: printf("gs %o ds %o wc %o cs %o\n",sekgs, sekds, sekwc, sekcs);
202: printf("ct1 %o ct2 %o ct3 %o ct4 %o ct5 %o ct6 %o\n",ct1,ct2,ct3,ct4,ct5,ct6);
203: printf("ct7 %o ct8 %o ct9 %o ct10 %o ct11 %o\n",ct7,ct8,ct9,ct10,ct11);
204: bp->b_flags |= B_DONE | B_ERROR;
205: s = spl6();
206: ekxintr(unit);
207: splx(s);
208: }
209: }
210:
211: ekstart(um)
212: register struct uba_ctlr *um;
213: {
214: register struct buf *bp,*dp;
215: register struct ekdevice *draddr;
216: register struct ekctl *ekp;
217: int cmd;
218:
219: dp = um->um_tab.b_actf;
220: bp = dp->b_actf;
221: ekp = &ek[minor(bp->b_dev)];
222:
223: um->um_tab.b_active++;
224: draddr = (struct ekdevice *)um->um_addr;
225: draddr->ekwc = -bp->b_bcount / sizeof (short);
226: if(bp->b_flags & B_READ)
227: cmd = EK_IE|EK_DIR|ekp->mode;
228: else
229: cmd = EK_IE|ekp->dma_device;
230: um->um_cmd = cmd|EK_GO;
231: ct4++;
232: draddr->ekcs = cmd;
233: ct5++;
234: DELAY(10);
235: if( ubago(ekxdinfo[minor(bp->b_dev)])== 0)
236: printf("ubago returned 0\n");
237: }
238:
239: ekxioctl(dev, cmd, arg)
240: dev_t dev;
241: int cmd;
242: register caddr_t arg;
243: {
244: register struct ekctl *ekp = &ek[minor(dev)];
245: register struct uba_device *ui = ekxdinfo[minor(dev)];
246: register struct ekdevice *draddr = (struct ekdevice *)ui->ui_addr;
247: u_short realcmd;
248:
249: if( (cmd != EKGS) && (cmd != EKDMA)){
250: if(copyin(arg, (caddr_t)&realcmd, sizeof(realcmd))){
251: u.u_error = EFAULT;
252: return;
253: }
254: }
255: switch(cmd){
256: case EKGC:
257: draddr->ekgc = realcmd;
258: return;
259: case EKDC:
260: draddr->ekdc = realcmd;
261: return;
262: case EKGS:
263: realcmd = draddr->ekgs;
264: break;
265: case EKDS:
266: draddr->ekdc = EKDC_READ|realcmd;
267: realcmd = draddr->ekds;
268: break;
269: case EKMOD:
270: ek->mode = realcmd & EK_FCTN;
271: return;
272: case EKDEV:
273: ek->dma_device = realcmd & EK_FCTN;
274: return;
275: default:
276: u.u_error = ENXIO;
277: return;
278: }
279: if(copyout((caddr_t)&realcmd, arg, sizeof(realcmd)))
280: u.u_error = EFAULT;
281: }
282: ekreset() {}
283: ekxdgo(um)
284: struct uba_ctlr *um;
285: {
286: register struct ekdevice *draddr = (struct ekdevice *)um->um_addr;
287:
288: ct6++;
289: draddr->ekba = um->um_ubinfo;
290: draddr->ekcs = um->um_cmd|((um->um_ubinfo>>12)&EK_X1617);
291: ct7++;
292: }
293: ekxintr(dr11)
294: register dr11;
295: {
296: register struct buf *bp,*dp;
297: register struct ekdevice *draddr;
298: register struct uba_ctlr *um;
299: register int stat;
300:
301: ct8++;
302: um = ekxminfo[dr11];
303:
304: if(um->um_tab.b_active == 0)
305: return;
306:
307: if(ekxdinfo[dr11]->ui_open == 0)
308: return;
309: dp = um->um_tab.b_actf;
310: bp = dp->b_actf;
311: draddr = (struct ekdevice *)um->um_addr;
312: stat = draddr->ekcs;
313:
314: if(stat & EK_ODEV){
315: ct11++;
316: }
317:
318: /*should check stat&EK_OVER for retry*/
319: if((stat&EK_ERROR) && draddr->ekwc && (draddr->ekba == 0)) {
320: draddr->ekcs = um->um_cmd|(((um->um_ubinfo>>12)+1)&EK_X1617);
321: ct10++;
322: }
323:
324: um->um_tab.b_active = 0;
325: um->um_tab.b_errcnt = 0;
326: um->um_tab.b_actf = dp->b_forw;
327: dp->b_errcnt = 0;
328: dp->b_active = 0;
329: bp->b_resid = (-draddr->ekwc * sizeof(short));
330: ubadone(um);
331: iodone(bp);
332: ct9++;
333: }
334: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.