xref: /csrg-svn/sys/vax/uba/va.c (revision 287)
1*287Sbill /*	va.c	3.6	06/22/80	*/
241Sbill 
341Sbill #include "../h/param.h"
441Sbill #include "../h/dir.h"
541Sbill #include "../h/user.h"
641Sbill #include "../h/buf.h"
741Sbill #include "../h/systm.h"
841Sbill #include "../h/map.h"
941Sbill #include "../h/pte.h"
1041Sbill #include "../h/uba.h"
1141Sbill #include "../h/vcmd.h"
1241Sbill 
1341Sbill /*
14*287Sbill  * Benson-Varian matrix printer/plotter
1541Sbill  * dma interface driver
1641Sbill  */
17*287Sbill int	vabdp = 1;
1841Sbill 
19*287Sbill unsigned minvaph();
2041Sbill 
2141Sbill #define	VAPRI	(PZERO-1)
2241Sbill 
23*287Sbill #define	ushort	unsigned short
24*287Sbill struct	varegs {
25*287Sbill 	ushort	vaba;
26*287Sbill 	short	vawc;
2741Sbill 	union {
28*287Sbill 		short	Vacsw;
2941Sbill 		struct {
30*287Sbill 			char Vacsl;
31*287Sbill 			char Vacsh;
32*287Sbill 		} vacsr;
33*287Sbill 	} vacs;
3441Sbill 	short	vadata;
3541Sbill };
3641Sbill 
37*287Sbill #define	vacsw	vacs.Vacsw
38*287Sbill #define	vacsh	vacs.vacsr.Vacsh
39*287Sbill #define	vacsl	vacs.vacsr.Vacsl
40*287Sbill 
4141Sbill #define	VAADDR	((struct varegs *)(UBA0_DEV + 0164000))
4241Sbill 
43*287Sbill /* vacsw bits */
44*287Sbill #define	ERROR		0100000		/* Some error has occurred */
45*287Sbill #define NPRTIMO		01000		/* DMA timeout error */
46*287Sbill #define NOTREADY	0400		/* Something besides NPRTIMO */
47*287Sbill #define DONE		0200
48*287Sbill #define	IENABLE		0100		/* Interrupt enable */
49*287Sbill #define	SUPPLIESLOW	04
50*287Sbill #define BOTOFFORM	02
51*287Sbill #define BYTEREVERSE	01		/* Reverse byte order in words */
5241Sbill 
53*287Sbill /* vacsh command bytes */
5441Sbill #define VAPLOT		0340
5541Sbill #define VAPRINT		0100
5641Sbill #define VAPRINTPLOT	0160
5741Sbill #define VAAUTOSTEP	0244
58*287Sbill #define VANOAUTOSTEP	0045		/* unused */
59*287Sbill #define	VAFORMFEED	0263		/* unused */
60*287Sbill #define	VASLEW		0265		/* unused */
61*287Sbill #define	VASTEP		0064		/* unused */
6241Sbill 
6341Sbill struct {
64*287Sbill 	char	va_open;
6541Sbill 	char	va_busy;
6641Sbill 	int	va_state;	/* State: bits are commands in vcmd.h. */
67*287Sbill 	int	va_wc;
6841Sbill 	int	va_bufp;
69*287Sbill 	struct	buf *va_bp;
70*287Sbill } va11;
7141Sbill int	va_ubinfo;
7241Sbill 
7341Sbill struct	buf rvabuf;		/* Used by physio for a buffer. */
7441Sbill 
7541Sbill vaopen()
7641Sbill {
7741Sbill 
78*287Sbill 	if (va11.va_open) {
7941Sbill 		u.u_error = ENXIO;
8041Sbill 		return;
8141Sbill 	}
82*287Sbill 	va11.va_open = 1;
83*287Sbill 	VAADDR->vawc = 0;
84*287Sbill 	va11.va_wc = 0;
85*287Sbill 	va11.va_state = 0;
86*287Sbill 	VAADDR->vacsl = IENABLE;
8741Sbill 	vatimo();
88*287Sbill 	vacmd(VPRINT);
8941Sbill 	if (u.u_error)
9041Sbill 		vaclose();
9141Sbill }
9241Sbill 
9341Sbill vastrategy(bp)
9441Sbill 	register struct buf *bp;
9541Sbill {
9641Sbill 	register int e;
9741Sbill 
98133Sbill 	(void) spl4();
99*287Sbill 	while (va11.va_busy)
100*287Sbill 		sleep((caddr_t)&va11, VAPRI);
101*287Sbill 	va11.va_busy = 1;
102*287Sbill 	va11.va_bp = bp;
103*287Sbill 	va_ubinfo = ubasetup(bp, vabdp);
104*287Sbill 	va11.va_bufp = va_ubinfo & 0x3ffff;
10541Sbill 	if (e = vaerror(DONE))
10641Sbill 		goto brkout;
107*287Sbill 	va11.va_wc = -(bp->b_bcount/2);
10841Sbill 	vastart();
109*287Sbill 	e = vaerror(DONE);	/* Wait for DMA to complete */
110*287Sbill 	va11.va_wc = 0;
111*287Sbill 	va11.va_bufp = 0;
11241Sbill 
113*287Sbill 	/*
114*287Sbill 	 * After printing a line of characters, VPRINTPLOT mode essentially
115*287Sbill 	 * reverts to VPLOT mode, plotting things until a new mode is set.
116*287Sbill 	 * This change is indicated by sending a VAAUTOSTEP command to
117*287Sbill 	 * the va.  We also change va_state to reflect this effective
118*287Sbill 	 * mode change.
11941Sbill 	 */
120*287Sbill 	if (va11.va_state & VPRINTPLOT) {
121*287Sbill 		va11.va_state = (va11.va_state & ~VPRINTPLOT) | VPLOT;
122*287Sbill 		VAADDR->vacsh = VAAUTOSTEP;
12341Sbill 		e |= vaerror(DONE);
12441Sbill 	}
125133Sbill 	(void) spl0();
12641Sbill brkout:
12741Sbill 	ubafree(va_ubinfo), va_ubinfo = 0;
128*287Sbill 	va11.va_bp = 0;
129*287Sbill 	va11.va_busy = 0;
13041Sbill 	iodone(bp);
13141Sbill 	if (e)
13241Sbill 		u.u_error = EIO;
133*287Sbill 	wakeup((caddr_t)&va11);
13441Sbill }
13541Sbill 
13641Sbill int	vablock = 16384;
13741Sbill 
13841Sbill unsigned
13941Sbill minvaph(bp)
14041Sbill struct buf *bp;
14141Sbill {
14241Sbill 	if (bp->b_bcount > vablock)
14341Sbill 		bp->b_bcount = vablock;
14441Sbill }
14541Sbill 
14641Sbill /*ARGSUSED*/
14741Sbill vawrite(dev)
14841Sbill {
14941Sbill 	physio(vastrategy, &rvabuf, dev, B_WRITE, minvaph);
15041Sbill }
15141Sbill 
15241Sbill /*
15341Sbill  * Vaerror waits until bit or ERROR gets set, then returns non-zero if
15441Sbill  * if it was ERROR that was set.
15541Sbill  */
15641Sbill vaerror(bit)
15741Sbill {
15841Sbill 	register int e;
15941Sbill 
160*287Sbill 	while ((e = VAADDR->vacsw & (bit|ERROR)) == 0)
161*287Sbill 		sleep((caddr_t)&va11, VAPRI);
16241Sbill 	return (e & ERROR);
16341Sbill }
16441Sbill 
16541Sbill vastart()
16641Sbill {
167*287Sbill 	if (va11.va_wc) {
168*287Sbill 		VAADDR->vaba = va11.va_bufp;
169*287Sbill 		VAADDR->vawc = va11.va_wc;
17041Sbill 		return;
17141Sbill 	}
17241Sbill }
17341Sbill 
17441Sbill /*ARGSUSED*/
17541Sbill vaioctl(dev, cmd, addr, flag)
17641Sbill 	register caddr_t addr;
17741Sbill {
17841Sbill 	register int vcmd;
17941Sbill 
18041Sbill 	switch (cmd) {
18141Sbill 
18241Sbill 	case VGETSTATE:
183*287Sbill 		(void) suword(addr, va11.va_state);
18441Sbill 		return;
18541Sbill 
18641Sbill 	case VSETSTATE:
18741Sbill 		vcmd = fuword(addr);
18841Sbill 		if (vcmd == -1) {
18941Sbill 			u.u_error = EFAULT;
19041Sbill 			return;
19141Sbill 		}
19241Sbill 		vacmd(vcmd);
19341Sbill 		return;
19441Sbill 
19541Sbill 	default:
19641Sbill 		u.u_error = ENOTTY;	/* Not a legal ioctl cmd. */
19741Sbill 		return;
19841Sbill 	}
19941Sbill }
20041Sbill 
201*287Sbill /*
202*287Sbill  * Send a command code to the va, and wait for it to complete.
203*287Sbill  * If an error occurs, u.u_error is set to EIO.
204*287Sbill  * In any case, update va11.va_state.
20541Sbill  */
20641Sbill vacmd(vcmd)
20741Sbill {
208133Sbill 	(void) spl4();
209*287Sbill 	(void) vaerror(DONE);		/* Wait for va to be ready */
21041Sbill 	switch (vcmd) {
21141Sbill 
21241Sbill 	case VPLOT:
21341Sbill 		/* Must turn on plot AND autostep modes. */
214*287Sbill 		VAADDR->vacsh = VAPLOT;
21541Sbill 		if (vaerror(DONE))
21641Sbill 			u.u_error = EIO;
217*287Sbill 		VAADDR->vacsh = VAAUTOSTEP;
21841Sbill 		break;
21941Sbill 
22041Sbill 	case VPRINT:
221*287Sbill 		VAADDR->vacsh = VAPRINT;
22241Sbill 		break;
22341Sbill 
22441Sbill 	case VPRINTPLOT:
225*287Sbill 		VAADDR->vacsh = VAPRINTPLOT;
22641Sbill 		break;
22741Sbill 	}
228*287Sbill 	va11.va_state =
229*287Sbill 		(va11.va_state & ~(VPLOT | VPRINT | VPRINTPLOT)) | vcmd;
23041Sbill 
23141Sbill 	if (vaerror(DONE))	/* Wait for command to complete. */
23241Sbill 		u.u_error = EIO;
233133Sbill 	(void) spl0();
23441Sbill }
23541Sbill 
23641Sbill vatimo()
23741Sbill {
238*287Sbill 	if (va11.va_open)
23941Sbill 		timeout(vatimo, (caddr_t)0, HZ/10);
24041Sbill 	vaintr(0);
24141Sbill }
24241Sbill 
24341Sbill /*ARGSUSED*/
24441Sbill vaintr(dev)
24541Sbill {
246*287Sbill 	wakeup((caddr_t)&va11);
24741Sbill }
24841Sbill 
24941Sbill vaclose()
25041Sbill {
25141Sbill 
252*287Sbill 	va11.va_open = 0;
253*287Sbill 	va11.va_busy = 0;
254*287Sbill 	va11.va_state = 0;
255*287Sbill 	va11.va_wc = 0;
256*287Sbill 	va11.va_bufp = 0;
257*287Sbill 	VAADDR->vacsl = 0;
25841Sbill }
259*287Sbill 
260*287Sbill #define	DELAY(N)	{ register int d; d = N; while (--d > 0); }
261*287Sbill 
262*287Sbill vareset()
263*287Sbill {
264*287Sbill 
265*287Sbill 	if (va11.va_open == 0)
266*287Sbill 		return;
267*287Sbill 	printf(" va");
268*287Sbill 	VAADDR->vacsl = IENABLE;
269*287Sbill 	if (va11.va_state & VPLOT) {
270*287Sbill 		VAADDR->vacsh = VAPLOT;
271*287Sbill 		DELAY(10000);
272*287Sbill 		VAADDR->vacsh = VAAUTOSTEP;
273*287Sbill 	} else if (va11.va_state & VPRINTPLOT)
274*287Sbill 		VAADDR->vacsh = VPRINTPLOT;
275*287Sbill 	else
276*287Sbill 		VAADDR->vacsh = VAPRINTPLOT;
277*287Sbill 	DELAY(10000);
278*287Sbill 	if (va11.va_busy == 0)
279*287Sbill 		return;
280*287Sbill 	if (va_ubinfo) {
281*287Sbill 		printf("<%d>", (va_ubinfo>>28)&0xf);
282*287Sbill 		ubafree(va_ubinfo), va_ubinfo = 0;
283*287Sbill 	}
284*287Sbill 	/* This code belongs in vastart() */
285*287Sbill 	va_ubinfo = ubasetup(va11.va_bp, vabdp);
286*287Sbill 	va11.va_bufp = va_ubinfo & 0x3ffff;
287*287Sbill 	va11.va_wc = (-va11.va_bp->b_bcount/2);
288*287Sbill 	/* End badly placed code */
289*287Sbill 	vastart();
290*287Sbill }
291