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