1 /* $NetBSD: z8530tty.c,v 1.41 1997/11/12 22:17:10 pk Exp $ */ 2 3 /*- 4 * Copyright (c) 1993, 1994, 1995, 1996, 1997 5 * Charles M. Hannum. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Charles M. Hannum. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1994 Gordon W. Ross 35 * Copyright (c) 1992, 1993 36 * The Regents of the University of California. All rights reserved. 37 * 38 * This software was developed by the Computer Systems Engineering group 39 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 40 * contributed to Berkeley. 41 * 42 * All advertising materials mentioning features or use of this software 43 * must display the following acknowledgement: 44 * This product includes software developed by the University of 45 * California, Lawrence Berkeley Laboratory. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. All advertising materials mentioning features or use of this software 56 * must display the following acknowledgement: 57 * This product includes software developed by the University of 58 * California, Berkeley and its contributors. 59 * 4. Neither the name of the University nor the names of its contributors 60 * may be used to endorse or promote products derived from this software 61 * without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 73 * SUCH DAMAGE. 74 * 75 * @(#)zs.c 8.1 (Berkeley) 7/19/93 76 */ 77 78 /* 79 * Zilog Z8530 Dual UART driver (tty interface) 80 * 81 * This is the "slave" driver that will be attached to 82 * the "zsc" driver for plain "tty" async. serial lines. 83 * 84 * Credits, history: 85 * 86 * The original version of this code was the sparc/dev/zs.c driver 87 * as distributed with the Berkeley 4.4 Lite release. Since then, 88 * Gordon Ross reorganized the code into the current parent/child 89 * driver scheme, separating the Sun keyboard and mouse support 90 * into independent child drivers. 91 * 92 * RTS/CTS flow-control support was a collaboration of: 93 * Gordon Ross <gwr@netbsd.org>, 94 * Bill Studenmund <wrstuden@loki.stanford.edu> 95 * Ian Dall <Ian.Dall@dsto.defence.gov.au> 96 */ 97 98 #include <sys/param.h> 99 #include <sys/systm.h> 100 #include <sys/proc.h> 101 #include <sys/device.h> 102 #include <sys/conf.h> 103 #include <sys/file.h> 104 #include <sys/ioctl.h> 105 #include <sys/malloc.h> 106 #include <sys/tty.h> 107 #include <sys/time.h> 108 #include <sys/kernel.h> 109 #include <sys/syslog.h> 110 111 #include <dev/ic/z8530reg.h> 112 #include <machine/z8530var.h> 113 114 #include "locators.h" 115 116 /* 117 * How many input characters we can buffer. 118 * The port-specific var.h may override this. 119 * Note: must be a power of two! 120 */ 121 #ifndef ZSTTY_RING_SIZE 122 #define ZSTTY_RING_SIZE 2048 123 #endif 124 125 /* 126 * Make this an option variable one can patch. 127 * But be warned: this must be a power of 2! 128 */ 129 u_int zstty_rbuf_size = ZSTTY_RING_SIZE; 130 131 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ 132 u_int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE * 1) / 4; 133 u_int zstty_rbuf_lowat = (ZSTTY_RING_SIZE * 3) / 4; 134 135 struct zstty_softc { 136 struct device zst_dev; /* required first: base device */ 137 struct tty *zst_tty; 138 struct zs_chanstate *zst_cs; 139 140 u_int zst_overflows, 141 zst_floods, 142 zst_errors; 143 144 int zst_hwflags, /* see z8530var.h */ 145 zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */ 146 147 u_int zst_r_hiwat, 148 zst_r_lowat; 149 u_char *volatile zst_rbget, 150 *volatile zst_rbput; 151 volatile u_int zst_rbavail; 152 u_char *zst_rbuf, 153 *zst_ebuf; 154 155 /* 156 * The transmit byte count and address are used for pseudo-DMA 157 * output in the hardware interrupt code. PDMA can be suspended 158 * to get pending changes done; heldtbc is used for this. It can 159 * also be stopped for ^S; this sets TS_TTSTOP in tp->t_state. 160 */ 161 u_char *zst_tba; /* transmit buffer address */ 162 u_int zst_tbc, /* transmit byte count */ 163 zst_heldtbc; /* held tbc while xmission stopped */ 164 165 /* Flags to communicate with zstty_softint() */ 166 volatile u_char zst_rx_flags, /* receiver blocked */ 167 #define RX_TTY_BLOCKED 0x01 168 #define RX_TTY_OVERFLOWED 0x02 169 #define RX_IBUF_BLOCKED 0x04 170 #define RX_IBUF_OVERFLOWED 0x08 171 #define RX_ANY_BLOCK 0x0f 172 zst_tx_busy, /* working on an output chunk */ 173 zst_tx_done, /* done with one output chunk */ 174 zst_tx_stopped, /* H/W level stop (lost CTS) */ 175 zst_st_check, /* got a status interrupt */ 176 zst_rx_ready; 177 }; 178 179 /* Macros to clear/set/test flags. */ 180 #define SET(t, f) (t) |= (f) 181 #define CLR(t, f) (t) &= ~(f) 182 #define ISSET(t, f) ((t) & (f)) 183 184 /* Definition of the driver for autoconfig. */ 185 #ifdef __BROKEN_INDIRECT_CONFIG 186 static int zstty_match(struct device *, void *, void *); 187 #else 188 static int zstty_match(struct device *, struct cfdata *, void *); 189 #endif 190 static void zstty_attach(struct device *, struct device *, void *); 191 192 struct cfattach zstty_ca = { 193 sizeof(struct zstty_softc), zstty_match, zstty_attach 194 }; 195 196 struct cfdriver zstty_cd = { 197 NULL, "zstty", DV_TTY 198 }; 199 200 struct zsops zsops_tty; 201 202 /* Routines called from other code. */ 203 cdev_decl(zs); /* open, close, read, write, ioctl, stop, ... */ 204 205 static void zsstart __P((struct tty *)); 206 static int zsparam __P((struct tty *, struct termios *)); 207 static void zs_modem __P((struct zstty_softc *zst, int onoff)); 208 static int zshwiflow __P((struct tty *, int)); 209 static void zs_hwiflow __P((struct zstty_softc *)); 210 211 /* 212 * zstty_match: how is this zs channel configured? 213 */ 214 #ifdef __BROKEN_INDIRECT_CONFIG 215 int 216 zstty_match(parent, vcf, aux) 217 struct device *parent; 218 void *vcf, *aux; 219 { 220 struct cfdata *cf = vcf; 221 struct zsc_attach_args *args = aux; 222 223 /* Exact match is better than wildcard. */ 224 if (cf->cf_loc[ZSCCF_CHANNEL] == args->channel) 225 return 2; 226 227 /* This driver accepts wildcard. */ 228 if (cf->cf_loc[ZSCCF_CHANNEL] == ZSCCF_CHANNEL_DEFAULT) 229 return 1; 230 231 return 0; 232 } 233 #else /* __BROKEN_INDIRECT_CONFIG */ 234 int 235 zstty_match(parent, cf, aux) 236 struct device *parent; 237 struct cfdata *cf; 238 void *aux; 239 { 240 struct zsc_attach_args *args = aux; 241 242 /* Exact match is better than wildcard. */ 243 if (cf->cf_loc[ZSCCF_CHANNEL] == args->channel) 244 return 2; 245 246 /* This driver accepts wildcard. */ 247 if (cf->cf_loc[ZSCCF_CHANNEL] == ZSCCF_CHANNEL_DEFAULT) 248 return 1; 249 250 return 0; 251 } 252 #endif /* __BROKEN_INDIRECT_CONFIG */ 253 254 void 255 zstty_attach(parent, self, aux) 256 struct device *parent, *self; 257 void *aux; 258 259 { 260 struct zsc_softc *zsc = (void *) parent; 261 struct zstty_softc *zst = (void *) self; 262 struct cfdata *cf = self->dv_cfdata; 263 struct zsc_attach_args *args = aux; 264 struct zs_chanstate *cs; 265 struct tty *tp; 266 int channel, s, tty_unit; 267 dev_t dev; 268 269 tty_unit = zst->zst_dev.dv_unit; 270 channel = args->channel; 271 cs = zsc->zsc_cs[channel]; 272 cs->cs_private = zst; 273 cs->cs_ops = &zsops_tty; 274 275 zst->zst_cs = cs; 276 zst->zst_swflags = cf->cf_flags; /* softcar, etc. */ 277 zst->zst_hwflags = args->hwflags; 278 dev = makedev(zs_major, tty_unit); 279 280 if (zst->zst_swflags) 281 printf(" flags 0x%x", zst->zst_swflags); 282 283 if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) 284 printf(" (console)"); 285 else { 286 #ifdef KGDB 287 /* 288 * Allow kgdb to "take over" this port. Returns true 289 * if this serial port is in-use by kgdb. 290 */ 291 if (zs_check_kgdb(cs, dev)) { 292 printf(" (kgdb)\n"); 293 /* 294 * This is the kgdb port (exclusive use) 295 * so skip the normal attach code. 296 */ 297 return; 298 } 299 #endif 300 } 301 printf("\n"); 302 303 tp = ttymalloc(); 304 tp->t_oproc = zsstart; 305 tp->t_param = zsparam; 306 tp->t_hwiflow = zshwiflow; 307 tty_attach(tp); 308 309 zst->zst_tty = tp; 310 zst->zst_rbuf = malloc(zstty_rbuf_size << 1, M_DEVBUF, M_WAITOK); 311 zst->zst_ebuf = zst->zst_rbuf + (zstty_rbuf_size << 1); 312 /* Disable the high water mark. */ 313 zst->zst_r_hiwat = 0; 314 zst->zst_r_lowat = 0; 315 zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf; 316 zst->zst_rbavail = zstty_rbuf_size; 317 318 /* XXX - Do we need an MD hook here? */ 319 320 /* 321 * Hardware init 322 */ 323 if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) { 324 /* Call zsparam similar to open. */ 325 struct termios t; 326 327 s = splzs(); 328 329 /* Turn on interrupts. */ 330 cs->cs_creg[1] = cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE; 331 zs_write_reg(cs, 1, cs->cs_creg[1]); 332 333 /* Fetch the current modem control status, needed later. */ 334 cs->cs_rr0 = zs_read_csr(cs); 335 336 splx(s); 337 338 /* Setup the "new" parameters in t. */ 339 t.c_ispeed = 0; 340 t.c_ospeed = cs->cs_defspeed; 341 t.c_cflag = cs->cs_defcflag; 342 /* Make sure zsparam will see changes. */ 343 tp->t_ospeed = 0; 344 (void) zsparam(tp, &t); 345 346 /* Make sure DTR is on now. */ 347 zs_modem(zst, 1); 348 } else { 349 /* Not the console; may need reset. */ 350 int reset; 351 reset = (channel == 0) ? 352 ZSWR9_A_RESET : ZSWR9_B_RESET; 353 s = splzs(); 354 zs_write_reg(cs, 9, reset); 355 splx(s); 356 357 /* Will raise DTR in open. */ 358 zs_modem(zst, 0); 359 } 360 } 361 362 363 /* 364 * Return pointer to our tty. 365 */ 366 struct tty * 367 zstty(dev) 368 dev_t dev; 369 { 370 struct zstty_softc *zst; 371 int unit = minor(dev); 372 373 #ifdef DIAGNOSTIC 374 if (unit >= zstty_cd.cd_ndevs) 375 panic("zstty"); 376 #endif 377 zst = zstty_cd.cd_devs[unit]; 378 return (zst->zst_tty); 379 } 380 381 382 /* 383 * Open a zs serial (tty) port. 384 */ 385 int 386 zsopen(dev, flags, mode, p) 387 dev_t dev; 388 int flags; 389 int mode; 390 struct proc *p; 391 { 392 struct tty *tp; 393 struct zs_chanstate *cs; 394 struct zstty_softc *zst; 395 int error, s, s2, unit; 396 397 unit = minor(dev); 398 if (unit >= zstty_cd.cd_ndevs) 399 return (ENXIO); 400 zst = zstty_cd.cd_devs[unit]; 401 if (zst == NULL) 402 return (ENXIO); 403 tp = zst->zst_tty; 404 cs = zst->zst_cs; 405 406 /* If KGDB took the line, then tp==NULL */ 407 if (tp == NULL) 408 return (EBUSY); 409 410 if (ISSET(tp->t_state, TS_ISOPEN) && 411 ISSET(tp->t_state, TS_XCLUDE) && 412 p->p_ucred->cr_uid != 0) 413 return (EBUSY); 414 415 s = spltty(); 416 417 /* We need to set this early for the benefit of zssoft(). */ 418 SET(tp->t_state, TS_WOPEN); 419 420 /* 421 * Do the following iff this is a first open. 422 */ 423 if (!ISSET(tp->t_state, TS_ISOPEN)) { 424 struct termios t; 425 426 tp->t_dev = dev; 427 428 s2 = splzs(); 429 430 /* Turn on interrupts. */ 431 cs->cs_creg[1] = cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE; 432 zs_write_reg(cs, 1, cs->cs_creg[1]); 433 434 /* Fetch the current modem control status, needed later. */ 435 cs->cs_rr0 = zs_read_csr(cs); 436 437 splx(s2); 438 439 /* 440 * Initialize the termios status to the defaults. Add in the 441 * sticky bits from TIOCSFLAGS. 442 */ 443 t.c_ispeed = 0; 444 t.c_ospeed = cs->cs_defspeed; 445 t.c_cflag = cs->cs_defcflag; 446 if (ISSET(zst->zst_swflags, TIOCFLAG_CLOCAL)) 447 SET(t.c_cflag, CLOCAL); 448 if (ISSET(zst->zst_swflags, TIOCFLAG_CRTSCTS)) 449 SET(t.c_cflag, CRTSCTS); 450 if (ISSET(zst->zst_swflags, TIOCFLAG_CDTRCTS)) 451 SET(t.c_cflag, CDTRCTS); 452 if (ISSET(zst->zst_swflags, TIOCFLAG_MDMBUF)) 453 SET(t.c_cflag, MDMBUF); 454 /* Make sure zsparam will see changes. */ 455 tp->t_ospeed = 0; 456 (void) zsparam(tp, &t); 457 /* 458 * Note: zsparam has done: cflag, ispeed, ospeed 459 * so we just need to do: iflag, oflag, lflag, cc 460 * For "raw" mode, just leave all zeros. 461 */ 462 if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_RAW)) { 463 tp->t_iflag = TTYDEF_IFLAG; 464 tp->t_oflag = TTYDEF_OFLAG; 465 tp->t_lflag = TTYDEF_LFLAG; 466 } else { 467 tp->t_iflag = 0; 468 tp->t_oflag = 0; 469 tp->t_lflag = 0; 470 } 471 ttychars(tp); 472 ttsetwater(tp); 473 474 /* 475 * Turn on DTR. We must always do this, even if carrier is not 476 * present, because otherwise we'd have to use TIOCSDTR 477 * immediately after setting CLOCAL, which applications do not 478 * expect. We always assert DTR while the device is open 479 * unless explicitly requested to deassert it. 480 */ 481 zs_modem(zst, 1); 482 483 s2 = splzs(); 484 485 /* Clear the input ring, and unblock. */ 486 zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf; 487 zst->zst_rbavail = zstty_rbuf_size; 488 zs_iflush(cs); 489 CLR(zst->zst_rx_flags, RX_ANY_BLOCK); 490 zs_hwiflow(zst); 491 492 splx(s2); 493 } 494 error = 0; 495 496 /* If we're doing a blocking open... */ 497 if (!ISSET(flags, O_NONBLOCK)) 498 /* ...then wait for carrier. */ 499 while (!ISSET(tp->t_state, TS_CARR_ON) && 500 !ISSET(tp->t_cflag, CLOCAL | MDMBUF)) { 501 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 502 ttopen, 0); 503 if (error) { 504 /* 505 * If the open was interrupted and nobody 506 * else has the device open, then hang up. 507 */ 508 if (!ISSET(tp->t_state, TS_ISOPEN)) { 509 zs_modem(zst, 0); 510 CLR(tp->t_state, TS_WOPEN); 511 ttwakeup(tp); 512 } 513 break; 514 } 515 SET(tp->t_state, TS_WOPEN); 516 } 517 518 splx(s); 519 if (error == 0) 520 error = (*linesw[tp->t_line].l_open)(dev, tp); 521 return (error); 522 } 523 524 /* 525 * Close a zs serial port. 526 */ 527 int 528 zsclose(dev, flags, mode, p) 529 dev_t dev; 530 int flags; 531 int mode; 532 struct proc *p; 533 { 534 struct zstty_softc *zst = zstty_cd.cd_devs[minor(dev)]; 535 struct zs_chanstate *cs = zst->zst_cs; 536 struct tty *tp = zst->zst_tty; 537 int s; 538 539 /* XXX This is for cons.c. */ 540 if (!ISSET(tp->t_state, TS_ISOPEN)) 541 return 0; 542 543 (*linesw[tp->t_line].l_close)(tp, flags); 544 ttyclose(tp); 545 546 s = splzs(); 547 548 /* If we were asserting flow control, then deassert it. */ 549 SET(zst->zst_rx_flags, RX_IBUF_BLOCKED); 550 zs_hwiflow(zst); 551 552 splx(s); 553 554 /* Clear any break condition set with TIOCSBRK. */ 555 zs_break(cs, 0); 556 557 /* 558 * Hang up if necessary. Wait a bit, so the other side has time to 559 * notice even if we immediately open the port again. 560 */ 561 if (ISSET(tp->t_cflag, HUPCL)) { 562 zs_modem(zst, 0); 563 (void) tsleep(cs, TTIPRI, ttclos, hz); 564 } 565 566 s = splzs(); 567 568 /* Turn off interrupts if not the console. */ 569 if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) 570 cs->cs_creg[1] = cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE; 571 else 572 cs->cs_creg[1] = cs->cs_preg[1] = 0; 573 zs_write_reg(cs, 1, cs->cs_creg[1]); 574 575 splx(s); 576 577 return (0); 578 } 579 580 /* 581 * Read/write zs serial port. 582 */ 583 int 584 zsread(dev, uio, flags) 585 dev_t dev; 586 struct uio *uio; 587 int flags; 588 { 589 struct zstty_softc *zst = zstty_cd.cd_devs[minor(dev)]; 590 struct tty *tp = zst->zst_tty; 591 592 return ((*linesw[tp->t_line].l_read)(tp, uio, flags)); 593 } 594 595 int 596 zswrite(dev, uio, flags) 597 dev_t dev; 598 struct uio *uio; 599 int flags; 600 { 601 struct zstty_softc *zst = zstty_cd.cd_devs[minor(dev)]; 602 struct tty *tp = zst->zst_tty; 603 604 return ((*linesw[tp->t_line].l_write)(tp, uio, flags)); 605 } 606 607 int 608 zsioctl(dev, cmd, data, flag, p) 609 dev_t dev; 610 u_long cmd; 611 caddr_t data; 612 int flag; 613 struct proc *p; 614 { 615 struct zstty_softc *zst = zstty_cd.cd_devs[minor(dev)]; 616 struct zs_chanstate *cs = zst->zst_cs; 617 struct tty *tp = zst->zst_tty; 618 int error; 619 620 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 621 if (error >= 0) 622 return (error); 623 624 error = ttioctl(tp, cmd, data, flag, p); 625 if (error >= 0) 626 return (error); 627 628 #ifdef ZS_MD_IOCTL 629 error = ZS_MD_IOCTL; 630 if (error >= 0) 631 return (error); 632 #endif /* ZS_MD_IOCTL */ 633 634 switch (cmd) { 635 case TIOCSBRK: 636 zs_break(cs, 1); 637 break; 638 639 case TIOCCBRK: 640 zs_break(cs, 0); 641 break; 642 643 case TIOCGFLAGS: 644 *(int *)data = zst->zst_swflags; 645 break; 646 647 case TIOCSFLAGS: 648 error = suser(p->p_ucred, &p->p_acflag); 649 if (error) 650 return (error); 651 zst->zst_swflags = *(int *)data; 652 break; 653 654 case TIOCSDTR: 655 zs_modem(zst, 1); 656 break; 657 658 case TIOCCDTR: 659 zs_modem(zst, 0); 660 break; 661 662 case TIOCMSET: 663 case TIOCMBIS: 664 case TIOCMBIC: 665 case TIOCMGET: 666 default: 667 return (ENOTTY); 668 } 669 return (0); 670 } 671 672 /* 673 * Start or restart transmission. 674 */ 675 static void 676 zsstart(tp) 677 struct tty *tp; 678 { 679 struct zstty_softc *zst = zstty_cd.cd_devs[minor(tp->t_dev)]; 680 struct zs_chanstate *cs = zst->zst_cs; 681 int s; 682 683 s = spltty(); 684 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 685 goto out; 686 if (zst->zst_tx_stopped) 687 goto out; 688 689 if (tp->t_outq.c_cc <= tp->t_lowat) { 690 if (ISSET(tp->t_state, TS_ASLEEP)) { 691 CLR(tp->t_state, TS_ASLEEP); 692 wakeup((caddr_t)&tp->t_outq); 693 } 694 selwakeup(&tp->t_wsel); 695 if (tp->t_outq.c_cc == 0) 696 goto out; 697 } 698 699 /* Grab the first contiguous region of buffer space. */ 700 { 701 u_char *tba; 702 int tbc; 703 704 tba = tp->t_outq.c_cf; 705 tbc = ndqb(&tp->t_outq, 0); 706 707 (void) splzs(); 708 709 zst->zst_tba = tba; 710 zst->zst_tbc = tbc; 711 } 712 713 SET(tp->t_state, TS_BUSY); 714 zst->zst_tx_busy = 1; 715 716 /* Enable transmit completion interrupts if necessary. */ 717 if (!ISSET(cs->cs_preg[1], ZSWR1_TIE)) { 718 SET(cs->cs_preg[1], ZSWR1_TIE); 719 cs->cs_creg[1] = cs->cs_preg[1]; 720 zs_write_reg(cs, 1, cs->cs_creg[1]); 721 } 722 723 /* Output the first character of the contiguous buffer. */ 724 { 725 zs_write_data(cs, *zst->zst_tba); 726 zst->zst_tbc--; 727 zst->zst_tba++; 728 } 729 out: 730 splx(s); 731 return; 732 } 733 734 /* 735 * Stop output, e.g., for ^S or output flush. 736 */ 737 void 738 zsstop(tp, flag) 739 struct tty *tp; 740 int flag; 741 { 742 struct zstty_softc *zst = zstty_cd.cd_devs[minor(tp->t_dev)]; 743 int s; 744 745 s = splzs(); 746 if (ISSET(tp->t_state, TS_BUSY)) { 747 /* Stop transmitting at the next chunk. */ 748 zst->zst_tbc = 0; 749 zst->zst_heldtbc = 0; 750 if (!ISSET(tp->t_state, TS_TTSTOP)) 751 SET(tp->t_state, TS_FLUSH); 752 } 753 splx(s); 754 } 755 756 /* 757 * Set ZS tty parameters from termios. 758 * XXX - Should just copy the whole termios after 759 * making sure all the changes could be done. 760 */ 761 static int 762 zsparam(tp, t) 763 struct tty *tp; 764 struct termios *t; 765 { 766 struct zstty_softc *zst = zstty_cd.cd_devs[minor(tp->t_dev)]; 767 struct zs_chanstate *cs = zst->zst_cs; 768 int ospeed, cflag; 769 u_char tmp3, tmp4, tmp5, tmp15; 770 int s, error; 771 772 ospeed = t->c_ospeed; 773 cflag = t->c_cflag; 774 775 /* Check requested parameters. */ 776 if (ospeed < 0) 777 return (EINVAL); 778 if (t->c_ispeed && t->c_ispeed != ospeed) 779 return (EINVAL); 780 781 /* 782 * For the console, always force CLOCAL and !HUPCL, so that the port 783 * is always active. 784 */ 785 if (ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR) || 786 ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) { 787 SET(cflag, CLOCAL); 788 CLR(cflag, HUPCL); 789 } 790 791 /* 792 * Only whack the UART when params change. 793 * Some callers need to clear tp->t_ospeed 794 * to make sure initialization gets done. 795 */ 796 if (tp->t_ospeed == ospeed && 797 tp->t_cflag == cflag) 798 return (0); 799 800 /* 801 * Call MD functions to deal with changed 802 * clock modes or H/W flow control modes. 803 * The BRG divisor is set now. (reg 12,13) 804 */ 805 error = zs_set_speed(cs, ospeed); 806 if (error) 807 return (error); 808 error = zs_set_modes(cs, cflag); 809 if (error) 810 return (error); 811 812 /* 813 * Block interrupts so that state will not 814 * be altered until we are done setting it up. 815 * 816 * Initial values in cs_preg are set before 817 * our attach routine is called. The master 818 * interrupt enable is handled by zsc.c 819 * 820 */ 821 s = splzs(); 822 823 cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd; 824 tmp15 = cs->cs_preg[15]; 825 #if 0 826 if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD)) 827 SET(tmp15, ZSWR15_DCD_IE); 828 else 829 CLR(tmp15, ZSWR15_DCD_IE); 830 if (ISSET(cs->cs_rr0_mask, ZSRR0_CTS)) 831 SET(tmp15, ZSWR15_CTS_IE); 832 else 833 CLR(tmp15, ZSWR15_CTS_IE); 834 #else 835 SET(tmp15, ZSWR15_DCD_IE | ZSWR15_CTS_IE); 836 #endif 837 cs->cs_preg[15] = tmp15; 838 839 /* Recompute character size bits. */ 840 tmp3 = cs->cs_preg[3]; 841 tmp5 = cs->cs_preg[5]; 842 CLR(tmp3, ZSWR3_RXSIZE); 843 CLR(tmp5, ZSWR5_TXSIZE); 844 switch (ISSET(cflag, CSIZE)) { 845 case CS5: 846 SET(tmp3, ZSWR3_RX_5); 847 SET(tmp5, ZSWR5_TX_5); 848 break; 849 case CS6: 850 SET(tmp3, ZSWR3_RX_6); 851 SET(tmp5, ZSWR5_TX_6); 852 break; 853 case CS7: 854 SET(tmp3, ZSWR3_RX_7); 855 SET(tmp5, ZSWR5_TX_7); 856 break; 857 case CS8: 858 SET(tmp3, ZSWR3_RX_8); 859 SET(tmp5, ZSWR5_TX_8); 860 break; 861 } 862 cs->cs_preg[3] = tmp3; 863 cs->cs_preg[5] = tmp5; 864 865 /* 866 * Recompute the stop bits and parity bits. Note that 867 * zs_set_speed() may have set clock selection bits etc. 868 * in wr4, so those must preserved. 869 */ 870 tmp4 = cs->cs_preg[4]; 871 CLR(tmp4, ZSWR4_SBMASK | ZSWR4_PARMASK); 872 if (ISSET(cflag, CSTOPB)) 873 SET(tmp4, ZSWR4_TWOSB); 874 else 875 SET(tmp4, ZSWR4_ONESB); 876 if (!ISSET(cflag, PARODD)) 877 SET(tmp4, ZSWR4_EVENP); 878 if (ISSET(cflag, PARENB)) 879 SET(tmp4, ZSWR4_PARENB); 880 cs->cs_preg[4] = tmp4; 881 882 /* And copy to tty. */ 883 tp->t_ispeed = 0; 884 tp->t_ospeed = ospeed; 885 tp->t_cflag = cflag; 886 887 /* 888 * If nothing is being transmitted, set up new current values, 889 * else mark them as pending. 890 */ 891 if (!cs->cs_heldchange) { 892 if (zst->zst_tx_busy) { 893 zst->zst_heldtbc = zst->zst_tbc; 894 zst->zst_tbc = 0; 895 cs->cs_heldchange = 1; 896 } else 897 zs_loadchannelregs(cs); 898 } 899 900 if (!ISSET(cflag, CHWFLOW)) { 901 /* Disable the high water mark. */ 902 zst->zst_r_hiwat = 0; 903 zst->zst_r_lowat = 0; 904 if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) { 905 CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED); 906 zst->zst_rx_ready = 1; 907 cs->cs_softreq = 1; 908 } 909 if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) { 910 CLR(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED); 911 zs_hwiflow(zst); 912 } 913 } else { 914 zst->zst_r_hiwat = zstty_rbuf_hiwat; 915 zst->zst_r_lowat = zstty_rbuf_lowat; 916 } 917 918 splx(s); 919 920 /* 921 * Update the tty layer's idea of the carrier bit, in case we changed 922 * CLOCAL or MDMBUF. We don't hang up here; we only do that by 923 * explicit request. 924 */ 925 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(cs->cs_rr0, ZSRR0_DCD)); 926 927 if (!ISSET(cflag, CHWFLOW)) { 928 if (zst->zst_tx_stopped) { 929 zst->zst_tx_stopped = 0; 930 zsstart(tp); 931 } 932 } 933 934 return (0); 935 } 936 937 /* 938 * Raise or lower modem control (DTR/RTS) signals. If a character is 939 * in transmission, the change is deferred. 940 */ 941 static void 942 zs_modem(zst, onoff) 943 struct zstty_softc *zst; 944 int onoff; 945 { 946 struct zs_chanstate *cs = zst->zst_cs; 947 int s; 948 949 if (cs->cs_wr5_dtr == 0) 950 return; 951 952 s = splzs(); 953 if (onoff) 954 SET(cs->cs_preg[5], cs->cs_wr5_dtr); 955 else 956 CLR(cs->cs_preg[5], cs->cs_wr5_dtr); 957 958 if (!cs->cs_heldchange) { 959 if (zst->zst_tx_busy) { 960 zst->zst_heldtbc = zst->zst_tbc; 961 zst->zst_tbc = 0; 962 cs->cs_heldchange = 1; 963 } else 964 zs_loadchannelregs(cs); 965 } 966 splx(s); 967 } 968 969 /* 970 * Try to block or unblock input using hardware flow-control. 971 * This is called by kern/tty.c if MDMBUF|CRTSCTS is set, and 972 * if this function returns non-zero, the TS_TBLOCK flag will 973 * be set or cleared according to the "block" arg passed. 974 */ 975 int 976 zshwiflow(tp, block) 977 struct tty *tp; 978 int block; 979 { 980 struct zstty_softc *zst = zstty_cd.cd_devs[minor(tp->t_dev)]; 981 struct zs_chanstate *cs = zst->zst_cs; 982 int s; 983 984 if (cs->cs_wr5_rts == 0) 985 return (0); 986 987 s = splzs(); 988 if (block) { 989 if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) { 990 SET(zst->zst_rx_flags, RX_TTY_BLOCKED); 991 zs_hwiflow(zst); 992 } 993 } else { 994 if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) { 995 CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED); 996 zst->zst_rx_ready = 1; 997 cs->cs_softreq = 1; 998 } 999 if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) { 1000 CLR(zst->zst_rx_flags, RX_TTY_BLOCKED); 1001 zs_hwiflow(zst); 1002 } 1003 } 1004 splx(s); 1005 return (1); 1006 } 1007 1008 /* 1009 * Internal version of zshwiflow 1010 * called at splzs 1011 */ 1012 static void 1013 zs_hwiflow(zst) 1014 struct zstty_softc *zst; 1015 { 1016 struct zs_chanstate *cs = zst->zst_cs; 1017 1018 if (cs->cs_wr5_rts == 0) 1019 return; 1020 1021 if (ISSET(zst->zst_rx_flags, RX_ANY_BLOCK)) { 1022 CLR(cs->cs_preg[5], cs->cs_wr5_rts); 1023 CLR(cs->cs_creg[5], cs->cs_wr5_rts); 1024 } else { 1025 SET(cs->cs_preg[5], cs->cs_wr5_rts); 1026 SET(cs->cs_creg[5], cs->cs_wr5_rts); 1027 } 1028 zs_write_reg(cs, 5, cs->cs_creg[5]); 1029 } 1030 1031 1032 /**************************************************************** 1033 * Interface to the lower layer (zscc) 1034 ****************************************************************/ 1035 1036 static void zstty_rxint __P((struct zs_chanstate *)); 1037 static void zstty_txint __P((struct zs_chanstate *)); 1038 static void zstty_stint __P((struct zs_chanstate *)); 1039 1040 #define integrate static inline 1041 static void zstty_softint __P((struct zs_chanstate *)); 1042 integrate void zstty_rxsoft __P((struct zstty_softc *, struct tty *)); 1043 integrate void zstty_txsoft __P((struct zstty_softc *, struct tty *)); 1044 integrate void zstty_stsoft __P((struct zstty_softc *, struct tty *)); 1045 static void zstty_diag __P((void *)); 1046 1047 /* 1048 * receiver ready interrupt. 1049 * called at splzs 1050 */ 1051 static void 1052 zstty_rxint(cs) 1053 struct zs_chanstate *cs; 1054 { 1055 struct zstty_softc *zst = cs->cs_private; 1056 u_char *put, *end; 1057 u_int cc; 1058 u_char rr0, rr1, c; 1059 1060 end = zst->zst_ebuf; 1061 put = zst->zst_rbput; 1062 cc = zst->zst_rbavail; 1063 1064 while (cc > 0) { 1065 /* 1066 * First read the status, because reading the received char 1067 * destroys the status of this char. 1068 */ 1069 rr1 = zs_read_reg(cs, 1); 1070 c = zs_read_data(cs); 1071 1072 if (ISSET(rr1, ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) { 1073 /* Clear the receive error. */ 1074 zs_write_csr(cs, ZSWR0_RESET_ERRORS); 1075 } 1076 1077 put[0] = c; 1078 put[1] = rr1; 1079 put += 2; 1080 if (put >= end) 1081 put = zst->zst_rbuf; 1082 cc--; 1083 1084 rr0 = zs_read_csr(cs); 1085 if (!ISSET(rr0, ZSRR0_RX_READY)) 1086 break; 1087 } 1088 1089 /* 1090 * Current string of incoming characters ended because 1091 * no more data was available or we ran out of space. 1092 * Schedule a receive event if any data was received. 1093 * If we're out of space, turn off receive interrupts. 1094 */ 1095 zst->zst_rbput = put; 1096 zst->zst_rbavail = cc; 1097 if (!ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) { 1098 zst->zst_rx_ready = 1; 1099 cs->cs_softreq = 1; 1100 } 1101 1102 /* 1103 * See if we are in danger of overflowing a buffer. If 1104 * so, use hardware flow control to ease the pressure. 1105 */ 1106 if (!ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED) && 1107 cc < zst->zst_r_hiwat) { 1108 SET(zst->zst_rx_flags, RX_IBUF_BLOCKED); 1109 zs_hwiflow(zst); 1110 } 1111 1112 /* 1113 * If we're out of space, disable receive interrupts 1114 * until the queue has drained a bit. 1115 */ 1116 if (!cc) { 1117 SET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED); 1118 CLR(cs->cs_preg[1], ZSWR1_RIE); 1119 cs->cs_creg[1] = cs->cs_preg[1]; 1120 zs_write_reg(cs, 1, cs->cs_creg[1]); 1121 } 1122 1123 #if 0 1124 printf("%xH%04d\n", zst->zst_rx_flags, zst->zst_rbavail); 1125 #endif 1126 } 1127 1128 /* 1129 * transmitter ready interrupt. (splzs) 1130 */ 1131 static void 1132 zstty_txint(cs) 1133 struct zs_chanstate *cs; 1134 { 1135 struct zstty_softc *zst = cs->cs_private; 1136 1137 /* 1138 * If we've delayed a parameter change, do it now, and restart 1139 * output. 1140 */ 1141 if (cs->cs_heldchange) { 1142 zs_loadchannelregs(cs); 1143 cs->cs_heldchange = 0; 1144 zst->zst_tbc = zst->zst_heldtbc; 1145 zst->zst_heldtbc = 0; 1146 } 1147 1148 /* Output the next character in the buffer, if any. */ 1149 if (cs->cs_heldchar != 0) { 1150 /* An "out-of-band" character is waiting to be output */ 1151 zs_write_data(cs, cs->cs_heldchar); 1152 cs->cs_heldchar = 0; 1153 } else if (zst->zst_tbc > 0) { 1154 zs_write_data(cs, *zst->zst_tba); 1155 zst->zst_tbc--; 1156 zst->zst_tba++; 1157 } else { 1158 /* Disable transmit completion interrupts if necessary. */ 1159 if (ISSET(cs->cs_preg[1], ZSWR1_TIE)) { 1160 CLR(cs->cs_preg[1], ZSWR1_TIE); 1161 cs->cs_creg[1] = cs->cs_preg[1]; 1162 zs_write_reg(cs, 1, cs->cs_creg[1]); 1163 } 1164 if (zst->zst_tx_busy) { 1165 zst->zst_tx_busy = 0; 1166 zst->zst_tx_done = 1; 1167 cs->cs_softreq = 1; 1168 } 1169 } 1170 } 1171 1172 /* 1173 * status change interrupt. (splzs) 1174 */ 1175 static void 1176 zstty_stint(cs) 1177 struct zs_chanstate *cs; 1178 { 1179 struct zstty_softc *zst = cs->cs_private; 1180 u_char rr0, delta; 1181 1182 rr0 = zs_read_csr(cs); 1183 zs_write_csr(cs, ZSWR0_RESET_STATUS); 1184 1185 /* 1186 * Check here for console break, so that we can abort 1187 * even when interrupts are locking up the machine. 1188 */ 1189 if (ISSET(rr0, ZSRR0_BREAK) && 1190 ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) { 1191 zs_abort(cs); 1192 return; 1193 } 1194 1195 delta = rr0 ^ cs->cs_rr0; 1196 cs->cs_rr0 = rr0; 1197 if (ISSET(delta, cs->cs_rr0_mask)) { 1198 SET(cs->cs_rr0_delta, delta); 1199 1200 /* 1201 * Stop output immediately if we lose the output 1202 * flow control signal or carrier detect. 1203 */ 1204 if (ISSET(~rr0, cs->cs_rr0_mask)) { 1205 zst->zst_tbc = 0; 1206 zst->zst_heldtbc = 0; 1207 } 1208 1209 zst->zst_st_check = 1; 1210 cs->cs_softreq = 1; 1211 } 1212 } 1213 1214 void 1215 zstty_diag(arg) 1216 void *arg; 1217 { 1218 struct zstty_softc *zst = arg; 1219 int overflows, floods; 1220 int s; 1221 1222 s = splzs(); 1223 overflows = zst->zst_overflows; 1224 zst->zst_overflows = 0; 1225 floods = zst->zst_floods; 1226 zst->zst_floods = 0; 1227 zst->zst_errors = 0; 1228 splx(s); 1229 1230 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", 1231 zst->zst_dev.dv_xname, 1232 overflows, overflows == 1 ? "" : "s", 1233 floods, floods == 1 ? "" : "s"); 1234 } 1235 1236 integrate void 1237 zstty_rxsoft(zst, tp) 1238 struct zstty_softc *zst; 1239 struct tty *tp; 1240 { 1241 struct zs_chanstate *cs = zst->zst_cs; 1242 int (*rint) __P((int c, struct tty *tp)) = linesw[tp->t_line].l_rint; 1243 u_char *get, *end; 1244 u_int cc, scc; 1245 u_char rr1; 1246 int code; 1247 int s; 1248 1249 end = zst->zst_ebuf; 1250 get = zst->zst_rbget; 1251 scc = cc = zstty_rbuf_size - zst->zst_rbavail; 1252 1253 if (cc == zstty_rbuf_size) { 1254 zst->zst_floods++; 1255 if (zst->zst_errors++ == 0) 1256 timeout(zstty_diag, zst, 60 * hz); 1257 } 1258 1259 while (cc) { 1260 code = get[0]; 1261 rr1 = get[1]; 1262 if (ISSET(rr1, ZSRR1_DO | ZSRR1_FE | ZSRR1_PE)) { 1263 if (ISSET(rr1, ZSRR1_DO)) { 1264 zst->zst_overflows++; 1265 if (zst->zst_errors++ == 0) 1266 timeout(zstty_diag, zst, 60 * hz); 1267 } 1268 if (ISSET(rr1, ZSRR1_FE)) 1269 SET(code, TTY_FE); 1270 if (ISSET(rr1, ZSRR1_PE)) 1271 SET(code, TTY_PE); 1272 } 1273 if ((*rint)(code, tp) == -1) { 1274 /* 1275 * The line discipline's buffer is out of space. 1276 */ 1277 if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) { 1278 /* 1279 * We're either not using flow control, or the 1280 * line discipline didn't tell us to block for 1281 * some reason. Either way, we have no way to 1282 * know when there's more space available, so 1283 * just drop the rest of the data. 1284 */ 1285 get += cc << 1; 1286 if (get >= end) 1287 get -= zstty_rbuf_size << 1; 1288 cc = 0; 1289 } else { 1290 /* 1291 * Don't schedule any more receive processing 1292 * until the line discipline tells us there's 1293 * space available (through comhwiflow()). 1294 * Leave the rest of the data in the input 1295 * buffer. 1296 */ 1297 SET(zst->zst_rx_flags, RX_TTY_OVERFLOWED); 1298 } 1299 break; 1300 } 1301 get += 2; 1302 if (get >= end) 1303 get = zst->zst_rbuf; 1304 cc--; 1305 } 1306 1307 if (cc != scc) { 1308 zst->zst_rbget = get; 1309 s = splzs(); 1310 cc = zst->zst_rbavail += scc - cc; 1311 /* Buffers should be ok again, release possible block. */ 1312 if (cc >= zst->zst_r_lowat) { 1313 if (ISSET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED)) { 1314 CLR(zst->zst_rx_flags, RX_IBUF_OVERFLOWED); 1315 SET(cs->cs_preg[1], ZSWR1_RIE); 1316 cs->cs_creg[1] = cs->cs_preg[1]; 1317 zs_write_reg(cs, 1, cs->cs_creg[1]); 1318 } 1319 if (ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED)) { 1320 CLR(zst->zst_rx_flags, RX_IBUF_BLOCKED); 1321 zs_hwiflow(zst); 1322 } 1323 } 1324 splx(s); 1325 } 1326 1327 #if 0 1328 printf("%xS%04d\n", zst->zst_rx_flags, zst->zst_rbavail); 1329 #endif 1330 } 1331 1332 integrate void 1333 zstty_txsoft(zst, tp) 1334 struct zstty_softc *zst; 1335 struct tty *tp; 1336 { 1337 1338 CLR(tp->t_state, TS_BUSY); 1339 if (ISSET(tp->t_state, TS_FLUSH)) 1340 CLR(tp->t_state, TS_FLUSH); 1341 else 1342 ndflush(&tp->t_outq, (int)(zst->zst_tba - tp->t_outq.c_cf)); 1343 (*linesw[tp->t_line].l_start)(tp); 1344 } 1345 1346 integrate void 1347 zstty_stsoft(zst, tp) 1348 struct zstty_softc *zst; 1349 struct tty *tp; 1350 { 1351 struct zs_chanstate *cs = zst->zst_cs; 1352 u_char rr0, delta; 1353 int s; 1354 1355 s = splzs(); 1356 rr0 = cs->cs_rr0; 1357 delta = cs->cs_rr0_delta; 1358 cs->cs_rr0_delta = 0; 1359 splx(s); 1360 1361 if (ISSET(delta, cs->cs_rr0_dcd)) { 1362 /* 1363 * Inform the tty layer that carrier detect changed. 1364 */ 1365 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(rr0, ZSRR0_DCD)); 1366 } 1367 1368 if (ISSET(delta, cs->cs_rr0_cts)) { 1369 /* Block or unblock output according to flow control. */ 1370 if (ISSET(rr0, cs->cs_rr0_cts)) { 1371 zst->zst_tx_stopped = 0; 1372 (*linesw[tp->t_line].l_start)(tp); 1373 } else { 1374 zst->zst_tx_stopped = 1; 1375 } 1376 } 1377 } 1378 1379 /* 1380 * Software interrupt. Called at zssoft 1381 * 1382 * The main job to be done here is to empty the input ring 1383 * by passing its contents up to the tty layer. The ring is 1384 * always emptied during this operation, therefore the ring 1385 * must not be larger than the space after "high water" in 1386 * the tty layer, or the tty layer might drop our input. 1387 * 1388 * Note: an "input blockage" condition is assumed to exist if 1389 * EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set. 1390 */ 1391 static void 1392 zstty_softint(cs) 1393 struct zs_chanstate *cs; 1394 { 1395 struct zstty_softc *zst = cs->cs_private; 1396 struct tty *tp = zst->zst_tty; 1397 int s; 1398 1399 s = spltty(); 1400 1401 if (zst->zst_rx_ready) { 1402 zst->zst_rx_ready = 0; 1403 zstty_rxsoft(zst, tp); 1404 } 1405 1406 if (zst->zst_st_check) { 1407 zst->zst_st_check = 0; 1408 zstty_stsoft(zst, tp); 1409 } 1410 1411 if (zst->zst_tx_done) { 1412 zst->zst_tx_done = 0; 1413 zstty_txsoft(zst, tp); 1414 } 1415 1416 splx(s); 1417 } 1418 1419 struct zsops zsops_tty = { 1420 zstty_rxint, /* receive char available */ 1421 zstty_stint, /* external/status */ 1422 zstty_txint, /* xmit buffer empty */ 1423 zstty_softint, /* process software interrupt */ 1424 }; 1425