BSD 4 development
[unix-history] / usr / src / sys / newdev / dhdm.c
CommitLineData
7097c902
BJ
1/* dhdm.c 3.1 9/14/80 */
2
3/*
4 * DM-BB driver
5 */
6#include "../h/param.h"
7#include "../h/tty.h"
8#include "../h/conf.h"
9#include "../h/map.h"
10#include "../h/pte.h"
11#include "../h/uba.h"
12
13#define DMADDR ((struct device *)(UBA0_DEV+0170500))
14
15struct tty dh11[];
16int ndh11; /* Set by dh.c to number of lines */
17
18#define DONE 0200
19#define SCENABL 040
20#define CLSCAN 01000
21#define TURNON 03 /* CD lead, line enable */
22#define RQS 04 /* request to send */
23#define TURNOFF 1 /* line enable only */
24#define CARRIER 0100
25
26struct device
27{
28 short dmcsr;
29 short dmlstat;
30 short junk[2];
31};
32
33/*
34 * Turn on the line associated with the (DH) device dev.
35 */
36dmopen(dev)
37{
38 register struct tty *tp;
39 register struct device *addr;
40 register d;
41
42 d = minor(dev);
43 tp = &dh11[d];
44 addr = DMADDR;
45 addr += d>>4;
46 spl5();
47 addr->dmcsr &= ~SCENABL;
48 while (addr->dmcsr & SCBUSY)
49 ;
50 addr->dmcsr = d&017;
51 addr->dmlstat = TURNON;
52 if (addr->dmlstat&CARRIER)
53 tp->t_state |= CARR_ON;
54 addr->dmcsr = IENABLE|SCENABL;
55 while ((tp->t_state&CARR_ON)==0)
56 sleep((caddr_t)&tp->t_rawq, TTIPRI);
57 spl0();
58}
59
60/*
61 * Dump control bits into the DM registers.
62 */
63dmctl(dev, bits, how)
64{
65 register struct device *addr;
66 register d, s;
67
68 d = minor(dev);
69 if (d >= ndh11)
70 return;
71 addr = DMADDR;
72 addr += d>>4;
73 s = spl5();
74 addr->dmcsr &= ~SCENABL;
75 while (addr->dmcsr & SCBUSY)
76 ;
77 addr->dmcsr = d&017;
78 switch(how) {
79 case DMSET:
80 addr->dmlstat = bits;
81 break;
82 case DMBIS:
83 addr->dmlstat |= bits;
84 break;
85 case DMBIC:
86 addr->dmlstat &= ~bits;
87 break;
88 }
89 addr->dmcsr = IENABLE|SCENABL;
90 splx(s);
91}
92
93/*
94 * DM11 interrupt.
95 * Mainly, deal with carrier transitions.
96 */
97dmint(dev)
98{
99 register struct tty *tp;
100 register struct device *addr;
101 register d;
102
103 d = minor(dev);
104 addr = DMADDR;
105 addr += d;
106 if (addr->dmcsr&DONE && addr->dmcsr&CARRTRANS) {
107 tp = &dh11[(d<<4)+(addr->dmcsr&017)];
108 if (tp < &dh11[ndh11]) {
109 wakeup((caddr_t)&tp->t_rawq);
110 if ((tp->t_state&WOPEN)==0 &&
111 (tp->t_local&LMDMBUF)) {
112 if (addr->dmlstat & CARRIER) {
113 tp->t_state &= ~TTSTOP;
114 ttstart(tp);
115 } else if ((tp->t_state&TTSTOP) == 0) {
116 tp->t_state |= TTSTOP;
117 dhstop(tp, 0);
118 }
119 else if ((addr->dmlstat&CARRIER)==0) {
120 if ((tp->t_state&WOPEN)==0 &&
121 (tp->t_local&LNOHANG)==0) {
122 gsignal(tp->t_pgrp, SIGHUP);
123 gsignal(tp->t_pgrp, SIGCONT);
124 addr->dmlstat = 0;
125 flushtty(tp, FREAD|FWRITE);
126 }
127 tp->t_state &= ~CARR_ON;
128 } else
129 tp->t_state |= CARR_ON;
130 }
131 addr->dmcsr = IENABLE|SCENABL;
132 }
133}