|
|
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.1 (Berkeley) 6/5/86
7: */
8:
9: /*
10: * DMZ-32 driver
11: * HISTORY
12: * 23-Apr-85 Joe Camaratta (jcc) at Siemens RTL
13: * Driver for DEC's DMZ32 24-line asynchronous multiplexor.
14: * Based on Chris Maloney's driver for DEC's DMF32
15: *
16: * 9-Aug-85 Mike Meyer (mwm) at ucb
17: * Mangled into shape for 4.3.
18: */
19:
20: #include "dmz.h"
21: #if NDMZ > 0
22:
23:
24: #include "../machine/pte.h"
25:
26:
27: #include "bk.h"
28: #include "uba.h"
29: #include "param.h"
30: #include "conf.h"
31: #include "dir.h"
32: #include "user.h"
33: #include "proc.h"
34: #include "ioctl.h"
35: #include "tty.h"
36: #include "map.h"
37: #include "buf.h"
38: #include "vm.h"
39: #include "bkmac.h"
40: #include "clist.h"
41: #include "file.h"
42: #include "uio.h"
43: #include "kernel.h"
44: #include "syslog.h"
45:
46: #include "ubareg.h"
47: #include "ubavar.h"
48: #include "dmzreg.h"
49: #include "dmreg.h"
50:
51: int dmzprobe(), dmzattach(), dmzrint(), dmzxint();
52: struct uba_device *dmzinfo[NDMZ];
53: u_short dmzstd[] = {0, 0};
54: struct uba_driver dmzdriver = {
55: dmzprobe, 0, dmzattach, 0, dmzstd, "dmz", dmzinfo
56: };
57:
58: #define NDMZLINES (NDMZ*24)
59:
60: int ttrstrt();
61: struct tty dmz_tty[NDMZLINES];
62:
63: int dmzsoftCAR[NDMZ];
64:
65: struct {
66: char dmz_state; /* dmz state */
67: int dmz_count; /* dmz dma count */
68: } dmz_softc[NDMZ*24];
69:
70: #define ST_TXOFF (0x01) /* transmission turned off (^S) */
71: #define ST_DMA (0x02) /* dma inprogress */
72: #define ST_INBUSY (0x04) /* stop transmission in busy */
73:
74: char dmz_speeds[] = {
75: 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0
76: };
77:
78: #ifndef PORTSELECTOR
79: #define ISPEED B9600
80: #define IFLAGS (EVENP|ODDP|ECHO)
81: #else
82: #define ISPEED B4800
83: #define IFLAGS (EVENP|ODDP)
84: #endif
85:
86: #ifndef lint
87: int ndmz = NDMZLINES; /* Used by pstat/iostat */
88: #endif
89:
90: short dmzact[NDMZ]; /* Mask of active octets on the dmz */
91: int dmzstart();
92:
93: /*
94: * SILO_TIMEOUT represents the number of milliseconds characters can sit
95: * in the input silo without causing an interrupt. If data overruns or
96: * slow XON/XOFF occur, set it lower but AT LEAST equal to 1.
97: */
98: #define SILO_TIMEOUT (3)
99:
100: /*
101: * DO_DMA_COUNT represents the threshold of the number of output
102: * characters beyond which the driver uses DMA mode.
103: */
104: #define DO_DMA_COUNT (10)
105:
106: #define TRUE (1)
107: #define FALSE (0)
108:
109: int cbase[NUBA]; /* base address in unibus map */
110: int dmz_ubinfo[NUBA]; /* info about allocated unibus map */
111:
112: #define UBACVT(x, uban) (cbase[uban] + ((x) - (char *)cfree))
113:
114: /* These flags are for debugging purposes only */
115: int dmz_dma_on = 1;
116:
117: dmzprobe(reg)
118: caddr_t reg;
119: {
120: register int br, cvec;
121: register struct dmzdevice *dmz_addr;
122: register unsigned int a;
123:
124: dmz_addr = (struct dmzdevice *)reg;
125:
126: #ifdef lint
127: br = 0; cvec = br; br = cvec; dmzxinta(0); dmzxintb(0); dmzxintc(0);
128: dmzrinta(0); dmzrintb(0); dmzrintc(0);
129: #endif
130:
131: br = 0x15;
132:
133: a = dmz_addr->dmz_config;
134: if (((a>>12) & ~DMZ_INTERFACE) != 0) {
135: printf(" Unknown interface type\n");
136: return (0);
137: }
138: if (((a>>8) & DMZ_NOC_MASK) != 3) {
139: printf(" Not all octets are available\n");
140: return (0);
141: }
142:
143: cvec = (uba_hd[numuba].uh_lastiv -= 4 * 6);
144: dmz_addr->dmz_config = cvec >> 2;
145:
146: return (sizeof(struct dmzdevice));
147: }
148:
149: dmzattach(ui)
150: struct uba_device *ui;
151: {
152: dmzsoftCAR[ui->ui_unit] = ui->ui_flags;
153: cbase[ui->ui_ubanum] = -1;
154: }
155:
156: /* ARGSUSED */
157: dmzopen(device, flag)
158: dev_t device;
159: int flag;
160: {
161: register struct tty *tp;
162: register int unit, controller;
163: register struct dmzdevice *dmz_addr;
164: register struct uba_device *ui;
165: int priority;
166: int octet;
167:
168: unit = minor(device);
169: controller = DMZ(unit);
170: octet = OCTET(unit);
171:
172: if (unit >= NDMZLINES ||
173: (ui = dmzinfo[controller]) == 0 ||
174: ui->ui_alive == 0)
175: return (ENXIO);
176:
177: tp = &dmz_tty[unit];
178:
179: if ((tp->t_state & TS_XCLUDE) && u.u_uid != 0)
180: return (EBUSY);
181:
182: dmz_addr = (struct dmzdevice *)ui->ui_addr;
183: tp->t_addr = (caddr_t)dmz_addr;
184: tp->t_oproc = dmzstart;
185:
186: /*
187: * Set up Unibus map registers. Block uba resets, which can
188: * clear the state.
189: */
190: priority = spl5();
191: if (cbase[ui->ui_ubanum] == -1) {
192: dmz_ubinfo[ui->ui_ubanum] =
193: uballoc(ui->ui_ubanum, (caddr_t)cfree,
194: nclist * sizeof(struct cblock), 0);
195: if (dmz_ubinfo[ui->ui_ubanum] == 0) {
196: splx(priority);
197: printf("dmz: insufficient unibus map regs\n");
198: return (ENOMEM);
199: }
200: cbase[ui->ui_ubanum] = UBAI_ADDR(dmz_ubinfo[ui->ui_ubanum]);
201: }
202:
203: if ((dmzact[controller] & (1 << octet)) == 0) {
204: dmz_addr->octet[octet].octet_csr |= DMZ_IE;
205: dmzact[controller] |= 1 << octet;
206: dmz_addr->octet[octet].octet_receive.octet_sato = SILO_TIMEOUT;
207: }
208:
209: splx(priority);
210:
211: if ((tp->t_state & TS_ISOPEN) == 0) {
212: ttychars(tp);
213: #ifndef PORTSELECTOR
214: if (tp->t_ispeed == 0) {
215: #else
216: tp->t_state |= TS_HUPCLS;
217: #endif PORTSELECTOR
218: tp->t_ispeed = ISPEED;
219: tp->t_ospeed = ISPEED;
220: tp->t_flags = IFLAGS;
221: #ifndef PORTSELECTOR
222: }
223: #endif PORTSELECTOR
224: dmz_softc[unit].dmz_state = 0;
225: }
226: dmzparam(unit);
227:
228: /*
229: * Wait for carrier, then process line discipline specific open.
230: */
231: if ((dmzmctl(unit, DMZ_ON, DMSET) & DMZ_CAR) ||
232: (dmzsoftCAR[controller] & (1 << (unit % 24))))
233: tp->t_state |= TS_CARR_ON;
234: priority = spl5();
235: while ((tp->t_state & TS_CARR_ON) == 0) {
236: tp->t_state |= TS_WOPEN;
237: sleep((caddr_t) &tp->t_rawq, TTIPRI);
238: }
239: splx(priority);
240:
241: return ((*linesw[tp->t_line].l_open)(device, tp));
242: }
243:
244: dmzparam(unit)
245: register int unit;
246: {
247: register struct tty *tp;
248: register struct dmzdevice *dmz_addr;
249: register int line_parameters;
250: register int octet;
251: int priority;
252:
253: octet = OCTET(unit);
254:
255: tp = &dmz_tty[unit];
256: dmz_addr = (struct dmzdevice *)tp->t_addr;
257:
258: priority = spl5();
259: if ((tp->t_ispeed) == 0) {
260: tp->t_state |= TS_HUPCLS;
261: (void) dmzmctl(unit, DMZ_OFF, DMSET);
262: splx(priority);
263: return;
264: }
265:
266: line_parameters = (dmz_speeds[tp->t_ospeed] << 12) | (dmz_speeds[tp->t_ispeed] << 8);
267:
268: if ((tp->t_ispeed) == B134)
269: line_parameters |= DMZ_6BT | DMZ_PEN;
270: else if (tp->t_flags & (RAW | LITOUT | PASS8))
271: line_parameters |= DMZ_8BT;
272: else
273: line_parameters |= DMZ_7BT | DMZ_PEN;
274:
275: if (tp->t_flags & EVENP)
276: line_parameters |= DMZ_EPR;
277: if ((tp->t_ospeed) == B110)
278: line_parameters |= DMZ_SCD;
279:
280: line_parameters |= (unit & 07);
281:
282: dmz_addr->octet[octet].octet_lprm = line_parameters;
283: splx(priority);
284: }
285:
286: /* ARGSUSED */
287: dmzclose(device, flag)
288: dev_t device;
289: int flag;
290: {
291: register struct tty *tp;
292: register int unit;
293:
294: unit = minor(device);
295: tp = &dmz_tty[unit];
296: (*linesw[tp->t_line].l_close)(tp);
297:
298: /*
299: * Clear break, hang-up and close the modem.
300: */
301: (void) dmzmctl(unit, DMZ_BRK, DMBIC);
302: if (tp->t_state & TS_HUPCLS || (tp->t_state & TS_ISOPEN) == 0)
303: (void) dmzmctl(unit, DMZ_OFF, DMSET);
304: ttyclose(tp);
305: return;
306: }
307:
308: dmzreset(uban)
309: int uban;
310: {
311: register int controller, unit;
312: register struct tty *tp;
313: register struct uba_device *ui;
314: register struct dmzdevice *dmz_addr;
315: int i;
316: int octet;
317:
318: for (controller = 0; controller < NDMZ; controller++) {
319: ui = dmzinfo[controller];
320: if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
321: continue;
322: printf("dmz%d ", controller);
323: dmz_addr = (struct dmzdevice *) ui->ui_addr;
324:
325: if (dmz_ubinfo[uban]) {
326: dmz_ubinfo[uban] = uballoc(uban, (caddr_t)cfree,
327: nclist * sizeof(struct cblock), 0);
328: cbase[uban] = UBAI_ADDR(dmz_ubinfo[uban]);
329: }
330:
331: for (octet = 0; octet < 3; octet++)
332: if ((dmzact[controller] & (1 << octet)) != 0) {
333: dmz_addr->octet[octet].octet_csr |= DMZ_IE;
334: dmz_addr->octet[octet].octet_receive.octet_sato = SILO_TIMEOUT;
335: }
336:
337: unit = controller * 24;
338:
339: /*
340: * If a unit is open or waiting for open to complete,
341: * reset it.
342: */
343: for (i = 0; i < 24; i++) {
344: dmz_softc[unit].dmz_state = 0;
345: tp = &dmz_tty[unit];
346: if (tp->t_state & (TS_ISOPEN | TS_WOPEN)) {
347: dmzparam(unit);
348: (void) dmzmctl(unit, DMZ_ON, DMSET);
349: tp->t_state &= ~TS_BUSY;
350: dmzstart(tp);
351: }
352: unit++;
353: }
354: }
355: return;
356: }
357:
358: dmzread(device, uio)
359: dev_t device;
360: struct uio *uio;
361: {
362: register struct tty *tp;
363: int xstatus;
364:
365: tp = &dmz_tty[minor(device)];
366: xstatus = (*linesw[tp->t_line].l_read)(tp, uio);
367: return (xstatus);
368: }
369:
370: dmzwrite(device, uio)
371: dev_t device;
372: struct uio *uio;
373: {
374: register struct tty *tp;
375: int xstatus;
376:
377: tp = &dmz_tty[minor(device)];
378: xstatus = (*linesw[tp->t_line].l_write)(tp, uio);
379: return (xstatus);
380: }
381:
382: dmzrinta(controller)
383: int controller;
384: {
385: dmzrint(controller, 0);
386: }
387:
388: dmzrintb(controller)
389: int controller;
390: {
391: dmzrint(controller, 1);
392: }
393:
394: dmzrintc(controller)
395: int controller;
396: {
397: dmzrint(controller, 2);
398: }
399:
400: dmzrint(controller, octet)
401: int controller;
402: register int octet;
403: {
404: register struct tty *tp;
405: register int character;
406: register struct dmzdevice *dmz_addr;
407: register struct tty *tp0;
408: register int unit;
409: register struct uba_device *ui;
410: int overrun;
411:
412: overrun = 0;
413: ui = dmzinfo[controller];
414: if (ui == 0 || ui->ui_alive == 0)
415: return;
416: dmz_addr = (struct dmzdevice *) ui->ui_addr;
417: tp0 = &dmz_tty[controller * 24];
418:
419: while ((character = dmz_addr->octet[octet].octet_receive.octet_rb) < 0) {
420: unit = (character >> 8) & 07; /* unit is bits 8-10 of rb */
421: tp = tp0 + (octet * 8 + unit);
422:
423: if (character & DMZ_DSC) {
424: dmz_addr->octet[octet].octet_csr = DMZ_IE | IR_RMSTSC | unit;
425: if (dmz_addr->octet[octet].octet_rmstsc & DMZ_CAR)
426: (void)(*linesw[tp->t_line].l_modem)(tp, 1);
427: else if ((dmzsoftCAR[controller] &
428: (1 << (octet * 8 + unit))) == 0 &&
429: (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
430: (void)dmzmctl(tp - dmz_tty, DMZ_OFF, DMSET);
431: continue;
432: }
433:
434: if ((tp->t_state&TS_ISOPEN)==0) {
435: wakeup((caddr_t)&tp->t_rawq);
436: #ifdef PORTSELECTOR
437: if ((tp->t_state&TS_WOPEN) == 0)
438: #endif
439: continue;
440: }
441:
442: if (character & DMZ_PE) {
443: if ((tp->t_flags & (EVENP | ODDP)) == EVENP ||
444: (tp->t_flags & (EVENP | ODDP)) == ODDP)
445: continue;
446: }
447:
448: if ((character & DMZ_DO) && overrun == 0) {
449: log(LOG_WARNING, "dmz%d: silo overflow\n", controller);
450: overrun = 1;
451: }
452:
453: if (character & DMZ_FE) {
454: if (tp->t_flags & RAW)
455: character = 0;
456: else
457: character = tp->t_intrc;
458: }
459:
460: (*linesw[tp->t_line].l_rint)(character, tp);
461: }
462:
463: return;
464: }
465:
466: dmzxinta(controller)
467: int controller;
468: {
469: dmzxint(controller, 0);
470: }
471:
472: dmzxintb(controller)
473: int controller;
474: {
475: dmzxint(controller, 1);
476: }
477:
478: dmzxintc(controller)
479: int controller;
480: {
481: dmzxint(controller, 2);
482: }
483:
484: dmzxint(controller, octet)
485: int controller;
486: register int octet;
487: {
488: register struct tty *tp;
489: register struct dmzdevice *dmz_addr;
490: register struct uba_device *ui;
491: register int unit, t;
492: int priority;
493:
494: ui = dmzinfo[controller];
495: dmz_addr = (struct dmzdevice *)ui->ui_addr;
496:
497: priority = spl5();
498:
499: while ((t = dmz_addr->octet[octet].octet_csr) & DMZ_TRDY) {
500: unit = controller * 24 + (octet * 8 + ((t>>8) & 07));
501: tp = &dmz_tty[unit];
502: tp->t_state &= ~TS_BUSY;
503:
504: if (t & DMZ_NXM)
505: printf("dmz%d: NXM line %d\n", controller,
506: octet * 8 + (unit & 07));
507:
508: if (tp->t_state & TS_FLUSH) {
509: tp->t_state &= ~TS_FLUSH;
510: dmz_addr->octet[octet].octet_csr =
511: DMZ_IE | IR_LCTMR | (unit & 07);
512: dmz_addr->octet[octet].octet_lctmr =
513: (dmz_addr->octet[octet].octet_lctmr | DMZ_TE);
514: } else
515: if (dmz_softc[unit].dmz_state & ST_DMA)
516: ndflush(&tp->t_outq, dmz_softc[unit].dmz_count);
517: dmz_softc[unit].dmz_state = 0;
518:
519: if (tp->t_line)
520: (*linesw[tp->t_line].l_start)(tp);
521: else
522: dmzstart(tp);
523: }
524:
525: splx(priority);
526: return;
527: }
528:
529: dmzstart(tp)
530: register struct tty *tp;
531: {
532: register struct dmzdevice *dmz_addr;
533: register int unit, nch, room;
534: int controller, octet;
535: int priority, car, use_dma;
536: register int i;
537: register char *cp;
538:
539: unit = minor(tp->t_dev);
540: controller = DMZ(unit);
541: octet = OCTET(unit);
542: dmz_addr = (struct dmzdevice *)tp->t_addr;
543:
544: priority = spl5();
545:
546: if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
547: goto out;
548:
549: /*
550: * If the transmitter has been disabled, reenable it.
551: * If the transmitter was disabled before the xint (the
552: * ST_INBUSY was still on), then reset the BUSY state and
553: * we will wait for the interrupt. If !TS_BUSY, we already
554: * saw the interrupt so we can start another transmission.
555: */
556: if (dmz_softc[unit].dmz_state & ST_TXOFF) {
557: dmz_addr->octet[octet].octet_csr =
558: DMZ_IE | IR_LCTMR | (unit & 07);
559: dmz_addr->octet[octet].octet_lctmr =
560: (dmz_addr->octet[octet].octet_lctmr | DMZ_TE);
561: dmz_softc[unit].dmz_state &= ~ST_TXOFF;
562: if (dmz_softc[unit].dmz_state & ST_INBUSY) {
563: dmz_softc[unit].dmz_state &= ~ST_INBUSY;
564: tp->t_state |= TS_BUSY;
565: goto out;
566: }
567: }
568:
569: if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
570: if (tp->t_state & TS_ASLEEP) {
571: tp->t_state &= ~TS_ASLEEP;
572: wakeup((caddr_t)&tp->t_outq);
573: }
574: if (tp->t_wsel) {
575: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
576: tp->t_wsel = 0;
577: tp->t_state &= ~TS_WCOLL;
578: }
579: }
580:
581: if (tp->t_outq.c_cc == 0)
582: goto out;
583: if (tp->t_flags & (RAW | LITOUT))
584: nch = ndqb(&tp->t_outq, 0);
585: else {
586: nch = ndqb(&tp->t_outq, 0200);
587: if (nch == 0) {
588: nch = getc(&tp->t_outq);
589: timeout(ttrstrt, (caddr_t)tp, (nch & 0x7f)+6);
590: tp->t_state |= TS_TIMEOUT;
591: goto out;
592: }
593: }
594:
595: /*
596: * Should we use DMA or SILO mode?
597: * If nch is greater than DO_DMA_COUNT then DMA.
598: */
599: if (nch) {
600: dmz_addr->octet[octet].octet_csr =
601: DMZ_IE | IR_LCTMR | (unit & 07);
602: dmz_addr->octet[octet].octet_lctmr =
603: (dmz_addr->octet[octet].octet_lctmr | DMZ_TE);
604: tp->t_state |= TS_BUSY;
605:
606: use_dma = FALSE;
607: room = DMZ_SIZ;
608:
609: if (nch > DO_DMA_COUNT)
610: use_dma = TRUE;
611:
612: if (use_dma && dmz_dma_on) {
613: car = UBACVT(tp->t_outq.c_cf,
614: dmzinfo[controller]->ui_ubanum);
615: dmz_softc[unit].dmz_count = nch;
616: dmz_softc[unit].dmz_state |= ST_DMA;
617: dmz_addr->octet[octet].octet_csr =
618: DMZ_IE | IR_TBA | (unit & 07);
619: dmz_addr->octet[octet].octet_tba = car;
620: dmz_addr->octet[octet].octet_tcc =
621: ((car >> 2) & 0xc000) | nch;
622: } else {
623: dmz_softc[unit].dmz_state &= ~ST_DMA;
624: cp = tp->t_outq.c_cf;
625: nch = MIN(nch, room);
626: dmz_addr->octet[octet].octet_csr =
627: DMZ_IE | IR_TBUF | (unit & 07);
628: for (i = 0; i < nch; i++)
629: dmz_addr->octet[octet].octet_tbf = *cp++ ;
630: ndflush(&tp->t_outq, nch);
631: }
632: }
633:
634: out:
635: splx(priority);
636: return;
637: }
638:
639: /* ARGSUSED */
640: dmzstop(tp, flag)
641: register struct tty *tp;
642: {
643: register struct dmzdevice *dmz_addr;
644: register int unit, priority, octet;
645:
646: priority = spl5();
647: dmz_addr = (struct dmzdevice *) tp->t_addr;
648: unit = minor(tp->t_dev);
649: octet = OCTET(unit);
650:
651: dmz_addr->octet[octet].octet_csr = IR_LCTMR | (unit & 07) | DMZ_IE;
652: dmz_addr->octet[octet].octet_lctmr =
653: (dmz_addr->octet[octet].octet_lctmr & ~DMZ_TE);
654: dmz_softc[unit].dmz_state |= ST_TXOFF;
655: if ((tp->t_state & TS_TTSTOP) == 0) {
656: tp->t_state |= (TS_FLUSH | TS_BUSY);
657: dmz_addr->octet[octet].octet_lctmr =
658: (dmz_addr->octet[octet].octet_lctmr | DMZ_FLS);
659: } else if (tp->t_state & TS_BUSY) {
660: dmz_softc[unit].dmz_state |= ST_INBUSY;
661: tp->t_state &= ~TS_BUSY;
662: }
663:
664: splx(priority);
665: return;
666: }
667:
668: /* ARGSUSED */
669: dmzioctl(device, command, data, flag)
670: dev_t device;
671: caddr_t data;
672: {
673: register struct tty *tp;
674: register int unit;
675: int error;
676:
677: unit = minor(device);
678: tp = &dmz_tty[unit];
679:
680: error = (*linesw[tp->t_line].l_ioctl)(tp, command, data, flag);
681: if (error >= 0)
682: return (error);
683: error = ttioctl(tp, command, data, flag);
684: if (error >= 0) {
685: if (command == TIOCSETP || command == TIOCSETN ||
686: command == TIOCLSET || command == TIOCLBIS ||
687: command == TIOCLBIC)
688: dmzparam(unit);
689: return (error);
690: }
691:
692: switch (command) {
693: case TIOCSBRK:
694: (void) dmzmctl(unit, DMZ_BRK, DMBIS);
695: break;
696: case TIOCCBRK:
697: (void) dmzmctl(unit, DMZ_BRK, DMBIC);
698: break;
699: case TIOCSDTR:
700: (void) dmzmctl(unit, DMZ_DTR | DMZ_RTS, DMBIS);
701: break;
702: case TIOCCDTR:
703: (void) dmzmctl(unit, DMZ_DTR | DMZ_RTS, DMBIC);
704: break;
705: case TIOCMSET:
706: (void) dmzmctl(unit, dmtodmz(*(int *)data), DMSET);
707: break;
708: case TIOCMBIS:
709: (void) dmzmctl(unit, dmtodmz(*(int *)data), DMBIS);
710: break;
711: case TIOCMBIC:
712: (void) dmzmctl(unit, dmtodmz(*(int *)data), DMBIC);
713: break;
714: case TIOCMGET:
715: *(int *)data = dmzmctl(unit, 0, DMGET);
716: break;
717: default:
718: return (ENOTTY);
719: }
720: return (0);
721: }
722:
723: dmzmctl(unit, bits, how)
724: register int unit;
725: int bits, how;
726: {
727: register struct dmzdevice *dmz_addr;
728: register int modem_status, line_control;
729: int priority;
730: int octet;
731:
732: octet = OCTET(unit);
733: dmz_addr = (struct dmzdevice *) dmzinfo[DMZ(unit)]->ui_addr;
734:
735: priority = spl5();
736: dmz_addr->octet[octet].octet_csr = DMZ_IE | IR_RMSTSC | (unit & 07);
737: modem_status = dmz_addr->octet[octet].octet_rmstsc & 0xff00;
738:
739: dmz_addr->octet[octet].octet_csr = DMZ_IE | IR_LCTMR | (unit & 07);
740: line_control = dmz_addr->octet[octet].octet_lctmr;
741:
742:
743: switch (how) {
744: case DMSET:
745: line_control = bits;
746: break;
747: case DMBIS:
748: line_control |= bits;
749: break;
750: case DMBIC:
751: line_control &= ~bits;
752: break;
753: case DMGET:
754: (void) splx(priority);
755: return (dmztodm(modem_status, line_control));
756: }
757:
758: dmz_addr->octet[octet].octet_csr =
759: DMZ_IE | IR_LCTMR | (unit & 07);
760: dmz_addr->octet[octet].octet_lctmr = line_control;
761:
762: splx(priority);
763: return (modem_status);
764: }
765:
766: /*
767: * Routine to convert modem status from dm to dmz lctmr format.
768: */
769: dmtodmz(bits)
770: register int bits;
771: {
772: register int lcr = DMZ_LCE;
773:
774: if (bits & DML_DTR)
775: lcr |= DMZ_DTR;
776: if (bits & DML_RTS)
777: lcr |= DMZ_RTS;
778: if (bits & DML_ST)
779: lcr |= DMF_ST;
780: if (bits & DML_USR)
781: lcr |= DMZ_USRW;
782: return (lcr);
783: }
784:
785: /*
786: * Routine to convert modem status from dmz receive modem status
787: * and line control register to dm format.
788: * If dmz user modem read bit set, set DML_USR.
789: */
790: dmztodm(rms, lcr)
791: register int rms, lcr;
792: {
793:
794: rms = ((rms & (DMZ_DSR|DMZ_RNG|DMZ_CAR|DMZ_CTS|DMF_SR)) >> 7) |
795: ((rms & DMZ_USRR) >> 1) | DML_LE;
796: if (lcr & DMZ_DTR)
797: rms |= DML_DTR;
798: if (lcr & DMF_ST)
799: rms |= DML_ST;
800: if (lcr & DMZ_RTS)
801: rms |= DML_RTS;
802: return (rms);
803: }
804: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.