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