|
|
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: * @(#)dhu.c 7.2 (Berkeley) 12/19/86
7: */
8:
9: /*
10: * based on dh.c 6.3 84/03/15
11: * and on dmf.c 6.2 84/02/16
12: *
13: * Dave Johnson, Brown University Computer Science
14: * ddj%brown@csnet-relay
15: */
16:
17: #include "dhu.h"
18: #if NDHU > 0
19: /*
20: * DHU-11 driver
21: */
22: #include "../machine/pte.h"
23:
24: #include "bk.h"
25: #include "param.h"
26: #include "conf.h"
27: #include "dir.h"
28: #include "user.h"
29: #include "proc.h"
30: #include "ioctl.h"
31: #include "tty.h"
32: #include "map.h"
33: #include "buf.h"
34: #include "vm.h"
35: #include "kernel.h"
36: #include "syslog.h"
37:
38: #include "uba.h"
39: #include "ubareg.h"
40: #include "ubavar.h"
41: #include "dhureg.h"
42:
43: #include "bkmac.h"
44: #include "clist.h"
45: #include "file.h"
46: #include "uio.h"
47:
48: /*
49: * Definition of the driver for the auto-configuration program.
50: */
51: int dhuprobe(), dhuattach(), dhurint(), dhuxint();
52: struct uba_device *dhuinfo[NDHU];
53: u_short dhustd[] = { 160440, 160500, 0 }; /* some common addresses */
54: struct uba_driver dhudriver =
55: { dhuprobe, 0, dhuattach, 0, dhustd, "dhu", dhuinfo };
56:
57: #define NDHULINE (NDHU*16)
58:
59: #define UNIT(x) (minor(x))
60:
61: #ifndef PORTSELECTOR
62: #define ISPEED B9600
63: #define IFLAGS (EVENP|ODDP|ECHO)
64: #else
65: #define ISPEED B4800
66: #define IFLAGS (EVENP|ODDP)
67: #endif
68:
69: /*
70: * default receive silo timeout value -- valid values are 2..255
71: * number of ms. to delay between first char received and receive interrupt
72: *
73: * A value of 20 gives same response as ABLE dh/dm with silo alarm = 0
74: */
75: #define DHU_DEF_TIMO 20
76:
77: /*
78: * Other values for silo timeout register defined here but not used:
79: * receive interrupt only on modem control or silo alarm (3/4 full)
80: */
81: #define DHU_POLL_TIMO 0
82: /*
83: * receive interrupt immediately on receive character
84: */
85: #define DHU_NO_TIMO 1
86:
87: /*
88: * Local variables for the driver
89: */
90: /*
91: * Baud rates: no 50, 200, or 38400 baud; all other rates are from "Group B".
92: * EXTA => 19200 baud
93: * EXTB => 2000 baud
94: */
95: char dhu_speeds[] =
96: { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 8, 10, 11, 13, 14, 9 };
97:
98: short dhusoftCAR[NDHU];
99:
100: struct tty dhu_tty[NDHULINE];
101: int ndhu = NDHULINE;
102: int dhuact; /* mask of active dhu's */
103: int dhustart(), ttrstrt();
104:
105: /*
106: * The clist space is mapped by one terminal driver onto each UNIBUS.
107: * The identity of the board which allocated resources is recorded,
108: * so the process may be repeated after UNIBUS resets.
109: * The UBACVT macro converts a clist space address for unibus uban
110: * into an i/o space address for the DMA routine.
111: */
112: int dhu_uballoc[NUBA]; /* which dhu (if any) allocated unibus map */
113: int cbase[NUBA]; /* base address of clists in unibus map */
114: #define UBACVT(x, uban) (cbase[uban] + ((x)-(char *)cfree))
115:
116: /*
117: * Routine for configuration to force a dhu to interrupt.
118: */
119: /*ARGSUSED*/
120: dhuprobe(reg)
121: caddr_t reg;
122: {
123: register int br, cvec; /* these are ``value-result'' */
124: register struct dhudevice *dhuaddr = (struct dhudevice *)reg;
125: int i;
126:
127: #ifdef lint
128: br = 0; cvec = br; br = cvec;
129: if (ndhu == 0) ndhu = 1;
130: dhurint(0); dhuxint(0);
131: #endif
132: /*
133: * The basic idea here is:
134: * do a self-test by setting the Master-Reset bit
135: * if this fails, then return
136: * if successful, there will be 8 diagnostic codes in RX FIFO
137: * therefore ask for a Received-Data-Available interrupt
138: * wait for it...
139: * reset the interrupt-enable bit and flush out the diag. codes
140: */
141: dhuaddr->dhucsr = DHU_CS_MCLR;
142: for (i = 0; i < 1000; i++) {
143: DELAY(10000);
144: if ((dhuaddr->dhucsr&DHU_CS_MCLR) == 0)
145: break;
146: }
147: if (dhuaddr->dhucsr&DHU_CS_MCLR)
148: return(0);
149: if (dhuaddr->dhucsr&DHU_CS_DFAIL)
150: return(0);
151: dhuaddr->dhucsr = DHU_CS_RIE;
152: DELAY(1000);
153: dhuaddr->dhucsr = 0;
154: while (dhuaddr->dhurbuf < 0)
155: /* void */;
156: return (sizeof(struct dhudevice));
157: }
158:
159: /*
160: * Routine called to attach a dhu.
161: */
162: dhuattach(ui)
163: struct uba_device *ui;
164: {
165:
166: dhusoftCAR[ui->ui_unit] = ui->ui_flags;
167: cbase[ui->ui_ubanum] = -1;
168: dhu_uballoc[ui->ui_unit] = -1;
169: }
170:
171: /*
172: * Open a DHU11 line, mapping the clist onto the uba if this
173: * is the first dhu on this uba. Turn on this dhu if this is
174: * the first use of it.
175: */
176: /*ARGSUSED*/
177: dhuopen(dev, flag)
178: dev_t dev;
179: {
180: register struct tty *tp;
181: register int unit, dhu;
182: register struct dhudevice *addr;
183: register struct uba_device *ui;
184: int s;
185:
186: unit = UNIT(dev);
187: dhu = unit >> 4;
188: if (unit >= NDHULINE || (ui = dhuinfo[dhu])== 0 || ui->ui_alive == 0)
189: return (ENXIO);
190: tp = &dhu_tty[unit];
191: if (tp->t_state & TS_XCLUDE && u.u_uid != 0)
192: return (EBUSY);
193: addr = (struct dhudevice *)ui->ui_addr;
194: tp->t_addr = (caddr_t)addr;
195: tp->t_oproc = dhustart;
196: /*
197: * While setting up state for this uba and this dhu,
198: * block uba resets which can clear the state.
199: */
200: s = spl5();
201: if (cbase[ui->ui_ubanum] == -1) {
202: dhu_uballoc[ui->ui_ubanum] = dhu;
203: cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum,
204: (caddr_t)cfree, nclist*sizeof(struct cblock), 0));
205: }
206: if ((dhuact&(1<<dhu)) == 0) {
207: addr->dhucsr = DHU_SELECT(0) | DHU_IE;
208: addr->dhutimo = DHU_DEF_TIMO;
209: dhuact |= (1<<dhu);
210: /* anything else to configure whole board */
211: }
212: (void) splx(s);
213: /*
214: * If this is first open, initialize tty state to default.
215: */
216: if ((tp->t_state&TS_ISOPEN) == 0) {
217: ttychars(tp);
218: #ifndef PORTSELECTOR
219: if (tp->t_ispeed == 0) {
220: #else
221: tp->t_state |= TS_HUPCLS;
222: #endif PORTSELECTOR
223: tp->t_ispeed = ISPEED;
224: tp->t_ospeed = ISPEED;
225: tp->t_flags = IFLAGS;
226: #ifndef PORTSELECTOR
227: }
228: #endif PORTSELECTOR
229: tp->t_dev = dev;
230: dhuparam(unit);
231: }
232: /*
233: * Wait for carrier, then process line discipline specific open.
234: */
235: s = spl5();
236: if ((dhumctl(dev, DHU_ON, DMSET) & DHU_CAR) ||
237: (dhusoftCAR[dhu] & (1<<(unit&0xf))))
238: tp->t_state |= TS_CARR_ON;
239: while ((tp->t_state & TS_CARR_ON) == 0) {
240: tp->t_state |= TS_WOPEN;
241: sleep((caddr_t)&tp->t_rawq, TTIPRI);
242: }
243: (void) splx(s);
244: return ((*linesw[tp->t_line].l_open)(dev, tp));
245: }
246:
247: /*
248: * Close a DHU11 line, turning off the modem control.
249: */
250: /*ARGSUSED*/
251: dhuclose(dev, flag)
252: dev_t dev;
253: int flag;
254: {
255: register struct tty *tp;
256: register unit;
257:
258: unit = UNIT(dev);
259: tp = &dhu_tty[unit];
260: (*linesw[tp->t_line].l_close)(tp);
261: (void) dhumctl(unit, DHU_BRK, DMBIC);
262: if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN)==0)
263: #ifdef PORTSELECTOR
264: {
265: extern int wakeup();
266:
267: (void) dhumctl(unit, DHU_OFF, DMSET);
268: /* Hold DTR low for 0.5 seconds */
269: timeout(wakeup, (caddr_t) &tp->t_dev, hz/2);
270: sleep((caddr_t) &tp->t_dev, PZERO);
271: }
272: #else
273: (void) dhumctl(unit, DHU_OFF, DMSET);
274: #endif PORTSELECTOR
275: ttyclose(tp);
276: }
277:
278: dhuread(dev, uio)
279: dev_t dev;
280: struct uio *uio;
281: {
282: register struct tty *tp = &dhu_tty[UNIT(dev)];
283:
284: return ((*linesw[tp->t_line].l_read)(tp, uio));
285: }
286:
287: dhuwrite(dev, uio)
288: dev_t dev;
289: struct uio *uio;
290: {
291: register struct tty *tp = &dhu_tty[UNIT(dev)];
292:
293: return ((*linesw[tp->t_line].l_write)(tp, uio));
294: }
295:
296: /*
297: * DHU11 receiver interrupt.
298: */
299: dhurint(dhu)
300: int dhu;
301: {
302: register struct tty *tp;
303: register c;
304: register struct dhudevice *addr;
305: register struct tty *tp0;
306: register struct uba_device *ui;
307: register line;
308: int overrun = 0;
309:
310: #ifdef VAX630
311: (void) spl5();
312: #endif
313: ui = dhuinfo[dhu];
314: if (ui == 0 || ui->ui_alive == 0)
315: return;
316: addr = (struct dhudevice *)ui->ui_addr;
317: tp0 = &dhu_tty[dhu<<4];
318: /*
319: * Loop fetching characters from the silo for this
320: * dhu until there are no more in the silo.
321: */
322: while ((c = addr->dhurbuf) < 0) { /* (c & DHU_RB_VALID) == on */
323: line = DHU_RX_LINE(c);
324: tp = tp0 + line;
325: if ((c & DHU_RB_STAT) == DHU_RB_STAT) {
326: /*
327: * modem changed or diag info
328: */
329: if (c & DHU_RB_DIAG) {
330: /* decode diagnostic messages */
331: continue;
332: }
333: if (c & DHU_ST_DCD)
334: (void)(*linesw[tp->t_line].l_modem)(tp, 1);
335: else if ((dhusoftCAR[dhu] & (1<<line)) == 0 &&
336: (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
337: (void) dhumctl((dhu<<4)|line, DHU_OFF, DMSET);
338: continue;
339: }
340: if ((tp->t_state&TS_ISOPEN) == 0) {
341: wakeup((caddr_t)&tp->t_rawq);
342: #ifdef PORTSELECTOR
343: if ((tp->t_state&TS_WOPEN) == 0)
344: #endif
345: continue;
346: }
347: if (c & DHU_RB_PE)
348: if ((tp->t_flags&(EVENP|ODDP)) == EVENP ||
349: (tp->t_flags&(EVENP|ODDP)) == ODDP)
350: continue;
351: if ((c & DHU_RB_DO) && overrun == 0) {
352: log(LOG_WARNING, "dhu%d: silo overflow\n", dhu);
353: overrun = 1;
354: }
355: if (c & DHU_RB_FE)
356: /*
357: * At framing error (break) generate
358: * a null (in raw mode, for getty), or a
359: * interrupt (in cooked/cbreak mode).
360: */
361: if (tp->t_flags&RAW)
362: c = 0;
363: else
364: c = tp->t_intrc;
365: #if NBK > 0
366: if (tp->t_line == NETLDISC) {
367: c &= 0x7f;
368: BKINPUT(c, tp);
369: } else
370: #endif
371: (*linesw[tp->t_line].l_rint)(c, tp);
372: }
373: }
374:
375: /*
376: * Ioctl for DHU11.
377: */
378: /*ARGSUSED*/
379: dhuioctl(dev, cmd, data, flag)
380: caddr_t data;
381: {
382: register struct tty *tp;
383: register int unit = UNIT(dev);
384: int error;
385:
386: tp = &dhu_tty[unit];
387: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
388: if (error >= 0)
389: return (error);
390: error = ttioctl(tp, cmd, data, flag);
391: if (error >= 0) {
392: if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLSET ||
393: cmd == TIOCLBIC || cmd == TIOCLBIS)
394: dhuparam(unit);
395: return (error);
396: }
397:
398: switch (cmd) {
399: case TIOCSBRK:
400: (void) dhumctl(unit, DHU_BRK, DMBIS);
401: break;
402:
403: case TIOCCBRK:
404: (void) dhumctl(unit, DHU_BRK, DMBIC);
405: break;
406:
407: case TIOCSDTR:
408: (void) dhumctl(unit, DHU_DTR|DHU_RTS, DMBIS);
409: break;
410:
411: case TIOCCDTR:
412: (void) dhumctl(unit, DHU_DTR|DHU_RTS, DMBIC);
413: break;
414:
415: case TIOCMSET:
416: (void) dhumctl(dev, dmtodhu(*(int *)data), DMSET);
417: break;
418:
419: case TIOCMBIS:
420: (void) dhumctl(dev, dmtodhu(*(int *)data), DMBIS);
421: break;
422:
423: case TIOCMBIC:
424: (void) dhumctl(dev, dmtodhu(*(int *)data), DMBIC);
425: break;
426:
427: case TIOCMGET:
428: *(int *)data = dhutodm(dhumctl(dev, 0, DMGET));
429: break;
430: default:
431: return (ENOTTY);
432: }
433: return (0);
434: }
435:
436: dmtodhu(bits)
437: register int bits;
438: {
439: register int b = 0;
440:
441: if (bits & DML_RTS) b |= DHU_RTS;
442: if (bits & DML_DTR) b |= DHU_DTR;
443: if (bits & DML_LE) b |= DHU_LE;
444: return(b);
445: }
446:
447: dhutodm(bits)
448: register int bits;
449: {
450: register int b = 0;
451:
452: if (bits & DHU_DSR) b |= DML_DSR;
453: if (bits & DHU_RNG) b |= DML_RNG;
454: if (bits & DHU_CAR) b |= DML_CAR;
455: if (bits & DHU_CTS) b |= DML_CTS;
456: if (bits & DHU_RTS) b |= DML_RTS;
457: if (bits & DHU_DTR) b |= DML_DTR;
458: if (bits & DHU_LE) b |= DML_LE;
459: return(b);
460: }
461:
462:
463: /*
464: * Set parameters from open or stty into the DHU hardware
465: * registers.
466: */
467: dhuparam(unit)
468: register int unit;
469: {
470: register struct tty *tp;
471: register struct dhudevice *addr;
472: register int lpar;
473: int s;
474:
475: tp = &dhu_tty[unit];
476: addr = (struct dhudevice *)tp->t_addr;
477: /*
478: * Block interrupts so parameters will be set
479: * before the line interrupts.
480: */
481: s = spl5();
482: if ((tp->t_ispeed) == 0) {
483: tp->t_state |= TS_HUPCLS;
484: (void)dhumctl(unit, DHU_OFF, DMSET);
485: splx(s);
486: return;
487: }
488: lpar = (dhu_speeds[tp->t_ospeed]<<12) | (dhu_speeds[tp->t_ispeed]<<8);
489: if ((tp->t_ispeed) == B134)
490: lpar |= DHU_LP_BITS6|DHU_LP_PENABLE;
491: else if (tp->t_flags & (RAW|LITOUT|PASS8))
492: lpar |= DHU_LP_BITS8;
493: else
494: lpar |= DHU_LP_BITS7|DHU_LP_PENABLE;
495: if (tp->t_flags&EVENP)
496: lpar |= DHU_LP_EPAR;
497: if ((tp->t_ospeed) == B110)
498: lpar |= DHU_LP_TWOSB;
499: addr->dhucsr = DHU_SELECT(unit) | DHU_IE;
500: addr->dhulpr = lpar;
501: splx(s);
502: }
503:
504: /*
505: * DHU11 transmitter interrupt.
506: * Restart each line which used to be active but has
507: * terminated transmission since the last interrupt.
508: */
509: dhuxint(dhu)
510: int dhu;
511: {
512: register struct tty *tp;
513: register struct dhudevice *addr;
514: register struct tty *tp0;
515: register struct uba_device *ui;
516: register int line, t;
517: u_short cntr;
518:
519: #ifdef VAX630
520: (void) spl5();
521: #endif
522: ui = dhuinfo[dhu];
523: tp0 = &dhu_tty[dhu<<4];
524: addr = (struct dhudevice *)ui->ui_addr;
525: while ((t = addr->dhucsrh) & DHU_CSH_TI) {
526: line = DHU_TX_LINE(t);
527: tp = tp0 + line;
528: tp->t_state &= ~TS_BUSY;
529: if (t & DHU_CSH_NXM) {
530: printf("dhu(%d,%d): NXM fault\n", dhu, line);
531: /* SHOULD RESTART OR SOMETHING... */
532: }
533: if (tp->t_state&TS_FLUSH)
534: tp->t_state &= ~TS_FLUSH;
535: else {
536: addr->dhucsrl = DHU_SELECT(line) | DHU_IE;
537: /*
538: * Do arithmetic in a short to make up
539: * for lost 16&17 bits.
540: */
541: cntr = addr->dhubar1 -
542: UBACVT(tp->t_outq.c_cf, ui->ui_ubanum);
543: ndflush(&tp->t_outq, (int)cntr);
544: }
545: if (tp->t_line)
546: (*linesw[tp->t_line].l_start)(tp);
547: else
548: dhustart(tp);
549: }
550: }
551:
552: /*
553: * Start (restart) transmission on the given DHU11 line.
554: */
555: dhustart(tp)
556: register struct tty *tp;
557: {
558: register struct dhudevice *addr;
559: register int car, dhu, unit, nch;
560: int s;
561:
562: unit = minor(tp->t_dev);
563: dhu = unit >> 4;
564: unit &= 0xf;
565: addr = (struct dhudevice *)tp->t_addr;
566:
567: /*
568: * Must hold interrupts in following code to prevent
569: * state of the tp from changing.
570: */
571: s = spl5();
572: /*
573: * If it's currently active, or delaying, no need to do anything.
574: */
575: if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
576: goto out;
577: /*
578: * If there are sleepers, and output has drained below low
579: * water mark, wake up the sleepers..
580: */
581: if (tp->t_outq.c_cc<=TTLOWAT(tp)) {
582: if (tp->t_state&TS_ASLEEP) {
583: tp->t_state &= ~TS_ASLEEP;
584: wakeup((caddr_t)&tp->t_outq);
585: }
586: if (tp->t_wsel) {
587: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
588: tp->t_wsel = 0;
589: tp->t_state &= ~TS_WCOLL;
590: }
591: }
592: /*
593: * Now restart transmission unless the output queue is
594: * empty.
595: */
596: if (tp->t_outq.c_cc == 0)
597: goto out;
598: if (tp->t_flags & (RAW|LITOUT))
599: nch = ndqb(&tp->t_outq, 0);
600: else {
601: nch = ndqb(&tp->t_outq, 0200);
602: /*
603: * If first thing on queue is a delay process it.
604: */
605: if (nch == 0) {
606: nch = getc(&tp->t_outq);
607: timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
608: tp->t_state |= TS_TIMEOUT;
609: goto out;
610: }
611: }
612: /*
613: * If characters to transmit, restart transmission.
614: */
615: if (nch) {
616: car = UBACVT(tp->t_outq.c_cf, dhuinfo[dhu]->ui_ubanum);
617: addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
618: addr->dhulcr &= ~DHU_LC_TXABORT;
619: addr->dhubcr = nch;
620: addr->dhubar1 = car;
621: addr->dhubar2 = ((car >> DHU_XBA_SHIFT) & DHU_BA2_XBA) |
622: DHU_BA2_DMAGO;
623: tp->t_state |= TS_BUSY;
624: }
625: out:
626: splx(s);
627: }
628:
629: /*
630: * Stop output on a line, e.g. for ^S/^Q or output flush.
631: */
632: /*ARGSUSED*/
633: dhustop(tp, flag)
634: register struct tty *tp;
635: {
636: register struct dhudevice *addr;
637: register int unit, s;
638:
639: addr = (struct dhudevice *)tp->t_addr;
640: /*
641: * Block input/output interrupts while messing with state.
642: */
643: s = spl5();
644: if (tp->t_state & TS_BUSY) {
645: /*
646: * Device is transmitting; stop output
647: * by selecting the line and setting the
648: * abort xmit bit. We will get an xmit interrupt,
649: * where we will figure out where to continue the
650: * next time the transmitter is enabled. If
651: * TS_FLUSH is set, the outq will be flushed.
652: * In either case, dhustart will clear the TXABORT bit.
653: */
654: unit = minor(tp->t_dev);
655: addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
656: addr->dhulcr |= DHU_LC_TXABORT;
657: if ((tp->t_state&TS_TTSTOP)==0)
658: tp->t_state |= TS_FLUSH;
659: }
660: (void) splx(s);
661: }
662:
663: /*
664: * DHU11 modem control
665: */
666: dhumctl(dev, bits, how)
667: dev_t dev;
668: int bits, how;
669: {
670: register struct dhudevice *dhuaddr;
671: register int unit, mbits;
672: int s;
673:
674: unit = UNIT(dev);
675: dhuaddr = (struct dhudevice *)(dhu_tty[unit].t_addr);
676: unit &= 0xf;
677: s = spl5();
678: dhuaddr->dhucsr = DHU_SELECT(unit) | DHU_IE;
679: /*
680: * combine byte from stat register (read only, bits 16..23)
681: * with lcr register (read write, bits 0..15).
682: */
683: mbits = dhuaddr->dhulcr | (dhuaddr->dhustat << 16);
684: switch (how) {
685: case DMSET:
686: mbits = (mbits & 0xff0000) | bits;
687: break;
688:
689: case DMBIS:
690: mbits |= bits;
691: break;
692:
693: case DMBIC:
694: mbits &= ~bits;
695: break;
696:
697: case DMGET:
698: (void) splx(s);
699: return(mbits);
700: }
701: dhuaddr->dhulcr = (mbits & 0xffff) | DHU_LC_RXEN;
702: dhuaddr->dhulcr2 = DHU_LC2_TXEN;
703: (void) splx(s);
704: return(mbits);
705: }
706:
707: /*
708: * Reset state of driver if UBA reset was necessary.
709: * Reset the line and modem control registers.
710: * restart transmitters.
711: */
712: dhureset(uban)
713: int uban;
714: {
715: register int dhu, unit;
716: register struct tty *tp;
717: register struct uba_device *ui;
718: register struct dhudevice *addr;
719: int i;
720:
721: for (dhu = 0; dhu < NDHU; dhu++) {
722: ui = dhuinfo[dhu];
723: if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
724: continue;
725: printf(" dhu%d", dhu);
726: if (dhu_uballoc[uban] == dhu) {
727: int info;
728:
729: info = uballoc(uban, (caddr_t)cfree,
730: nclist * sizeof(struct cblock), UBA_CANTWAIT);
731: if (info)
732: cbase[uban] = UBAI_ADDR(info);
733: else {
734: printf(" [can't get uba map]");
735: cbase[uban] = -1;
736: }
737: }
738: addr = (struct dhudevice *)ui->ui_addr;
739: addr->dhucsr = DHU_SELECT(0) | DHU_IE;
740: addr->dhutimo = DHU_DEF_TIMO;
741: unit = dhu * 16;
742: for (i = 0; i < 16; i++) {
743: tp = &dhu_tty[unit];
744: if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
745: dhuparam(unit);
746: (void)dhumctl(unit, DHU_ON, DMSET);
747: tp->t_state &= ~TS_BUSY;
748: dhustart(tp);
749: }
750: unit++;
751: }
752: }
753: }
754: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.