xref: /csrg-svn/sys/vax/uba/va.c (revision 9362)
1*9362Smckusick /*	va.c	4.13.1.2	82/11/27	*/
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"
18*9362Smckusick #include "../h/uio.h"
1941Sbill 
20287Sbill unsigned minvaph();
2141Sbill 
2241Sbill #define	VAPRI	(PZERO-1)
2341Sbill 
243183Swnj struct	vadevice {
253183Swnj 	u_short	vaba;			/* buffer address */
263183Swnj 	short	vawc;			/* word count (2's complement) */
2741Sbill 	union {
283183Swnj 		short	Vacsw;		/* control status as word */
293183Swnj 		struct {		/* control status as bytes */
30287Sbill 			char Vacsl;
31287Sbill 			char Vacsh;
32287Sbill 		} vacsr;
33287Sbill 	} vacs;
343183Swnj 	short	vadata;			/* programmed i/o data buffer */
3541Sbill };
3641Sbill 
37287Sbill #define	vacsw	vacs.Vacsw
38287Sbill #define	vacsh	vacs.vacsr.Vacsh
39287Sbill #define	vacsl	vacs.vacsr.Vacsl
40287Sbill 
41287Sbill /* vacsw bits */
423183Swnj #define	VA_ERROR	0100000		/* some error has occurred */
433183Swnj #define	VA_NPRTIMO	0001000		/* DMA timeout error */
443183Swnj #define	VA_NOTREADY	0000400		/* something besides NPRTIMO */
453183Swnj #define	VA_DONE		0000200
463183Swnj #define	VA_IENABLE	0000100		/* interrupt enable */
47*9362Smckusick #define	VA_DMAGO	0000010		/* DMA go bit */
483183Swnj #define	VA_SUPPLIESLOW	0000004
493183Swnj #define	VA_BOTOFFORM	0000002
503183Swnj #define	VA_BYTEREVERSE	0000001		/* reverse byte order in words */
5141Sbill 
52287Sbill /* vacsh command bytes */
533183Swnj #define	VAPLOT		0000340
543183Swnj #define	VAPRINT		0000100
553183Swnj #define	VAPRINTPLOT	0000160
563183Swnj #define	VAAUTOSTEP	0000244
573183Swnj #define	VANOAUTOSTEP	0000045
583183Swnj #define	VAFORMFEED	0000263
593183Swnj #define	VASLEW		0000265
603183Swnj #define	VASTEP		0000064
6141Sbill 
623183Swnj struct va_softc {
639361Smckusick 	char	sc_openf;
649361Smckusick 	char	sc_busy;
659361Smckusick 	int	sc_state;
669361Smckusick 	int	sc_wc;
679361Smckusick 	struct	buf *sc_bp;
689361Smckusick 	int	sc_ubinfo;
693183Swnj } va_softc[NVA];
7041Sbill 
713183Swnj #define	VAUNIT(dev)	(minor(dev))
723183Swnj 
733183Swnj struct	buf rvabuf[NVA];
743183Swnj 
759361Smckusick int	vaprobe(), vaattach();
763183Swnj struct	uba_device *vadinfo[NVA];
773183Swnj u_short	vastd[] = { 0764000, 0 };
783183Swnj struct	uba_driver vadriver =
799361Smckusick     { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo };
803183Swnj 
813183Swnj vaprobe(reg)
823183Swnj 	caddr_t reg;
8341Sbill {
843183Swnj 	register int br, cvec;		/* value-result */
853183Swnj 	register struct vadevice *vaaddr = (struct vadevice *)reg;
8641Sbill 
879267Smckusick #ifdef lint
889267Smckusick 	br = 0; cvec = br; br = cvec;
899267Smckusick 	vaintr(0);
909267Smckusick #endif
913183Swnj 	vaaddr->vacsl = VA_IENABLE;
923183Swnj 	vaaddr->vaba = 0;
933183Swnj 	vaaddr->vacsh = VAPLOT;
94*9362Smckusick #ifndef VARIANGOBIT
959361Smckusick 	vaaddr->vacsl = 0;
96*9362Smckusick #endif
973183Swnj 	vaaddr->vawc = -1;
989361Smckusick 	DELAY(100000);
993183Swnj 	vaaddr->vacsl = 0;
100*9362Smckusick 	return (sizeof (struct vadevice));
1013183Swnj }
1023183Swnj 
1033183Swnj /*ARGSUSED*/
1043183Swnj vaattach(ui)
1053183Swnj 	struct uba_device *ui;
1063183Swnj {
1073183Swnj 
1083183Swnj }
1093183Swnj 
1103183Swnj vaopen(dev)
1113183Swnj 	dev_t dev;
1123183Swnj {
1133183Swnj 	register struct va_softc *sc;
1143183Swnj 	register struct vadevice *vaaddr;
1153183Swnj 	register struct uba_device *ui;
1163183Swnj 
1179361Smckusick 	if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf ||
1189361Smckusick 	    (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) {
11941Sbill 		u.u_error = ENXIO;
12041Sbill 		return;
12141Sbill 	}
1223183Swnj 	vaaddr = (struct vadevice *)ui->ui_addr;
1233183Swnj 	sc->sc_openf = 1;
1243183Swnj 	vaaddr->vawc = 0;
1259361Smckusick 	sc->sc_wc = 0;
1263183Swnj 	sc->sc_state = 0;
1273183Swnj 	vaaddr->vacsl = VA_IENABLE;
1283183Swnj 	vatimo(dev);
1293183Swnj 	vacmd(dev, VPRINT);
13041Sbill 	if (u.u_error)
1313183Swnj 		vaclose(dev);
13241Sbill }
13341Sbill 
13441Sbill vastrategy(bp)
13541Sbill 	register struct buf *bp;
13641Sbill {
1379361Smckusick 	register int e;
1389361Smckusick 	register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)];
1399361Smckusick 	register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)];
1409361Smckusick 	register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr;
14141Sbill 
1429361Smckusick 	(void) spl4();
1439361Smckusick 	while (sc->sc_busy)
1449361Smckusick 		sleep((caddr_t)sc, VAPRI);
1459361Smckusick 	sc->sc_busy = 1;
1469361Smckusick 	sc->sc_bp = bp;
1479361Smckusick 	sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
1489361Smckusick 	if (e = vawait(bp->b_dev))
1499361Smckusick 		goto brkout;
1509361Smckusick 	sc->sc_wc = -(bp->b_bcount/2);
1519361Smckusick 	vastart(bp->b_dev);
1529361Smckusick 	e = vawait(bp->b_dev);
1539361Smckusick 	sc->sc_wc = 0;
1549361Smckusick 	if (sc->sc_state & VPRINTPLOT) {
1559361Smckusick 		sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT;
1569361Smckusick 		vaaddr->vacsh = VAAUTOSTEP;
1579361Smckusick 		e |= vawait(bp->b_dev);
15841Sbill 	}
1599361Smckusick 	(void) spl0();
1609361Smckusick brkout:
1619361Smckusick 	ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
1629361Smckusick 	sc->sc_bp = 0;
1639361Smckusick 	sc->sc_busy = 0;
1649361Smckusick 	iodone(bp);
1659361Smckusick 	if (e)
1669361Smckusick 		u.u_error = EIO;
1679361Smckusick 	wakeup((caddr_t)sc);
16841Sbill }
16941Sbill 
17041Sbill int	vablock = 16384;
17141Sbill 
17241Sbill unsigned
17341Sbill minvaph(bp)
1743183Swnj 	struct buf *bp;
17541Sbill {
1763183Swnj 
17741Sbill 	if (bp->b_bcount > vablock)
17841Sbill 		bp->b_bcount = vablock;
17941Sbill }
18041Sbill 
18141Sbill /*ARGSUSED*/
182*9362Smckusick vawrite(dev, uio)
1833183Swnj 	dev_t dev;
184*9362Smckusick 	struct uio *uio;
18541Sbill {
1869267Smckusick 
187*9362Smckusick 	if (VAUNIT(dev) > NVA)
188*9362Smckusick 		u.u_error = ENXIO;
189*9362Smckusick 	else
190*9362Smckusick 		physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE,
191*9362Smckusick 		    minvaph, uio);
19241Sbill }
19341Sbill 
1949361Smckusick vawait(dev)
1959361Smckusick 	dev_t dev;
19641Sbill {
1979361Smckusick 	register struct vadevice *vaaddr =
1989361Smckusick 	    (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
1999361Smckusick 	register int e;
20041Sbill 
2019361Smckusick 	while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0)
2029361Smckusick 		sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI);
2039361Smckusick 	if (e & VA_NPRTIMO)
2049361Smckusick 		printf("va%d: npr timeout\n", VAUNIT(dev));
2059361Smckusick 	return (e & VA_ERROR);
20641Sbill }
20741Sbill 
2089361Smckusick vastart(dev)
2099361Smckusick 	dev_t;
21041Sbill {
2119361Smckusick 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
2129361Smckusick 	register struct vadevice *vaaddr =
2139361Smckusick 	    (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
2143183Swnj 
2159361Smckusick 	if (sc->sc_wc == 0)
2169361Smckusick 		return;
2179361Smckusick 	vaaddr->vaba = sc->sc_ubinfo;
218*9362Smckusick #ifndef VARIANGOBIT
2199361Smckusick 	vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30;
220*9362Smckusick #else
221*9362Smckusick 	vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30 | VA_IENABLE | VA_DMAGO;
222*9362Smckusick #endif
2239361Smckusick 	vaaddr->vawc = sc->sc_wc;
22441Sbill }
22541Sbill 
22641Sbill /*ARGSUSED*/
227*9362Smckusick vaioctl(dev, cmd, data, flag)
228*9362Smckusick 	register caddr_t data;
22941Sbill {
23041Sbill 	register int vcmd;
2313183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
23241Sbill 
23341Sbill 	switch (cmd) {
23441Sbill 
23541Sbill 	case VGETSTATE:
236*9362Smckusick 		*(int *)data = sc->sc_state;
23741Sbill 		return;
23841Sbill 
23941Sbill 	case VSETSTATE:
240*9362Smckusick 		vacmd(dev, *(int *)data);
24141Sbill 		return;
24241Sbill 
24341Sbill 	default:
2443183Swnj 		u.u_error = ENOTTY;
24541Sbill 		return;
24641Sbill 	}
24741Sbill }
24841Sbill 
2493183Swnj vacmd(dev, vcmd)
2503183Swnj 	dev_t dev;
2513183Swnj 	int vcmd;
25241Sbill {
2533183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
2549361Smckusick 	register struct vadevice *vaaddr =
2559361Smckusick 	    (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
2563183Swnj 
2579361Smckusick 	(void) spl4();
2589361Smckusick 	(void) vawait(dev);
25941Sbill 	switch (vcmd) {
26041Sbill 
26141Sbill 	case VPLOT:
26241Sbill 		/* Must turn on plot AND autostep modes. */
2639361Smckusick 		vaaddr->vacsh = VAPLOT;
2649361Smckusick 		if (vawait(dev))
26541Sbill 			u.u_error = EIO;
2669361Smckusick 		vaaddr->vacsh = VAAUTOSTEP;
26741Sbill 		break;
26841Sbill 
26941Sbill 	case VPRINT:
2709361Smckusick 		vaaddr->vacsh = VAPRINT;
27141Sbill 		break;
27241Sbill 
27341Sbill 	case VPRINTPLOT:
2749361Smckusick 		vaaddr->vacsh = VAPRINTPLOT;
27541Sbill 		break;
27641Sbill 	}
2773183Swnj 	sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd;
2789361Smckusick 	if (vawait(dev))
27941Sbill 		u.u_error = EIO;
2809361Smckusick 	(void) spl0();
28141Sbill }
28241Sbill 
2833183Swnj vatimo(dev)
2843183Swnj 	dev_t dev;
28541Sbill {
2863183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
2873183Swnj 
2883183Swnj 	if (sc->sc_openf)
2899361Smckusick 		timeout(vatimo, (caddr_t)dev, hz/10);
2909267Smckusick 	vaintr(dev);
29141Sbill }
29241Sbill 
29341Sbill /*ARGSUSED*/
29441Sbill vaintr(dev)
2953183Swnj 	dev_t dev;
29641Sbill {
2979361Smckusick 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
2983183Swnj 
2999361Smckusick 	wakeup((caddr_t)sc);
30041Sbill }
30141Sbill 
3023183Swnj vaclose(dev)
3033183Swnj 	dev_t dev;
30441Sbill {
3053183Swnj 	register struct va_softc *sc = &va_softc[VAUNIT(dev)];
3063183Swnj 	register struct vadevice *vaaddr =
3073183Swnj 	    (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
30841Sbill 
3093183Swnj 	sc->sc_openf = 0;
3109361Smckusick 	sc->sc_busy = 0;
3113183Swnj 	sc->sc_state = 0;
3129361Smckusick 	sc->sc_ubinfo = 0;
3133183Swnj 	vaaddr->vacsl = 0;
31441Sbill }
315287Sbill 
3163183Swnj vareset(uban)
3173183Swnj 	int uban;
318287Sbill {
3193183Swnj 	register int va11;
3209361Smckusick 	register struct uba_device *ui;
3219361Smckusick 	register struct va_softc *sc = va_softc;
3223183Swnj 	register struct vadevice *vaaddr;
323287Sbill 
3243183Swnj 	for (va11 = 0; va11 < NVA; va11++, sc++) {
3259361Smckusick 		if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 ||
3269361Smckusick 		    ui->ui_ubanum != uban || sc->sc_openf == 0)
3273183Swnj 			continue;
3283183Swnj 		printf(" va%d", va11);
3299361Smckusick 		vaaddr = (struct vadevice *)ui->ui_addr;
3303183Swnj 		vaaddr->vacsl = VA_IENABLE;
3313183Swnj 		if (sc->sc_state & VPLOT) {
3323183Swnj 			vaaddr->vacsh = VAPLOT;
3333183Swnj 			DELAY(10000);
3343183Swnj 			vaaddr->vacsh = VAAUTOSTEP;
3353183Swnj 		} else if (sc->sc_state & VPRINTPLOT)
3363183Swnj 			vaaddr->vacsh = VPRINTPLOT;
3373183Swnj 		else
3383183Swnj 			vaaddr->vacsh = VAPRINTPLOT;
339287Sbill 		DELAY(10000);
3409361Smckusick 		if (sc->sc_busy == 0)
3419361Smckusick 			continue;
3429361Smckusick 		if (sc->sc_ubinfo) {
3439361Smckusick 			printf("<%d>", (sc->sc_ubinfo>>28)&0xf);
3449361Smckusick 			ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
3453183Swnj 		}
3469361Smckusick 		sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP);
3479361Smckusick 		sc->sc_wc = -(sc->sc_bp->b_bcount/2);
3489361Smckusick 		vastart(sc->sc_bp->b_dev);
349287Sbill 	}
350287Sbill }
3516432Ssam 
3526432Ssam vaselect()
3536432Ssam {
3546432Ssam 	return (1);
3556432Ssam }
3561564Sbill #endif
357