xref: /csrg-svn/sys/vax/uba/dmz.c (revision 39061)
125224Smckusick /*
229216Smckusick  * Copyright (c) 1985, 1986 Regents of the University of California.
325224Smckusick  * All rights reserved.  The Berkeley software License Agreement
425224Smckusick  * specifies the terms and conditions for redistribution.
525224Smckusick  *
6*39061Smarc  *	@(#)dmz.c	7.6 (Berkeley) 09/06/89
725224Smckusick  */
825224Smckusick 
925224Smckusick /*
1025224Smckusick  * DMZ-32 driver
1125224Smckusick  */
1225224Smckusick 
1325224Smckusick #include "dmz.h"
1425224Smckusick #if NDMZ > 0
1525224Smckusick 
1637511Smckusick #include "machine/pte.h"
1725224Smckusick 
1825224Smckusick #include "bk.h"
1925224Smckusick #include "uba.h"
2025224Smckusick #include "param.h"
2125224Smckusick #include "conf.h"
2225224Smckusick #include "dir.h"
2325224Smckusick #include "user.h"
2426837Skarels #include "proc.h"
2525224Smckusick #include "ioctl.h"
2625224Smckusick #include "tty.h"
2725224Smckusick #include "map.h"
2825224Smckusick #include "buf.h"
2925224Smckusick #include "vm.h"
3025224Smckusick #include "bkmac.h"
3125224Smckusick #include "clist.h"
3225224Smckusick #include "file.h"
3325224Smckusick #include "uio.h"
3425224Smckusick #include "kernel.h"
3525435Skarels #include "syslog.h"
3625224Smckusick 
3730537Skarels #include "dmx.h"
3825224Smckusick #include "ubareg.h"
3925224Smckusick #include "ubavar.h"
4030537Skarels #include "dmxreg.h"
4125224Smckusick #include "dmzreg.h"
4225655Skarels #include "dmreg.h"
4325224Smckusick 
4430537Skarels extern	int dmx_timeout;		/* silo timeout, in ms */
4530537Skarels int	dmzstart();
4625224Smckusick 
4725224Smckusick /*
4830322Skarels  * The clist space is mapped by one terminal driver onto each UNIBUS.
4930322Skarels  * The identity of the board which allocated resources is recorded,
5030322Skarels  * so the process may be repeated after UNIBUS resets.
5130322Skarels  * The UBACVT macro converts a clist space address for unibus uban
5230322Skarels  * into an i/o space address for the DMA routine.
5330322Skarels  */
5430322Skarels int	dmz_uballoc[NUBA];	/* which dmz (if any) allocated unibus map */
5530322Skarels int	cbase[NUBA];		/* base address of clists in unibus map */
5625224Smckusick 
5730537Skarels /*
5830537Skarels  * Autoconfiguration and variables for DMZ32
5930537Skarels  */
6030537Skarels int dmzprobe(), dmzattach();
6130537Skarels struct uba_device *dmzinfo[NDMZ];
6230537Skarels u_short dmzstd[] = { 0 };
6330537Skarels struct uba_driver dmzdriver = {
6430537Skarels 	dmzprobe, 0, dmzattach, 0, dmzstd, "dmz", dmzinfo
6530537Skarels };
6625224Smckusick 
6730537Skarels struct	tty dmz_tty[NDMZ*24];
6830537Skarels struct	dmx_softc dmz_softc[3 * NDMZ];
6930537Skarels #ifndef lint
7030537Skarels int	ndmz = NDMZ*24;			/* used by iostat */
7130537Skarels #endif
7230537Skarels 
7325224Smckusick dmzprobe(reg)
7425224Smckusick 	caddr_t reg;
7525224Smckusick {
7625224Smckusick 	register int br, cvec;
7725224Smckusick 	register struct dmzdevice *dmz_addr;
7825224Smckusick 	register unsigned int a;
7925224Smckusick 
8025224Smckusick 	dmz_addr = (struct dmzdevice *)reg;
8125224Smckusick 
8225224Smckusick #ifdef lint
8325224Smckusick 	br = 0; cvec = br; br = cvec; dmzxinta(0); dmzxintb(0); dmzxintc(0);
8425224Smckusick 	dmzrinta(0); dmzrintb(0); dmzrintc(0);
8525224Smckusick #endif
8625224Smckusick 
8725224Smckusick 	br = 0x15;
8825224Smckusick 
8925224Smckusick 	a = dmz_addr->dmz_config;
9025224Smckusick 	if (((a>>12) & ~DMZ_INTERFACE) != 0) {
9125224Smckusick 		printf("	Unknown interface type\n");
9225224Smckusick 		return (0);
9325224Smckusick 	}
9425224Smckusick 	if (((a>>8) & DMZ_NOC_MASK) != 3) {
9525224Smckusick 		printf("	Not all octets are available\n");
9625224Smckusick 		return (0);
9725224Smckusick 	}
9825224Smckusick 
9925224Smckusick 	cvec = (uba_hd[numuba].uh_lastiv -= 4 * 6);
10025224Smckusick 	dmz_addr->dmz_config = cvec >> 2;
10125224Smckusick 
10225224Smckusick 	return (sizeof(struct dmzdevice));
10325224Smckusick }
10425224Smckusick 
10525224Smckusick dmzattach(ui)
10630537Skarels 	register struct uba_device *ui;
10725224Smckusick {
10830537Skarels 	register struct dmx_softc *sc;
10930537Skarels 	register int i;
11030537Skarels 
11130537Skarels 	sc = &dmz_softc[3 * ui->ui_unit];
11230537Skarels 	for (i = 0; i < 3; i++, sc++) {
11330537Skarels 		sc->dmx_type = 'z';
11430537Skarels 		sc->dmx_unit = ui->ui_unit;
11530537Skarels 		sc->dmx_unit0 = 8 * i;
11630537Skarels 		sc->dmx_ubanum = ui->ui_ubanum;
11730537Skarels 		sc->dmx_softCAR = (ui->ui_flags >> (8 * i)) & 0xff;
11830537Skarels 		sc->dmx_tty = &dmz_tty[((ui->ui_unit * 3) + i) * 8];
11930537Skarels 		sc->dmx_octet = (struct dmx_octet *)
12030537Skarels 		    &((struct dmzdevice *)ui->ui_addr)->dmz_octet[i];
12130537Skarels 	}
12230537Skarels 
12326218Skarels 	cbase[ui->ui_ubanum] = -1;
12436610Sbostic 	dmz_uballoc[ui->ui_ubanum] = -1;
12525224Smckusick }
12625224Smckusick 
12730537Skarels /*
12830537Skarels  * Open a DMF32 line, mapping the clist onto the uba if this
12930537Skarels  * is the first dmf on this uba.  Turn on this dmf if this is
13030537Skarels  * the first use of it.
13130537Skarels  */
13230537Skarels /*ARGSUSED*/
13330537Skarels dmzopen(dev, flag)
13430537Skarels 	dev_t dev;
13525224Smckusick {
13625224Smckusick 	register struct tty *tp;
13730537Skarels 	struct dmx_softc *sc;
13830537Skarels 	int unit, dmz;
13930537Skarels 	struct uba_device *ui;
14030537Skarels 	int s;
141*39061Smarc 	int dmxparam();
14225224Smckusick 
14330537Skarels 	unit = minor(dev);
14430537Skarels 	dmz = DMZ(unit);
14530537Skarels 	if (unit >= NDMZ*24 || (ui = dmzinfo[dmz])== 0 || ui->ui_alive == 0)
14625224Smckusick 		return (ENXIO);
14725224Smckusick 
14825224Smckusick 	tp = &dmz_tty[unit];
14930537Skarels 	sc = &dmz_softc[unit / 8];
15030537Skarels 	tp->t_addr = (caddr_t)sc->dmx_octet;
15125224Smckusick 	tp->t_oproc = dmzstart;
15230537Skarels 	tp->t_dev = dev;			/* needed before dmxopen */
153*39061Smarc 	tp->t_param = dmxparam;
15425224Smckusick 
15525224Smckusick 	/*
15630537Skarels 	 * While setting up state for this uba,
15730537Skarels 	 * block uba resets which can clear the state.
15825224Smckusick 	 */
15930537Skarels 	s = spl6();
16026218Skarels 	if (cbase[ui->ui_ubanum] == -1) {
16130537Skarels 		dmz_uballoc[ui->ui_ubanum] = dmz;
16230322Skarels 		cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum,
16330322Skarels 		    (caddr_t)cfree, nclist*sizeof(struct cblock), 0));
16425224Smckusick 	}
16530537Skarels 	splx(s);
16625224Smckusick 
167*39061Smarc 	return (dmxopen(tp, sc, flag));
16825224Smckusick }
16925224Smckusick 
17030537Skarels /*
17130537Skarels  * Close a DMZ32 line.
17230537Skarels  */
17330537Skarels /*ARGSUSED*/
17430537Skarels dmzclose(dev, flag)
17530537Skarels 	dev_t dev;
17625224Smckusick 	int flag;
17725224Smckusick {
17825224Smckusick 
17930537Skarels 	dmxclose(&dmz_tty[minor(dev)]);
18025224Smckusick }
18125224Smckusick 
182*39061Smarc dmzread(dev, uio, flag)
18330537Skarels 	dev_t dev;
18430537Skarels 	struct uio *uio;
18525224Smckusick {
18625224Smckusick 	register struct tty *tp;
18725224Smckusick 
18830537Skarels 	tp = &dmz_tty[minor(dev)];
189*39061Smarc 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
19025224Smckusick }
19125224Smckusick 
19230537Skarels dmzwrite(dev, uio)
19330537Skarels 	dev_t dev;
19425224Smckusick 	struct uio *uio;
19525224Smckusick {
19625224Smckusick 	register struct tty *tp;
19725224Smckusick 
19830537Skarels 	tp = &dmz_tty[minor(dev)];
19930537Skarels 	return ((*linesw[tp->t_line].l_write)(tp, uio));
20025224Smckusick }
20125224Smckusick 
20230537Skarels /*
20330537Skarels  * DMZ32 receiver interrupts.
20430537Skarels  */
20530537Skarels dmzrinta(dmz)
20630537Skarels 	int dmz;
20725224Smckusick {
20830537Skarels 	struct uba_device *ui;
20925224Smckusick 
21030537Skarels 	ui = dmzinfo[dmz];
21130537Skarels 	if (ui == 0 || ui->ui_alive == 0)
21230537Skarels 		return;
21330537Skarels 	dmxrint(&dmz_softc[3 * dmz + 0]);
21425224Smckusick }
21525224Smckusick 
21630537Skarels dmzrintb(dmz)
21730537Skarels 	int dmz;
21825224Smckusick {
21930537Skarels 	struct uba_device *ui;
22025224Smckusick 
22130537Skarels 	ui = dmzinfo[dmz];
22230537Skarels 	if (ui == 0 || ui->ui_alive == 0)
22330537Skarels 		return;
22430537Skarels 	dmxrint(&dmz_softc[3 * dmz + 1]);
22525224Smckusick }
22625224Smckusick 
22730537Skarels dmzrintc(dmz)
22830537Skarels 	int dmz;
22925224Smckusick {
23030537Skarels 	struct uba_device *ui;
23125224Smckusick 
23230537Skarels 	ui = dmzinfo[dmz];
23325224Smckusick 	if (ui == 0 || ui->ui_alive == 0)
23425224Smckusick 		return;
23530537Skarels 	dmxrint(&dmz_softc[3 * dmz + 2]);
23625224Smckusick }
23725224Smckusick 
23830537Skarels /*
23930537Skarels  * Ioctl for DMZ32.
24030537Skarels  */
24130537Skarels dmzioctl(dev, cmd, data, flag)
24230537Skarels 	dev_t dev;
24330537Skarels 	caddr_t data;
24425224Smckusick {
24530537Skarels 	int unit = minor(dev);
24630537Skarels 
24730537Skarels 	return (dmxioctl(&dmz_tty[unit], cmd, data, flag));
24825224Smckusick }
24925224Smckusick 
25030537Skarels /*
25130537Skarels  * DMZ32 transmitter interrupts.
25230537Skarels  */
25330537Skarels dmzxinta(dmz)
25430537Skarels 	int dmz;
25525224Smckusick {
25630537Skarels 
25730537Skarels 	dmxxint(&dmz_softc[3 * dmz + 0]);
25825224Smckusick }
25925224Smckusick 
26030537Skarels dmzxintb(dmz)
26130537Skarels 	int dmz;
26225224Smckusick {
26330537Skarels 
26430537Skarels 	dmxxint(&dmz_softc[3 * dmz + 1]);
26525224Smckusick }
26625224Smckusick 
26730537Skarels dmzxintc(dmz)
26830537Skarels 	int dmz;
26925224Smckusick {
27025224Smckusick 
27130537Skarels 	dmxxint(&dmz_softc[3 * dmz + 2]);
27225224Smckusick }
27325224Smckusick 
27430537Skarels /*
27530537Skarels  * Start (restart) transmission on the given line.
27630537Skarels  */
27725224Smckusick dmzstart(tp)
27830537Skarels 	struct tty *tp;
27925224Smckusick {
28025224Smckusick 
28130537Skarels 	dmxstart(tp, &dmz_softc[minor(tp->t_dev) >> 3]);
28225224Smckusick }
28325224Smckusick 
28430537Skarels /*
28530537Skarels  * Stop output on a line, e.g. for ^S/^Q or output flush.
28630537Skarels  */
28725224Smckusick dmzstop(tp, flag)
28830537Skarels 	struct tty *tp;
28925224Smckusick {
29025224Smckusick 
29130537Skarels 	dmxstop(tp, &dmz_softc[minor(tp->t_dev) >> 3], flag);
29225224Smckusick }
29325224Smckusick 
29430537Skarels /*
29530537Skarels  * Reset state of driver if UBA reset was necessary.
29630537Skarels  * Reset the csr, lpr, and lcr registers on open lines, and
29730537Skarels  * restart transmitters.
29830537Skarels  */
29930537Skarels dmzreset(uban)
30030537Skarels 	int uban;
30125224Smckusick {
30230537Skarels 	register int dmz;
30325224Smckusick 	register struct tty *tp;
30430537Skarels 	register struct uba_device *ui;
30530537Skarels 	register struct dmzdevice *addr;
30630537Skarels 	int i;
30725224Smckusick 
30830537Skarels 	for (dmz = 0; dmz < NDMZ; dmz++) {
30930537Skarels 		ui = dmzinfo[dmz];
31030537Skarels 		if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
31130537Skarels 			continue;
31230537Skarels 		printf("dmz%d ", dmz);
31330537Skarels 		addr = (struct dmzdevice *)ui->ui_addr;
31425224Smckusick 
31530537Skarels 		if (dmz_uballoc[uban] == dmz) {
31630537Skarels 			int info;
31725224Smckusick 
31830537Skarels 			info = uballoc(uban, (caddr_t)cfree,
31930537Skarels 			    nclist * sizeof(struct cblock), UBA_CANTWAIT);
32030537Skarels 			if (info)
32130537Skarels 				cbase[uban] = UBAI_ADDR(info);
32230537Skarels 			else {
32330537Skarels 				printf(" [can't get uba map]");
32430537Skarels 				cbase[uban] = -1;
32530537Skarels 			}
32630537Skarels 		}
32725224Smckusick 
32830537Skarels 		for (i = 0; i < 3; i++)
32930537Skarels 			if (dmz_softc[3 * dmz + i].dmx_flags & DMX_ACTIVE) {
33030537Skarels 				addr->dmz_octet[i].csr = DMF_IE;
33130537Skarels 				addr->dmz_octet[i].rsp = dmx_timeout;
33230537Skarels 			}
33325224Smckusick 
33430537Skarels 		/*
33530537Skarels 		 * If a unit is open or waiting for open to complete,
33630537Skarels 		 * reset it.
33730537Skarels 		 */
33830537Skarels 		tp = &dmz_tty[dmz * 24];
33930537Skarels 		for (i = 0; i < 24; i++, tp++) {
34030537Skarels 			if (tp->t_state & (TS_ISOPEN | TS_WOPEN)) {
341*39061Smarc 				dmxparam(tp, &tp->t_termios);
34230537Skarels 				(void) dmxmctl(tp, DMF_ON, DMSET);
34330537Skarels 				tp->t_state &= ~TS_BUSY;
34430537Skarels 				dmzstart(tp);
34530537Skarels 			}
34630537Skarels 		}
34725224Smckusick 	}
34825224Smckusick }
34925224Smckusick #endif
350