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