xref: /original-bsd/sys/vax/uba/ct.c (revision 39bdaf89)
1a7d36711Smckusick /*
2ca77bbffSmckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
3a7d36711Smckusick  * All rights reserved.  The Berkeley software License Agreement
4a7d36711Smckusick  * specifies the terms and conditions for redistribution.
5a7d36711Smckusick  *
6*39bdaf89Sbostic  *	@(#)ct.c	7.6 (Berkeley) 12/16/90
7a7d36711Smckusick  */
8a3f0d044Swnj 
98ff17834Swnj #include "ct.h"
10a3f0d044Swnj #if NCT > 0
11a3f0d044Swnj /*
123b27d6b7Skarels  * GP DR11C driver used for C/A/T or Autologic APS micro-5
13a3f0d044Swnj  */
14*39bdaf89Sbostic #include "../include/pte.h"
15a3f0d044Swnj 
16*39bdaf89Sbostic #include "sys/param.h"
17*39bdaf89Sbostic #include "sys/systm.h"
18*39bdaf89Sbostic #include "sys/ioctl.h"
19*39bdaf89Sbostic #include "sys/tty.h"
20*39bdaf89Sbostic #include "sys/map.h"
21*39bdaf89Sbostic #include "sys/buf.h"
22*39bdaf89Sbostic #include "sys/conf.h"
23*39bdaf89Sbostic #include "sys/user.h"
24*39bdaf89Sbostic #include "sys/kernel.h"
25a3f0d044Swnj 
26146803c9Sbloom #include "ubareg.h"
27146803c9Sbloom #include "ubavar.h"
28f65a77c3Sroot 
29a3f0d044Swnj #define	PCAT	(PZERO+9)
30a3f0d044Swnj #define	CATHIWAT	100
31a3f0d044Swnj #define	CATLOWAT	30
32a3f0d044Swnj 
333b27d6b7Skarels #define	REQUEST_B	0x8000
343b27d6b7Skarels #define REQUEST_A	0x80
353b27d6b7Skarels #define	INT_ENB_A	0x40
363b27d6b7Skarels #define	INT_ENB_B	0x20
373b27d6b7Skarels #define	CSR1		0x2
383b27d6b7Skarels #define	CSR0		0x1
393b27d6b7Skarels 
408ff17834Swnj struct ct_softc {
413b27d6b7Skarels 	int	sc_state;
428ff17834Swnj 	struct	clist sc_oq;
438ff17834Swnj } ct_softc[NCT];
44a3f0d044Swnj 
453b27d6b7Skarels #define	CT_OPEN		0x1
463b27d6b7Skarels #define	CT_RUNNING	0x2
473b27d6b7Skarels 
488ff17834Swnj struct ctdevice {
493b27d6b7Skarels 	u_short	ctcsr;
503b27d6b7Skarels 	u_short	ctobuf;
513b27d6b7Skarels 	u_short ctibuf;
52a3f0d044Swnj };
53a3f0d044Swnj 
548ff17834Swnj int	ctprobe(), ctattach(), ctintr();
558ff17834Swnj struct	uba_device *ctdinfo[NCT];
563b27d6b7Skarels u_short	ctstd[] = { 0167770, 0 };
578ff17834Swnj struct	uba_driver ctdriver =
588ff17834Swnj     { ctprobe, 0, ctattach, 0, ctstd, "ct", ctdinfo };
59a3f0d044Swnj 
608ac36657Swnj #define	CTUNIT(dev)	(minor(dev))
618ac36657Swnj 
623b27d6b7Skarels int	ct_init	= 0;	/* set to CSR1 for testing loopback on controller */
633b27d6b7Skarels 
ctprobe(reg)648ff17834Swnj ctprobe(reg)
658ff17834Swnj 	caddr_t reg;
66a3f0d044Swnj {
673b9ff7f8Sbugs 	register int br, cvec;		/* value-result */
688ff17834Swnj 	register struct ctdevice *ctaddr = (struct ctdevice *)reg;
698ff17834Swnj 
704f5d781bSwnj #ifdef lint
714f5d781bSwnj 	br = 0; cvec = br; br = cvec;
724f5d781bSwnj 	ctintr(0);
734f5d781bSwnj #endif
743b27d6b7Skarels 	/*
753b27d6b7Skarels 	 * There is no way to make a DR11c interrupt without some
763b27d6b7Skarels 	 * external support. We can't always trust that the typesetter
773b27d6b7Skarels 	 * will be online and ready so we've made other provisions.
783b27d6b7Skarels 	 * This probe assumes setting the B Int Enb will generate
793b27d6b7Skarels 	 * an interrupt. To do this, we set CSR0 and loop this back
803b27d6b7Skarels 	 * to REQUEST_B in the second plug on the controller.
813b27d6b7Skarels 	 * Then, we reset the vector to be that for the "real" device.
823b27d6b7Skarels 	 */
833b27d6b7Skarels 	ctaddr->ctcsr = INT_ENB_B | CSR0; /* Assume hardware loopback! */
843b27d6b7Skarels 	DELAY(1000);
853b27d6b7Skarels 	ctaddr->ctcsr = ct_init; /* should be CSR1 for loopback testing */
863b27d6b7Skarels 	if (cvec & 04) {
873b27d6b7Skarels 		printf("ct: resetting vector %o to %o\n", cvec, cvec&0773);
883b27d6b7Skarels 		cvec &= 0773;
893b27d6b7Skarels 	}
90d2841364Skre 	return (sizeof (struct ctdevice));
91a3f0d044Swnj }
92a3f0d044Swnj 
938ac36657Swnj /*ARGSUSED*/
948ac36657Swnj ctattach(ui)
956a131df8Skarels 	struct uba_device *ui;
968ac36657Swnj {
978ac36657Swnj }
988ac36657Swnj 
ctopen(dev)998ff17834Swnj ctopen(dev)
1008ff17834Swnj 	dev_t dev;
101a3f0d044Swnj {
1028ff17834Swnj 	register struct ct_softc *sc;
1038ff17834Swnj 	register struct uba_device *ui;
1048ff17834Swnj 	register struct ctdevice *ctaddr;
1058ff17834Swnj 
1068ff17834Swnj 	if (CTUNIT(dev) >= NCT || (ui = ctdinfo[CTUNIT(dev)]) == 0 ||
1073b27d6b7Skarels 	    ui->ui_alive == 0)
1083b27d6b7Skarels 		return (ENODEV);
1093b27d6b7Skarels 	if ((sc = &ct_softc[CTUNIT(dev)])->sc_state&CT_OPEN)
1103b27d6b7Skarels 		return (EBUSY);
1113b27d6b7Skarels 	sc->sc_state = CT_OPEN;
1123b27d6b7Skarels 	ctaddr = (struct ctdevice *)ui->ui_addr;
1133b27d6b7Skarels 	ctaddr->ctcsr |= INT_ENB_A;
1140015c898Sroot 	return (0);
1158ff17834Swnj }
1168ff17834Swnj 
ctclose(dev)1178ff17834Swnj ctclose(dev)
1188ff17834Swnj 	dev_t dev;
1198ff17834Swnj {
1203b27d6b7Skarels 	ct_softc[CTUNIT(dev)].sc_state = 0;
1218ff17834Swnj 	ctintr(dev);
1223b27d6b7Skarels 	return (0);
123a3f0d044Swnj }
124a3f0d044Swnj 
ctwrite(dev,uio)125f6034122Sroot ctwrite(dev, uio)
1268ff17834Swnj 	dev_t dev;
127f6034122Sroot 	struct uio *uio;
128a3f0d044Swnj {
1298ff17834Swnj 	register struct ct_softc *sc = &ct_softc[CTUNIT(dev)];
1308ff17834Swnj 	register int c;
1311db00297Skarels 	int s, error;
132a3f0d044Swnj 
1333b27d6b7Skarels 	while ((c = uwritec(uio)) >= 0) {
1343b27d6b7Skarels 		s = spl5();
1358ff17834Swnj 		while (sc->sc_oq.c_cc > CATHIWAT)
1361db00297Skarels 			if (error = tsleep((caddr_t)&sc->sc_oq, PCAT | PCATCH,
1371db00297Skarels 			    devout, 0))
1381db00297Skarels 				goto out;
1398ff17834Swnj 		while (putc(c, &sc->sc_oq) < 0)
1401db00297Skarels 			if (error = tsleep((caddr_t)&lbolt, PCAT | PCATCH,
1411db00297Skarels 			    ttybuf, 0))
1421db00297Skarels 				goto out;
1433b27d6b7Skarels 		if ( ! (sc->sc_state & CT_RUNNING) )
1448ff17834Swnj 			ctintr(dev);
1453b27d6b7Skarels 		splx(s);
146a3f0d044Swnj 	}
1473b27d6b7Skarels 	return (0);
1481db00297Skarels out:
1491db00297Skarels 	splx(s);
1501db00297Skarels 	return (error);
151a3f0d044Swnj }
152a3f0d044Swnj 
1533b27d6b7Skarels /*
1543b27d6b7Skarels  * The C/A/T is usually wired to accept data on the .5us DATA_AVAIL strobe.
1553b27d6b7Skarels  * If you use this with a C/A/T you can remove the lines with "APSu5" below.
1563b27d6b7Skarels  * This is way out of spec for the Autologic APS micro-5 which requires
1573b27d6b7Skarels  * at least a 40 microsec strobe. We therefore use CSR1 output as the
1583b27d6b7Skarels  * "strobe". It is set after data is loaded and reset only in the
1593b27d6b7Skarels  * interrupt routine. Therefore, the "strobe" is high for adequate time.
1603b27d6b7Skarels  * The constant "ctdelay" determines the "low" time for the strobe
1613b27d6b7Skarels  * and may have to be larger on a 780. "2" gives about 10us on a 750.
1623b27d6b7Skarels  */
1633b27d6b7Skarels int	ctdelay	= 2;	/* here so it's visible & changeable */
1643b27d6b7Skarels 
ctintr(dev)1658ff17834Swnj ctintr(dev)
1668ff17834Swnj 	dev_t dev;
167a3f0d044Swnj {
168a3f0d044Swnj 	register int c;
1698ff17834Swnj 	register struct ct_softc *sc = &ct_softc[CTUNIT(dev)];
1708ff17834Swnj 	register struct ctdevice *ctaddr =
1718ff17834Swnj 	    (struct ctdevice *)ctdinfo[CTUNIT(dev)]->ui_addr;
172a3f0d044Swnj 
1733b27d6b7Skarels 	if ((ctaddr->ctcsr&(INT_ENB_B|REQUEST_B)) == (INT_ENB_B|REQUEST_B)) {
1743b27d6b7Skarels 		ctaddr->ctcsr &= ~(CSR0 | INT_ENB_B);	/* set in ctprobe */
1753b27d6b7Skarels 	}
1763b27d6b7Skarels 	if ((ctaddr->ctcsr&(INT_ENB_A|REQUEST_A)) == (INT_ENB_A|REQUEST_A)) {
1778ff17834Swnj 		if ((c = getc(&sc->sc_oq)) >= 0) {
1783b27d6b7Skarels 			ctaddr->ctcsr &= ~CSR1;	/* APSu5 - drop strobe */
1793b27d6b7Skarels 			ctaddr->ctobuf = c;
1803b27d6b7Skarels 			DELAY(ctdelay);		/* APSu5 - pause a bit */
1813b27d6b7Skarels 			ctaddr->ctcsr |= CSR1;	/* APSu5 - raise strobe */
1823b27d6b7Skarels 			sc->sc_state |= CT_RUNNING;
1838ff17834Swnj 			if (sc->sc_oq.c_cc==0 || sc->sc_oq.c_cc==CATLOWAT)
1846a131df8Skarels 				wakeup((caddr_t)&sc->sc_oq);
1853b27d6b7Skarels 		} else if (sc->sc_state == 0) {
1868ff17834Swnj 				ctaddr->ctcsr = 0;
1873b27d6b7Skarels 		} else
1883b27d6b7Skarels 			sc->sc_state &= ~CT_RUNNING;
189a3f0d044Swnj 	}
190a3f0d044Swnj }
191a3f0d044Swnj #endif
192