vax header files in their place
[unix-history] / usr / src / sys / vax / uba / dn.c
CommitLineData
406ddcbe 1/* dn.c 4.6 82/08/22 */
7119e7c0
BJ
2
3#include "dn.h"
4#if NDN > 0
5/*
6 * DN-11 ACU interface
7 */
8
9#include "../h/param.h"
10#include "../h/systm.h"
11#include "../h/dir.h"
12#include "../h/user.h"
13#include "../h/buf.h"
14#include "../h/map.h"
15#include "../h/pte.h"
16#include "../h/ubavar.h"
17#include "../h/conf.h"
18#include "../h/ioctl.h"
19
20struct dndevice {
401127f3 21 u_short dn_reg[4];
7119e7c0
BJ
22};
23
24struct uba_device *dninfo[NDN];
25int dnprobe(), dnattach();
26u_short dnstd[] = { 0175200 };
27struct uba_driver dndriver =
28 { dnprobe, 0, dnattach, 0, dnstd, "dn", dninfo };
29
401127f3
SL
30#define CRQ 0x001 /* call request */
31#define DPR 0x002 /* digit present */
32#define MENABLE 0x004 /* master enable */
33#define MAINT 0x008 /* maintenance mode */
34#define PND 0x010 /* present next digit */
35#define DSS 0x020 /* data set status */
36#define IENABLE 0x040 /* interrupt enable */
37#define DONE 0x080 /* operation complete */
38#define DLO 0x1000 /* data line occupied */
39#define ACR 0x4000 /* abandon call and retry */
40#define PWI 0x8000 /* power indicate */
7119e7c0
BJ
41
42#define DNPRI (PZERO+5)
43#define DNUNIT(dev) (minor(dev)>>2)
44#define DNREG(dev) ((dev)&03)
45
46#define OBUFSIZ 40 /* largest phone # dialer can handle */
47
48/*
49 * There's no good way to determine the correct number of dialers attached
89b8a44c 50 * to a single device (especially when dialers such as Vadic-821 MACS
401127f3 51 * exist which can address four chassis, each with its own dialer).
7119e7c0
BJ
52 */
53dnprobe(reg)
54 caddr_t reg;
55{
401127f3 56 register int br, cvec; /* value-result, must be r11, r10 */
7119e7c0
BJ
57 register struct dndevice *dnaddr = (struct dndevice *)reg;
58
59 /*
60 * If there's at least one dialer out there it better be
401127f3 61 * at chassis 0.
7119e7c0
BJ
62 */
63 dnaddr->dn_reg[0] = MENABLE|IENABLE|DONE;
64 DELAY(5);
65 dnaddr->dn_reg[0] = 0;
9c0adba0 66 return (sizeof (struct dndevice));
7119e7c0
BJ
67}
68
69dnattach(ui)
70 struct uba_device *ui;
401127f3 71{}
7119e7c0
BJ
72
73/*ARGSUSED*/
74dnopen(dev, flag)
75 dev_t dev;
76{
77 register struct dndevice *dp;
401127f3 78 register u_short unit, *dnreg;
7119e7c0
BJ
79 register struct uba_device *ui;
80 register short dialer;
81
82 if ((unit = DNUNIT(dev)) >= NDN || (ui = dninfo[unit]) == 0 ||
401127f3
SL
83 ui->ui_alive == 0) {
84 u.u_error = ENXIO;
85 return;
86 }
87 dialer = DNREG(dev);
88 dp = (struct dndevice *)ui->ui_addr;
89 if (dp->dn_reg[dialer] & PWI) {
7119e7c0
BJ
90 u.u_error = ENXIO;
91 return;
92 }
93 dnreg = &(dp->dn_reg[dialer]);
94 if (*dnreg&(DLO|CRQ)) {
95 u.u_error = EBUSY;
96 return;
97 }
98 dp->dn_reg[0] |= MENABLE;
99 *dnreg = IENABLE|MENABLE|CRQ;
100}
101
102/*ARGSUSED*/
103dnclose(dev, flag)
104 dev_t dev;
105{
106 register struct dndevice *dp;
107
108 dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr;
109 dp->dn_reg[DNREG(dev)] = MENABLE;
110}
111
406ddcbe 112dnwrite(dev, uio)
7119e7c0 113 dev_t dev;
406ddcbe 114 struct uio *uio;
7119e7c0 115{
401127f3
SL
116 register u_short *dnreg;
117 register int cc;
7119e7c0 118 register struct dndevice *dp;
401127f3 119 char buf[OBUFSIZ];
7119e7c0
BJ
120 register char *cp;
121 extern lbolt;
122
123 dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr;
124 dnreg = &(dp->dn_reg[DNREG(dev)]);
406ddcbe 125 cc = MIN(uio->uio_resid, OBUFSIZ);
401127f3 126 cp = buf;
406ddcbe 127 u.u_error = uiomove(cp, (unsigned)cc, UIO_WRITE, uio);
7119e7c0
BJ
128 if (u.u_error)
129 return;
130 while ((*dnreg & (PWI|ACR|DSS)) == 0 && cc >= 0) {
401127f3
SL
131 spl4();
132 if ((*dnreg & PND) == 0 || cc == 0)
7119e7c0
BJ
133 sleep((caddr_t)dnreg, DNPRI);
134 else switch(*cp) {
135
136 case '-':
137 sleep((caddr_t)&lbolt, DNPRI);
138 sleep((caddr_t)&lbolt, DNPRI);
139 break;
140
141 case 'f':
142 *dnreg &= ~CRQ;
143 sleep((caddr_t)&lbolt, DNPRI);
144 *dnreg |= CRQ;
145 break;
146
147 case '*': case ':':
148 *cp = 012;
149 goto dial;
150
151 case '#': case ';':
152 *cp = 013;
153 goto dial;
154
155 case 'e': case '<':
156 *cp = 014;
157 goto dial;
158
159 case 'w': case '=':
160 *cp = 015;
161 goto dial;
162
163 default:
164 if (*cp < '0' || *cp > '9')
165 break;
166 dial:
401127f3 167 *dnreg = (*cp << 8) | (IENABLE|MENABLE|DPR|CRQ);
7119e7c0
BJ
168 sleep((caddr_t)dnreg, DNPRI);
169 }
170 cp++, cc--;
171 spl0();
172 }
401127f3 173 if (*dnreg & (PWI|ACR))
7119e7c0
BJ
174 u.u_error = EIO;
175}
176
7119e7c0
BJ
177dnintr(dev)
178 dev_t dev;
179{
401127f3 180 register u_short *basereg, *dnreg;
7119e7c0 181
401127f3 182 basereg = (u_short *)dninfo[dev]->ui_addr;
7119e7c0 183 *basereg &= ~MENABLE;
401127f3
SL
184 for (dnreg = basereg; dnreg < basereg + 4; dnreg++)
185 if (*dnreg & DONE) {
7119e7c0
BJ
186 *dnreg &= ~(DONE|DPR);
187 wakeup((caddr_t)dnreg);
188 }
189 *basereg |= MENABLE;
190}
191#endif