1 /* $NetBSD: dz.c,v 1.2 2002/03/17 19:40:54 atatat Exp $ */ 2 /* 3 * Copyright (c) 1996 Ken C. Wellsch. All rights reserved. 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Ralph Campbell and Rick Macklem. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: dz.c,v 1.2 2002/03/17 19:40:54 atatat Exp $"); 41 42 #include "opt_ddb.h" 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/callout.h> 47 #include <sys/ioctl.h> 48 #include <sys/tty.h> 49 #include <sys/proc.h> 50 #include <sys/map.h> 51 #include <sys/buf.h> 52 #include <sys/conf.h> 53 #include <sys/file.h> 54 #include <sys/uio.h> 55 #include <sys/kernel.h> 56 #include <sys/syslog.h> 57 #include <sys/device.h> 58 59 #include <machine/bus.h> 60 61 #include <dev/dec/dzreg.h> 62 #include <dev/dec/dzvar.h> 63 64 #define DZ_READ_BYTE(adr) \ 65 bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->sc_dr.adr) 66 #define DZ_READ_WORD(adr) \ 67 bus_space_read_2(sc->sc_iot, sc->sc_ioh, sc->sc_dr.adr) 68 #define DZ_WRITE_BYTE(adr, val) \ 69 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_dr.adr, val) 70 #define DZ_WRITE_WORD(adr, val) \ 71 bus_space_write_2(sc->sc_iot, sc->sc_ioh, sc->sc_dr.adr, val) 72 73 #include "ioconf.h" 74 75 /* A DZ-11 has 8 ports while a DZV/DZQ-11 has only 4. We use 8 by default */ 76 77 #define NDZLINE 8 78 79 #define DZ_C2I(c) ((c)<<3) /* convert controller # to index */ 80 #define DZ_I2C(c) ((c)>>3) /* convert minor to controller # */ 81 #define DZ_PORT(u) ((u)&07) /* extract the port # */ 82 83 /* Flags used to monitor modem bits, make them understood outside driver */ 84 85 #define DML_DTR TIOCM_DTR 86 #define DML_DCD TIOCM_CD 87 #define DML_RI TIOCM_RI 88 #define DML_BRK 0100000 /* no equivalent, we will mask */ 89 90 static struct speedtab dzspeedtab[] = 91 { 92 { 0, 0 }, 93 { 50, DZ_LPR_B50 }, 94 { 75, DZ_LPR_B75 }, 95 { 110, DZ_LPR_B110 }, 96 { 134, DZ_LPR_B134 }, 97 { 150, DZ_LPR_B150 }, 98 { 300, DZ_LPR_B300 }, 99 { 600, DZ_LPR_B600 }, 100 { 1200, DZ_LPR_B1200 }, 101 { 1800, DZ_LPR_B1800 }, 102 { 2000, DZ_LPR_B2000 }, 103 { 2400, DZ_LPR_B2400 }, 104 { 3600, DZ_LPR_B3600 }, 105 { 4800, DZ_LPR_B4800 }, 106 { 7200, DZ_LPR_B7200 }, 107 { 9600, DZ_LPR_B9600 }, 108 { 19200, DZ_LPR_B19200 }, 109 { -1, -1 } 110 }; 111 112 static void dzstart(struct tty *); 113 static int dzparam(struct tty *, struct termios *); 114 static unsigned dzmctl(struct dz_softc *, int, int, int); 115 static void dzscan(void *); 116 cdev_decl(dz); 117 118 /* 119 * The DZ series doesn't interrupt on carrier transitions, 120 * so we have to use a timer to watch it. 121 */ 122 int dz_timer; /* true if timer started */ 123 struct callout dzscan_ch; 124 125 #define DZ_DZ 8 /* Unibus DZ-11 board linecount */ 126 #define DZ_DZV 4 /* Q-bus DZV-11 or DZQ-11 */ 127 128 void 129 dzattach(struct dz_softc *sc, struct evcnt *parent_evcnt) 130 { 131 int n; 132 133 sc->sc_rxint = sc->sc_brk = 0; 134 135 sc->sc_dr.dr_tcrw = sc->sc_dr.dr_tcr; 136 DZ_WRITE_WORD(dr_csr, DZ_CSR_MSE | DZ_CSR_RXIE | DZ_CSR_TXIE); 137 DZ_WRITE_BYTE(dr_dtr, 0); 138 DZ_WRITE_BYTE(dr_break, 0); 139 140 /* Initialize our softc structure. Should be done in open? */ 141 142 for (n = 0; n < sc->sc_type; n++) 143 sc->sc_dz[n].dz_tty = ttymalloc(); 144 145 evcnt_attach_dynamic(&sc->sc_rintrcnt, EVCNT_TYPE_INTR, parent_evcnt, 146 sc->sc_dev.dv_xname, "rintr"); 147 evcnt_attach_dynamic(&sc->sc_tintrcnt, EVCNT_TYPE_INTR, parent_evcnt, 148 sc->sc_dev.dv_xname, "tintr"); 149 150 /* Alas no interrupt on modem bit changes, so we manually scan */ 151 152 if (dz_timer == 0) { 153 dz_timer = 1; 154 callout_init(&dzscan_ch); 155 callout_reset(&dzscan_ch, hz, dzscan, NULL); 156 } 157 printf("\n"); 158 return; 159 } 160 161 /* Receiver Interrupt */ 162 163 void 164 dzrint(void *arg) 165 { 166 struct dz_softc *sc = arg; 167 struct tty *tp; 168 int cc, line; 169 unsigned c; 170 int overrun = 0; 171 172 sc->sc_rxint++; 173 174 while ((c = DZ_READ_WORD(dr_rbuf)) & DZ_RBUF_DATA_VALID) { 175 cc = c & 0xFF; 176 line = DZ_PORT(c>>8); 177 tp = sc->sc_dz[line].dz_tty; 178 179 /* Must be caught early */ 180 if (sc->sc_dz[line].dz_catch && 181 (*sc->sc_dz[line].dz_catch)(sc->sc_dz[line].dz_private, cc)) 182 continue; 183 184 if (!(tp->t_state & TS_ISOPEN)) { 185 wakeup((caddr_t)&tp->t_rawq); 186 continue; 187 } 188 189 if ((c & DZ_RBUF_OVERRUN_ERR) && overrun == 0) { 190 log(LOG_WARNING, "%s: silo overflow, line %d\n", 191 sc->sc_dev.dv_xname, line); 192 overrun = 1; 193 } 194 195 /* A BREAK key will appear as a NULL with a framing error */ 196 if (c & DZ_RBUF_FRAMING_ERR) 197 cc |= TTY_FE; 198 if (c & DZ_RBUF_PARITY_ERR) 199 cc |= TTY_PE; 200 201 (*tp->t_linesw->l_rint)(cc, tp); 202 } 203 } 204 205 /* Transmitter Interrupt */ 206 207 void 208 dzxint(void *arg) 209 { 210 struct dz_softc *sc = arg; 211 struct tty *tp; 212 struct clist *cl; 213 int line, ch, csr; 214 u_char tcr; 215 216 /* 217 * Switch to POLLED mode. 218 * Some simple measurements indicated that even on 219 * one port, by freeing the scanner in the controller 220 * by either providing a character or turning off 221 * the port when output is complete, the transmitter 222 * was ready to accept more output when polled again. 223 * With just two ports running the game "worms," 224 * almost every interrupt serviced both transmitters! 225 * Each UART is double buffered, so if the scanner 226 * is quick enough and timing works out, we can even 227 * feed the same port twice. 228 * 229 * Ragge 980517: 230 * Do not need to turn off interrupts, already at interrupt level. 231 * Remove the pdma stuff; no great need of it right now. 232 */ 233 234 while (((csr = DZ_READ_WORD(dr_csr)) & DZ_CSR_TX_READY) != 0) { 235 236 line = DZ_PORT(csr>>8); 237 238 tp = sc->sc_dz[line].dz_tty; 239 cl = &tp->t_outq; 240 tp->t_state &= ~TS_BUSY; 241 242 /* Just send out a char if we have one */ 243 /* As long as we can fill the chip buffer, we just loop here */ 244 if (cl->c_cc) { 245 tp->t_state |= TS_BUSY; 246 ch = getc(cl); 247 DZ_WRITE_BYTE(dr_tbuf, ch); 248 continue; 249 } 250 /* Nothing to send; clear the scan bit */ 251 /* Clear xmit scanner bit; dzstart may set it again */ 252 tcr = DZ_READ_WORD(dr_tcrw); 253 tcr &= 255; 254 tcr &= ~(1 << line); 255 DZ_WRITE_BYTE(dr_tcr, tcr); 256 if (sc->sc_dz[line].dz_catch) 257 continue; 258 259 if (tp->t_state & TS_FLUSH) 260 tp->t_state &= ~TS_FLUSH; 261 else 262 ndflush (&tp->t_outq, cl->c_cc); 263 264 (*tp->t_linesw->l_start)(tp); 265 } 266 } 267 268 int 269 dzopen(dev_t dev, int flag, int mode, struct proc *p) 270 { 271 struct tty *tp; 272 int unit, line; 273 struct dz_softc *sc; 274 int s, error = 0; 275 276 unit = DZ_I2C(minor(dev)); 277 line = DZ_PORT(minor(dev)); 278 if (unit >= dz_cd.cd_ndevs || dz_cd.cd_devs[unit] == NULL) 279 return (ENXIO); 280 281 sc = dz_cd.cd_devs[unit]; 282 283 if (line >= sc->sc_type) 284 return ENXIO; 285 286 /* if some other device is using the line, it's busy */ 287 if (sc->sc_dz[line].dz_catch) 288 return EBUSY; 289 290 tp = sc->sc_dz[line].dz_tty; 291 if (tp == NULL) 292 return (ENODEV); 293 tp->t_oproc = dzstart; 294 tp->t_param = dzparam; 295 tp->t_dev = dev; 296 if ((tp->t_state & TS_ISOPEN) == 0) { 297 ttychars(tp); 298 if (tp->t_ispeed == 0) { 299 tp->t_iflag = TTYDEF_IFLAG; 300 tp->t_oflag = TTYDEF_OFLAG; 301 tp->t_cflag = TTYDEF_CFLAG; 302 tp->t_lflag = TTYDEF_LFLAG; 303 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 304 } 305 (void) dzparam(tp, &tp->t_termios); 306 ttsetwater(tp); 307 } else if ((tp->t_state & TS_XCLUDE) && p->p_ucred->cr_uid != 0) 308 return (EBUSY); 309 /* Use DMBIS and *not* DMSET or else we clobber incoming bits */ 310 if (dzmctl(sc, line, DML_DTR, DMBIS) & DML_DCD) 311 tp->t_state |= TS_CARR_ON; 312 s = spltty(); 313 while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) && 314 !(tp->t_state & TS_CARR_ON)) { 315 tp->t_wopen++; 316 error = ttysleep(tp, (caddr_t)&tp->t_rawq, 317 TTIPRI | PCATCH, ttopen, 0); 318 tp->t_wopen--; 319 if (error) 320 break; 321 } 322 (void) splx(s); 323 if (error) 324 return (error); 325 return ((*tp->t_linesw->l_open)(dev, tp)); 326 } 327 328 /*ARGSUSED*/ 329 int 330 dzclose(dev_t dev, int flag, int mode, struct proc *p) 331 { 332 struct dz_softc *sc; 333 struct tty *tp; 334 int unit, line; 335 336 337 unit = DZ_I2C(minor(dev)); 338 line = DZ_PORT(minor(dev)); 339 sc = dz_cd.cd_devs[unit]; 340 341 tp = sc->sc_dz[line].dz_tty; 342 343 (*tp->t_linesw->l_close)(tp, flag); 344 345 /* Make sure a BREAK state is not left enabled. */ 346 (void) dzmctl(sc, line, DML_BRK, DMBIC); 347 348 /* Do a hangup if so required. */ 349 if ((tp->t_cflag & HUPCL) || tp->t_wopen || !(tp->t_state & TS_ISOPEN)) 350 (void) dzmctl(sc, line, 0, DMSET); 351 352 return (ttyclose(tp)); 353 } 354 355 int 356 dzread(dev_t dev, struct uio *uio, int flag) 357 { 358 struct tty *tp; 359 struct dz_softc *sc; 360 361 sc = dz_cd.cd_devs[DZ_I2C(minor(dev))]; 362 363 tp = sc->sc_dz[DZ_PORT(minor(dev))].dz_tty; 364 return ((*tp->t_linesw->l_read)(tp, uio, flag)); 365 } 366 367 int 368 dzwrite(dev_t dev, struct uio *uio, int flag) 369 { 370 struct tty *tp; 371 struct dz_softc *sc; 372 373 sc = dz_cd.cd_devs[DZ_I2C(minor(dev))]; 374 375 tp = sc->sc_dz[DZ_PORT(minor(dev))].dz_tty; 376 return ((*tp->t_linesw->l_write)(tp, uio, flag)); 377 } 378 379 int 380 dzpoll(dev, events, p) 381 dev_t dev; 382 int events; 383 struct proc *p; 384 { 385 struct tty *tp; 386 struct dz_softc *sc; 387 388 sc = dz_cd.cd_devs[DZ_I2C(minor(dev))]; 389 390 tp = sc->sc_dz[DZ_PORT(minor(dev))].dz_tty; 391 return ((*tp->t_linesw->l_poll)(tp, events, p)); 392 } 393 394 /*ARGSUSED*/ 395 int 396 dzioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 397 { 398 struct dz_softc *sc; 399 struct tty *tp; 400 int unit, line; 401 int error; 402 403 unit = DZ_I2C(minor(dev)); 404 line = DZ_PORT(minor(dev)); 405 sc = dz_cd.cd_devs[unit]; 406 tp = sc->sc_dz[line].dz_tty; 407 408 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p); 409 if (error >= 0) 410 return (error); 411 412 error = ttioctl(tp, cmd, data, flag, p); 413 if (error >= 0) 414 return (error); 415 416 switch (cmd) { 417 418 case TIOCSBRK: 419 (void) dzmctl(sc, line, DML_BRK, DMBIS); 420 break; 421 422 case TIOCCBRK: 423 (void) dzmctl(sc, line, DML_BRK, DMBIC); 424 break; 425 426 case TIOCSDTR: 427 (void) dzmctl(sc, line, DML_DTR, DMBIS); 428 break; 429 430 case TIOCCDTR: 431 (void) dzmctl(sc, line, DML_DTR, DMBIC); 432 break; 433 434 case TIOCMSET: 435 (void) dzmctl(sc, line, *(int *)data, DMSET); 436 break; 437 438 case TIOCMBIS: 439 (void) dzmctl(sc, line, *(int *)data, DMBIS); 440 break; 441 442 case TIOCMBIC: 443 (void) dzmctl(sc, line, *(int *)data, DMBIC); 444 break; 445 446 case TIOCMGET: 447 *(int *)data = (dzmctl(sc, line, 0, DMGET) & ~DML_BRK); 448 break; 449 450 default: 451 return (EPASSTHROUGH); 452 } 453 return (0); 454 } 455 456 struct tty * 457 dztty(dev_t dev) 458 { 459 struct dz_softc *sc = dz_cd.cd_devs[DZ_I2C(minor(dev))]; 460 struct tty *tp = sc->sc_dz[DZ_PORT(minor(dev))].dz_tty; 461 462 return (tp); 463 } 464 465 /*ARGSUSED*/ 466 void 467 dzstop(struct tty *tp, int flag) 468 { 469 if (tp->t_state & TS_BUSY) 470 if (!(tp->t_state & TS_TTSTOP)) 471 tp->t_state |= TS_FLUSH; 472 } 473 474 void 475 dzstart(struct tty *tp) 476 { 477 struct dz_softc *sc; 478 struct clist *cl; 479 int unit, line, s; 480 char state; 481 482 unit = DZ_I2C(minor(tp->t_dev)); 483 line = DZ_PORT(minor(tp->t_dev)); 484 sc = dz_cd.cd_devs[unit]; 485 486 s = spltty(); 487 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 488 return; 489 cl = &tp->t_outq; 490 if (cl->c_cc <= tp->t_lowat) { 491 if (tp->t_state & TS_ASLEEP) { 492 tp->t_state &= ~TS_ASLEEP; 493 wakeup((caddr_t)cl); 494 } 495 selwakeup(&tp->t_wsel); 496 } 497 if (cl->c_cc == 0) 498 return; 499 500 tp->t_state |= TS_BUSY; 501 502 state = DZ_READ_WORD(dr_tcrw) & 255; 503 if ((state & (1 << line)) == 0) { 504 DZ_WRITE_BYTE(dr_tcr, state | (1 << line)); 505 } 506 dzxint(sc); 507 splx(s); 508 } 509 510 static int 511 dzparam(struct tty *tp, struct termios *t) 512 { 513 struct dz_softc *sc; 514 int cflag = t->c_cflag; 515 int unit, line; 516 int ispeed = ttspeedtab(t->c_ispeed, dzspeedtab); 517 int ospeed = ttspeedtab(t->c_ospeed, dzspeedtab); 518 unsigned lpr; 519 int s; 520 521 unit = DZ_I2C(minor(tp->t_dev)); 522 line = DZ_PORT(minor(tp->t_dev)); 523 sc = dz_cd.cd_devs[unit]; 524 525 /* check requested parameters */ 526 if (ospeed < 0 || ispeed < 0 || ispeed != ospeed) 527 return (EINVAL); 528 529 tp->t_ispeed = t->c_ispeed; 530 tp->t_ospeed = t->c_ospeed; 531 tp->t_cflag = cflag; 532 533 if (ospeed == 0) { 534 (void) dzmctl(sc, line, 0, DMSET); /* hang up line */ 535 return (0); 536 } 537 538 s = spltty(); 539 540 lpr = DZ_LPR_RX_ENABLE | ((ispeed&0xF)<<8) | line; 541 542 switch (cflag & CSIZE) 543 { 544 case CS5: 545 lpr |= DZ_LPR_5_BIT_CHAR; 546 break; 547 case CS6: 548 lpr |= DZ_LPR_6_BIT_CHAR; 549 break; 550 case CS7: 551 lpr |= DZ_LPR_7_BIT_CHAR; 552 break; 553 default: 554 lpr |= DZ_LPR_8_BIT_CHAR; 555 break; 556 } 557 if (cflag & PARENB) 558 lpr |= DZ_LPR_PARENB; 559 if (cflag & PARODD) 560 lpr |= DZ_LPR_OPAR; 561 if (cflag & CSTOPB) 562 lpr |= DZ_LPR_2_STOP; 563 564 DZ_WRITE_WORD(dr_lpr, lpr); 565 566 (void) splx(s); 567 return (0); 568 } 569 570 static unsigned 571 dzmctl(struct dz_softc *sc, int line, int bits, int how) 572 { 573 unsigned status; 574 unsigned mbits; 575 unsigned bit; 576 int s; 577 578 s = spltty(); 579 580 mbits = 0; 581 582 bit = (1 << line); 583 584 /* external signals as seen from the port */ 585 586 status = DZ_READ_BYTE(dr_dcd) | sc->sc_dsr; 587 588 if (status & bit) 589 mbits |= DML_DCD; 590 591 status = DZ_READ_BYTE(dr_ring); 592 593 if (status & bit) 594 mbits |= DML_RI; 595 596 /* internal signals/state delivered to port */ 597 598 status = DZ_READ_BYTE(dr_dtr); 599 600 if (status & bit) 601 mbits |= DML_DTR; 602 603 if (sc->sc_brk & bit) 604 mbits |= DML_BRK; 605 606 switch (how) 607 { 608 case DMSET: 609 mbits = bits; 610 break; 611 612 case DMBIS: 613 mbits |= bits; 614 break; 615 616 case DMBIC: 617 mbits &= ~bits; 618 break; 619 620 case DMGET: 621 (void) splx(s); 622 return (mbits); 623 } 624 625 if (mbits & DML_DTR) { 626 DZ_WRITE_BYTE(dr_dtr, DZ_READ_BYTE(dr_dtr) | bit); 627 } else { 628 DZ_WRITE_BYTE(dr_dtr, DZ_READ_BYTE(dr_dtr) & ~bit); 629 } 630 631 if (mbits & DML_BRK) { 632 sc->sc_brk |= bit; 633 DZ_WRITE_BYTE(dr_break, sc->sc_brk); 634 } else { 635 sc->sc_brk &= ~bit; 636 DZ_WRITE_BYTE(dr_break, sc->sc_brk); 637 } 638 639 (void) splx(s); 640 return (mbits); 641 } 642 643 /* 644 * This is called by timeout() periodically. 645 * Check to see if modem status bits have changed. 646 */ 647 static void 648 dzscan(void *arg) 649 { 650 struct dz_softc *sc; 651 struct tty *tp; 652 int n, bit, port; 653 unsigned csr; 654 int s; 655 656 s = spltty(); 657 658 for (n = 0; n < dz_cd.cd_ndevs; n++) { 659 660 if (dz_cd.cd_devs[n] == NULL) 661 continue; 662 663 sc = dz_cd.cd_devs[n]; 664 665 for (port = 0; port < sc->sc_type; port++) { 666 667 tp = sc->sc_dz[port].dz_tty; 668 bit = (1 << port); 669 670 if ((DZ_READ_BYTE(dr_dcd) | sc->sc_dsr) & bit) { 671 if (!(tp->t_state & TS_CARR_ON)) 672 (*tp->t_linesw->l_modem) (tp, 1); 673 } else if ((tp->t_state & TS_CARR_ON) && 674 (*tp->t_linesw->l_modem)(tp, 0) == 0) { 675 DZ_WRITE_BYTE(dr_tcr, 676 (DZ_READ_WORD(dr_tcrw) & 255) & ~bit); 677 } 678 } 679 680 /* 681 * If the RX interrupt rate is this high, switch 682 * the controller to Silo Alarm - which means don't 683 * interrupt until the RX silo has 16 characters in 684 * it (the silo is 64 characters in all). 685 * Avoid oscillating SA on and off by not turning 686 * if off unless the rate is appropriately low. 687 */ 688 689 csr = DZ_READ_WORD(dr_csr); 690 691 if (sc->sc_rxint > (16*10)) { 692 if ((csr & DZ_CSR_SAE) == 0) 693 DZ_WRITE_WORD(dr_csr, csr | DZ_CSR_SAE); 694 } else if ((csr & DZ_CSR_SAE) != 0) 695 if (sc->sc_rxint < 10) 696 DZ_WRITE_WORD(dr_csr, csr & ~(DZ_CSR_SAE)); 697 698 sc->sc_rxint = 0; 699 } 700 (void) splx(s); 701 callout_reset(&dzscan_ch, hz, dzscan, NULL); 702 return; 703 } 704 705 /* 706 * Called after an ubareset. The DZ card is reset, but the only thing 707 * that must be done is to start the receiver and transmitter again. 708 * No DMA setup to care about. 709 */ 710 void 711 dzreset(struct device *dev) 712 { 713 struct dz_softc *sc = (void *)dev; 714 struct tty *tp; 715 int i; 716 717 for (i = 0; i < sc->sc_type; i++) { 718 tp = sc->sc_dz[i].dz_tty; 719 720 if (((tp->t_state & TS_ISOPEN) == 0) || (tp->t_wopen == 0)) 721 continue; 722 723 dzparam(tp, &tp->t_termios); 724 dzmctl(sc, i, DML_DTR, DMSET); 725 tp->t_state &= ~TS_BUSY; 726 dzstart(tp); /* Kick off transmitter again */ 727 } 728 } 729