|
|
1.1 root 1: /*
2: * Copyright (c) 1985, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)dmz.c 7.9 (Berkeley) 4/12/90
7: */
8:
9: /*
10: * DMZ-32 driver
11: */
12:
13: #include "dmz.h"
14: #if NDMZ > 0
15:
16: #include "machine/pte.h"
17:
18: #include "uba.h"
19: #include "param.h"
20: #include "conf.h"
21: #include "user.h"
22: #include "proc.h"
23: #include "ioctl.h"
24: #include "tty.h"
25: #include "map.h"
26: #include "buf.h"
27: #include "vm.h"
28: #include "bkmac.h"
29: #include "clist.h"
30: #include "file.h"
31: #include "uio.h"
32: #include "kernel.h"
33: #include "syslog.h"
34:
35: #include "dmx.h"
36: #include "ubareg.h"
37: #include "ubavar.h"
38: #include "dmxreg.h"
39: #include "dmzreg.h"
40: #include "dmreg.h"
41:
42: extern int dmx_timeout; /* silo timeout, in ms */
43: int dmzstart();
44:
45: /*
46: * The clist space is mapped by one terminal driver onto each UNIBUS.
47: * The identity of the board which allocated resources is recorded,
48: * so the process may be repeated after UNIBUS resets.
49: * The UBACVT macro converts a clist space address for unibus uban
50: * into an i/o space address for the DMA routine.
51: */
52: int dmz_uballoc[NUBA]; /* which dmz (if any) allocated unibus map */
53: int cbase[NUBA]; /* base address of clists in unibus map */
54:
55: /*
56: * Autoconfiguration and variables for DMZ32
57: */
58: int dmzprobe(), dmzattach();
59: struct uba_device *dmzinfo[NDMZ];
60: u_short dmzstd[] = { 0 };
61: struct uba_driver dmzdriver = {
62: dmzprobe, 0, dmzattach, 0, dmzstd, "dmz", dmzinfo
63: };
64:
65: struct tty dmz_tty[NDMZ*24];
66: struct dmx_softc dmz_softc[3 * NDMZ];
67: #ifndef lint
68: int ndmz = NDMZ*24; /* used by iostat */
69: #endif
70:
71: dmzprobe(reg)
72: caddr_t reg;
73: {
74: register int br, cvec;
75: register struct dmzdevice *dmz_addr;
76: register unsigned int a;
77:
78: dmz_addr = (struct dmzdevice *)reg;
79:
80: #ifdef lint
81: br = 0; cvec = br; br = cvec; dmzxinta(0); dmzxintb(0); dmzxintc(0);
82: dmzrinta(0); dmzrintb(0); dmzrintc(0);
83: #endif
84:
85: br = 0x15;
86:
87: a = dmz_addr->dmz_config;
88: if (((a>>12) & ~DMZ_INTERFACE) != 0) {
89: printf(" Unknown interface type\n");
90: return (0);
91: }
92: if (((a>>8) & DMZ_NOC_MASK) != 3) {
93: printf(" Not all octets are available\n");
94: return (0);
95: }
96:
97: cvec = (uba_hd[numuba].uh_lastiv -= 4 * 6);
98: dmz_addr->dmz_config = cvec >> 2;
99:
100: return (sizeof(struct dmzdevice));
101: }
102:
103: dmzattach(ui)
104: register struct uba_device *ui;
105: {
106: register struct dmx_softc *sc;
107: register int i;
108:
109: sc = &dmz_softc[3 * ui->ui_unit];
110: for (i = 0; i < 3; i++, sc++) {
111: sc->dmx_type = 'z';
112: sc->dmx_unit = ui->ui_unit;
113: sc->dmx_unit0 = 8 * i;
114: sc->dmx_ubanum = ui->ui_ubanum;
115: sc->dmx_softCAR = (ui->ui_flags >> (8 * i)) & 0xff;
116: sc->dmx_tty = &dmz_tty[((ui->ui_unit * 3) + i) * 8];
117: sc->dmx_octet = (struct dmx_octet *)
118: &((struct dmzdevice *)ui->ui_addr)->dmz_octet[i];
119: }
120:
121: cbase[ui->ui_ubanum] = -1;
122: dmz_uballoc[ui->ui_ubanum] = -1;
123: }
124:
125: /*
126: * Open a DMF32 line, mapping the clist onto the uba if this
127: * is the first dmf on this uba. Turn on this dmf if this is
128: * the first use of it.
129: */
130: /*ARGSUSED*/
131: dmzopen(dev, flag)
132: dev_t dev;
133: {
134: register struct tty *tp;
135: struct dmx_softc *sc;
136: int unit, dmz;
137: struct uba_device *ui;
138: int s;
139: int dmxparam();
140:
141: unit = minor(dev);
142: dmz = DMZ(unit);
143: if (unit >= NDMZ*24 || (ui = dmzinfo[dmz])== 0 || ui->ui_alive == 0)
144: return (ENXIO);
145:
146: tp = &dmz_tty[unit];
147: sc = &dmz_softc[unit / 8];
148: tp->t_addr = (caddr_t)sc->dmx_octet;
149: tp->t_oproc = dmzstart;
150: tp->t_dev = dev; /* needed before dmxopen */
151: tp->t_param = dmxparam;
152:
153: /*
154: * While setting up state for this uba,
155: * block uba resets which can clear the state.
156: */
157: s = spl6();
158: if (cbase[ui->ui_ubanum] == -1) {
159: dmz_uballoc[ui->ui_ubanum] = dmz;
160: cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum,
161: (caddr_t)cfree, nclist*sizeof(struct cblock), 0));
162: }
163: splx(s);
164:
165: return (dmxopen(tp, sc, flag));
166: }
167:
168: /*
169: * Close a DMZ32 line.
170: */
171: /*ARGSUSED*/
172: dmzclose(dev, flag)
173: dev_t dev;
174: int flag;
175: {
176:
177: return (dmxclose(&dmz_tty[minor(dev)]));
178: }
179:
180: dmzread(dev, uio, flag)
181: dev_t dev;
182: struct uio *uio;
183: {
184: register struct tty *tp;
185:
186: tp = &dmz_tty[minor(dev)];
187: return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
188: }
189:
190: dmzwrite(dev, uio)
191: dev_t dev;
192: struct uio *uio;
193: {
194: register struct tty *tp;
195:
196: tp = &dmz_tty[minor(dev)];
197: return ((*linesw[tp->t_line].l_write)(tp, uio));
198: }
199:
200: /*
201: * DMZ32 receiver interrupts.
202: */
203: dmzrinta(dmz)
204: int dmz;
205: {
206: struct uba_device *ui;
207:
208: ui = dmzinfo[dmz];
209: if (ui == 0 || ui->ui_alive == 0)
210: return;
211: dmxrint(&dmz_softc[3 * dmz + 0]);
212: }
213:
214: dmzrintb(dmz)
215: int dmz;
216: {
217: struct uba_device *ui;
218:
219: ui = dmzinfo[dmz];
220: if (ui == 0 || ui->ui_alive == 0)
221: return;
222: dmxrint(&dmz_softc[3 * dmz + 1]);
223: }
224:
225: dmzrintc(dmz)
226: int dmz;
227: {
228: struct uba_device *ui;
229:
230: ui = dmzinfo[dmz];
231: if (ui == 0 || ui->ui_alive == 0)
232: return;
233: dmxrint(&dmz_softc[3 * dmz + 2]);
234: }
235:
236: /*
237: * Ioctl for DMZ32.
238: */
239: dmzioctl(dev, cmd, data, flag)
240: dev_t dev;
241: caddr_t data;
242: {
243: int unit = minor(dev);
244:
245: return (dmxioctl(&dmz_tty[unit], cmd, data, flag));
246: }
247:
248: /*
249: * DMZ32 transmitter interrupts.
250: */
251: dmzxinta(dmz)
252: int dmz;
253: {
254:
255: dmxxint(&dmz_softc[3 * dmz + 0]);
256: }
257:
258: dmzxintb(dmz)
259: int dmz;
260: {
261:
262: dmxxint(&dmz_softc[3 * dmz + 1]);
263: }
264:
265: dmzxintc(dmz)
266: int dmz;
267: {
268:
269: dmxxint(&dmz_softc[3 * dmz + 2]);
270: }
271:
272: /*
273: * Start (restart) transmission on the given line.
274: */
275: dmzstart(tp)
276: struct tty *tp;
277: {
278:
279: dmxstart(tp, &dmz_softc[minor(tp->t_dev) >> 3]);
280: }
281:
282: /*
283: * Stop output on a line, e.g. for ^S/^Q or output flush.
284: */
285: dmzstop(tp, flag)
286: struct tty *tp;
287: {
288:
289: dmxstop(tp, &dmz_softc[minor(tp->t_dev) >> 3], flag);
290: }
291:
292: /*
293: * Reset state of driver if UBA reset was necessary.
294: * Reset the csr, lpr, and lcr registers on open lines, and
295: * restart transmitters.
296: */
297: dmzreset(uban)
298: int uban;
299: {
300: register int dmz;
301: register struct tty *tp;
302: register struct uba_device *ui;
303: register struct dmzdevice *addr;
304: int i;
305:
306: for (dmz = 0; dmz < NDMZ; dmz++) {
307: ui = dmzinfo[dmz];
308: if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
309: continue;
310: printf("dmz%d ", dmz);
311: addr = (struct dmzdevice *)ui->ui_addr;
312:
313: if (dmz_uballoc[uban] == dmz) {
314: int info;
315:
316: info = uballoc(uban, (caddr_t)cfree,
317: nclist * sizeof(struct cblock), UBA_CANTWAIT);
318: if (info)
319: cbase[uban] = UBAI_ADDR(info);
320: else {
321: printf(" [can't get uba map]");
322: cbase[uban] = -1;
323: }
324: }
325:
326: for (i = 0; i < 3; i++)
327: if (dmz_softc[3 * dmz + i].dmx_flags & DMX_ACTIVE) {
328: addr->dmz_octet[i].csr = DMF_IE;
329: addr->dmz_octet[i].rsp = dmx_timeout;
330: }
331:
332: /*
333: * If a unit is open or waiting for open to complete,
334: * reset it.
335: */
336: tp = &dmz_tty[dmz * 24];
337: for (i = 0; i < 24; i++, tp++) {
338: if (tp->t_state & (TS_ISOPEN | TS_WOPEN)) {
339: dmxparam(tp, &tp->t_termios);
340: (void) dmxmctl(tp, DMF_ON, DMSET);
341: tp->t_state &= ~TS_BUSY;
342: dmzstart(tp);
343: }
344: }
345: }
346: }
347: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.