xref: /original-bsd/sys/vax/uba/dmz.c (revision 9e5284e4)
115b1a157Smckusick /*
270b8b6e8Smckusick  * Copyright (c) 1985, 1986 Regents of the University of California.
315b1a157Smckusick  * All rights reserved.  The Berkeley software License Agreement
415b1a157Smckusick  * specifies the terms and conditions for redistribution.
515b1a157Smckusick  *
6*9e5284e4Smarc  *	@(#)dmz.c	7.12 (Berkeley) 05/16/91
715b1a157Smckusick  */
815b1a157Smckusick 
915b1a157Smckusick /*
1015b1a157Smckusick  * DMZ-32 driver
1115b1a157Smckusick  */
1215b1a157Smckusick 
1315b1a157Smckusick #include "dmz.h"
1415b1a157Smckusick #if NDMZ > 0
1515b1a157Smckusick 
1639bdaf89Sbostic #include "../include/pte.h"
1715b1a157Smckusick 
1839bdaf89Sbostic #include "sys/param.h"
1915b1a157Smckusick #include "uba.h"
2039bdaf89Sbostic #include "sys/conf.h"
2139bdaf89Sbostic #include "sys/user.h"
2239bdaf89Sbostic #include "sys/proc.h"
2339bdaf89Sbostic #include "sys/ioctl.h"
2439bdaf89Sbostic #include "sys/tty.h"
2539bdaf89Sbostic #include "sys/map.h"
2639bdaf89Sbostic #include "sys/buf.h"
2739bdaf89Sbostic #include "sys/vm.h"
2839bdaf89Sbostic #include "sys/clist.h"
2939bdaf89Sbostic #include "sys/file.h"
3039bdaf89Sbostic #include "sys/uio.h"
3139bdaf89Sbostic #include "sys/kernel.h"
3239bdaf89Sbostic #include "sys/syslog.h"
3315b1a157Smckusick 
345d07d0fcSkarels #include "dmx.h"
3515b1a157Smckusick #include "ubareg.h"
3615b1a157Smckusick #include "ubavar.h"
375d07d0fcSkarels #include "dmxreg.h"
3815b1a157Smckusick #include "dmzreg.h"
39118ccd4eSkarels #include "dmreg.h"
4015b1a157Smckusick 
415d07d0fcSkarels extern	int dmx_timeout;		/* silo timeout, in ms */
4215b1a157Smckusick int	dmzstart();
4315b1a157Smckusick 
4415b1a157Smckusick /*
45987c469bSkarels  * The clist space is mapped by one terminal driver onto each UNIBUS.
46987c469bSkarels  * The identity of the board which allocated resources is recorded,
47987c469bSkarels  * so the process may be repeated after UNIBUS resets.
48987c469bSkarels  * The UBACVT macro converts a clist space address for unibus uban
49987c469bSkarels  * into an i/o space address for the DMA routine.
50987c469bSkarels  */
51987c469bSkarels int	dmz_uballoc[NUBA];	/* which dmz (if any) allocated unibus map */
52987c469bSkarels int	cbase[NUBA];		/* base address of clists in unibus map */
5315b1a157Smckusick 
545d07d0fcSkarels /*
555d07d0fcSkarels  * Autoconfiguration and variables for DMZ32
565d07d0fcSkarels  */
575d07d0fcSkarels int dmzprobe(), dmzattach();
585d07d0fcSkarels struct uba_device *dmzinfo[NDMZ];
595d07d0fcSkarels u_short dmzstd[] = { 0 };
605d07d0fcSkarels struct uba_driver dmzdriver = {
615d07d0fcSkarels 	dmzprobe, 0, dmzattach, 0, dmzstd, "dmz", dmzinfo
625d07d0fcSkarels };
635d07d0fcSkarels 
645d07d0fcSkarels struct	tty dmz_tty[NDMZ*24];
655d07d0fcSkarels struct	dmx_softc dmz_softc[3 * NDMZ];
665d07d0fcSkarels #ifndef lint
675d07d0fcSkarels int	ndmz = NDMZ*24;			/* used by iostat */
685d07d0fcSkarels #endif
6915b1a157Smckusick 
dmzprobe(reg)7015b1a157Smckusick dmzprobe(reg)
7115b1a157Smckusick 	caddr_t reg;
7215b1a157Smckusick {
7315b1a157Smckusick 	register int br, cvec;
7415b1a157Smckusick 	register struct dmzdevice *dmz_addr;
7515b1a157Smckusick 	register unsigned int a;
7615b1a157Smckusick 
7715b1a157Smckusick 	dmz_addr = (struct dmzdevice *)reg;
7815b1a157Smckusick 
7915b1a157Smckusick #ifdef lint
8015b1a157Smckusick 	br = 0; cvec = br; br = cvec; dmzxinta(0); dmzxintb(0); dmzxintc(0);
8115b1a157Smckusick 	dmzrinta(0); dmzrintb(0); dmzrintc(0);
8215b1a157Smckusick #endif
8315b1a157Smckusick 
8415b1a157Smckusick 	br = 0x15;
8515b1a157Smckusick 
8615b1a157Smckusick 	a = dmz_addr->dmz_config;
8715b1a157Smckusick 	if (((a>>12) & ~DMZ_INTERFACE) != 0) {
8815b1a157Smckusick 		printf("	Unknown interface type\n");
8915b1a157Smckusick 		return (0);
9015b1a157Smckusick 	}
9115b1a157Smckusick 	if (((a>>8) & DMZ_NOC_MASK) != 3) {
9215b1a157Smckusick 		printf("	Not all octets are available\n");
9315b1a157Smckusick 		return (0);
9415b1a157Smckusick 	}
9515b1a157Smckusick 
9615b1a157Smckusick 	cvec = (uba_hd[numuba].uh_lastiv -= 4 * 6);
9715b1a157Smckusick 	dmz_addr->dmz_config = cvec >> 2;
9815b1a157Smckusick 
9915b1a157Smckusick 	return (sizeof(struct dmzdevice));
10015b1a157Smckusick }
10115b1a157Smckusick 
dmzattach(ui)10215b1a157Smckusick dmzattach(ui)
1035d07d0fcSkarels 	register struct uba_device *ui;
10415b1a157Smckusick {
1055d07d0fcSkarels 	register struct dmx_softc *sc;
1065d07d0fcSkarels 	register int i;
1075d07d0fcSkarels 
1085d07d0fcSkarels 	sc = &dmz_softc[3 * ui->ui_unit];
1095d07d0fcSkarels 	for (i = 0; i < 3; i++, sc++) {
1105d07d0fcSkarels 		sc->dmx_type = 'z';
1115d07d0fcSkarels 		sc->dmx_unit = ui->ui_unit;
1125d07d0fcSkarels 		sc->dmx_unit0 = 8 * i;
1135d07d0fcSkarels 		sc->dmx_ubanum = ui->ui_ubanum;
1145d07d0fcSkarels 		sc->dmx_softCAR = (ui->ui_flags >> (8 * i)) & 0xff;
1155d07d0fcSkarels 		sc->dmx_tty = &dmz_tty[((ui->ui_unit * 3) + i) * 8];
1165d07d0fcSkarels 		sc->dmx_octet = (struct dmx_octet *)
1175d07d0fcSkarels 		    &((struct dmzdevice *)ui->ui_addr)->dmz_octet[i];
1185d07d0fcSkarels 	}
1195d07d0fcSkarels 
120ed30b6adSkarels 	cbase[ui->ui_ubanum] = -1;
1219ca9de02Sbostic 	dmz_uballoc[ui->ui_ubanum] = -1;
12215b1a157Smckusick }
12315b1a157Smckusick 
1245d07d0fcSkarels /*
1255d07d0fcSkarels  * Open a DMF32 line, mapping the clist onto the uba if this
1265d07d0fcSkarels  * is the first dmf on this uba.  Turn on this dmf if this is
1275d07d0fcSkarels  * the first use of it.
1285d07d0fcSkarels  */
12915b1a157Smckusick /*ARGSUSED*/
dmzopen(dev,flag)1305d07d0fcSkarels dmzopen(dev, flag)
1315d07d0fcSkarels 	dev_t dev;
13215b1a157Smckusick {
13315b1a157Smckusick 	register struct tty *tp;
1345d07d0fcSkarels 	struct dmx_softc *sc;
1355d07d0fcSkarels 	int unit, dmz;
1365d07d0fcSkarels 	struct uba_device *ui;
1375d07d0fcSkarels 	int s;
138f6f5d34cSmarc 	int dmxparam();
13915b1a157Smckusick 
1405d07d0fcSkarels 	unit = minor(dev);
1415d07d0fcSkarels 	dmz = DMZ(unit);
1425d07d0fcSkarels 	if (unit >= NDMZ*24 || (ui = dmzinfo[dmz])== 0 || ui->ui_alive == 0)
14315b1a157Smckusick 		return (ENXIO);
14415b1a157Smckusick 
14515b1a157Smckusick 	tp = &dmz_tty[unit];
1465d07d0fcSkarels 	sc = &dmz_softc[unit / 8];
1475d07d0fcSkarels 	tp->t_addr = (caddr_t)sc->dmx_octet;
14815b1a157Smckusick 	tp->t_oproc = dmzstart;
1495d07d0fcSkarels 	tp->t_dev = dev;			/* needed before dmxopen */
150f6f5d34cSmarc 	tp->t_param = dmxparam;
15115b1a157Smckusick 
15215b1a157Smckusick 	/*
1535d07d0fcSkarels 	 * While setting up state for this uba,
1545d07d0fcSkarels 	 * block uba resets which can clear the state.
15515b1a157Smckusick 	 */
1565d07d0fcSkarels 	s = spl6();
157ed30b6adSkarels 	if (cbase[ui->ui_ubanum] == -1) {
1585d07d0fcSkarels 		dmz_uballoc[ui->ui_ubanum] = dmz;
159987c469bSkarels 		cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum,
160987c469bSkarels 		    (caddr_t)cfree, nclist*sizeof(struct cblock), 0));
16115b1a157Smckusick 	}
1625d07d0fcSkarels 	splx(s);
16315b1a157Smckusick 
164f6f5d34cSmarc 	return (dmxopen(tp, sc, flag));
16515b1a157Smckusick }
16615b1a157Smckusick 
16715b1a157Smckusick /*
1685d07d0fcSkarels  * Close a DMZ32 line.
16915b1a157Smckusick  */
17015b1a157Smckusick /*ARGSUSED*/
dmzclose(dev,flag,mode,p)171*9e5284e4Smarc dmzclose(dev, flag, mode, p)
1725d07d0fcSkarels 	dev_t dev;
173*9e5284e4Smarc 	int flag, mode;
174*9e5284e4Smarc 	struct proc *p;
17515b1a157Smckusick {
17615b1a157Smckusick 
177*9e5284e4Smarc 	return (dmxclose(&dmz_tty[minor(dev)]), flag);
17815b1a157Smckusick }
17915b1a157Smckusick 
dmzread(dev,uio,flag)180f6f5d34cSmarc dmzread(dev, uio, flag)
1815d07d0fcSkarels 	dev_t dev;
1825d07d0fcSkarels 	struct uio *uio;
1835d07d0fcSkarels {
1845d07d0fcSkarels 	register struct tty *tp;
1855d07d0fcSkarels 
1865d07d0fcSkarels 	tp = &dmz_tty[minor(dev)];
187f6f5d34cSmarc 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
1885d07d0fcSkarels }
1895d07d0fcSkarels 
dmzwrite(dev,uio)1905d07d0fcSkarels dmzwrite(dev, uio)
1915d07d0fcSkarels 	dev_t dev;
1925d07d0fcSkarels 	struct uio *uio;
1935d07d0fcSkarels {
1945d07d0fcSkarels 	register struct tty *tp;
1955d07d0fcSkarels 
1965d07d0fcSkarels 	tp = &dmz_tty[minor(dev)];
1975d07d0fcSkarels 	return ((*linesw[tp->t_line].l_write)(tp, uio));
1985d07d0fcSkarels }
1995d07d0fcSkarels 
2005d07d0fcSkarels /*
2015d07d0fcSkarels  * DMZ32 receiver interrupts.
2025d07d0fcSkarels  */
dmzrinta(dmz)2035d07d0fcSkarels dmzrinta(dmz)
2045d07d0fcSkarels 	int dmz;
2055d07d0fcSkarels {
2065d07d0fcSkarels 	struct uba_device *ui;
2075d07d0fcSkarels 
2085d07d0fcSkarels 	ui = dmzinfo[dmz];
2095d07d0fcSkarels 	if (ui == 0 || ui->ui_alive == 0)
2105d07d0fcSkarels 		return;
2115d07d0fcSkarels 	dmxrint(&dmz_softc[3 * dmz + 0]);
2125d07d0fcSkarels }
2135d07d0fcSkarels 
dmzrintb(dmz)2145d07d0fcSkarels dmzrintb(dmz)
2155d07d0fcSkarels 	int dmz;
2165d07d0fcSkarels {
2175d07d0fcSkarels 	struct uba_device *ui;
2185d07d0fcSkarels 
2195d07d0fcSkarels 	ui = dmzinfo[dmz];
2205d07d0fcSkarels 	if (ui == 0 || ui->ui_alive == 0)
2215d07d0fcSkarels 		return;
2225d07d0fcSkarels 	dmxrint(&dmz_softc[3 * dmz + 1]);
2235d07d0fcSkarels }
2245d07d0fcSkarels 
dmzrintc(dmz)2255d07d0fcSkarels dmzrintc(dmz)
2265d07d0fcSkarels 	int dmz;
2275d07d0fcSkarels {
2285d07d0fcSkarels 	struct uba_device *ui;
2295d07d0fcSkarels 
2305d07d0fcSkarels 	ui = dmzinfo[dmz];
2315d07d0fcSkarels 	if (ui == 0 || ui->ui_alive == 0)
2325d07d0fcSkarels 		return;
2335d07d0fcSkarels 	dmxrint(&dmz_softc[3 * dmz + 2]);
2345d07d0fcSkarels }
2355d07d0fcSkarels 
2365d07d0fcSkarels /*
2375d07d0fcSkarels  * Ioctl for DMZ32.
2385d07d0fcSkarels  */
dmzioctl(dev,cmd,data,flag)2395d07d0fcSkarels dmzioctl(dev, cmd, data, flag)
2405d07d0fcSkarels 	dev_t dev;
2415d07d0fcSkarels 	caddr_t data;
2425d07d0fcSkarels {
2435d07d0fcSkarels 	int unit = minor(dev);
2445d07d0fcSkarels 
2455d07d0fcSkarels 	return (dmxioctl(&dmz_tty[unit], cmd, data, flag));
2465d07d0fcSkarels }
2475d07d0fcSkarels 
2485d07d0fcSkarels /*
2495d07d0fcSkarels  * DMZ32 transmitter interrupts.
2505d07d0fcSkarels  */
dmzxinta(dmz)2515d07d0fcSkarels dmzxinta(dmz)
2525d07d0fcSkarels 	int dmz;
2535d07d0fcSkarels {
2545d07d0fcSkarels 
2555d07d0fcSkarels 	dmxxint(&dmz_softc[3 * dmz + 0]);
2565d07d0fcSkarels }
2575d07d0fcSkarels 
dmzxintb(dmz)2585d07d0fcSkarels dmzxintb(dmz)
2595d07d0fcSkarels 	int dmz;
2605d07d0fcSkarels {
2615d07d0fcSkarels 
2625d07d0fcSkarels 	dmxxint(&dmz_softc[3 * dmz + 1]);
2635d07d0fcSkarels }
2645d07d0fcSkarels 
dmzxintc(dmz)2655d07d0fcSkarels dmzxintc(dmz)
2665d07d0fcSkarels 	int dmz;
2675d07d0fcSkarels {
2685d07d0fcSkarels 
2695d07d0fcSkarels 	dmxxint(&dmz_softc[3 * dmz + 2]);
2705d07d0fcSkarels }
2715d07d0fcSkarels 
2725d07d0fcSkarels /*
2735d07d0fcSkarels  * Start (restart) transmission on the given line.
2745d07d0fcSkarels  */
2755d07d0fcSkarels dmzstart(tp)
2765d07d0fcSkarels 	struct tty *tp;
2775d07d0fcSkarels {
2785d07d0fcSkarels 
2795d07d0fcSkarels 	dmxstart(tp, &dmz_softc[minor(tp->t_dev) >> 3]);
2805d07d0fcSkarels }
2815d07d0fcSkarels 
2825d07d0fcSkarels /*
2835d07d0fcSkarels  * Stop output on a line, e.g. for ^S/^Q or output flush.
2845d07d0fcSkarels  */
2855d07d0fcSkarels dmzstop(tp, flag)
2865d07d0fcSkarels 	struct tty *tp;
2875d07d0fcSkarels {
2885d07d0fcSkarels 
2895d07d0fcSkarels 	dmxstop(tp, &dmz_softc[minor(tp->t_dev) >> 3], flag);
2905d07d0fcSkarels }
2915d07d0fcSkarels 
2925d07d0fcSkarels /*
2935d07d0fcSkarels  * Reset state of driver if UBA reset was necessary.
2945d07d0fcSkarels  * Reset the csr, lpr, and lcr registers on open lines, and
2955d07d0fcSkarels  * restart transmitters.
2965d07d0fcSkarels  */
dmzreset(uban)29715b1a157Smckusick dmzreset(uban)
29815b1a157Smckusick 	int uban;
29915b1a157Smckusick {
3005d07d0fcSkarels 	register int dmz;
30115b1a157Smckusick 	register struct tty *tp;
30215b1a157Smckusick 	register struct uba_device *ui;
3035d07d0fcSkarels 	register struct dmzdevice *addr;
30415b1a157Smckusick 	int i;
30515b1a157Smckusick 
3065d07d0fcSkarels 	for (dmz = 0; dmz < NDMZ; dmz++) {
3075d07d0fcSkarels 		ui = dmzinfo[dmz];
30815b1a157Smckusick 		if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
30915b1a157Smckusick 			continue;
3105d07d0fcSkarels 		printf("dmz%d ", dmz);
3115d07d0fcSkarels 		addr = (struct dmzdevice *)ui->ui_addr;
31215b1a157Smckusick 
3135d07d0fcSkarels 		if (dmz_uballoc[uban] == dmz) {
314987c469bSkarels 			int info;
315987c469bSkarels 
316987c469bSkarels 			info = uballoc(uban, (caddr_t)cfree,
317987c469bSkarels 			    nclist * sizeof(struct cblock), UBA_CANTWAIT);
318987c469bSkarels 			if (info)
319987c469bSkarels 				cbase[uban] = UBAI_ADDR(info);
320987c469bSkarels 			else {
321987c469bSkarels 				printf(" [can't get uba map]");
322987c469bSkarels 				cbase[uban] = -1;
323987c469bSkarels 			}
324140e9938Skarels 		}
325140e9938Skarels 
3265d07d0fcSkarels 		for (i = 0; i < 3; i++)
3275d07d0fcSkarels 			if (dmz_softc[3 * dmz + i].dmx_flags & DMX_ACTIVE) {
3285d07d0fcSkarels 				addr->dmz_octet[i].csr = DMF_IE;
3295d07d0fcSkarels 				addr->dmz_octet[i].rsp = dmx_timeout;
33015b1a157Smckusick 			}
33115b1a157Smckusick 
33215b1a157Smckusick 		/*
33315b1a157Smckusick 		 * If a unit is open or waiting for open to complete,
33415b1a157Smckusick 		 * reset it.
33515b1a157Smckusick 		 */
3365d07d0fcSkarels 		tp = &dmz_tty[dmz * 24];
3375d07d0fcSkarels 		for (i = 0; i < 24; i++, tp++) {
33815b1a157Smckusick 			if (tp->t_state & (TS_ISOPEN | TS_WOPEN)) {
339f6f5d34cSmarc 				dmxparam(tp, &tp->t_termios);
3405d07d0fcSkarels 				(void) dmxmctl(tp, DMF_ON, DMSET);
34115b1a157Smckusick 				tp->t_state &= ~TS_BUSY;
34215b1a157Smckusick 				dmzstart(tp);
34315b1a157Smckusick 			}
34415b1a157Smckusick 		}
34515b1a157Smckusick 	}
34615b1a157Smckusick }
34715b1a157Smckusick #endif
348