|
|
1.1 root 1: /* ******************************************************************** */
2: /* */
3: /* METHEUS Corporation */
4: /* */
5: /* UNIX - DMA Interface Driver Source Code */
6: /* */
7: /* This program and the subroutines implemented thereby are */
8: /* proprietary information of Metheus Corporation and may not */
9: /* be reproduced, or disclosed or released to, or used by any */
10: /* other person without the express written consent of Metheus */
11: /* Corporation. */
12: /* */
13: /* (c) 1983 Metheus Corporation */
14: /* All rights reserved */
15: /* */
16: /* UNIX DR-11W DMA Interface Software by Ed Mills */
17: /* */
18: /* Version: UNIX DMA Interface Driver low-level (OM) routines */
19: /* Release: 1.0 */
20: /* Date: May 15, 1983 */
21: /* */
22: /* */
23: /* */
24: /* FUNCTIONAL DESCRIPTION: */
25: /* */
26: /* OPEN: */
27: /* omopen initializes the device and allows */
28: /* IO to commence. Only one user may have the */
29: /* device open at any given time. */
30: /* omopen sets the read mode to no stall and */
31: /* and the timeout period to 1 second. (see below) */
32: /* omopen sets the write mode to no stall and */
33: /* and the timeout period to 1 minute. (see below) */
34: /* */
35: /* CLOSE: */
36: /* omclose disallows further IO and makes the */
37: /* device available for another user to open. */
38: /* */
39: /* READ: */
40: /* omread has two modes, stall and no stall. */
41: /* In stall mode omread behaves as a standard */
42: /* read. It stalls until the requested amount */
43: /* of data has been read and then returns. */
44: /* In no stall mode omread waits for the timeout */
45: /* period (set via ioctl) to expire. If the */
46: /* requested data is available before the end of */
47: /* the timeout period, it is returned. If not, */
48: /* then as much data as was available is returned. */
49: /* In either case, the user level read returns the */
50: /* actual number read. */
51: /* Since the OMEGA 440 can only transmit words, */
52: /* the count requested from omread must be even */
53: /* or an IO error will be generated. */
54: /* */
55: /* WRITE: */
56: /* omwrite transmits the requested number of bytes */
57: /* to the device. Like READ, WRITE has two modes, */
58: /* stall and no stall which behave similarly to */
59: /* omread's. */
60: /* Since the OMEGA 440 can only transmit words, */
61: /* the count sent to omwrite must be even or an */
62: /* IO error will be generated. */
63: /* */
64: /* IOCTL: */
65: /* omioctl has 14 commands, OM_SETRSTALL, */
66: /* OM_SETNORSTALL, OM_GETRSTALL,, OM_SETRTIMEOUT, */
67: /* OM_GETRTIMEOUT, OM_SETWSTALL, OM_SETNOWSTALL, */
68: /* OM_GETWSTALL, OM_SETWTIMEOUT, OM_GETWTIMEOUT, */
69: /* OM_WRITEREADY, OM_READREADY, OM_BUSY, */
70: /* and OM_RESET. */
71: /* */
72: /* OM_SETRSTALL: */
73: /* Set omread to stall mode. */
74: /* */
75: /* OM_SETNORSTALL: */
76: /* Set omread to no stall mode. */
77: /* */
78: /* OM_GETRSTALL: */
79: /* Returns true if in read stall mode. */
80: /* */
81: /* OM_SETRTIMEOUT: */
82: /* Sets the read stall mode timeout period in */
83: /* tenths of a second. */
84: /* */
85: /* OM_GETRTIMEOUT: */
86: /* Returns the read stall mode timeout period in */
87: /* tenths of a second. */
88: /* */
89: /* OM_SETWSTALL: */
90: /* Set omwrite to stall mode. */
91: /* */
92: /* OM_SETNOWSTALL: */
93: /* Set omwrite to no stall mode. */
94: /* */
95: /* OM_GETWSTALL: */
96: /* Returns true if in write stall mode. */
97: /* */
98: /* OM_SETWTIMEOUT: */
99: /* Sets the write stall mode timeout period in */
100: /* tenths of a second. */
101: /* */
102: /* OM_GETWTIMEOUT: */
103: /* Returns the write stall mode timeout period in */
104: /* tenths of a second. */
105: /* */
106: /* OM_WRITEREADY: */
107: /* Returns a value of 1 if the device can accept */
108: /* data, 0 otherwise. Internally this is the */
109: /* DR11-W STAT A bit. */
110: /* */
111: /* OM_READREADY: */
112: /* Returns a value of 1 if the device has data */
113: /* to be read, 0 otherwise. Internally this is */
114: /* the DR11-W STAT B bit. */
115: /* */
116: /* OM_BUSY: */
117: /* Returns a value of 1 if the device is busy, */
118: /* 0 otherwise. Internally this is the DR11-W */
119: /* STAT C bit. */
120: /* */
121: /* OM_RESET: */
122: /* Resets the OMEGA to its power on condition */
123: /* by asserting the CSR MAINTENANCE bit. */
124: /* */
125: /* */
126: /* CAVEATS: */
127: /* */
128: /* This driver is designed to allow multiple devices, */
129: /* although it has only been tested with one. */
130: /* This driver should also function with the DR11-B, */
131: /* although this hasn't been tested either. */
132: /* */
133: /* USER NOTES: */
134: /* */
135: /* All IO is done with an even number of bytes. Hence, */
136: /* when writing, a zero byte should be appended on the */
137: /* end of odd length byte arrays. This must only be done */
138: /* between commands, never within one. When reading, the */
139: /* user must gaurentee that there is an even number number */
140: /* of bytes to be read. i.e. send the read pixel command */
141: /* twice. */
142: /* */
143: /* Data pending to be read can prevent write operations. */
144: /* Hopefully, one always knows when there is data to be */
145: /* read. If not, one can read 2 bytes at a time until the */
146: /* READREADY ioctl clears. CLEARINPUT_OM() in om-dmacros.h */
147: /* does this. */
148: /* */
149: /* If the OMEGA ever does hang, typing ^C's on the */
150: /* terminal and THEN cycling the OMEGA's power seems */
151: /* to fix things. */
152: /* */
153: /* */
154: /* INSTALLATION: */
155: /* */
156: /* The standard DR11-W parameters are, */
157: /* */
158: /* Base address 0772410 */
159: /* CSR address 0772414 */
160: /* Interrupt vector 0124 */
161: /* Interrupt priority 5 */
162: /* */
163: /* The following line should be in the system configuration file. */
164: /*
165: device om0 at uba? csr 0172414 vector omintr
166: /* */
167: /* The configure routine should reflect the new device. */
168: /* (/usr/beaver/usr/sys/dev/conf.c on vlsi-vax.) */
169: /* */
170: /* For vlsi-vax the following was added,
171:
172: #include "om.h"
173: #if NOM > 0
174: int omopen(),omclose(),omread(),omwrite(),omioctl();
175: #else
176: #define omopen nodev
177: #define omclose nodev
178: #define omread nodev
179: #define omwrite nodev
180: #define omioctl nodev
181: #endif
182:
183: struct cdevsw cdevsw[] =
184: {
185: omopen, omclose, omread, omwrite,
186: omioctl, nulldev, nodev, 0,
187: 0,
188: };
189: */
190: /* ******************************************************************** */
191: /* */
192: /* Finally, om.h should be put in the configuration directory */
193: /* to define NOM. */
194: /* */
195: /* ******************************************************************** */
196:
197: #include "om.h"
198: #if NOM > 0
199:
200: #include "../h/param.h"
201: #include "../h/dir.h"
202: #include "../h/user.h"
203: #include "../h/buf.h"
204: #include "../h/systm.h"
205: #include "../h/ubavar.h"
206: #include <sys/om-consts.h>
207:
208: #define OMPRI (PZERO)
209:
210: struct omdevice {
211: unsigned short WC; /* 2410 Word count. */
212: unsigned short BAR; /* 2412 Bus address register. */
213: unsigned short CSR_EIR; /* 2414 Control and status register -
214: Error and information register. */
215: /* We never use the EIR. We should always
216: write CSR bit 15 as a zero. */
217: unsigned short IDR_ODR; /* 2416 Input data register -
218: Output data register. */
219: };
220:
221: /* DR11-W CSR register bits. */
222: #define OM_ERROR 0100000
223: #define OM_NEXMEM 0040000
224: #define OM_ATTN 0020000
225: #define OM_MAINT 0010000
226: #define OM_STATA 0004000
227: #define OM_STATB 0002000
228: #define OM_STATC 0001000
229: #define OM_CYCLE 0000400
230: #define OM_READY 0000200
231: #define OM_IENABLE 0000100
232: #define OM_XBA 0000060
233: #define OM_FUNCTION3 0000010
234: #define OM_FUNCTION2 0000004
235: #define OM_FUNCTION1 0000002
236: #define OM_GO 0000001
237:
238: /* Amounts to shift by to get the status bits from the CSR. */
239: #define OM_STATA_SHIFT 11
240: #define OM_STATB_SHIFT 10
241: #define OM_STATC_SHIFT 9
242:
243: /* DR11-W EIR register bits. OM_ERROR, OM_NEXMEM, and OM_ATTN also apply. */
244: #define OM_MCREQ 0010000
245: #define OM_ACLO 0004000
246: #define OM_PARERR 0002000
247: #define OM_BURSTDL 0001000
248: #define OM_NCBURST 0000400
249: #define OM_EIRREG 0000001
250:
251: /* The following are specific to the OMEGA 440 as interfaced to the DR11-W. */
252: #define OM_READ OM_FUNCTION1 /* Read from OMEGA. */
253: #define OM_WRITE 0 /* Write to OMEGA. */
254: #define OM_WAKEUP OM_FUNCTION3 /* Have OMEGA assert ATTN line which
255: will cause an error, stop any pending
256: DMA, and cause an interrupt if
257: enabled. */
258: #define OM_WRITE_SHIFT OM_STATA_SHIFT /* Ready to write bit. */
259: #define OM_READ_SHIFT OM_STATB_SHIFT /* Ready to read bit. */
260: #define OM_BUSY_SHIFT OM_STATC_SHIFT /* Busy bit. */
261:
262: struct om_softc {
263: short sc_state; /* Current state of the device. */
264: short sc_operation; /* Current operation (read or write). */
265: unsigned int
266: sc_rtimoticks, /* Number of ticks before timing out
267: on a no stall read. */
268: sc_wtimoticks, /* Number of ticks before timing out
269: on a no stall write. */
270: sc_currenttimo; /* The number of the current timeout call
271: to omrwtimo. */
272: int sc_ubinfo; /* UNIBUS information. */
273: int sc_ubadd; /* physical unibus address for cursor */
274: unsigned char sc_curbuf[512]; /* buffer for cursor dma commands */
275: } om_softc[NOM];
276:
277:
278: /* sc_state bits */
279: #define OMSC_OPEN (1 << 0) /* The device is open. */
280: #define OMSC_BUSY (1 << 1) /* The device is busy. */
281: #define OMSC_NORSTALL (1 << 2) /* The device is set to use
282: no stall mode for reads. */
283: #define OMSC_NOWSTALL (1 << 3) /* The device is set to use
284: no stall mode for writes. */
285: #define OMSC_TIMEDOUT (1 << 4) /* The device timed out on a
286: stall mode read or write. */
287:
288: struct uba_device *omdinfo[NOM];
289:
290: #define OMUNIT(dev) (minor(dev))
291:
292: struct buf rombuf[NOM];
293:
294: int omprobe(), omattach(), omstrategy(), omrwtimo();
295: unsigned minomph();
296:
297: u_short omstd[] = { 0772410, 0772430, 0 };
298: struct uba_driver omdriver = {
299: omprobe, /* Address of probe routine to cause an interrupt. */
300: 0, /* ? */
301: omattach, /* Address of attach routine to set IO address. */
302: 0, /* ? */
303: omstd, /* Address of the device (omdevice) on the UNIBUS. */
304: "om", /* Name of the device. */
305: omdinfo, /* UBA device information for the device. */
306: 0, 0
307: };
308:
309:
310: /* OMPROBE */
311: /* Omprobe generates an interrupt when called by asserting the OMEGA attention
312: line with interrupts enabled. */
313:
314: omprobe(reg)
315: caddr_t reg;
316: {
317: register int br, cvec; /* value-result */
318: register struct omdevice *omaddr = (struct omdevice *)(reg-04);
319:
320: #ifdef lint
321: br = 0; cvec = br; br = cvec;
322: #endif
323: /* Stop any DMA and force an interrupt. */
324: omaddr->CSR_EIR = (OM_ATTN | OM_WAKEUP | OM_IENABLE);
325: DELAY(100);
326: omaddr->CSR_EIR = OM_IENABLE;
327: /* kludge */
328: br = 0x15;
329: switch ((int)omaddr & 070)
330: {
331: case 010:
332: cvec = 0124;
333: break;
334: case 030:
335: cvec = 0134;
336: break;
337: }
338: return (sizeof (struct omdevice));
339: }
340:
341:
342: /* OMATTACH */
343: /* Attach to and initialize the device. */
344:
345: omattach(ui) struct uba_device *ui;
346: {
347: register struct omdevice *omaddr;
348: register struct om_softc *omsp;
349:
350: /* Move the address back from the CSR to the begining of the device. */
351: ui->ui_addr -= 04;
352: ui->ui_physaddr -= 04;
353: omaddr = (struct omdevice *)ui->ui_addr;
354:
355: /* Initialize the DR11-W by setting then clearing MAINT in the CSR
356: with CYCLE and GO clear. */
357: omaddr->CSR_EIR = 0;
358: omaddr->CSR_EIR = OM_MAINT;
359: DELAY(100);
360: omaddr->CSR_EIR = 0;
361:
362: omaddr->CSR_EIR = OM_IENABLE; /* Enable interrupts. */
363:
364: /* Set the current timeout to zero. */
365: /* What I want here is for OMUNIT(ui->ui_unit) to give the minor
366: device number of each device as we attach to it. I think that's
367: what it does. When there is only one device, I know that's what
368: it does. I check range just to make sure things never get out
369: of hand. Since all we need from sc_currenttimo is that it be
370: distinct each time we increment it, we don't really care where
371: it starts. */
372: omsp = &om_softc[OMUNIT(ui->ui_unit)];
373: if ((OMUNIT(ui->ui_unit) >= 0) && (OMUNIT(ui->ui_unit) < NOM))
374: omsp->sc_currenttimo = 0;
375:
376: /* allocate a physical unibus dma buffer for cursor tracking */
377: if(omsp->sc_ubadd == 0)
378: { omsp->sc_ubadd = uballoc(0, /* which unibus adapter */
379: (caddr_t)omsp->sc_curbuf,
380: sizeof(omsp->sc_curbuf), 0);
381: if(omsp->sc_ubadd == 0)
382: panic("UB AD 0 in omattach");
383: }
384: }
385:
386: /* OMOPEN */
387: /* Open the device. */
388:
389: omopen(dev)
390: dev_t dev;
391: {
392: register struct om_softc *sc;
393: register struct uba_device *ui;
394: register struct omdevice *omaddr;
395:
396: if ((OMUNIT(dev) >= NOM) || /* No such device. */
397: ((ui = omdinfo[OMUNIT(dev)]) == 0)) { /* Device not there. */
398: u.u_error = ENXIO;
399: return;
400: }
401:
402: if ((ui->ui_alive) == 0) { /* Dead. */
403: u.u_error = EIO;
404: return;
405: }
406:
407: if (((sc = &om_softc[OMUNIT(dev)])->sc_state)&OMSC_OPEN) {
408: u.u_error = EBUSY; /* Already open. */
409: return;
410: }
411:
412: /* Set only the open bit in the state. */
413: (sc->sc_state) = OMSC_OPEN;
414:
415: /* Set the read no stall timeout to 1 second. */
416: (sc->sc_rtimoticks) = hz;
417:
418: /* Set the write no stall timeout to 1 minute. */
419: (sc->sc_wtimoticks) = hz*60;
420:
421: /* Start the self-kicker. */
422: omtimo(dev);
423:
424: /* Stop any DMA without causing an interrupt. (No OM_IENABLE bit.) */
425: omaddr = (struct omdevice *)ui->ui_addr;
426: omaddr->CSR_EIR = (OM_WAKEUP | OM_ATTN);
427: DELAY(100);
428:
429: /* ************************************************************************ */
430: /*
431: /* The following commented piece of code will cause the OMEGA to do a
432: /* hardware reset each time it is opened. This gaurentees the device to
433: /* be in a known state, but doesn't allow a program to manipulate an
434: /* image produced by a previous program since it clears the screen.
435: /*
436: /* ************************************************************************ */
437: /*
438: /* /* Initialize the DR11-W by setting then clearing MAINT in the CSR
439: /* with CYCLE and GO clear. */
440: /* omaddr->CSR_EIR = 0;
441: /* omaddr->CSR_EIR = OM_MAINT;
442: /* DELAY(100);
443: /* omaddr->CSR_EIR = 0;
444: /*
445: /* /* Wait for the omega to become ready. */
446: /* while((omaddr->CSR_EIR)&OM_STATC)
447: /* sleep((caddr_t)sc, OMPRI);
448: /*
449: /* ************************************************************************ */
450:
451: /* Enable interrupts. */
452: omaddr->CSR_EIR = OM_IENABLE;
453:
454:
455: /* Make sure the device is really there and OK. */
456: /* forget this! */
457: /* if (((omaddr->CSR_EIR) >> OM_BUSY_SHIFT) & 1) {
458: /* u.u_error = EIO;
459: /* sc->sc_state = 0;
460: /* return;
461: /* }
462: */
463: }
464:
465:
466: /* OMCLOSE */
467: /* Close the device. */
468:
469: omclose(dev)
470: dev_t dev;
471: {
472: register struct om_softc *sc = &om_softc[OMUNIT(dev)];
473:
474: /* Set the state blank. */
475: sc->sc_state = 0;
476: }
477:
478:
479: /* OMREAD */
480: /* Reads characters from the device. If in stall mode, the read will be the
481: standard read which will not return until the requested number of characters
482: have been read. If in no stall mode, then the read will return after an
483: interval set in omioctl and report how many characters it read.
484: The count must be even since the DMA is by words. */
485:
486: omread(dev)
487: dev_t dev;
488: {
489: register struct om_softc *sc = &om_softc[OMUNIT(dev)];
490: register struct omdevice *omaddr =
491: (struct omdevice *)omdinfo[OMUNIT(dev)]->ui_addr;
492: register int spl;
493:
494: /* Make sure that the count is even. */
495: if (u.u_count & 1) {
496: u.u_error = EINVAL;
497: return;
498: }
499:
500: /* Set the DR11-W to read. */
501: sc->sc_operation = OM_READ;
502:
503: /* The following is to make up for something physio should really do
504: for us. If bp->b_resid has been left non-zero by the last call,
505: (ie an error), and the present call has a count of zero then the
506: old residual will be returned as the count. To correct this, we just
507: set the residual to zero before we start. */
508: rombuf[OMUNIT(dev)].b_resid = 0;
509:
510: /* Are we in no stall or stall mode? */
511: if ((sc->sc_state) & OMSC_NORSTALL) {
512:
513: /* We're in no stall mode. */
514:
515: /* Start the timer running. */
516: /* Don't let anything stop us once the timer's running. */
517: spl = spl6();
518: timeout(omrwtimo, (caddr_t)
519: ( ((sc->sc_currenttimo)<<8) | OMUNIT(dev) ),
520: (sc->sc_rtimoticks));
521:
522: /* Perform the read. */
523: physio(omstrategy, &rombuf[OMUNIT(dev)], dev, B_READ, minomph);
524: if (u.u_error) (void) splx(spl);
525:
526: /* Update the current timeout number. */
527: (sc->sc_currenttimo)++;
528:
529: /* Did we timeout? */
530: if ((sc->sc_state) & OMSC_TIMEDOUT) {
531:
532: /* Clear the timeout. */
533: (sc->sc_state) &= (~OMSC_TIMEDOUT);
534:
535: /* Patch up the error. */
536:
537: /* We made the error ourself, ignore it. */
538: u.u_error = 0;
539: }
540: }
541:
542: else {
543:
544: /* We're in stall mode. */
545:
546: /* Perform the read. */
547: physio(omstrategy, &rombuf[OMUNIT(dev)], dev, B_READ, minomph);
548: }
549: }
550:
551:
552: /* OMWRITE */
553: /* omwrite writes the passed data to the device using DMA.
554: The count must be even since the DMA is by words. */
555: /* Timeouts are handled as in omread. */
556:
557: omwrite(dev)
558: dev_t dev;
559: {
560: register struct om_softc *sc = &om_softc[OMUNIT(dev)];
561: register int spl;
562:
563: /* Make sure that the count is even. */
564: if (u.u_count & 1) {
565: u.u_error = EINVAL;
566: return;
567: }
568:
569: /* This call is to write around a system bug--on a B_WRITE call to
570: physio, the system checks to see if the user has read access to the
571: requested block. Then it locks necessary pages in virtual memory.
572: It checks for write access in the course of this, and, if the user
573: does not have it, panics ("vslock"). So, if the user sends, say, an
574: address in his code (0 is an example), the system crashes. So I
575: start by checking for write access. */
576: if (useracc(u.u_base,u.u_count,B_WRITE) == NULL) {
577: u.u_error = EFAULT;
578: return;
579: }
580:
581: /* Set the DR11-W to write. */
582: sc->sc_operation = OM_WRITE;
583:
584: /* The following is to make up for something physio should really do
585: for us. If bp->b_resid has been left non-zero by the last call,
586: (ie an error), and the present call has a count of zero then the
587: old residual will be returned as the count. To correct this, we just
588: set the residual to zero before we start. */
589: rombuf[OMUNIT(dev)].b_resid = 0;
590:
591: /* Are we in no stall or stall mode? */
592: if ((sc->sc_state) & OMSC_NOWSTALL) {
593:
594: /* We're in no stall mode. */
595:
596: /* Start the timer running. */
597: /* Don't let anything stop us once the timer's running. */
598: spl = spl6();
599: timeout(omrwtimo, (caddr_t)
600: ( ((sc->sc_currenttimo)<<8) | OMUNIT(dev) ),
601: (sc->sc_wtimoticks));
602:
603: /* Perform the write. */
604: physio(omstrategy, &rombuf[OMUNIT(dev)], dev,
605: B_WRITE, minomph);
606: if (u.u_error) (void) splx(spl);
607:
608: /* Update the current timeout number. */
609: (sc->sc_currenttimo)++;
610:
611: /* Did we timeout? */
612: if ((sc->sc_state) & OMSC_TIMEDOUT) {
613:
614: /* Clear the timeout. */
615: (sc->sc_state) &= (~OMSC_TIMEDOUT);
616:
617: /* Patch up the error. */
618:
619: /* We made the error ourself, ignore it. */
620: u.u_error = 0;
621: }
622: }
623:
624: else {
625:
626: /* We're in stall mode. */
627:
628: /* Perform the write. */
629: physio(omstrategy, &rombuf[OMUNIT(dev)], dev,
630: B_WRITE, minomph);
631: }
632: }
633:
634:
635: /* OMIOCTL */
636: /* IO control function. */
637:
638: omioctl(dev, cmd, addr, flag)
639: dev_t dev;
640: int cmd;
641: register caddr_t addr;
642: int flag;
643:
644: {
645: register struct om_softc *sc = &om_softc[OMUNIT(dev)];
646: register struct omdevice *omaddr =
647: (struct omdevice *)omdinfo[OMUNIT(dev)]->ui_addr;
648: int temp;
649:
650: switch(cmd) {
651:
652: case OM_SETRSTALL:
653:
654: /* Set read stall mode. */
655: (sc->sc_state) &= (~OMSC_NORSTALL);
656: break;
657:
658: case OM_SETNORSTALL:
659:
660: /* Set read stall mode. */
661: (sc->sc_state) |= OMSC_NORSTALL;
662: break;
663:
664: case OM_GETRSTALL:
665:
666: /* Returns true if in read stall mode. */
667: temp = (!((sc->sc_state)&OMSC_NORSTALL));
668: if (copyout((caddr_t)&temp, addr, sizeof(temp))) {
669: u.u_error = EFAULT;
670: }
671: break;
672:
673: case OM_SETRTIMEOUT:
674:
675: /* Set the number of ticks before a no stall read times out.
676: The argument is given in tenths of a second. */
677: if (copyin(addr, (caddr_t)&temp, sizeof(temp))) {
678: u.u_error = EFAULT;
679: break;
680: }
681: if (temp < 1) {
682: u.u_error = EINVAL;
683: temp = 1;
684: }
685: (sc->sc_rtimoticks) = (temp * hz )/10;
686: break;
687:
688: case OM_GETRTIMEOUT:
689:
690: /* Returns the number of tenths of seconds before
691: a no stall read times out. */
692: /* The argument is given in tenths of a second. */
693: temp = ((sc->sc_rtimoticks)*10)/hz;
694: if (copyout((caddr_t)&temp, addr, sizeof(temp))) {
695: u.u_error = EFAULT;
696: }
697: break;
698:
699: case OM_SETWSTALL:
700:
701: /* Set write stall mode. */
702: (sc->sc_state) &= (~OMSC_NOWSTALL);
703: break;
704:
705: case OM_SETNOWSTALL:
706:
707: /* Set write stall mode. */
708: (sc->sc_state) |= OMSC_NOWSTALL;
709: break;
710:
711: case OM_GETWSTALL:
712:
713: /* Returns true if in write stall mode. */
714: temp = (!((sc->sc_state)&OMSC_NOWSTALL));
715: if (copyout((caddr_t)&temp, addr, sizeof(temp))) {
716: u.u_error = EFAULT;
717: }
718: break;
719:
720: case OM_SETWTIMEOUT:
721:
722: /* Set the number of ticks before a no stall write times out.
723: The argument is given in tenths of a second. */
724: if (copyin(addr, (caddr_t)&temp, sizeof(temp))) {
725: u.u_error = EFAULT;
726: break;
727: }
728: if (temp < 1) {
729: u.u_error = EINVAL;
730: temp = 1;
731: }
732: (sc->sc_wtimoticks) = (temp * hz )/10;
733: break;
734:
735: case OM_GETWTIMEOUT:
736:
737: /* Returns the number of tenths of seconds before
738: a no stall write times out. */
739: /* The argument is given in tenths of a second. */
740: temp = ((sc->sc_wtimoticks)*10)/hz;
741: if (copyout((caddr_t)&temp, addr, sizeof(temp))) {
742: u.u_error = EFAULT;
743: }
744: break;
745:
746: case OM_WRITEREADY:
747:
748: /* Returns a value of 1 if the device can accept
749: data, 0 otherwise. Internally this is the
750: DR11-W STAT A bit. */
751: temp = (((omaddr->CSR_EIR) >> OM_WRITE_SHIFT) & 1);
752: if (copyout((caddr_t)&temp, addr, sizeof(temp))) {
753: u.u_error = EFAULT;
754: }
755: break;
756:
757: case OM_READREADY:
758:
759: /* Returns a value of 1 if the device has data
760: to be read, 0 otherwise. Internally this is
761: the DR11-W STAT B bit. */
762: temp = (((omaddr->CSR_EIR) >> OM_READ_SHIFT) & 1);
763: if (copyout((caddr_t)&temp, addr, sizeof(temp))) {
764: u.u_error = EFAULT;
765: }
766: break;
767:
768: case OM_BUSY:
769:
770: /* Returns a value of 1 if the device is busy,
771: 0 otherwise. Internally this is the DR11-W
772: STAT C bit. */
773: temp = (((omaddr->CSR_EIR) >> OM_BUSY_SHIFT) & 1);
774: if (copyout((caddr_t)&temp, addr, sizeof(temp))) {
775: u.u_error = EFAULT;
776: }
777: break;
778:
779: case OM_RESET:
780:
781: /* Resets the OMEGA to its power on condition
782: by asserting the CSR MAINTENANCE bit. */
783:
784: /* Initialize the DR11-W by setting then clearing MAINT
785: in the CSR with CYCLE and GO clear. */
786: omaddr->CSR_EIR = 0;
787: omaddr->CSR_EIR = OM_MAINT;
788: DELAY(100);
789: omaddr->CSR_EIR = 0;
790:
791: /* Wait for the omega to become ready. */
792: /* forget this! */
793: /* while((omaddr->CSR_EIR)&OM_STATC)
794: /* tsleep((caddr_t)sc, OMPRI, 30);
795: */
796: break;
797:
798: default:
799:
800: /* Flag the error. */
801: u.u_error = EINVAL;
802: break;
803:
804: }
805:
806: return;
807: }
808:
809:
810: /* OMSTRATEGY */
811: /* Routine to determine the DMA strategy for physio. */
812:
813: omstrategy(bp)
814: register struct buf *bp;
815: {
816: register int e;
817: register int spl;
818: register struct om_softc *sc = &om_softc[OMUNIT(bp->b_dev)];
819: register struct uba_device *ui = omdinfo[OMUNIT(bp->b_dev)];
820: register struct omdevice *omaddr = (struct omdevice *)ui->ui_addr;
821:
822: spl = spl6();
823: while (sc->sc_state & OMSC_BUSY)
824: tsleep((caddr_t)sc, OMPRI, 30);
825: sc->sc_state |= OMSC_BUSY;
826: sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
827: omstart(bp->b_dev, bp->b_bcount);
828: e = omwait(bp->b_dev);
829: (bp->b_resid) = u.u_count - (bp->b_bcount) +
830: (((-(omaddr->WC))&0xFFFF)<<1);
831: (void) splx(spl);
832: ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
833: sc->sc_state &= ~OMSC_BUSY;
834: iodone(bp);
835: if (e)
836: /* Cause physio to terminate and
837: geterror to give an EIO error. */
838: (bp->b_flags) |= B_ERROR;
839: wakeup((caddr_t)sc);
840: }
841:
842:
843: /* MINOMPH */
844: /* Set the maximum physical transfer size. */
845:
846: unsigned
847: minomph(bp)
848: struct buf *bp;
849: {
850:
851: if (bp->b_bcount > OM_BLOCKSIZE)
852: bp->b_bcount = OM_BLOCKSIZE;
853: }
854:
855:
856: /* OMSTART */
857: /* Start a DMA IO transfer. */
858:
859: omstart(dev, count)
860: dev_t dev;
861: long count;
862: {
863: register int spl;
864: register struct om_softc *sc = &om_softc[OMUNIT(dev)];
865: register struct omdevice *omaddr =
866: (struct omdevice *)omdinfo[OMUNIT(dev)]->ui_addr;
867: int i;
868:
869: spl = spl7(); /* don't interrupt me with a cursor */
870: for (i = 100; (omaddr->CSR_EIR & OM_READY == 0) && i; --i)
871: ; /* wait in case cursor dma active */
872: if (i == 0)
873: {
874: (void) splx(spl);
875: printf("omstart: device busy\n");
876: u.u_error = EIO;
877: return;
878: }
879:
880: /* Set the DMA buffer address. */
881: (omaddr->BAR) = (sc->sc_ubinfo);
882:
883: /* Set the word count to the 2's complement
884: of the count in words. */
885: (omaddr->WC) = (-(count>>1));
886:
887: /* Start the transfer with interrupts enabled. */
888: (omaddr->CSR_EIR) = (OM_IENABLE | (sc->sc_operation) |
889: ((sc->sc_ubinfo >> 12) & OM_XBA));
890: (omaddr->CSR_EIR) = (OM_IENABLE | (sc->sc_operation) |
891: ((sc->sc_ubinfo >> 12) & OM_XBA)| OM_GO);
892:
893: (void) splx(spl);
894: return;
895: }
896:
897:
898: /* OMRWTIMO */
899: /* Routine to deal with no stall read/write timeouts. If the read/write
900: completed by itself, we just return. If not, we mark a timeout and
901: cause a DMA error and interrupt. */
902:
903: omrwtimo(timeoutinfo)
904: register unsigned int timeoutinfo;
905: /* The low 8 bits of timeoutinfo are the minor device number.
906: The remaining higher bits are the current timeout number. */
907: {
908: register int minordev = OMUNIT(timeoutinfo);
909: register struct om_softc *sc = &om_softc[minordev];
910: register struct omdevice *omaddr =
911: (struct omdevice *)omdinfo[minordev]->ui_addr;
912:
913: /* If this is not the timeout that omread/omwrite is waiting for
914: then we should just go away. */
915: if ((timeoutinfo&(~0377)) != ((sc->sc_currenttimo)<<8)) return;
916:
917: /* Mark that the device timed out. */
918: (sc->sc_state) |= OMSC_TIMEDOUT;
919:
920: /* Send an OM_WAKEUP signal to halt any pending DMA and generate
921: an interrupt so that omwait will see the error and tell everyone
922: the transfer is done. */
923: omaddr->CSR_EIR = (OM_ATTN | OM_WAKEUP | OM_IENABLE);
924: }
925:
926:
927: /* OMWAIT */
928: /* Wait for the DR11-W to come ready.
929: Return a non-zero value if there is an error. */
930:
931: omwait(dev)
932: dev_t dev;
933: {
934: register struct omdevice *omaddr =
935: (struct omdevice *)omdinfo[OMUNIT(dev)]->ui_addr;
936: register struct om_softc *sc = &om_softc[OMUNIT(dev)];
937: register int e;
938:
939: while (!((e = (omaddr->CSR_EIR)) & OM_READY)) {
940: tsleep((caddr_t)sc, OMPRI, 30);
941: }
942:
943: /* Reset any error conditions. */
944: (omaddr->CSR_EIR) = OM_IENABLE;
945:
946: return (e & OM_ERROR);
947: }
948:
949:
950: /* OMINTR */
951: /* Wakup any process waiting for an interrupt. */
952:
953: omintr(dev)
954: dev_t dev;
955: {
956: register struct om_softc *sc = &om_softc[OMUNIT(dev)];
957:
958: wakeup((caddr_t)sc);
959: }
960:
961:
962: /* OMTIMO */
963: /* Kick the driver every second. */
964:
965: omtimo(dev)
966: dev_t dev;
967: {
968: register struct om_softc *sc = &om_softc[OMUNIT(dev)];
969:
970: if (sc->sc_state&OMSC_OPEN)
971: timeout(omtimo, (caddr_t)dev, hz);
972: omintr(dev);
973: }
974:
975: omcur(dev, x, y) /* position cursor - called from bpd driver */
976: dev_t dev;
977: {
978: register struct uba_device *ui = omdinfo[minor(dev)];
979: register struct omdevice *omp = (struct omdevice *)(ui->ui_addr);
980: register struct om_softc *oms = &om_softc[minor(dev)];
981: register i, j;
982: int spl;
983:
984: spl = spl6();
985: if( (oms->sc_state & OMSC_OPEN == 0) ||
986: (oms->sc_state & OMSC_BUSY) ||
987: (omp->CSR_EIR & OM_READY == 0) )
988: return;
989: x *= 1280; x /= 1024; /* scale x coordinate */
990: y = 1024 - y; /* negate y coordinate */
991: /* setup cursor command */
992: oms->sc_curbuf[0] = 0x52; /* movp1 opcode */
993: oms->sc_curbuf[1] = x & 0xFF;
994: oms->sc_curbuf[2] = (x >> 8) & 0x07;
995: oms->sc_curbuf[3] = y & 0xFF;
996: oms->sc_curbuf[4] = (y >> 8) & 0x07;
997: oms->sc_curbuf[5] = 0x71; /* display cursor opcode */
998:
999: omp->BAR = oms->sc_ubadd; /* setup dma */
1000: omp->WC = -3;
1001: omp->CSR_EIR = OM_WRITE|(OM_XBA & (oms->sc_ubadd >> 12));
1002: omp->CSR_EIR = OM_WRITE|OM_GO|(OM_XBA & (oms->sc_ubadd >> 12));
1003: splx(spl);
1004: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.