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