xref: /original-bsd/sys/tahoe/vba/dr.c (revision 883fb6be)
1 /*	dr.c	1.6	86/12/15	*/
2 
3 #include "dr.h"
4 #if NDR > 0
5 /*
6  * DRV11-W DMA interface driver.
7  *
8  * UNTESTED WITH 4.3
9  */
10 #include "../machine/mtpr.h"
11 #include "../machine/pte.h"
12 
13 #include "param.h"
14 #include "conf.h"
15 #include "dir.h"
16 #include "user.h"
17 #include "proc.h"
18 #include "map.h"
19 #include "ioctl.h"
20 #include "buf.h"
21 #include "vm.h"
22 #include "uio.h"
23 #include "kernel.h"
24 
25 #include "../tahoevba/vbavar.h"
26 #include "../tahoevba/drreg.h"
27 
28 #define YES 1
29 #define NO  0
30 
31 struct  vba_device  *drinfo[NDR];
32 struct  dr_aux dr_aux[NDR];
33 
34 unsigned drminphys();
35 int	 drprobe(), drintr(), drattach(), drtimo(), drrwtimo();
36 int	 drstrategy();
37 extern	struct  vba_device  *drinfo[];
38 static	long drstd[] = { 0 };
39 struct  vba_driver drdriver =
40     { drprobe, 0, drattach, 0, drstd, "rs", drinfo };
41 
42 #define RSUNIT(dev) (minor(dev) & 7)
43 #define SPL_UP spl5
44 
45 /* -------- Per-unit data -------- */
46 
47 extern struct dr_aux dr_aux[];
48 
49 #ifdef DR_DEBUG
50 long	DR11 = 0;
51 #endif
52 
53 drprobe(reg, vi)
54 	caddr_t reg;
55 	struct vba_device *vi;
56 {
57 	register int br, cvec;		/* must be r12, r11 */
58 	struct rsdevice *dr;
59 
60 #ifdef lint
61 	br = 0; cvec = br; br = cvec;
62 	drintr(0);
63 #endif
64 	if (badaddr(reg, 2))
65 		return (0);
66 	dr = (struct rsdevice *)reg;
67 	dr->dr_intvect = --vi->ui_hd->vh_lastiv;
68 #ifdef DR_DEBUG
69 	printf("dprobe: Set interrupt vector %lx and init\n",dr->dr_intvec);
70 #endif
71 	/* generate interrupt here for autoconfig */
72 	dr->dr_cstat = MCLR;		/* init board and device */
73 #ifdef DR_DEBUG
74 	printf("drprobe: Initial status %lx\n", dr->dr_cstat);
75 #endif
76 	br = 0x18, cvec = dr->dr_intvect;	/* XXX */
77 	return (sizeof (struct rsdevice));		/* DR11 exist */
78 }
79 
80 /* ARGSUSED */
81 drattach(ui)
82 	struct vba_device *ui;
83 {
84 	register struct dr_aux *rsd;
85 
86 	rsd = &dr_aux[ui->ui_unit];
87 	rsd->dr_flags = DR_PRES;		/* This dr11 is present */
88 	rsd->dr_addr = (struct rsdevice *)ui->ui_addr; /* Save addr of this dr11 */
89 	rsd->dr_istat = 0;
90 	rsd->dr_bycnt = 0;
91 	rsd->dr_cmd = 0;
92 	rsd->currenttimo = 0;
93 }
94 
95 /*ARGSUSED*/
96 dropen(dev, flag)
97 	dev_t dev;
98 	int flag;
99 {
100 	register int unit = RSUNIT(dev);
101 	register struct rsdevice *dr;
102 	register struct dr_aux *rsd;
103 
104 	if (drinfo[unit] == 0 || !drinfo[unit]->ui_alive)
105 		return (ENXIO);
106 	dr = RSADDR(unit);
107 	rsd = &dr_aux[unit];
108 	if (rsd->dr_flags & DR_OPEN) {
109 #ifdef DR_DEBUG
110 		printf("\ndropen: dr11 unit %ld already open",unit);
111 #endif
112 		return (ENXIO);	  		/* DR11 already open */
113 	}
114 	rsd->dr_flags |= DR_OPEN;	/* Mark it OPEN */
115 	rsd->dr_istat = 0;		/* Clear status of previous interrupt */
116 	rsd->rtimoticks = hz;		/* Set read no stall timout to 1 sec */
117 	rsd->wtimoticks = hz*60;	/* Set write no stall timout to 1 min */
118 	dr->dr_cstat = DR_ZERO;		/* Clear function & latches */
119 	dr->dr_pulse = (RDMA | RATN);	/* clear leftover attn & e-o-r flags */
120 	drtimo(dev);			/* start the self kicker */
121 	return (0);
122 }
123 
124 drclose (dev)
125 	dev_t dev;
126 {
127 	register int unit = RSUNIT(dev);
128 	register struct dr_aux *dra;
129 	register struct rsdevice *rs;
130 	register short s;
131 
132 	dra = &dr_aux[unit];
133 	if ((dra->dr_flags & DR_OPEN) == 0) {
134 #ifdef DR_DEBUG
135 		printf("\ndrclose: DR11 device %ld not open",unit);
136 #endif
137 		return;
138 	}
139 	dra->dr_flags &= ~(DR_OPEN|DR_ACTV);
140 	rs = dra->dr_addr;
141 	s = SPL_UP();
142 	rs->dr_cstat = DR_ZERO;
143 	if (dra->dr_buf.b_flags & B_BUSY) {
144 		dra->dr_buf.b_flags &= ~B_BUSY;
145 		wakeup((caddr_t)&dra->dr_buf.b_flags);
146 	}
147 	splx(s);
148 }
149 
150 
151 /*	drread() works exactly like drwrite() except that the
152 	B_READ flag is used when physio() is called
153 */
154 drread (dev, uio)
155 	dev_t dev;
156 	struct uio *uio;
157 {	register struct dr_aux *dra;
158 	register struct buf *bp;
159 	register int spl, err;
160 	register int unit = RSUNIT(dev);
161 
162 	if (uio->uio_iov->iov_len <= 0 ||	/* Negative count */
163 	    uio->uio_iov->iov_len & 1 ||	/* odd count */
164 	    (int)uio->uio_iov->iov_base & 1)	/* odd destination address */
165 		return (EINVAL);
166 #ifdef DR_DEBUG
167 	if (DR11 & 8)
168 		printf("\ndrread: (len:%ld)(base:%lx)",
169 		    uio->uio_iov->iov_len,(int)uio->uio_iov->iov_base);
170 #endif
171 	dra = &dr_aux[RSUNIT(dev)];
172 	dra->dr_op = DR_READ;
173 	bp =  &dra->dr_buf;
174 	bp->b_resid = 0;
175 	if (dra->dr_flags & DR_NORSTALL) {
176 		/*
177 		 * We are in no stall mode, start the timer,
178 		 * raise IPL so nothing can stop us once the
179 		 * timer's running
180 		 */
181 		spl = SPL_UP();
182 		timeout(drrwtimo, (caddr_t)((dra->currenttimo<<8) | unit),
183 		    (int)dra->rtimoticks);
184 		err = physio(drstrategy, bp, dev,B_READ, drminphys, uio);
185 		splx(spl);
186 		if (err)
187 			return (err);
188 		dra->currenttimo++;	/* Update current timeout number */
189 		/* Did we timeout */
190 		if (dra->dr_flags & DR_TMDM) {
191 			dra->dr_flags &= ~DR_TMDM; /* Clear timeout flag */
192 			u.u_error = 0;	/* Made the error ourself, ignore it */
193 		}
194 		return (err);
195 	}
196 	return (physio(drstrategy, bp, dev,B_READ, drminphys, uio));
197 }
198 
199 drwrite(dev, uio)
200 	dev_t dev;
201 	struct uio *uio;
202 {	register struct dr_aux *dra;
203 	register struct buf *bp;
204 	register int unit = RSUNIT(dev);
205 	int spl, err;
206 
207 	if (uio->uio_iov->iov_len <= 0 || uio->uio_iov->iov_len & 1 ||
208 	    (int)uio->uio_iov->iov_base & 1)
209 		return (EINVAL);
210 #ifdef DR_DEBUG
211 	if (DR11 & 4)
212 		printf("\ndrwrite: (len:%ld)(base:%lx)",
213 		    uio->uio_iov->iov_len,(int)uio->uio_iov->iov_base);
214 #endif
215 	dra = &dr_aux[RSUNIT(dev)];
216 	dra->dr_op = DR_WRITE;
217 	bp =  &dra->dr_buf;
218 	bp->b_resid = 0;
219 	if (dra->dr_flags & DR_NOWSTALL) {
220 		/*
221 		 * We are in no stall mode, start the timer,
222 		 * raise IPL so nothing can stop us once the
223 		 * timer's running
224 		 */
225 		spl = SPL_UP();
226 		timeout(drrwtimo,(caddr_t)((dra->currenttimo<<8) | unit),
227 		    (int)dra->wtimoticks);
228 		err = physio (drstrategy, bp, dev,B_WRITE, drminphys, uio);
229 		splx(spl);
230 		if (err)
231 			return (err);
232 		dra->currenttimo++;	/* Update current timeout number */
233 		/* Did we timeout */
234 		if (dra->dr_flags & DR_TMDM) {
235 			dra->dr_flags &= ~DR_TMDM;	/* Clear timeout flag */
236 			u.u_error = 0;	/* Made the error ourself, ignore it */
237 		}
238 		return (err);
239 	}
240 	return (physio(drstrategy, bp, dev,B_WRITE, drminphys, uio));
241 }
242 
243 /*
244  * Routine used by calling program to issue commands to dr11 driver and
245  * through it to the device.
246  * It is also used to read status from the device and driver and to wait
247  * for attention interrupts.
248  * Status is returned in an 8 elements unsigned short integer array, the
249  * first two elements of the array are also used to pass arguments to
250  * drioctl() if required.
251  * The function bits to be written to the dr11 are included in the cmd
252  * argument. Even if they are not being written to the dr11 in a particular
253  * drioctl() call, they will update the copy of cmd that is stored in the
254  * driver. When drstrategy() is called, this updated copy is used if a
255  * deferred function bit write has been specified. The "side effect" of
256  * calls to the drioctl() requires that the last call prior to a read or
257  * write has an appropriate copy of the function bits in cmd if they are
258  * to be used in drstrategy().
259  * When used as command value, the contents of data[0] is the command
260  * parameter.
261  */
262 drioctl(dev, cmd, data)
263 	dev_t dev;
264 	int cmd;
265 	long *data;
266 {
267 	register int unit = RSUNIT(dev);
268 	register struct dr_aux *dra;
269 	register struct rsdevice *rsaddr = RSADDR(unit);
270 	int s;
271 	u_short status;
272 	long temp;
273 
274 #ifdef DR_DEBUG
275 	if (DR11 & 0x10)
276 		printf("\ndrioctl: (dev:%lx)(cmd:%lx)(data:%lx)(data[0]:%lx)",
277 		    dev,cmd,data,data[0]);
278 #endif
279 	dra = &dr_aux[unit];
280 	dra->dr_cmd = 0;	/* Fresh copy; clear all previous flags */
281 	switch (cmd) {
282 
283 	case DRWAIT:		/* Wait for attention interrupt */
284 #ifdef DR_DEBUG
285 		printf("\ndrioctl: wait for attention interrupt");
286 #endif
287 		s = SPL_UP();
288 		/*
289 		 * If the attention flag in dr_flags is set, it probably
290 		 * means that an attention has arrived by the time a
291 		 * previous DMA end-of-range interrupt was serviced. If
292 		 * ATRX is set, we will return with out sleeping, since
293 		 * we have received an attention since the last call to
294 		 * wait on attention.  This may not be appropriate for
295 		 * some applications.
296 		 */
297 		if ((dra->dr_flags & DR_ATRX) == 0) {
298 			dra->dr_flags |= DR_ATWT;	/* Set waiting flag */
299 			/*
300 			 * Enable interrupt; use pulse reg.
301 			 * so function bits are not changed
302 			 */
303 			rsaddr->dr_pulse = IENB;
304 			sleep((caddr_t)&dra->dr_cmd, DRPRI);
305 		}
306 		splx(s);
307 		break;
308 
309 	case DRPIOW:			/* Write to p-i/o register */
310 		rsaddr->dr_data = data[0];
311 		break;
312 
313 	case DRPACL:			/* Send pulse to device */
314 		rsaddr->dr_pulse = FCN2;
315 		break;
316 
317 	case DRDACL:			/* Defer alco pulse until go */
318 		dra->dr_cmd |= DR_DACL;
319 		break;
320 
321 	case DRPCYL:			/* Set cycle with next go */
322 		dra->dr_cmd |= DR_PCYL;
323 		break;
324 
325 	case DRDFCN:			/* Update function with next go */
326 		dra->dr_cmd |= DR_DFCN;
327 		break;
328 
329 	case DRRATN:			/* Reset attention flag */
330 		rsaddr->dr_pulse = RATN;
331 		break;
332 
333 	case DRRDMA:			/* Reset DMA e-o-r flag */
334 		rsaddr->dr_pulse = RDMA;
335 		break;
336 
337 	case DRSFCN:			/* Set function bits */
338 		temp = data[0] & DR_FMSK;
339 		/*
340 		 * This has a very important side effect -- It clears
341 		 * the interrupt enable flag. That is fine for this driver,
342 		 * but if it is desired to leave interrupt enable at all
343 		 * times, it will be necessary to read the status register
344 		 * first to get IENB, or carry a software flag that indicates
345 		 * whether interrupts are set, and or this into the control
346 		 * register value being written.
347 		 */
348 		rsaddr->dr_cstat = temp;
349 		break;
350 
351 	case DRRPER:			/* Clear parity flag */
352 		rsaddr->dr_pulse = RPER;
353 		break;
354 
355 	case DRSETRSTALL:		/* Set read stall mode. */
356 		dra->dr_flags &= (~DR_NORSTALL);
357 		break;
358 
359 	case DRSETNORSTALL:		/* Set no stall read  mode. */
360 		dra->dr_flags |= DR_NORSTALL;
361 		break;
362 
363 	case DRGETRSTALL:		/* Returns true if in read stall mode */
364 		data[0]  = (dra->dr_flags & DR_NORSTALL)? 0 : 1;
365 		break;
366 
367 	case DRSETRTIMEOUT:		/* Set read stall timeout (1/10 secs) */
368 		if (data[0] < 1) {
369 			u.u_error = EINVAL;
370 			temp = 1;
371 		}
372 		dra->rtimoticks = (data[0] * hz )/10;
373 		break;
374 
375 	case DRGETRTIMEOUT:		/* Return read stall timeout */
376 		data[0] = ((dra->rtimoticks)*10)/hz;
377 		break;
378 
379 	case DRSETWSTALL:		/* Set write stall mode. */
380 		dra->dr_flags &= (~DR_NOWSTALL);
381 		break;
382 
383 	case DRSETNOWSTALL:		/* Set write stall mode. */
384 		dra->dr_flags |= DR_NOWSTALL;
385 		break;
386 
387 	case DRGETWSTALL:		/* Return true if in write stall mode */
388 		data[0] = (dra->dr_flags & DR_NOWSTALL)? 0 : 1;
389 		break;
390 
391 	case DRSETWTIMEOUT:		/* Set write stall timeout (1/10's) */
392 		if (data[0] < 1) {
393 			u.u_error = EINVAL;
394 			temp = 1;
395 		}
396 		dra->wtimoticks = (data[0] * hz )/10;
397 		break;
398 
399 	case DRGETWTIMEOUT:		/* Return write stall timeout */
400 		data[0] = ((dra->wtimoticks)*10)/hz;
401 		break;
402 
403 	case DRWRITEREADY:		/* Return true if can write data */
404 		data[0] = (rsaddr->dr_cstat & STTA)? 1 : 0;
405 		break;
406 
407 	case DRREADREADY:		/* Return true if data to be read */
408 		data[0] = (rsaddr->dr_cstat & STTB)? 1 : 0;
409 		break;
410 
411 	case DRBUSY:			/* Return true if device busy */
412 		/*
413 		 * Internally this is the DR11-W
414 		 * STAT C bit, but there is a bug in the Omega 500/FIFO
415 		 * interface board that it cannot drive this signal low
416 		 * for certain DR11-W ctlr such as the Ikon. We use the
417 		 * REDY signal of the CSR on the Ikon DR11-W instead.
418 		 */
419 #ifdef notdef
420 		data[0] = (rsaddr->dr_cstat & STTC)? 1 : 0;
421 #else
422 		data[0] = ((rsaddr->dr_cstat & REDY)? 0 : 1);
423 #endif
424 		break;
425 
426 	case DRRESET:			/* Reset device */
427 		/* Reset DMA ATN RPER flag */
428 		rsaddr->dr_pulse = (MCLR|RDMA|RATN|RPER);
429 		DELAY(0x1f000);
430 		while ((rsaddr->dr_cstat & REDY) == 0)
431 			sleep((caddr_t)dra, DRPRI);	/* Wakeup by drtimo() */
432 		dra->dr_istat = 0;
433 		dra->dr_cmd = 0;
434 		dra->currenttimo = 0;
435 		break;
436 
437 	case DR11STAT: {		/* Copy back dr11 status to user */
438 		register struct dr11io *dr = (struct dr11io *)data;
439 		dr->arg[0] = dra->dr_flags;
440 		dr->arg[1] = rsaddr->dr_cstat;
441 		dr->arg[2] = dra->dr_istat;	/* Status at last interrupt */
442 		dr->arg[3] = rsaddr->dr_data;	/* P-i/o input data */
443 		status = (u_short)((rsaddr->dr_addmod << 8) & 0xff00);
444 		dr->arg[4] = status | (u_short)(rsaddr->dr_intvect & 0xff);
445 		dr->arg[5] = rsaddr->dr_range;
446 		dr->arg[6] = rsaddr->dr_rahi;
447 		dr->arg[7] = rsaddr->dr_ralo;
448 		break;
449 	}
450 	case DR11LOOP:			/* Perform loopback test */
451 		/*
452 		 * NB: MUST HAVE LOOPBACK CABLE ATTACHED --
453 		 * Test results are printed on system console
454 		 */
455 		if (suser())
456 			dr11loop(rsaddr, dra, unit);
457 		break;
458 
459 	default:
460 		return (EINVAL);
461 	}
462 #ifdef DR_DEBUG
463 	if (DR11 & 0x10)
464 		printf("**** (data[0]:%lx)",data[0]);
465 #endif
466 	return (0);
467 }
468 
469 #define NPAT	2
470 #define DMATBL	20
471 u_short	tstpat[DMATBL] = { 0xAAAA, 0x5555};
472 long	DMAin = 0;
473 
474 /*
475  * Perform loopback test -- MUST HAVE LOOPBACK CABLE ATTACHED
476  * Test results are printed on system console
477  */
478 dr11loop(dr, dra, unit)
479 	struct rsdevice *dr;
480 	struct dr_aux *dra;
481 	int unit;
482 {
483 	register long result, ix;
484 	long addr, wait;
485 
486 	dr->dr_cstat = MCLR;		/* Clear board & device, disable intr */
487 	printf("\n\t ----- DR11 unit %ld loopback test -----", unit);
488 	printf("\n\t Program I/O ...");
489 	for (ix=0;ix<NPAT;ix++) {
490 		dr->dr_data = tstpat[ix];	/* Write to Data out register */
491 		result = dr->dr_data & 0xFFFF;	/* Read it back */
492 		if (result != tstpat[ix]) {
493 			printf("Failed, expected : %lx --- actual : %lx",
494 				tstpat[ix], result);
495 			return;
496 		}
497 	}
498 	printf("OK\n\t Functions & Status Bits ...");
499 	dr->dr_cstat = (FCN1 | FCN3);
500 	result = dr->dr_cstat & 0xffff;		/* Read them back */
501 	if ((result & (STTC | STTA)) != (STTC |STTA)) {
502 		printf("Failed, expected : %lx --- actual : %lx, ISR:%lx",
503 			(STTA|STTC), (result & (STTA|STTC)), result);
504 		return;
505 	}
506 	dr->dr_cstat = FCN2;
507 	result = dr->dr_cstat & 0xffff;		/* Read them back */
508 	if ((result & STTB) != STTB) {
509 		printf("Failed, expected : %lx --- actual : %lx, ISR:%lx",
510 			STTB, (result & STTB), result);
511 		return;
512 	}
513 	printf("OK\n\t DMA output ...");
514 	if (DMAin)
515 		goto dmain;
516 	/* Initialize DMA data buffer */
517 	for (ix=0; ix<DMATBL; ix++)
518 		tstpat[ix] = 0xCCCC + ix;
519 	tstpat[DMATBL-1] = 0xCCCC;	/* Last word output */
520 	/* Setup normal DMA */
521 	addr = (long)vtoph((struct proc *)0, (unsigned)tstpat);
522 	dr->dr_walo = (addr >> 1) & 0xffff;
523 	dr->dr_wahi = (addr >> 17) & 0x7fff;
524 	/* Set DMA range count: (number of words - 1) */
525 	dr->dr_range = DMATBL - 1;
526 	/* Set address modifier code to be used for DMA access to memory */
527 	dr->dr_addmod = DRADDMOD;
528 
529 	/*
530 	 * Clear dmaf and attf to assure a clean dma start, also disable
531 	 * attention interrupt
532 	 */
533 	dr->dr_pulse = RDMA|RATN|RMSK;  /* Use pulse register */
534 	dr->dr_cstat = GO|CYCL;		  /* GO...... */
535 
536 	/* Wait for DMA complete; REDY and DMAF are true in ISR */
537 	wait = 0;
538 	while ((result=(dr->dr_cstat & (REDY|DMAF))) != (REDY|DMAF)) {
539 		printf("\n\tWait for DMA complete...ISR : %lx", result);
540 		if (++wait > 5) {
541 			printf("\n\t DMA output fails...timeout!!, ISR:%lx",
542 				result);
543 			return;
544 		}
545 	}
546 	result = dr->dr_data & 0xffff;		/* Read last word output */
547 	if (result != 0xCCCC) {
548 		printf("\n\t Fails, expected : %lx --- actual : %lx",
549 			0xCCCC, result);
550 		return;
551 	}
552 	printf("OK\n\t DMA input ...");
553 dmain:
554 	dr->dr_data = 0x1111;		/* DMA input data */
555 	/* Setup normal DMA */
556 	addr = (long)vtoph((struct proc *)0, (unsigned)tstpat);
557 	dr->dr_walo = (addr >> 1) & 0xffff;
558 	dr->dr_wahi = (addr >> 17) & 0x7fff;
559 	dr->dr_range = DMATBL - 1;
560 	dr->dr_addmod = (char)DRADDMOD;
561 	dr->dr_cstat = FCN1;		/* Set FCN1 in ICR to DMA in*/
562 	if ((dra->dr_flags & DR_LOOPTST) == 0) {
563 		/* Use pulse reg */
564 		dr->dr_pulse = RDMA|RATN|RMSK|CYCL|GO;
565 		/* Wait for DMA complete; REDY and DMAF are true in ISR */
566 		wait = 0;
567 		while ((result=(dr->dr_cstat & (REDY|DMAF))) != (REDY|DMAF)) {
568 			printf("\n\tWait for DMA to complete...ISR:%lx",result);
569 			if (++wait > 5) {
570 				printf("\n\t DMA input timeout!!, ISR:%lx",
571 					result);
572 				return;
573 			}
574 		}
575 	} else  {
576 		/* Enable DMA e-o-r interrupt */
577 		dr->dr_pulse = IENB|RDMA|RATN|CYCL|GO;
578 		/* Wait for DMA complete; DR_LOOPTST is false in dra->dr_flags*/
579 		wait = 0;
580 		while (dra->dr_flags & DR_LOOPTST) {
581 			result = dr->dr_cstat & 0xffff;
582 			printf("\n\tWait for DMA e-o-r intr...ISR:%lx", result);
583 			if (++wait > 7) {
584 				printf("\n\t DMA e-o-r timeout!!, ISR:%lx",
585 					result);
586 				dra->dr_flags &= ~DR_LOOPTST;
587 				return;
588 			}
589 		}
590 		dra->dr_flags |= DR_LOOPTST;
591 	}
592 	mtpr(P1DC, tstpat);			/* Purge cache */
593 	mtpr(P1DC, 0x3ff+tstpat);
594 	for (ix=0; ix<DMATBL; ix++) {
595 		if (tstpat[ix] != 0x1111) {
596 			printf("\n\t Fails, ix:%d, expected:%x --- actual:%x",
597 				ix, 0x1111, tstpat[ix]);
598 			return;
599 		}
600 	}
601 	if ((dra->dr_flags & DR_LOOPTST) == 0) {
602 		dra->dr_flags |= DR_LOOPTST;
603 		printf(" OK..\n\tDMA end of range interrupt...");
604 		goto dmain;
605 	}
606 	printf(" OK..\n\tAttention interrupt....");
607 	dr->dr_pulse = IENB|RDMA;
608 	dr->dr_pulse = FCN2;
609 	/* Wait for ATTN interrupt; DR_LOOPTST is false in dra->dr_flags*/
610 	wait = 0;
611 	while (dra->dr_flags & DR_LOOPTST) {
612 		result = dr->dr_cstat & 0xffff;
613 		printf("\n\tWait for Attention intr...ISR:%lx",result);
614 		if (++wait > 7) {
615 			printf("\n\t Attention interrupt timeout!!, ISR:%lx",
616 				result);
617 			dra->dr_flags &= ~DR_LOOPTST;
618 			return;
619 		}
620 	}
621 	dra->dr_flags &= ~DR_LOOPTST;
622 	printf(" OK..\n\tDone...");
623 }
624 
625 /* Reset state on Unibus reset */
626 /*ARGSUSED*/
627 drreset(uban)
628 	int uban;
629 {
630 
631 }
632 
633 /*
634  * An interrupt is caused either by an error,
635  * base address overflow, or transfer complete
636  */
637 drintr(dr11)
638 	int dr11;
639 {
640 	register struct dr_aux *dra = &dr_aux[dr11];
641 	register struct rsdevice *rsaddr = RSADDR(dr11);
642 	register struct buf *bp;
643 	register short status;
644 
645 	status = rsaddr->dr_cstat & 0xffff;	/* get board status register */
646 	dra->dr_istat = status;
647 #ifdef DR_DEBUG
648 	if (DR11 & 2)
649 		printf("\ndrintr: dr11 status : %lx",status & 0xffff);
650 #endif
651 	if (dra->dr_flags & DR_LOOPTST) {	/* doing loopback test */
652 		dra->dr_flags &= ~DR_LOOPTST;
653 		return;
654 	}
655 	/*
656 	 * Make sure this is not a stray interrupt; at least one of dmaf or attf
657 	 * must be set. Note that if the dr11 interrupt enable latch is reset
658 	 * during a hardware interrupt ack sequence, and by the we get to this
659 	 * point in the interrupt code it will be 0. This is done to give the
660 	 * programmer some control over how the two more-or-less independent
661 	 * interrupt sources on the board are handled.
662 	 * If the attention flag is set when drstrategy() is called to start a
663 	 * dma read or write an interrupt will be generated as soon as the
664 	 * strategy routine enables interrupts for dma end-of-range. This will
665 	 * cause execution of the interrupt routine (not necessarily bad) and
666 	 * will cause the interrupt enable mask to be reset (very bad since the
667 	 * dma end-of-range condition will not be able to generate an interrupt
668 	 * when it occurs) causing the dma operation to time-out (even though
669 	 * the dma transfer will be done successfully) or hang the process if a
670 	 * software time-out capability is not implemented. One way to avoid
671 	 * this situation is to check for a pending attention interrupt (attf
672 	 * set) by calling drioctl() before doing a read or a write. For the
673 	 * time being this driver will solve the problem by clearing the attf
674 	 * flag in the status register before enabling interrupts in
675 	 * drstrategy().
676 	 *
677 	 * **** The IKON 10084 for which this driver is written will set both
678 	 * attf and dmaf if dma is terminated by an attention pulse. This will
679 	 * cause a wakeup(&dr_aux), which will be ignored since it is not being
680 	 * waited on, and an iodone(bp) which is the desired action. Some other
681 	 * dr11 emulators, in particular the IKON 10077 for the Multibus, donot
682 	 * dmaf in this case. This may require some addtional code in the inter-
683 	 * rupt routine to ensure that en iodone(bp) is issued when dma is term-
684 	 * inated by attention.
685 	 */
686 	bp = dra->dr_actf;
687 	if ((status & (ATTF | DMAF)) == 0) {
688 		printf("dr%d: stray interrupt, status=%x", dr11, status);
689 		return;
690 	}
691 	if (status & DMAF) {		/* End-of-range interrupt */
692 		dra->dr_flags |= DR_DMAX;
693 
694 #ifdef DR_DEBUG
695 		if (DR11 & 2)
696 		printf("\ndrintr: e-o-r interrupt,cstat:%lx,dr_flags:%lx",
697 			status&0xffff, dra->dr_flags & DR_ACTV);
698 #endif
699 		if ((dra->dr_flags & DR_ACTV) == 0) {
700 			/* We are not doing DMA !! */
701 			bp->b_flags |= B_ERROR;
702 		} else {
703 			if (dra->dr_op == DR_READ)
704 				mtpr(P1DC, bp->b_un.b_addr);
705 			dra->dr_bycnt -= bp->b_bcount;
706 			if (dra->dr_bycnt >0) {
707 				bp->b_un.b_addr += bp->b_bcount;
708 				bp->b_bcount = (dra->dr_bycnt > NBPG) ? NBPG:
709 					dra->dr_bycnt;
710 				drstart(rsaddr, dra, bp);
711 				return;
712 			}
713 		}
714 		dra->dr_flags &= ~DR_ACTV;
715 		wakeup((caddr_t)dra);		/* Wakeup waiting in drwait() */
716 		rsaddr->dr_pulse = (RPER|RDMA|RATN); /* reset dma e-o-r flag */
717 	}
718 	/*
719 	 * Now test for attention interrupt -- It may be set in addition to
720 	 * the dma e-o-r interrupt. If we get one we will issue a wakeup to
721 	 * the drioctl() routine which is presumable waiting for one.
722 	 * The program may have to monitor the attention interrupt received
723 	 * flag in addition to doing waits for the interrupt. Futhermore,
724 	 * interrupts are not enabled unless dma is in progress or drioctl()
725 	 * has been called to wait for attention -- this may produce some
726 	 * strange results if attf is set on the dr11 when a read or a write
727 	 * is initiated, since that will enables interrupts.
728 	 * **** The appropriate code for this interrupt routine will probably
729 	 * be rather application dependent.
730 	 */
731 	if (status & ATTF) {
732 		dra->dr_flags |= DR_ATRX;
733 		dra->dr_flags &= ~DR_ATWT;
734 		rsaddr->dr_cstat = RATN;	/* reset attention flag */
735 		/*
736 		 * Some applications which use attention to terminate
737 		 * dma may also want to issue an iodone() here to
738 		 * wakeup physio().
739 		 */
740 		wakeup((caddr_t)&dra->dr_cmd);
741 	}
742 }
743 
744 unsigned
745 drminphys(bp)
746 	struct buf *bp;
747 {
748 
749 	if (bp->b_bcount > 65536)
750 		bp->b_bcount = 65536;
751 }
752 
753 /*
754  * This routine performs the device unique operations on the DR11W
755  * it is passed as an argument to and invoked by physio
756  */
757 drstrategy (bp)
758 	register struct buf *bp;
759 {
760 	register int s;
761 	int unit = RSUNIT(bp->b_dev);
762 	register struct rsdevice *rsaddr = RSADDR(unit);
763 	register struct dr_aux *dra = &dr_aux[unit];
764 	register int ok;
765 #ifdef DR_DEBUG
766 	register char *caddr;
767 	long drva();
768 #endif
769 
770 	if ((dra->dr_flags & DR_OPEN) == 0) {	/* Device not open */
771 		bp->b_error = ENXIO;
772 		bp->b_flags |= B_ERROR;
773 		iodone (bp);
774 		return;
775 	}
776 	while (dra->dr_flags & DR_ACTV)
777 		/* Device is active; should never be in here... */
778 		sleep((caddr_t)&dra->dr_flags,DRPRI);
779 	dra->dr_actf = bp;
780 #ifdef DR_DEBUG
781 	drva(dra, bp->b_proc, bp->b_un.b_addr, bp->b_bcount);
782 #endif
783 	dra->dr_oba = bp->b_un.b_addr;	/* Save original addr, count */
784 	dra->dr_obc = bp->b_bcount;
785 	dra->dr_bycnt = bp->b_bcount;	/* Save xfer count used by drintr() */
786 	if ((((long)bp->b_un.b_addr & 0x3fffffff) >> PGSHIFT) !=
787 	    ((((long)bp->b_un.b_addr & 0x3fffffff) + bp->b_bcount) >> PGSHIFT))
788 		bp->b_bcount = NBPG - (((long)bp->b_un.b_addr) & PGOFSET);
789 	dra->dr_flags |= DR_ACTV;	/* Mark active (use in intr handler) */
790 	s = SPL_UP();
791 	drstart(rsaddr,dra,bp);
792 	splx(s);
793 	ok = drwait(rsaddr,dra);
794 #ifdef DR_DEBUG
795 	if (DR11 & 0x40) {
796 		caddr = (char *)dra->dr_oba;
797 		if (dra->dr_op == DR_READ)
798 			printf("\nAfter read: (%lx)(%lx)",
799 			    caddr[0]&0xff, caddr[1]&0xff);
800 	}
801 #endif
802 	dra->dr_flags &= ~DR_ACTV;		/* Clear active flag */
803 	bp->b_un.b_addr = dra->dr_oba;	/* Restore original addr, count */
804 	bp->b_bcount = dra->dr_obc;
805 	if (!ok)
806 		bp->b_flags |= B_ERROR;
807 	/* Mark buffer B_DONE,so physstrat() in ml/machdep.c won't sleep */
808 	iodone(bp);
809 	wakeup((caddr_t)&dra->dr_flags);
810 	/*
811 	 * Return to the calling program (physio()). Physio() will sleep
812 	 * until awaken by a call to iodone() in the interupt handler --
813 	 * which will be called by the dispatcher when it receives dma
814 	 * end-of-range interrupt.
815 	 */
816 }
817 
818 drwait(rs, dr)
819 	register struct rsdevice *rs;
820 	register struct dr_aux *dr;
821 {
822 	int s;
823 
824 	s = SPL_UP();
825 	while (dr->dr_flags & DR_ACTV)
826 		sleep((caddr_t)dr, DRPRI);
827 	splx(s);
828 	if (dr->dr_flags & DR_TMDM) {		/* DMA timed out */
829 		dr->dr_flags &= ~DR_TMDM;
830 		return (0);
831 	}
832 	if (rs->dr_cstat & (PERR|BERR|TERR)) {
833 		dr->dr_actf->b_flags |= B_ERROR;
834 		return (0);
835 	}
836 	dr->dr_flags &= ~DR_DMAX;
837 	return (1);
838 }
839 
840 /*
841  *
842  * The lower 8-bit of tinfo is the minor device number, the
843  * remaining higher 8-bit is the current timout number
844  */
845 drrwtimo(tinfo)
846 	register u_long tinfo;
847 {
848 	register long unit = tinfo & 0xff;
849 	register struct dr_aux *dr = &dr_aux[unit];
850 	register struct rsdevice *rs = dr->dr_addr;
851 
852 	/*
853 	 * If this is not the timeout that drwrite/drread is waiting
854 	 * for then we should just go away
855 	 */
856 	if ((tinfo &~ 0xff) != (dr->currenttimo << 8))
857 		return;
858 	/* Mark the device timed out */
859 	dr->dr_flags |= DR_TMDM;
860 	dr->dr_flags &= ~DR_ACTV;
861 	rs->dr_pulse = RMSK;			/* Inihibit interrupt */
862 	rs->dr_pulse = (RPER|RDMA|RATN|IENB);	/* Clear DMA logic */
863 	/*
864 	 * Some applications will not issue a master after dma timeout,
865 	 * since doing so sends an INIT H pulse to the external device,
866 	 * which may produce undesirable side-effects.
867 	 */
868 	/* Wake up process waiting in drwait() and flag the error */
869 	dr->dr_actf->b_flags |= B_ERROR;
870 	wakeup((caddr_t)dr->dr_cmd);
871 }
872 
873 /*
874  * Kick the driver every second
875  */
876 drtimo(dev)
877 	dev_t dev;
878 {
879 	register int unit = RSUNIT(dev);
880 	register struct dr_aux *dr;
881 
882 	dr = &dr_aux[unit];
883 	if (dr->dr_flags & DR_OPEN)
884 		timeout(drtimo, (caddr_t)dev, hz);
885 	wakeup((caddr_t)dr);	/* Wakeup any process waiting for interrupt */
886 }
887 
888 #ifdef DR_DEBUG
889 drva(dra, p, va, bcnt)
890 	struct dr_aux *dra;
891 	struct proc *p;
892 	char *va;
893 	long bcnt;
894 {
895 	register long first, last , np;
896 
897 	if (DR11 & 0x20)  {
898 		first = ((long)(vtoph(p, (unsigned)va))) >> 10;
899 		last = ((long)(vtoph(p, (unsigned)va+bcnt))) >> 10;
900 		np = bcnt / 0x3ff;
901 		printf("\ndrva: (op:%ld)(first:%ld)(last:%ld)(np:%ld)(cnt:%ld)",
902 			dra->dr_op,first,last,np,bcnt);
903 	}
904 }
905 #endif
906 
907 drstart(rsaddr, dra, bp)
908 	register struct rsdevice *rsaddr;
909 	register struct dr_aux *dra;
910 	register struct buf *bp;
911 {
912 	register long addr;
913 	u_short go;
914 
915 #ifdef DR_DEBUG
916 	if (dra->dr_op == DR_READ && (DR11 & 8)) {
917 		char *caddr = (char *)bp->b_un.b_addr;
918 		printf("\ndrstart: READ, bcnt:%ld",bp->b_bcount);
919 		printf(",(%lx)(%lx)",caddr[0]&0xff,caddr[1]&0xff);
920 	}
921 #endif
922 	/* we are doing raw IO, bp->b_un.b_addr is user's address */
923 	addr = (long)vtoph(bp->b_proc, (unsigned)bp->b_un.b_addr);
924 	/*
925 	 * Set DMA address into DR11 interace registers: DR11 requires that
926 	 * the address be right shifted 1 bit position before it is written
927 	 * to the board (The board will left shift it one bit position before
928 	 * it places the address on the bus
929 	 */
930 	rsaddr->dr_walo = (addr >> 1) & 0xffff;
931 	rsaddr->dr_wahi = (addr >> 17) & 0x7fff;
932 	/* Set DMA range count: (number of words - 1) */
933 	rsaddr->dr_range = (bp->b_bcount >> 1) - 1;
934 	/* Set address modifier code to be used for DMA access to memory */
935 	rsaddr->dr_addmod = DRADDMOD;
936 	/*
937 	 * Now determine whether this is a read or a write. ***** This is
938 	 * probably only usefull for link mode operation, since dr11 doesnot
939 	 * controll the direction of data transfer. The C1 control input
940 	 * controls whether the hardware is doing a read or a write. In link
941 	 * mode this is controlled by function 1 latch (looped back by the
942 	 * cable) and could be set the program. In the general case, the dr11
943 	 * doesnot know in advance what the direction of transfer is - although
944 	 * the program and protocol logic probably is
945 	 */
946 #ifdef DR_DEBUG
947 	if (DR11 & 1)
948 		printf(
949 "\ndrstrat: about to GO..,dr_cmd:%lx,drstat:%lx,drcnt:%ld,cdata:%lx,OP:%ld",
950 		    dra->dr_cmd, rsaddr->dr_cstat, rsaddr->dr_range,
951 		    rsaddr->dr_data, dra->dr_op);
952 #endif
953 	/*
954 	 * Update function latches may have been done already by drioctl() if
955 	 * request from drioctl()
956 	 */
957 	if (dra->dr_cmd & DR_DFCN) {		/* deferred function write */
958 		dra->dr_cmd &= ~DR_DFCN;	/* Clear request */
959 		go = dra->dr_cmd & DR_FMSK;	/* mask out fcn bits */
960 		rsaddr->dr_cstat = go;		/* Write it to the board */
961 	}
962 	/* Clear dmaf and attf to assure a clean dma start */
963 	rsaddr->dr_pulse = RATN|RDMA|RPER;
964 	rsaddr->dr_cstat = IENB|GO|CYCL|dra->dr_op; /* GO...... */
965 	/*
966 	 * Now check for software cycle request -- usually
967 	 * by transmitter in link mode.
968 	 */
969 	if (dra->dr_cmd & DR_PCYL) {
970 		dra->dr_cmd &= ~DR_PCYL;	/* Clear request */
971 		rsaddr->dr_pulse = CYCL;	/* Use pulse register again */
972 	}
973 	/*
974 	 * Now check for deferred ACLO FCNT2 pulse request -- usually to tell
975 	 * the transmitter (via its attention) that we have enabled dma.
976 	 */
977 	if (dra->dr_cmd & DR_DACL) {
978 		dra->dr_cmd &= ~DR_DACL;	/* Clear request */
979 		rsaddr->dr_pulse = FCN2;	/* Use pulse register again */
980 	}
981 }
982 #endif  NDR
983