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