Commit | Line | Data |
---|---|---|
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 | 21 | struct dndevice { |
401127f3 | 22 | u_short dn_reg[4]; |
7119e7c0 BJ |
23 | }; |
24 | ||
25 | struct uba_device *dninfo[NDN]; | |
39d536e6 | 26 | int dnprobe(), dnattach(), dnintr(); |
7119e7c0 BJ |
27 | u_short dnstd[] = { 0175200 }; |
28 | struct 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 | */ |
54 | dnprobe(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 |
75 | dnattach(ui) |
76 | struct uba_device *ui; | |
7da157da BJ |
77 | { |
78 | ||
79 | } | |
7119e7c0 BJ |
80 | |
81 | /*ARGSUSED*/ | |
82 | dnopen(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*/ | |
107 | dnclose(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 | 116 | dnwrite(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 |
183 | dnintr(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 |