xref: /csrg-svn/sys/vax/uba/va.c (revision 6432)
1*6432Ssam /*	va.c	4.12	82/04/01	*/
241Sbill 
31938Swnj #include "va.h"
41564Sbill #if NVA > 0
51564Sbill /*
63183Swnj  * Varian printer plotter
71564Sbill  */
841Sbill #include "../h/param.h"
941Sbill #include "../h/dir.h"
1041Sbill #include "../h/user.h"
1141Sbill #include "../h/buf.h"
1241Sbill #include "../h/systm.h"
1341Sbill #include "../h/map.h"
1441Sbill #include "../h/pte.h"
153183Swnj #include "../h/ubareg.h"
163183Swnj #include "../h/ubavar.h"
1741Sbill #include "../h/vcmd.h"
1841Sbill 
19287Sbill unsigned minvaph();
2041Sbill 
2141Sbill #define	VAPRI	(PZERO-1)
2241Sbill 
233183Swnj struct	vadevice {
243183Swnj 	u_short	vaba;			/* buffer address */
253183Swnj 	short	vawc;			/* word count (2's complement) */
2641Sbill 	union {
273183Swnj 		short	Vacsw;		/* control status as word */
283183Swnj 		struct {		/* control status as bytes */
29287Sbill 			char Vacsl;
30287Sbill 			char Vacsh;
31287Sbill 		} vacsr;
32287Sbill 	} vacs;
333183Swnj 	short	vadata;			/* programmed i/o data buffer */
3441Sbill };
3541Sbill 
36287Sbill #define	vacsw	vacs.Vacsw
37287Sbill #define	vacsh	vacs.vacsr.Vacsh
38287Sbill #define	vacsl	vacs.vacsr.Vacsl
39287Sbill 
40287Sbill /* vacsw bits */
413183Swnj #define	VA_ERROR	0100000		/* some error has occurred */
423183Swnj #define	VA_NPRTIMO	0001000		/* DMA timeout error */
433183Swnj #define	VA_NOTREADY	0000400		/* something besides NPRTIMO */
443183Swnj #define	VA_DONE		0000200
453183Swnj #define	VA_IENABLE	0000100		/* interrupt enable */
463183Swnj #define	VA_SUPPLIESLOW	0000004
473183Swnj #define	VA_BOTOFFORM	0000002
483183Swnj #define	VA_BYTEREVERSE	0000001		/* reverse byte order in words */
4941Sbill 
50287Sbill /* vacsh command bytes */
513183Swnj #define	VAPLOT		0000340
523183Swnj #define	VAPRINT		0000100
533183Swnj #define	VAPRINTPLOT	0000160
543183Swnj #define	VAAUTOSTEP	0000244
553183Swnj #define	VANOAUTOSTEP	0000045
563183Swnj #define	VAFORMFEED	0000263
573183Swnj #define	VASLEW		0000265
583183Swnj #define	VASTEP		0000064
5941Sbill 
603183Swnj struct va_softc {
613183Swnj 	char	sc_openf;
623183Swnj 	char	sc_busy;
633183Swnj 	int	sc_state;
643183Swnj 	int	sc_wc;
653183Swnj 	struct	buf *sc_bp;
663183Swnj 	int	sc_ubinfo;
673183Swnj } va_softc[NVA];
6841Sbill 
693183Swnj #define	VAUNIT(dev)	(minor(dev))
703183Swnj 
713183Swnj struct	buf rvabuf[NVA];
723183Swnj 
733183Swnj int	vaprobe(), vaattach();
743183Swnj struct	uba_device *vadinfo[NVA];
753183Swnj u_short	vastd[] = { 0764000, 0 };
763183Swnj struct	uba_driver vadriver =
773183Swnj     { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo };
783183Swnj 
793183Swnj vaprobe(reg)
803183Swnj 	caddr_t reg;
8141Sbill {
823183Swnj 	register int br, cvec;		/* value-result */
833183Swnj 	register struct vadevice *vaaddr = (struct vadevice *)reg;
8441Sbill 
854942Swnj #ifdef lint
864942Swnj 	br = 0; cvec = br; br = cvec;
874942Swnj 	vaintr(0);
884942Swnj #endif
893183Swnj 	vaaddr->vacsl = VA_IENABLE;
903183Swnj 	vaaddr->vaba = 0;
913183Swnj 	vaaddr->vacsh = VAPLOT;
923183Swnj 	vaaddr->vacsl = 0;
933183Swnj 	vaaddr->vawc = -1;
943183Swnj 	DELAY(10000);
953183Swnj 	vaaddr->vacsl = 0;
963183Swnj }
973183Swnj 
983183Swnj /*ARGSUSED*/
993183Swnj vaattach(ui)
1003183Swnj 	struct uba_device *ui;
1013183Swnj {
1023183Swnj 
1033183Swnj }
1043183Swnj 
1053183Swnj vaopen(dev)
1063183Swnj 	dev_t dev;
1073183Swnj {
1083183Swnj 	register struct va_softc *sc;
1093183Swnj 	register struct vadevice *vaaddr;
1103183Swnj 	register struct uba_device *ui;
1113183Swnj 
1123183Swnj 	if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf ||
1133183Swnj 	    (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) {
11441Sbill 		u.u_error = ENXIO;
11541Sbill 		return;
11641Sbill 	}
1173183Swnj 	vaaddr = (struct vadevice *)ui->ui_addr;
1183183Swnj 	sc->sc_openf = 1;
1193183Swnj 	vaaddr->vawc = 0;
1203183Swnj 	sc->sc_wc = 0;
1213183Swnj 	sc->sc_state = 0;
1223183Swnj 	vaaddr->vacsl = VA_IENABLE;
1233183Swnj 	vatimo(dev);
1243183Swnj 	vacmd(dev, VPRINT);
12541Sbill 	if (u.u_error)
1263183Swnj 		vaclose(dev);
12741Sbill }
12841Sbill 
12941Sbill vastrategy(bp)
13041Sbill 	register struct buf *bp;
13141Sbill {
13241Sbill 	register int e;
1333183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)];
1343183Swnj 	register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)];
1353183Swnj 	register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr;
13641Sbill 
137133Sbill 	(void) spl4();
1383183Swnj 	while (sc->sc_busy)
1393183Swnj 		sleep((caddr_t)sc, VAPRI);
1403183Swnj 	sc->sc_busy = 1;
1413183Swnj 	sc->sc_bp = bp;
1423183Swnj 	sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
1433183Swnj 	if (e = vawait(bp->b_dev))
14441Sbill 		goto brkout;
1453183Swnj 	sc->sc_wc = -(bp->b_bcount/2);
1463183Swnj 	vastart(bp->b_dev);
1473183Swnj 	e = vawait(bp->b_dev);
1483183Swnj 	sc->sc_wc = 0;
1493183Swnj 	if (sc->sc_state & VPRINTPLOT) {
1503183Swnj 		sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT;
1513183Swnj 		vaaddr->vacsh = VAAUTOSTEP;
1523183Swnj 		e |= vawait(bp->b_dev);
15341Sbill 	}
154133Sbill 	(void) spl0();
15541Sbill brkout:
1563183Swnj 	ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
1573183Swnj 	sc->sc_bp = 0;
1583183Swnj 	sc->sc_busy = 0;
15941Sbill 	iodone(bp);
16041Sbill 	if (e)
16141Sbill 		u.u_error = EIO;
1623183Swnj 	wakeup((caddr_t)sc);
16341Sbill }
16441Sbill 
16541Sbill int	vablock = 16384;
16641Sbill 
16741Sbill unsigned
16841Sbill minvaph(bp)
1693183Swnj 	struct buf *bp;
17041Sbill {
1713183Swnj 
17241Sbill 	if (bp->b_bcount > vablock)
17341Sbill 		bp->b_bcount = vablock;
17441Sbill }
17541Sbill 
17641Sbill /*ARGSUSED*/
17741Sbill vawrite(dev)
1783183Swnj 	dev_t dev;
17941Sbill {
1803183Swnj 
1813183Swnj 	physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph);
18241Sbill }
18341Sbill 
1843183Swnj vawait(dev)
1853183Swnj 	dev_t dev;
18641Sbill {
1873183Swnj 	register struct vadevice *vaaddr =
1883183Swnj 	    (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
18941Sbill 	register int e;
19041Sbill 
1913183Swnj 	while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0)
1923183Swnj 		sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI);
1933183Swnj 	if (e & VA_NPRTIMO)
1943183Swnj 		printf("va%d: npr timeout\n", VAUNIT(dev));
1953183Swnj 	return (e & VA_ERROR);
19641Sbill }
19741Sbill 
1983183Swnj vastart(dev)
1993183Swnj 	dev_t;
20041Sbill {
2013183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
2023183Swnj 	register struct vadevice *vaaddr =
2033183Swnj 	    (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
2043183Swnj 
2053183Swnj 	if (sc->sc_wc == 0)
20641Sbill 		return;
2073183Swnj 	vaaddr->vaba = sc->sc_ubinfo;
2083183Swnj 	vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30;
2093183Swnj 	vaaddr->vawc = sc->sc_wc;
21041Sbill }
21141Sbill 
21241Sbill /*ARGSUSED*/
21341Sbill vaioctl(dev, cmd, addr, flag)
21441Sbill 	register caddr_t addr;
21541Sbill {
21641Sbill 	register int vcmd;
2173183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
21841Sbill 
21941Sbill 	switch (cmd) {
22041Sbill 
22141Sbill 	case VGETSTATE:
2223183Swnj 		(void) suword(addr, sc->sc_state);
22341Sbill 		return;
22441Sbill 
22541Sbill 	case VSETSTATE:
22641Sbill 		vcmd = fuword(addr);
22741Sbill 		if (vcmd == -1) {
22841Sbill 			u.u_error = EFAULT;
22941Sbill 			return;
23041Sbill 		}
2313183Swnj 		vacmd(dev, vcmd);
23241Sbill 		return;
23341Sbill 
23441Sbill 	default:
2353183Swnj 		u.u_error = ENOTTY;
23641Sbill 		return;
23741Sbill 	}
23841Sbill }
23941Sbill 
2403183Swnj vacmd(dev, vcmd)
2413183Swnj 	dev_t dev;
2423183Swnj 	int vcmd;
24341Sbill {
2443183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
2453183Swnj 	register struct vadevice *vaaddr =
2463183Swnj 	    (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
2473183Swnj 
248133Sbill 	(void) spl4();
2493183Swnj 	(void) vawait(dev);
25041Sbill 	switch (vcmd) {
25141Sbill 
25241Sbill 	case VPLOT:
25341Sbill 		/* Must turn on plot AND autostep modes. */
2543183Swnj 		vaaddr->vacsh = VAPLOT;
2553183Swnj 		if (vawait(dev))
25641Sbill 			u.u_error = EIO;
2573183Swnj 		vaaddr->vacsh = VAAUTOSTEP;
25841Sbill 		break;
25941Sbill 
26041Sbill 	case VPRINT:
2613183Swnj 		vaaddr->vacsh = VAPRINT;
26241Sbill 		break;
26341Sbill 
26441Sbill 	case VPRINTPLOT:
2653183Swnj 		vaaddr->vacsh = VAPRINTPLOT;
26641Sbill 		break;
26741Sbill 	}
2683183Swnj 	sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd;
2693183Swnj 	if (vawait(dev))
27041Sbill 		u.u_error = EIO;
271133Sbill 	(void) spl0();
27241Sbill }
27341Sbill 
2743183Swnj vatimo(dev)
2753183Swnj 	dev_t dev;
27641Sbill {
2773183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
2783183Swnj 
2793183Swnj 	if (sc->sc_openf)
2803183Swnj 		timeout(vatimo, (caddr_t)dev, hz/10);
2813183Swnj 	vaintr(dev);
28241Sbill }
28341Sbill 
28441Sbill /*ARGSUSED*/
28541Sbill vaintr(dev)
2863183Swnj 	dev_t dev;
28741Sbill {
2883183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
2893183Swnj 
2903183Swnj 	wakeup((caddr_t)sc);
29141Sbill }
29241Sbill 
2933183Swnj vaclose(dev)
2943183Swnj 	dev_t dev;
29541Sbill {
2963183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
2973183Swnj 	register struct vadevice *vaaddr =
2983183Swnj 	    (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
29941Sbill 
3003183Swnj 	sc->sc_openf = 0;
3013183Swnj 	sc->sc_busy = 0;
3023183Swnj 	sc->sc_state = 0;
3033183Swnj 	sc->sc_ubinfo = 0;
3043183Swnj 	vaaddr->vacsl = 0;
30541Sbill }
306287Sbill 
3073183Swnj vareset(uban)
3083183Swnj 	int uban;
309287Sbill {
3103183Swnj 	register int va11;
3113183Swnj 	register struct uba_device *ui;
3123183Swnj 	register struct va_softc *sc = va_softc;
3133183Swnj 	register struct vadevice *vaaddr;
314287Sbill 
3153183Swnj 	for (va11 = 0; va11 < NVA; va11++, sc++) {
3163183Swnj 		if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 ||
3173183Swnj 		    ui->ui_ubanum != uban || sc->sc_openf == 0)
3183183Swnj 			continue;
3193183Swnj 		printf(" va%d", va11);
3203183Swnj 		vaaddr = (struct vadevice *)ui->ui_addr;
3213183Swnj 		vaaddr->vacsl = VA_IENABLE;
3223183Swnj 		if (sc->sc_state & VPLOT) {
3233183Swnj 			vaaddr->vacsh = VAPLOT;
3243183Swnj 			DELAY(10000);
3253183Swnj 			vaaddr->vacsh = VAAUTOSTEP;
3263183Swnj 		} else if (sc->sc_state & VPRINTPLOT)
3273183Swnj 			vaaddr->vacsh = VPRINTPLOT;
3283183Swnj 		else
3293183Swnj 			vaaddr->vacsh = VAPRINTPLOT;
330287Sbill 		DELAY(10000);
3313183Swnj 		if (sc->sc_busy == 0)
3323183Swnj 			continue;
3333183Swnj 		if (sc->sc_ubinfo) {
3343183Swnj 			printf("<%d>", (sc->sc_ubinfo>>28)&0xf);
3353183Swnj 			ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
3363183Swnj 		}
3373183Swnj 		sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP);
3383183Swnj 		sc->sc_wc = -(sc->sc_bp->b_bcount/2);
3393183Swnj 		vastart(sc->sc_bp->b_dev);
340287Sbill 	}
341287Sbill }
342*6432Ssam 
343*6432Ssam vaselect()
344*6432Ssam {
345*6432Ssam 	return (1);
346*6432Ssam }
3471564Sbill #endif
348