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*49759Smarc * @(#)dmz.c 7.12 (Berkeley) 05/16/91
725224Smckusick */
825224Smckusick
925224Smckusick /*
1025224Smckusick * DMZ-32 driver
1125224Smckusick */
1225224Smckusick
1325224Smckusick #include "dmz.h"
1425224Smckusick #if NDMZ > 0
1525224Smckusick
1645804Sbostic #include "../include/pte.h"
1725224Smckusick
1845804Sbostic #include "sys/param.h"
1925224Smckusick #include "uba.h"
2045804Sbostic #include "sys/conf.h"
2145804Sbostic #include "sys/user.h"
2245804Sbostic #include "sys/proc.h"
2345804Sbostic #include "sys/ioctl.h"
2445804Sbostic #include "sys/tty.h"
2545804Sbostic #include "sys/map.h"
2645804Sbostic #include "sys/buf.h"
2745804Sbostic #include "sys/vm.h"
2845804Sbostic #include "sys/clist.h"
2945804Sbostic #include "sys/file.h"
3045804Sbostic #include "sys/uio.h"
3145804Sbostic #include "sys/kernel.h"
3245804Sbostic #include "sys/syslog.h"
3325224Smckusick
3430537Skarels #include "dmx.h"
3525224Smckusick #include "ubareg.h"
3625224Smckusick #include "ubavar.h"
3730537Skarels #include "dmxreg.h"
3825224Smckusick #include "dmzreg.h"
3925655Skarels #include "dmreg.h"
4025224Smckusick
4130537Skarels extern int dmx_timeout; /* silo timeout, in ms */
4230537Skarels int dmzstart();
4325224Smckusick
4425224Smckusick /*
4530322Skarels * The clist space is mapped by one terminal driver onto each UNIBUS.
4630322Skarels * The identity of the board which allocated resources is recorded,
4730322Skarels * so the process may be repeated after UNIBUS resets.
4830322Skarels * The UBACVT macro converts a clist space address for unibus uban
4930322Skarels * into an i/o space address for the DMA routine.
5030322Skarels */
5130322Skarels int dmz_uballoc[NUBA]; /* which dmz (if any) allocated unibus map */
5230322Skarels int cbase[NUBA]; /* base address of clists in unibus map */
5325224Smckusick
5430537Skarels /*
5530537Skarels * Autoconfiguration and variables for DMZ32
5630537Skarels */
5730537Skarels int dmzprobe(), dmzattach();
5830537Skarels struct uba_device *dmzinfo[NDMZ];
5930537Skarels u_short dmzstd[] = { 0 };
6030537Skarels struct uba_driver dmzdriver = {
6130537Skarels dmzprobe, 0, dmzattach, 0, dmzstd, "dmz", dmzinfo
6230537Skarels };
6325224Smckusick
6430537Skarels struct tty dmz_tty[NDMZ*24];
6530537Skarels struct dmx_softc dmz_softc[3 * NDMZ];
6630537Skarels #ifndef lint
6730537Skarels int ndmz = NDMZ*24; /* used by iostat */
6830537Skarels #endif
6930537Skarels
dmzprobe(reg)7025224Smckusick dmzprobe(reg)
7125224Smckusick caddr_t reg;
7225224Smckusick {
7325224Smckusick register int br, cvec;
7425224Smckusick register struct dmzdevice *dmz_addr;
7525224Smckusick register unsigned int a;
7625224Smckusick
7725224Smckusick dmz_addr = (struct dmzdevice *)reg;
7825224Smckusick
7925224Smckusick #ifdef lint
8025224Smckusick br = 0; cvec = br; br = cvec; dmzxinta(0); dmzxintb(0); dmzxintc(0);
8125224Smckusick dmzrinta(0); dmzrintb(0); dmzrintc(0);
8225224Smckusick #endif
8325224Smckusick
8425224Smckusick br = 0x15;
8525224Smckusick
8625224Smckusick a = dmz_addr->dmz_config;
8725224Smckusick if (((a>>12) & ~DMZ_INTERFACE) != 0) {
8825224Smckusick printf(" Unknown interface type\n");
8925224Smckusick return (0);
9025224Smckusick }
9125224Smckusick if (((a>>8) & DMZ_NOC_MASK) != 3) {
9225224Smckusick printf(" Not all octets are available\n");
9325224Smckusick return (0);
9425224Smckusick }
9525224Smckusick
9625224Smckusick cvec = (uba_hd[numuba].uh_lastiv -= 4 * 6);
9725224Smckusick dmz_addr->dmz_config = cvec >> 2;
9825224Smckusick
9925224Smckusick return (sizeof(struct dmzdevice));
10025224Smckusick }
10125224Smckusick
dmzattach(ui)10225224Smckusick dmzattach(ui)
10330537Skarels register struct uba_device *ui;
10425224Smckusick {
10530537Skarels register struct dmx_softc *sc;
10630537Skarels register int i;
10730537Skarels
10830537Skarels sc = &dmz_softc[3 * ui->ui_unit];
10930537Skarels for (i = 0; i < 3; i++, sc++) {
11030537Skarels sc->dmx_type = 'z';
11130537Skarels sc->dmx_unit = ui->ui_unit;
11230537Skarels sc->dmx_unit0 = 8 * i;
11330537Skarels sc->dmx_ubanum = ui->ui_ubanum;
11430537Skarels sc->dmx_softCAR = (ui->ui_flags >> (8 * i)) & 0xff;
11530537Skarels sc->dmx_tty = &dmz_tty[((ui->ui_unit * 3) + i) * 8];
11630537Skarels sc->dmx_octet = (struct dmx_octet *)
11730537Skarels &((struct dmzdevice *)ui->ui_addr)->dmz_octet[i];
11830537Skarels }
11930537Skarels
12026218Skarels cbase[ui->ui_ubanum] = -1;
12136610Sbostic dmz_uballoc[ui->ui_ubanum] = -1;
12225224Smckusick }
12325224Smckusick
12430537Skarels /*
12530537Skarels * Open a DMF32 line, mapping the clist onto the uba if this
12630537Skarels * is the first dmf on this uba. Turn on this dmf if this is
12730537Skarels * the first use of it.
12830537Skarels */
12930537Skarels /*ARGSUSED*/
dmzopen(dev,flag)13030537Skarels dmzopen(dev, flag)
13130537Skarels dev_t dev;
13225224Smckusick {
13325224Smckusick register struct tty *tp;
13430537Skarels struct dmx_softc *sc;
13530537Skarels int unit, dmz;
13630537Skarels struct uba_device *ui;
13730537Skarels int s;
13839061Smarc int dmxparam();
13925224Smckusick
14030537Skarels unit = minor(dev);
14130537Skarels dmz = DMZ(unit);
14230537Skarels if (unit >= NDMZ*24 || (ui = dmzinfo[dmz])== 0 || ui->ui_alive == 0)
14325224Smckusick return (ENXIO);
14425224Smckusick
14525224Smckusick tp = &dmz_tty[unit];
14630537Skarels sc = &dmz_softc[unit / 8];
14730537Skarels tp->t_addr = (caddr_t)sc->dmx_octet;
14825224Smckusick tp->t_oproc = dmzstart;
14930537Skarels tp->t_dev = dev; /* needed before dmxopen */
15039061Smarc tp->t_param = dmxparam;
15125224Smckusick
15225224Smckusick /*
15330537Skarels * While setting up state for this uba,
15430537Skarels * block uba resets which can clear the state.
15525224Smckusick */
15630537Skarels s = spl6();
15726218Skarels if (cbase[ui->ui_ubanum] == -1) {
15830537Skarels dmz_uballoc[ui->ui_ubanum] = dmz;
15930322Skarels cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum,
16030322Skarels (caddr_t)cfree, nclist*sizeof(struct cblock), 0));
16125224Smckusick }
16230537Skarels splx(s);
16325224Smckusick
16439061Smarc return (dmxopen(tp, sc, flag));
16525224Smckusick }
16625224Smckusick
16730537Skarels /*
16830537Skarels * Close a DMZ32 line.
16930537Skarels */
17030537Skarels /*ARGSUSED*/
dmzclose(dev,flag,mode,p)171*49759Smarc dmzclose(dev, flag, mode, p)
17230537Skarels dev_t dev;
173*49759Smarc int flag, mode;
174*49759Smarc struct proc *p;
17525224Smckusick {
17625224Smckusick
177*49759Smarc return (dmxclose(&dmz_tty[minor(dev)]), flag);
17825224Smckusick }
17925224Smckusick
dmzread(dev,uio,flag)18039061Smarc dmzread(dev, uio, flag)
18130537Skarels dev_t dev;
18230537Skarels struct uio *uio;
18325224Smckusick {
18425224Smckusick register struct tty *tp;
18525224Smckusick
18630537Skarels tp = &dmz_tty[minor(dev)];
18739061Smarc return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
18825224Smckusick }
18925224Smckusick
dmzwrite(dev,uio)19030537Skarels dmzwrite(dev, uio)
19130537Skarels dev_t dev;
19225224Smckusick struct uio *uio;
19325224Smckusick {
19425224Smckusick register struct tty *tp;
19525224Smckusick
19630537Skarels tp = &dmz_tty[minor(dev)];
19730537Skarels return ((*linesw[tp->t_line].l_write)(tp, uio));
19825224Smckusick }
19925224Smckusick
20030537Skarels /*
20130537Skarels * DMZ32 receiver interrupts.
20230537Skarels */
dmzrinta(dmz)20330537Skarels dmzrinta(dmz)
20430537Skarels int dmz;
20525224Smckusick {
20630537Skarels struct uba_device *ui;
20725224Smckusick
20830537Skarels ui = dmzinfo[dmz];
20930537Skarels if (ui == 0 || ui->ui_alive == 0)
21030537Skarels return;
21130537Skarels dmxrint(&dmz_softc[3 * dmz + 0]);
21225224Smckusick }
21325224Smckusick
dmzrintb(dmz)21430537Skarels dmzrintb(dmz)
21530537Skarels int dmz;
21625224Smckusick {
21730537Skarels struct uba_device *ui;
21825224Smckusick
21930537Skarels ui = dmzinfo[dmz];
22030537Skarels if (ui == 0 || ui->ui_alive == 0)
22130537Skarels return;
22230537Skarels dmxrint(&dmz_softc[3 * dmz + 1]);
22325224Smckusick }
22425224Smckusick
dmzrintc(dmz)22530537Skarels dmzrintc(dmz)
22630537Skarels int dmz;
22725224Smckusick {
22830537Skarels struct uba_device *ui;
22925224Smckusick
23030537Skarels ui = dmzinfo[dmz];
23125224Smckusick if (ui == 0 || ui->ui_alive == 0)
23225224Smckusick return;
23330537Skarels dmxrint(&dmz_softc[3 * dmz + 2]);
23425224Smckusick }
23525224Smckusick
23630537Skarels /*
23730537Skarels * Ioctl for DMZ32.
23830537Skarels */
dmzioctl(dev,cmd,data,flag)23930537Skarels dmzioctl(dev, cmd, data, flag)
24030537Skarels dev_t dev;
24130537Skarels caddr_t data;
24225224Smckusick {
24330537Skarels int unit = minor(dev);
24430537Skarels
24530537Skarels return (dmxioctl(&dmz_tty[unit], cmd, data, flag));
24625224Smckusick }
24725224Smckusick
24830537Skarels /*
24930537Skarels * DMZ32 transmitter interrupts.
25030537Skarels */
dmzxinta(dmz)25130537Skarels dmzxinta(dmz)
25230537Skarels int dmz;
25325224Smckusick {
25430537Skarels
25530537Skarels dmxxint(&dmz_softc[3 * dmz + 0]);
25625224Smckusick }
25725224Smckusick
dmzxintb(dmz)25830537Skarels dmzxintb(dmz)
25930537Skarels int dmz;
26025224Smckusick {
26130537Skarels
26230537Skarels dmxxint(&dmz_softc[3 * dmz + 1]);
26325224Smckusick }
26425224Smckusick
dmzxintc(dmz)26530537Skarels dmzxintc(dmz)
26630537Skarels int dmz;
26725224Smckusick {
26825224Smckusick
26930537Skarels dmxxint(&dmz_softc[3 * dmz + 2]);
27025224Smckusick }
27125224Smckusick
27230537Skarels /*
27330537Skarels * Start (restart) transmission on the given line.
27430537Skarels */
27525224Smckusick dmzstart(tp)
27630537Skarels struct tty *tp;
27725224Smckusick {
27825224Smckusick
27930537Skarels dmxstart(tp, &dmz_softc[minor(tp->t_dev) >> 3]);
28025224Smckusick }
28125224Smckusick
28230537Skarels /*
28330537Skarels * Stop output on a line, e.g. for ^S/^Q or output flush.
28430537Skarels */
28525224Smckusick dmzstop(tp, flag)
28630537Skarels struct tty *tp;
28725224Smckusick {
28825224Smckusick
28930537Skarels dmxstop(tp, &dmz_softc[minor(tp->t_dev) >> 3], flag);
29025224Smckusick }
29125224Smckusick
29230537Skarels /*
29330537Skarels * Reset state of driver if UBA reset was necessary.
29430537Skarels * Reset the csr, lpr, and lcr registers on open lines, and
29530537Skarels * restart transmitters.
29630537Skarels */
dmzreset(uban)29730537Skarels dmzreset(uban)
29830537Skarels int uban;
29925224Smckusick {
30030537Skarels register int dmz;
30125224Smckusick register struct tty *tp;
30230537Skarels register struct uba_device *ui;
30330537Skarels register struct dmzdevice *addr;
30430537Skarels int i;
30525224Smckusick
30630537Skarels for (dmz = 0; dmz < NDMZ; dmz++) {
30730537Skarels ui = dmzinfo[dmz];
30830537Skarels if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
30930537Skarels continue;
31030537Skarels printf("dmz%d ", dmz);
31130537Skarels addr = (struct dmzdevice *)ui->ui_addr;
31225224Smckusick
31330537Skarels if (dmz_uballoc[uban] == dmz) {
31430537Skarels int info;
31525224Smckusick
31630537Skarels info = uballoc(uban, (caddr_t)cfree,
31730537Skarels nclist * sizeof(struct cblock), UBA_CANTWAIT);
31830537Skarels if (info)
31930537Skarels cbase[uban] = UBAI_ADDR(info);
32030537Skarels else {
32130537Skarels printf(" [can't get uba map]");
32230537Skarels cbase[uban] = -1;
32330537Skarels }
32430537Skarels }
32525224Smckusick
32630537Skarels for (i = 0; i < 3; i++)
32730537Skarels if (dmz_softc[3 * dmz + i].dmx_flags & DMX_ACTIVE) {
32830537Skarels addr->dmz_octet[i].csr = DMF_IE;
32930537Skarels addr->dmz_octet[i].rsp = dmx_timeout;
33030537Skarels }
33125224Smckusick
33230537Skarels /*
33330537Skarels * If a unit is open or waiting for open to complete,
33430537Skarels * reset it.
33530537Skarels */
33630537Skarels tp = &dmz_tty[dmz * 24];
33730537Skarels for (i = 0; i < 24; i++, tp++) {
33830537Skarels if (tp->t_state & (TS_ISOPEN | TS_WOPEN)) {
33939061Smarc dmxparam(tp, &tp->t_termios);
34030537Skarels (void) dmxmctl(tp, DMF_ON, DMSET);
34130537Skarels tp->t_state &= ~TS_BUSY;
34230537Skarels dmzstart(tp);
34330537Skarels }
34430537Skarels }
34525224Smckusick }
34625224Smckusick }
34725224Smckusick #endif
348