Commit | Line | Data |
---|---|---|
078d920f | 1 | /* dz.c 4.45 82/10/13 */ |
5074fa57 | 2 | |
66b4fb09 | 3 | #include "dz.h" |
a3cb8f60 | 4 | #if NDZ > 0 |
5074fa57 | 5 | /* |
bea90e0b | 6 | * DZ-11 and DZ32 Driver |
7e00c42b BJ |
7 | * |
8 | * This driver mimics dh.c; see it for explanation of common code. | |
5074fa57 | 9 | */ |
e2c4935e | 10 | #include "bk.h" |
5074fa57 BJ |
11 | #include "../h/param.h" |
12 | #include "../h/systm.h" | |
13 | #include "../h/tty.h" | |
14 | #include "../h/dir.h" | |
15 | #include "../h/user.h" | |
668cc26d | 16 | #include "../h/proc.h" |
5074fa57 BJ |
17 | #include "../h/map.h" |
18 | #include "../h/pte.h" | |
3f3a34c3 | 19 | #include "../h/buf.h" |
7e286c72 | 20 | #include "../h/vm.h" |
5074fa57 | 21 | #include "../h/conf.h" |
771d8988 | 22 | #include "../h/bk.h" |
cc343d94 | 23 | #include "../h/file.h" |
740e4029 | 24 | #include "../h/uio.h" |
d3ebf5ee | 25 | |
896962b1 BJ |
26 | #include "../vaxuba/pdma.h" |
27 | #include "../vaxuba/ubavar.h" | |
28 | ||
7e00c42b BJ |
29 | /* |
30 | * Driver information for auto-configuration stuff. | |
31 | */ | |
71236e46 | 32 | int dzprobe(), dzattach(), dzrint(); |
6a1a96ff | 33 | struct uba_device *dzinfo[NDZ]; |
3f3a34c3 | 34 | u_short dzstd[] = { 0 }; |
3f3a34c3 | 35 | struct uba_driver dzdriver = |
71236e46 | 36 | { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; |
3f3a34c3 | 37 | |
a3cb8f60 | 38 | #define NDZLINE (NDZ*8) |
5074fa57 | 39 | |
7e00c42b BJ |
40 | /* |
41 | * Registers and bits | |
42 | */ | |
43 | ||
bea90e0b BJ |
44 | /* bits in dzlpr */ |
45 | #define BITS7 0020 | |
46 | #define BITS8 0030 | |
47 | #define TWOSB 0040 | |
88d5b764 BJ |
48 | #define PENABLE 0100 |
49 | #define OPAR 0200 | |
5074fa57 | 50 | |
bea90e0b | 51 | /* bits in dzrbuf */ |
7e00c42b BJ |
52 | #define DZ_PE 010000 |
53 | #define DZ_FE 020000 | |
54 | #define DZ_DO 040000 | |
55 | ||
bea90e0b BJ |
56 | /* bits in dzcsr */ |
57 | #define DZ_32 000001 /* DZ32 mode */ | |
58 | #define DZ_MIE 000002 /* Modem Interrupt Enable */ | |
59 | #define DZ_CLR 000020 /* Reset dz */ | |
60 | #define DZ_MSE 000040 /* Master Scan Enable */ | |
61 | #define DZ_RIE 000100 /* Receiver Interrupt Enable */ | |
62 | #define DZ_MSC 004000 /* Modem Status Change */ | |
7e00c42b BJ |
63 | #define DZ_SAE 010000 /* Silo Alarm Enable */ |
64 | #define DZ_TIE 040000 /* Transmit Interrupt Enable */ | |
bea90e0b | 65 | #define DZ_IEN (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE) |
7e00c42b | 66 | |
bea90e0b BJ |
67 | /* flags for modem-control */ |
68 | #define DZ_ON DZ_DTR | |
7e00c42b | 69 | #define DZ_OFF 0 |
bea90e0b BJ |
70 | |
71 | /* bits in dzlcs */ | |
72 | #define DZ_ACK 0100000 /* ACK bit in dzlcs */ | |
73 | #define DZ_RTS 0010000 /* Request To Send */ | |
74 | #define DZ_ST 0004000 /* Secondary Transmit */ | |
75 | #define DZ_BRK 0002000 /* Break */ | |
76 | #define DZ_DTR 0001000 /* Data Terminal Ready */ | |
77 | #define DZ_LE 0000400 /* Line Enable */ | |
78 | #define DZ_DSR 0000200 /* Data Set Ready */ | |
79 | #define DZ_RI 0000100 /* Ring Indicate */ | |
80 | #define DZ_CD 0000040 /* Carrier Detect */ | |
81 | #define DZ_CTS 0000020 /* Clear To Send */ | |
82 | #define DZ_SR 0000010 /* Secondary Receive */ | |
5074fa57 | 83 | |
bea90e0b BJ |
84 | /* bits in dm lsr, copied from dh.c */ |
85 | #define DML_DSR 0000400 /* data set ready, not a real DM bit */ | |
86 | #define DML_RNG 0000200 /* ring */ | |
87 | #define DML_CAR 0000100 /* carrier detect */ | |
88 | #define DML_CTS 0000040 /* clear to send */ | |
89 | #define DML_SR 0000020 /* secondary receive */ | |
90 | #define DML_ST 0000010 /* secondary transmit */ | |
91 | #define DML_RTS 0000004 /* request to send */ | |
92 | #define DML_DTR 0000002 /* data terminal ready */ | |
93 | #define DML_LE 0000001 /* line enable */ | |
94 | ||
7e00c42b | 95 | int dzstart(), dzxint(), dzdma(); |
771d8988 | 96 | int ttrstrt(); |
a3cb8f60 BJ |
97 | struct tty dz_tty[NDZLINE]; |
98 | int dz_cnt = { NDZLINE }; | |
9dca4f86 | 99 | int dzact; |
5074fa57 BJ |
100 | |
101 | struct device { | |
bea90e0b BJ |
102 | short dzcsr; |
103 | short dzrbuf; | |
104 | union { | |
105 | struct { | |
106 | char dztcr0; | |
107 | char dzdtr0; | |
108 | char dztbuf0; | |
109 | char dzbrk0; | |
110 | } dz11; | |
111 | struct { | |
112 | short dzlcs0; | |
113 | char dztbuf0; | |
114 | char dzlnen0; | |
115 | } dz32; | |
116 | } dzun; | |
5074fa57 | 117 | }; |
bea90e0b BJ |
118 | |
119 | #define dzlpr dzrbuf | |
120 | #define dzmsr dzun.dz11.dzbrk0 | |
121 | #define dztcr dzun.dz11.dztcr0 | |
122 | #define dzdtr dzun.dz11.dzdtr0 | |
123 | #define dztbuf dzun.dz11.dztbuf0 | |
124 | #define dzlcs dzun.dz32.dzlcs0 | |
125 | #define dzbrk dzmsr | |
126 | #define dzlnen dzun.dz32.dzlnen0 | |
9c0adba0 | 127 | #define dzmtsr dzun.dz32.dztbuf0 |
bea90e0b BJ |
128 | |
129 | #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) | |
130 | ||
7e00c42b BJ |
131 | /* |
132 | * Software copy of dzbrk since it isn't readable | |
133 | */ | |
a3cb8f60 BJ |
134 | char dz_brk[NDZ]; |
135 | char dzsoftCAR[NDZ]; | |
bea90e0b | 136 | char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ |
5074fa57 | 137 | |
7e00c42b | 138 | /* |
bea90e0b | 139 | * The dz11 doesn't interrupt on carrier transitions, so |
7e00c42b BJ |
140 | * we have to use a timer to watch it. |
141 | */ | |
142 | char dz_timer; /* timer started? */ | |
143 | ||
144 | /* | |
145 | * Pdma structures for fast output code | |
146 | */ | |
a3cb8f60 | 147 | struct pdma dzpdma[NDZLINE]; |
7e00c42b | 148 | |
3f3a34c3 | 149 | char dz_speeds[] = |
57644725 | 150 | { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; |
5074fa57 | 151 | |
df07bd9e SL |
152 | #ifndef PORTSELECTOR |
153 | #define ISPEED B300 | |
154 | #define IFLAGS (EVENP|ODDP|ECHO) | |
155 | #else | |
156 | #define ISPEED B4800 | |
157 | #define IFLAGS (EVENP|ODDP) | |
158 | #endif | |
159 | ||
71236e46 | 160 | dzprobe(reg) |
3f3a34c3 BJ |
161 | caddr_t reg; |
162 | { | |
88d5b764 BJ |
163 | register int br, cvec; |
164 | register struct device *dzaddr = (struct device *)reg; | |
3f3a34c3 | 165 | |
71236e46 | 166 | #ifdef lint |
a0eab615 | 167 | br = 0; cvec = br; br = cvec; |
89b8a44c | 168 | dzrint(0); dzxint((struct tty *)0); |
71236e46 | 169 | #endif |
bea90e0b BJ |
170 | dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; |
171 | if (dzaddr->dzcsr & DZ_32) | |
172 | dzaddr->dzlnen = 1; | |
173 | else | |
174 | dzaddr->dztcr = 1; /* enable any line */ | |
88d5b764 | 175 | DELAY(100000); |
bea90e0b | 176 | dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ |
88d5b764 BJ |
177 | if (cvec && cvec != 0x200) |
178 | cvec -= 4; | |
9c0adba0 | 179 | return (sizeof (struct device)); |
3f3a34c3 BJ |
180 | } |
181 | ||
71236e46 | 182 | dzattach(ui) |
6a1a96ff | 183 | register struct uba_device *ui; |
3f3a34c3 BJ |
184 | { |
185 | register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; | |
186 | register struct tty *tp = &dz_tty[ui->ui_unit*8]; | |
71236e46 | 187 | register int cntr; |
a3cb8f60 | 188 | extern dzscan(); |
3f3a34c3 | 189 | |
71236e46 BJ |
190 | for (cntr = 0; cntr < 8; cntr++) { |
191 | pdp->p_addr = (struct device *)ui->ui_addr; | |
3f3a34c3 BJ |
192 | pdp->p_arg = (int)tp; |
193 | pdp->p_fcn = dzxint; | |
194 | pdp++, tp++; | |
195 | } | |
7e286c72 | 196 | dzsoftCAR[ui->ui_unit] = ui->ui_flags; |
be2b272c BJ |
197 | if (dz_timer == 0) { |
198 | dz_timer++; | |
7780575a | 199 | timeout(dzscan, (caddr_t)0, hz); |
be2b272c | 200 | } |
3f3a34c3 BJ |
201 | } |
202 | ||
5074fa57 | 203 | /*ARGSUSED*/ |
3f3a34c3 BJ |
204 | dzopen(dev, flag) |
205 | dev_t dev; | |
5074fa57 BJ |
206 | { |
207 | register struct tty *tp; | |
3f3a34c3 | 208 | register int unit; |
5074fa57 | 209 | |
3f3a34c3 BJ |
210 | unit = minor(dev); |
211 | if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) { | |
5074fa57 BJ |
212 | u.u_error = ENXIO; |
213 | return; | |
214 | } | |
3f3a34c3 BJ |
215 | tp = &dz_tty[unit]; |
216 | tp->t_addr = (caddr_t)&dzpdma[unit]; | |
5074fa57 | 217 | tp->t_oproc = dzstart; |
941944c9 BJ |
218 | tp->t_state |= TS_WOPEN; |
219 | if ((tp->t_state & TS_ISOPEN) == 0) { | |
5074fa57 | 220 | ttychars(tp); |
df07bd9e SL |
221 | tp->t_ospeed = tp->t_ispeed = ISPEED; |
222 | tp->t_flags = IFLAGS; | |
941944c9 | 223 | /* tp->t_state |= TS_HUPCLS; */ |
3f3a34c3 | 224 | dzparam(unit); |
941944c9 | 225 | } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) { |
5074fa57 BJ |
226 | u.u_error = EBUSY; |
227 | return; | |
228 | } | |
668cc26d | 229 | (void) dzmctl(dev, DZ_ON, DMSET); |
771d8988 | 230 | (void) spl5(); |
941944c9 BJ |
231 | while ((tp->t_state & TS_CARR_ON) == 0) { |
232 | tp->t_state |= TS_WOPEN; | |
5074fa57 BJ |
233 | sleep((caddr_t)&tp->t_rawq, TTIPRI); |
234 | } | |
771d8988 | 235 | (void) spl0(); |
3f3a34c3 | 236 | (*linesw[tp->t_line].l_open)(dev, tp); |
5074fa57 BJ |
237 | } |
238 | ||
3f3a34c3 BJ |
239 | /*ARGSUSED*/ |
240 | dzclose(dev, flag) | |
241 | dev_t dev; | |
5074fa57 BJ |
242 | { |
243 | register struct tty *tp; | |
3f3a34c3 | 244 | register int unit; |
bea90e0b | 245 | register struct device *dzaddr; |
fa627691 | 246 | int dz; |
5074fa57 | 247 | |
3f3a34c3 BJ |
248 | unit = minor(dev); |
249 | dz = unit >> 3; | |
250 | tp = &dz_tty[unit]; | |
5074fa57 | 251 | (*linesw[tp->t_line].l_close)(tp); |
bea90e0b BJ |
252 | dzaddr = dzpdma[unit].p_addr; |
253 | if (dzaddr->dzcsr&DZ_32) | |
668cc26d | 254 | (void) dzmctl(dev, DZ_BRK, DMBIC); |
bea90e0b BJ |
255 | else |
256 | dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); | |
4f5daa2a | 257 | if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) |
668cc26d | 258 | (void) dzmctl(dev, DZ_OFF, DMSET); |
5074fa57 BJ |
259 | ttyclose(tp); |
260 | } | |
261 | ||
740e4029 | 262 | dzread(dev, uio) |
3f3a34c3 | 263 | dev_t dev; |
740e4029 | 264 | struct uio *uio; |
5074fa57 BJ |
265 | { |
266 | register struct tty *tp; | |
267 | ||
3f3a34c3 | 268 | tp = &dz_tty[minor(dev)]; |
740e4029 | 269 | return ((*linesw[tp->t_line].l_read)(tp, uio)); |
5074fa57 BJ |
270 | } |
271 | ||
406ddcbe | 272 | dzwrite(dev, uio) |
3f3a34c3 | 273 | dev_t dev; |
406ddcbe | 274 | struct uio *uio; |
5074fa57 BJ |
275 | { |
276 | register struct tty *tp; | |
277 | ||
3f3a34c3 | 278 | tp = &dz_tty[minor(dev)]; |
078d920f | 279 | return ((*linesw[tp->t_line].l_write)(tp, uio)); |
5074fa57 BJ |
280 | } |
281 | ||
9dca4f86 | 282 | /*ARGSUSED*/ |
3f3a34c3 BJ |
283 | dzrint(dz) |
284 | int dz; | |
5074fa57 BJ |
285 | { |
286 | register struct tty *tp; | |
287 | register int c; | |
288 | register struct device *dzaddr; | |
9dca4f86 | 289 | register struct tty *tp0; |
3f3a34c3 | 290 | register int unit; |
b19fe459 | 291 | int overrun = 0; |
5074fa57 | 292 | |
88d5b764 BJ |
293 | if ((dzact & (1<<dz)) == 0) |
294 | return; | |
295 | unit = dz * 8; | |
296 | dzaddr = dzpdma[unit].p_addr; | |
297 | tp0 = &dz_tty[unit]; | |
bea90e0b BJ |
298 | dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ |
299 | dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ | |
300 | while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ | |
301 | c = dzaddr->dzmtsr; | |
302 | tp = tp0 + (c&7); | |
303 | if (tp >= &dz_tty[dz_cnt]) | |
304 | break; | |
305 | dzaddr->dzlcs = c&7; /* get status of modem lines */ | |
306 | dzwait(dzaddr); /* wait for them */ | |
307 | if (c & DZ_CD) /* carrier status change? */ | |
308 | if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ | |
309 | if ((tp->t_state&TS_CARR_ON) == 0) { | |
310 | wakeup((caddr_t)&tp->t_rawq); | |
311 | tp->t_state |= TS_CARR_ON; | |
312 | } | |
313 | } else { /* no carrier */ | |
314 | if (tp->t_state&TS_CARR_ON) { | |
315 | gsignal(tp->t_pgrp, SIGHUP); | |
316 | gsignal(tp->t_pgrp, SIGCONT); | |
317 | dzaddr->dzlcs = DZ_ACK|(c&7); | |
318 | flushtty(tp, FREAD|FWRITE); | |
319 | } | |
320 | tp->t_state &= ~TS_CARR_ON; | |
321 | } | |
322 | } | |
88d5b764 BJ |
323 | while ((c = dzaddr->dzrbuf) < 0) { /* char present */ |
324 | tp = tp0 + ((c>>8)&07); | |
325 | if (tp >= &dz_tty[dz_cnt]) | |
326 | continue; | |
941944c9 | 327 | if ((tp->t_state & TS_ISOPEN) == 0) { |
88d5b764 | 328 | wakeup((caddr_t)&tp->t_rawq); |
df07bd9e SL |
329 | #ifdef PORTSELECTOR |
330 | if ((tp->t_state&TS_WOPEN) == 0) | |
331 | #endif | |
5074fa57 | 332 | continue; |
9dca4f86 | 333 | } |
7e00c42b | 334 | if (c&DZ_FE) |
88d5b764 | 335 | if (tp->t_flags & RAW) |
7e00c42b | 336 | c = 0; |
88d5b764 BJ |
337 | else |
338 | c = tun.t_intrc; | |
b19fe459 | 339 | if (c&DZ_DO && overrun == 0) { |
bea90e0b | 340 | /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ |
b19fe459 BJ |
341 | overrun = 1; |
342 | } | |
7e00c42b | 343 | if (c&DZ_PE) |
88d5b764 BJ |
344 | if (((tp->t_flags & (EVENP|ODDP)) == EVENP) |
345 | || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) | |
346 | continue; | |
e2c4935e | 347 | #if NBK > 0 |
88d5b764 BJ |
348 | if (tp->t_line == NETLDISC) { |
349 | c &= 0177; | |
350 | BKINPUT(c, tp); | |
351 | } else | |
e2c4935e | 352 | #endif |
88d5b764 | 353 | (*linesw[tp->t_line].l_rint)(c, tp); |
5074fa57 BJ |
354 | } |
355 | } | |
356 | ||
357 | /*ARGSUSED*/ | |
942f05a9 | 358 | dzioctl(dev, cmd, data, flag) |
3f3a34c3 | 359 | dev_t dev; |
942f05a9 | 360 | caddr_t data; |
5074fa57 BJ |
361 | { |
362 | register struct tty *tp; | |
3f3a34c3 BJ |
363 | register int unit = minor(dev); |
364 | register int dz = unit >> 3; | |
bea90e0b | 365 | register struct device *dzaddr; |
5074fa57 | 366 | |
3f3a34c3 | 367 | tp = &dz_tty[unit]; |
942f05a9 | 368 | cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); |
771d8988 BJ |
369 | if (cmd == 0) |
370 | return; | |
942f05a9 SL |
371 | if (ttioctl(tp, cmd, data, flag)) { |
372 | if (cmd == TIOCSETP || cmd == TIOCSETN) | |
3f3a34c3 | 373 | dzparam(unit); |
dc44829a | 374 | } else switch(cmd) { |
3f3a34c3 | 375 | |
dc44829a | 376 | case TIOCSBRK: |
bea90e0b BJ |
377 | dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; |
378 | if (dzaddr->dzcsr&DZ_32) | |
668cc26d | 379 | (void) dzmctl(dev, DZ_BRK, DMBIS); |
bea90e0b BJ |
380 | else |
381 | dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); | |
dc44829a | 382 | break; |
942f05a9 | 383 | |
dc44829a | 384 | case TIOCCBRK: |
bea90e0b BJ |
385 | dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; |
386 | if (dzaddr->dzcsr&DZ_32) | |
668cc26d | 387 | (void) dzmctl(dev, DZ_BRK, DMBIC); |
bea90e0b BJ |
388 | else |
389 | dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); | |
dc44829a | 390 | break; |
942f05a9 | 391 | |
dc44829a | 392 | case TIOCSDTR: |
668cc26d | 393 | (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); |
dc44829a | 394 | break; |
942f05a9 | 395 | |
dc44829a | 396 | case TIOCCDTR: |
668cc26d | 397 | (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); |
bea90e0b | 398 | break; |
942f05a9 | 399 | |
bea90e0b | 400 | case TIOCMSET: |
942f05a9 | 401 | (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); |
bea90e0b | 402 | break; |
942f05a9 | 403 | |
bea90e0b | 404 | case TIOCMBIS: |
942f05a9 | 405 | (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); |
bea90e0b | 406 | break; |
942f05a9 | 407 | |
bea90e0b | 408 | case TIOCMBIC: |
942f05a9 | 409 | (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); |
bea90e0b | 410 | break; |
942f05a9 | 411 | |
bea90e0b | 412 | case TIOCMGET: |
942f05a9 | 413 | *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); |
dc44829a | 414 | break; |
942f05a9 | 415 | |
dc44829a | 416 | default: |
5074fa57 | 417 | u.u_error = ENOTTY; |
dc44829a | 418 | } |
5074fa57 | 419 | } |
bea90e0b BJ |
420 | |
421 | dmtodz(bits) | |
422 | register int bits; | |
423 | { | |
424 | register int b; | |
425 | ||
426 | b = (bits >>1) & 0370; | |
427 | if (bits & DML_ST) b |= DZ_ST; | |
428 | if (bits & DML_RTS) b |= DZ_RTS; | |
429 | if (bits & DML_DTR) b |= DZ_DTR; | |
430 | if (bits & DML_LE) b |= DZ_LE; | |
431 | return(b); | |
432 | } | |
433 | ||
434 | dztodm(bits) | |
435 | register int bits; | |
436 | { | |
437 | register int b; | |
438 | ||
439 | b = (bits << 1) & 0360; | |
440 | if (bits & DZ_DSR) b |= DML_DSR; | |
441 | if (bits & DZ_DTR) b |= DML_DTR; | |
442 | if (bits & DZ_ST) b |= DML_ST; | |
443 | if (bits & DZ_RTS) b |= DML_RTS; | |
444 | return(b); | |
445 | } | |
5074fa57 | 446 | |
3f3a34c3 BJ |
447 | dzparam(unit) |
448 | register int unit; | |
5074fa57 BJ |
449 | { |
450 | register struct tty *tp; | |
451 | register struct device *dzaddr; | |
3f3a34c3 | 452 | register int lpr; |
5074fa57 | 453 | |
3f3a34c3 BJ |
454 | tp = &dz_tty[unit]; |
455 | dzaddr = dzpdma[unit].p_addr; | |
5074fa57 | 456 | dzaddr->dzcsr = DZ_IEN; |
3f3a34c3 | 457 | dzact |= (1<<(unit>>3)); |
5074fa57 | 458 | if (tp->t_ispeed == 0) { |
668cc26d | 459 | (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ |
5074fa57 BJ |
460 | return; |
461 | } | |
3f3a34c3 | 462 | lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); |
be5b7974 | 463 | if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW)) |
5074fa57 BJ |
464 | lpr |= BITS8; |
465 | else | |
466 | lpr |= (BITS7|PENABLE); | |
467 | if ((tp->t_flags & EVENP) == 0) | |
468 | lpr |= OPAR; | |
7e00c42b BJ |
469 | if (tp->t_ispeed == B110) |
470 | lpr |= TWOSB; | |
5074fa57 BJ |
471 | dzaddr->dzlpr = lpr; |
472 | } | |
473 | ||
474 | dzxint(tp) | |
3f3a34c3 | 475 | register struct tty *tp; |
5074fa57 BJ |
476 | { |
477 | register struct pdma *dp; | |
bea90e0b | 478 | register s, dz, unit; |
5074fa57 | 479 | |
7e00c42b | 480 | s = spl5(); /* block pdma interrupts */ |
3f3a34c3 | 481 | dp = (struct pdma *)tp->t_addr; |
941944c9 BJ |
482 | tp->t_state &= ~TS_BUSY; |
483 | if (tp->t_state & TS_FLUSH) | |
484 | tp->t_state &= ~TS_FLUSH; | |
bea90e0b | 485 | else { |
46014098 | 486 | ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); |
bea90e0b BJ |
487 | dp->p_end = dp->p_mem = tp->t_outq.c_cf; |
488 | } | |
5074fa57 BJ |
489 | if (tp->t_line) |
490 | (*linesw[tp->t_line].l_start)(tp); | |
491 | else | |
492 | dzstart(tp); | |
bea90e0b BJ |
493 | dz = minor(tp->t_dev) >> 3; |
494 | unit = minor(tp->t_dev) & 7; | |
941944c9 | 495 | if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) |
bea90e0b BJ |
496 | if (dp->p_addr->dzcsr & DZ_32) |
497 | dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); | |
498 | else | |
499 | dp->p_addr->dztcr &= ~(1<<unit); | |
d3ebf5ee | 500 | splx(s); |
5074fa57 BJ |
501 | } |
502 | ||
503 | dzstart(tp) | |
3f3a34c3 | 504 | register struct tty *tp; |
5074fa57 BJ |
505 | { |
506 | register struct pdma *dp; | |
507 | register struct device *dzaddr; | |
3f3a34c3 | 508 | register int cc; |
bea90e0b | 509 | int s, dz, unit; |
5074fa57 | 510 | |
3f3a34c3 | 511 | dp = (struct pdma *)tp->t_addr; |
5074fa57 | 512 | dzaddr = dp->p_addr; |
3f3a34c3 | 513 | s = spl5(); |
941944c9 | 514 | if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) |
5074fa57 | 515 | goto out; |
941944c9 BJ |
516 | if (tp->t_outq.c_cc <= TTLOWAT(tp)) { |
517 | if (tp->t_state&TS_ASLEEP) { | |
518 | tp->t_state &= ~TS_ASLEEP; | |
519 | wakeup((caddr_t)&tp->t_outq); | |
520 | } | |
521 | if (tp->t_wsel) { | |
522 | selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); | |
523 | tp->t_wsel = 0; | |
524 | tp->t_state &= ~TS_WCOLL; | |
525 | } | |
5074fa57 BJ |
526 | } |
527 | if (tp->t_outq.c_cc == 0) | |
528 | goto out; | |
bea90e0b | 529 | if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT)) |
5074fa57 BJ |
530 | cc = ndqb(&tp->t_outq, 0); |
531 | else { | |
532 | cc = ndqb(&tp->t_outq, 0200); | |
533 | if (cc == 0) { | |
534 | cc = getc(&tp->t_outq); | |
7e00c42b | 535 | timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); |
941944c9 | 536 | tp->t_state |= TS_TIMEOUT; |
5074fa57 BJ |
537 | goto out; |
538 | } | |
539 | } | |
941944c9 | 540 | tp->t_state |= TS_BUSY; |
5074fa57 BJ |
541 | dp->p_end = dp->p_mem = tp->t_outq.c_cf; |
542 | dp->p_end += cc; | |
bea90e0b BJ |
543 | dz = minor(tp->t_dev) >> 3; |
544 | unit = minor(tp->t_dev) & 7; | |
545 | if (dzaddr->dzcsr & DZ_32) | |
546 | dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); | |
547 | else | |
548 | dzaddr->dztcr |= (1<<unit); | |
3f3a34c3 BJ |
549 | out: |
550 | splx(s); | |
5074fa57 BJ |
551 | } |
552 | ||
553 | /* | |
554 | * Stop output on a line. | |
5074fa57 BJ |
555 | */ |
556 | /*ARGSUSED*/ | |
557 | dzstop(tp, flag) | |
3f3a34c3 | 558 | register struct tty *tp; |
5074fa57 BJ |
559 | { |
560 | register struct pdma *dp; | |
561 | register int s; | |
562 | ||
3f3a34c3 | 563 | dp = (struct pdma *)tp->t_addr; |
88d5b764 | 564 | s = spl5(); |
941944c9 | 565 | if (tp->t_state & TS_BUSY) { |
5074fa57 | 566 | dp->p_end = dp->p_mem; |
941944c9 BJ |
567 | if ((tp->t_state&TS_TTSTOP)==0) |
568 | tp->t_state |= TS_FLUSH; | |
5074fa57 BJ |
569 | } |
570 | splx(s); | |
571 | } | |
572 | ||
bea90e0b BJ |
573 | dzmctl(dev, bits, how) |
574 | dev_t dev; | |
575 | int bits, how; | |
5074fa57 BJ |
576 | { |
577 | register struct device *dzaddr; | |
bea90e0b BJ |
578 | register int unit, mbits; |
579 | int b, s; | |
580 | ||
581 | unit = minor(dev); | |
582 | b = 1<<(unit&7); | |
3f3a34c3 | 583 | dzaddr = dzpdma[unit].p_addr; |
bea90e0b BJ |
584 | s = spl5(); |
585 | if (dzaddr->dzcsr & DZ_32) { | |
586 | dzwait(dzaddr) | |
587 | DELAY(100); /* IS 100 TOO MUCH? */ | |
588 | dzaddr->dzlcs = unit&7; | |
589 | DELAY(100); | |
590 | dzwait(dzaddr) | |
591 | DELAY(100); | |
592 | mbits = dzaddr->dzlcs; | |
593 | mbits &= 0177770; | |
594 | } else { | |
595 | mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; | |
596 | mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; | |
597 | mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; | |
598 | } | |
599 | switch (how) { | |
600 | case DMSET: | |
601 | mbits = bits; | |
602 | break; | |
603 | ||
604 | case DMBIS: | |
605 | mbits |= bits; | |
606 | break; | |
607 | ||
608 | case DMBIC: | |
609 | mbits &= ~bits; | |
610 | break; | |
611 | ||
612 | case DMGET: | |
613 | (void) splx(s); | |
614 | return(mbits); | |
615 | } | |
616 | if (dzaddr->dzcsr & DZ_32) { | |
617 | mbits |= DZ_ACK|(unit&7); | |
618 | dzaddr->dzlcs = mbits; | |
619 | } else { | |
620 | if (mbits & DZ_DTR) | |
621 | dzaddr->dzdtr |= b; | |
622 | else | |
623 | dzaddr->dzdtr &= ~b; | |
624 | } | |
625 | (void) splx(s); | |
626 | return(mbits); | |
5074fa57 BJ |
627 | } |
628 | ||
629 | dzscan() | |
630 | { | |
631 | register i; | |
632 | register struct device *dzaddr; | |
633 | register bit; | |
634 | register struct tty *tp; | |
bea90e0b | 635 | register car; |
5074fa57 BJ |
636 | |
637 | for (i = 0; i < dz_cnt ; i++) { | |
638 | dzaddr = dzpdma[i].p_addr; | |
be2b272c BJ |
639 | if (dzaddr == 0) |
640 | continue; | |
5074fa57 BJ |
641 | tp = &dz_tty[i]; |
642 | bit = 1<<(i&07); | |
bea90e0b BJ |
643 | car = 0; |
644 | if (dzsoftCAR[i>>3]&bit) | |
645 | car = 1; | |
646 | else if (dzaddr->dzcsr & DZ_32) { | |
647 | dzaddr->dzlcs = i&07; | |
648 | dzwait(dzaddr); | |
649 | car = dzaddr->dzlcs & DZ_CD; | |
650 | } else | |
651 | car = dzaddr->dzmsr&bit; | |
652 | if (car) { | |
5074fa57 | 653 | /* carrier present */ |
941944c9 | 654 | if ((tp->t_state & TS_CARR_ON) == 0) { |
5074fa57 | 655 | wakeup((caddr_t)&tp->t_rawq); |
941944c9 | 656 | tp->t_state |= TS_CARR_ON; |
5074fa57 BJ |
657 | } |
658 | } else { | |
941944c9 | 659 | if ((tp->t_state&TS_CARR_ON) && |
7e00c42b | 660 | (tp->t_local&LNOHANG)==0) { |
5074fa57 | 661 | /* carrier lost */ |
941944c9 | 662 | if (tp->t_state&TS_ISOPEN) { |
dc44829a | 663 | gsignal(tp->t_pgrp, SIGHUP); |
160cf9ed | 664 | gsignal(tp->t_pgrp, SIGCONT); |
dc44829a | 665 | dzaddr->dzdtr &= ~bit; |
cc343d94 | 666 | flushtty(tp, FREAD|FWRITE); |
dc44829a | 667 | } |
941944c9 | 668 | tp->t_state &= ~TS_CARR_ON; |
5074fa57 | 669 | } |
5074fa57 BJ |
670 | } |
671 | } | |
7780575a | 672 | timeout(dzscan, (caddr_t)0, 2*hz); |
5074fa57 | 673 | } |
9dca4f86 BJ |
674 | |
675 | dztimer() | |
676 | { | |
aa890753 BJ |
677 | register int dz; |
678 | register int s = spl5(); | |
9dca4f86 | 679 | |
a3cb8f60 | 680 | for (dz = 0; dz < NDZ; dz++) |
88d5b764 | 681 | dzrint(dz); |
aa890753 | 682 | splx(s); |
9dca4f86 | 683 | } |
46014098 BJ |
684 | |
685 | /* | |
686 | * Reset state of driver if UBA reset was necessary. | |
0072a3c2 | 687 | * Reset parameters and restart transmission on open lines. |
46014098 | 688 | */ |
3f3a34c3 | 689 | dzreset(uban) |
5aa9d5ea | 690 | int uban; |
46014098 | 691 | { |
3f3a34c3 | 692 | register int unit; |
46014098 | 693 | register struct tty *tp; |
6a1a96ff | 694 | register struct uba_device *ui; |
46014098 | 695 | |
a3cb8f60 | 696 | for (unit = 0; unit < NDZLINE; unit++) { |
5aa9d5ea RE |
697 | ui = dzinfo[unit >> 3]; |
698 | if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) | |
699 | continue; | |
b19fe459 BJ |
700 | if (unit%8 == 0) |
701 | printf(" dz%d", unit>>3); | |
3f3a34c3 | 702 | tp = &dz_tty[unit]; |
941944c9 | 703 | if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { |
3f3a34c3 | 704 | dzparam(unit); |
668cc26d | 705 | (void) dzmctl(unit, DZ_ON, DMSET); |
941944c9 | 706 | tp->t_state &= ~TS_BUSY; |
0072a3c2 | 707 | dzstart(tp); |
46014098 BJ |
708 | } |
709 | } | |
710 | dztimer(); | |
46014098 | 711 | } |
a5cc519e | 712 | #endif |