xref: /csrg-svn/sys/vax/uba/va.c (revision 1564)
1*1564Sbill /*	va.c	3.7	10/19/80	*/
241Sbill 
3*1564Sbill #include "../conf/va.h"
4*1564Sbill #if NVA > 0
5*1564Sbill /*
6*1564Sbill  * Benson-Varian matrix printer/plotter
7*1564Sbill  * dma interface driver
8*1564Sbill  */
941Sbill #include "../h/param.h"
1041Sbill #include "../h/dir.h"
1141Sbill #include "../h/user.h"
1241Sbill #include "../h/buf.h"
1341Sbill #include "../h/systm.h"
1441Sbill #include "../h/map.h"
1541Sbill #include "../h/pte.h"
1641Sbill #include "../h/uba.h"
1741Sbill #include "../h/vcmd.h"
1841Sbill 
19287Sbill int	vabdp = 1;
2041Sbill 
21287Sbill unsigned minvaph();
2241Sbill 
2341Sbill #define	VAPRI	(PZERO-1)
2441Sbill 
25287Sbill #define	ushort	unsigned short
26287Sbill struct	varegs {
27287Sbill 	ushort	vaba;
28287Sbill 	short	vawc;
2941Sbill 	union {
30287Sbill 		short	Vacsw;
3141Sbill 		struct {
32287Sbill 			char Vacsl;
33287Sbill 			char Vacsh;
34287Sbill 		} vacsr;
35287Sbill 	} vacs;
3641Sbill 	short	vadata;
3741Sbill };
3841Sbill 
39287Sbill #define	vacsw	vacs.Vacsw
40287Sbill #define	vacsh	vacs.vacsr.Vacsh
41287Sbill #define	vacsl	vacs.vacsr.Vacsl
42287Sbill 
43287Sbill /* vacsw bits */
44287Sbill #define	ERROR		0100000		/* Some error has occurred */
45*1564Sbill #define	NPRTIMO		01000		/* DMA timeout error */
46*1564Sbill #define	NOTREADY	0400		/* Something besides NPRTIMO */
47*1564Sbill #define	DONE		0200
48287Sbill #define	IENABLE		0100		/* Interrupt enable */
49287Sbill #define	SUPPLIESLOW	04
50*1564Sbill #define	BOTOFFORM	02
51*1564Sbill #define	BYTEREVERSE	01		/* Reverse byte order in words */
5241Sbill 
53287Sbill /* vacsh command bytes */
54*1564Sbill #define	VAPLOT		0340
55*1564Sbill #define	VAPRINT		0100
56*1564Sbill #define	VAPRINTPLOT	0160
57*1564Sbill #define	VAAUTOSTEP	0244
58*1564Sbill #define	VANOAUTOSTEP	0045		/* unused */
59287Sbill #define	VAFORMFEED	0263		/* unused */
60287Sbill #define	VASLEW		0265		/* unused */
61287Sbill #define	VASTEP		0064		/* unused */
6241Sbill 
6341Sbill struct {
64287Sbill 	char	va_open;
6541Sbill 	char	va_busy;
6641Sbill 	int	va_state;	/* State: bits are commands in vcmd.h. */
67287Sbill 	int	va_wc;
6841Sbill 	int	va_bufp;
69287Sbill 	struct	buf *va_bp;
70287Sbill } va11;
7141Sbill int	va_ubinfo;
7241Sbill 
7341Sbill struct	buf rvabuf;		/* Used by physio for a buffer. */
7441Sbill 
7541Sbill vaopen()
7641Sbill {
7741Sbill 
78287Sbill 	if (va11.va_open) {
7941Sbill 		u.u_error = ENXIO;
8041Sbill 		return;
8141Sbill 	}
82287Sbill 	va11.va_open = 1;
83287Sbill 	VAADDR->vawc = 0;
84287Sbill 	va11.va_wc = 0;
85287Sbill 	va11.va_state = 0;
86287Sbill 	VAADDR->vacsl = IENABLE;
8741Sbill 	vatimo();
88287Sbill 	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();
99287Sbill 	while (va11.va_busy)
100287Sbill 		sleep((caddr_t)&va11, VAPRI);
101287Sbill 	va11.va_busy = 1;
102287Sbill 	va11.va_bp = bp;
103287Sbill 	va_ubinfo = ubasetup(bp, vabdp);
104287Sbill 	va11.va_bufp = va_ubinfo & 0x3ffff;
10541Sbill 	if (e = vaerror(DONE))
10641Sbill 		goto brkout;
107287Sbill 	va11.va_wc = -(bp->b_bcount/2);
10841Sbill 	vastart();
109287Sbill 	e = vaerror(DONE);	/* Wait for DMA to complete */
110287Sbill 	va11.va_wc = 0;
111287Sbill 	va11.va_bufp = 0;
11241Sbill 
113287Sbill 	/*
114287Sbill 	 * After printing a line of characters, VPRINTPLOT mode essentially
115287Sbill 	 * reverts to VPLOT mode, plotting things until a new mode is set.
116287Sbill 	 * This change is indicated by sending a VAAUTOSTEP command to
117287Sbill 	 * the va.  We also change va_state to reflect this effective
118287Sbill 	 * mode change.
11941Sbill 	 */
120287Sbill 	if (va11.va_state & VPRINTPLOT) {
121287Sbill 		va11.va_state = (va11.va_state & ~VPRINTPLOT) | VPLOT;
122287Sbill 		VAADDR->vacsh = VAAUTOSTEP;
12341Sbill 		e |= vaerror(DONE);
12441Sbill 	}
125133Sbill 	(void) spl0();
12641Sbill brkout:
12741Sbill 	ubafree(va_ubinfo), va_ubinfo = 0;
128287Sbill 	va11.va_bp = 0;
129287Sbill 	va11.va_busy = 0;
13041Sbill 	iodone(bp);
13141Sbill 	if (e)
13241Sbill 		u.u_error = EIO;
133287Sbill 	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 
160287Sbill 	while ((e = VAADDR->vacsw & (bit|ERROR)) == 0)
161287Sbill 		sleep((caddr_t)&va11, VAPRI);
16241Sbill 	return (e & ERROR);
16341Sbill }
16441Sbill 
16541Sbill vastart()
16641Sbill {
167287Sbill 	if (va11.va_wc) {
168287Sbill 		VAADDR->vaba = va11.va_bufp;
169287Sbill 		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:
183287Sbill 		(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 
201287Sbill /*
202287Sbill  * Send a command code to the va, and wait for it to complete.
203287Sbill  * If an error occurs, u.u_error is set to EIO.
204287Sbill  * In any case, update va11.va_state.
20541Sbill  */
20641Sbill vacmd(vcmd)
20741Sbill {
208133Sbill 	(void) spl4();
209287Sbill 	(void) vaerror(DONE);		/* Wait for va to be ready */
21041Sbill 	switch (vcmd) {
21141Sbill 
21241Sbill 	case VPLOT:
21341Sbill 		/* Must turn on plot AND autostep modes. */
214287Sbill 		VAADDR->vacsh = VAPLOT;
21541Sbill 		if (vaerror(DONE))
21641Sbill 			u.u_error = EIO;
217287Sbill 		VAADDR->vacsh = VAAUTOSTEP;
21841Sbill 		break;
21941Sbill 
22041Sbill 	case VPRINT:
221287Sbill 		VAADDR->vacsh = VAPRINT;
22241Sbill 		break;
22341Sbill 
22441Sbill 	case VPRINTPLOT:
225287Sbill 		VAADDR->vacsh = VAPRINTPLOT;
22641Sbill 		break;
22741Sbill 	}
228287Sbill 	va11.va_state =
229287Sbill 		(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 {
238287Sbill 	if (va11.va_open)
23941Sbill 		timeout(vatimo, (caddr_t)0, HZ/10);
24041Sbill 	vaintr(0);
24141Sbill }
24241Sbill 
24341Sbill /*ARGSUSED*/
24441Sbill vaintr(dev)
24541Sbill {
246287Sbill 	wakeup((caddr_t)&va11);
24741Sbill }
24841Sbill 
24941Sbill vaclose()
25041Sbill {
25141Sbill 
252287Sbill 	va11.va_open = 0;
253287Sbill 	va11.va_busy = 0;
254287Sbill 	va11.va_state = 0;
255287Sbill 	va11.va_wc = 0;
256287Sbill 	va11.va_bufp = 0;
257287Sbill 	VAADDR->vacsl = 0;
25841Sbill }
259287Sbill 
260287Sbill #define	DELAY(N)	{ register int d; d = N; while (--d > 0); }
261287Sbill 
262287Sbill vareset()
263287Sbill {
264287Sbill 
265287Sbill 	if (va11.va_open == 0)
266287Sbill 		return;
267287Sbill 	printf(" va");
268287Sbill 	VAADDR->vacsl = IENABLE;
269287Sbill 	if (va11.va_state & VPLOT) {
270287Sbill 		VAADDR->vacsh = VAPLOT;
271287Sbill 		DELAY(10000);
272287Sbill 		VAADDR->vacsh = VAAUTOSTEP;
273287Sbill 	} else if (va11.va_state & VPRINTPLOT)
274287Sbill 		VAADDR->vacsh = VPRINTPLOT;
275287Sbill 	else
276287Sbill 		VAADDR->vacsh = VAPRINTPLOT;
277287Sbill 	DELAY(10000);
278287Sbill 	if (va11.va_busy == 0)
279287Sbill 		return;
280287Sbill 	if (va_ubinfo) {
281287Sbill 		printf("<%d>", (va_ubinfo>>28)&0xf);
282287Sbill 		ubafree(va_ubinfo), va_ubinfo = 0;
283287Sbill 	}
284287Sbill 	/* This code belongs in vastart() */
285287Sbill 	va_ubinfo = ubasetup(va11.va_bp, vabdp);
286287Sbill 	va11.va_bufp = va_ubinfo & 0x3ffff;
287287Sbill 	va11.va_wc = (-va11.va_bp->b_bcount/2);
288287Sbill 	/* End badly placed code */
289287Sbill 	vastart();
290287Sbill }
291*1564Sbill #endif
292