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