1 /* $NetBSD: z8530tty.c,v 1.77 2001/05/30 15:24:24 lukem Exp $ */ 2 3 /*- 4 * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999 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 * The driver was massively overhauled in November 1997 by Charles Hannum, 98 * fixing *many* bugs, and substantially improving performance. 99 */ 100 101 #include "opt_kgdb.h" 102 103 #include <sys/param.h> 104 #include <sys/systm.h> 105 #include <sys/proc.h> 106 #include <sys/device.h> 107 #include <sys/conf.h> 108 #include <sys/file.h> 109 #include <sys/ioctl.h> 110 #include <sys/malloc.h> 111 #include <sys/timepps.h> 112 #include <sys/tty.h> 113 #include <sys/time.h> 114 #include <sys/kernel.h> 115 #include <sys/syslog.h> 116 117 #include <dev/ic/z8530reg.h> 118 #include <machine/z8530var.h> 119 120 #include <dev/cons.h> 121 122 #include "locators.h" 123 124 /* 125 * How many input characters we can buffer. 126 * The port-specific var.h may override this. 127 * Note: must be a power of two! 128 */ 129 #ifndef ZSTTY_RING_SIZE 130 #define ZSTTY_RING_SIZE 2048 131 #endif 132 133 static struct cnm_state zstty_cnm_state; 134 /* 135 * Make this an option variable one can patch. 136 * But be warned: this must be a power of 2! 137 */ 138 u_int zstty_rbuf_size = ZSTTY_RING_SIZE; 139 140 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ 141 u_int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE * 1) / 4; 142 u_int zstty_rbuf_lowat = (ZSTTY_RING_SIZE * 3) / 4; 143 144 static int zsppscap = 145 PPS_TSFMT_TSPEC | 146 PPS_CAPTUREASSERT | 147 PPS_CAPTURECLEAR | 148 #ifdef PPS_SYNC 149 PPS_HARDPPSONASSERT | PPS_HARDPPSONCLEAR | 150 #endif /* PPS_SYNC */ 151 PPS_OFFSETASSERT | PPS_OFFSETCLEAR; 152 153 struct zstty_softc { 154 struct device zst_dev; /* required first: base device */ 155 struct tty *zst_tty; 156 struct zs_chanstate *zst_cs; 157 158 struct callout zst_diag_ch; 159 160 u_int zst_overflows, 161 zst_floods, 162 zst_errors; 163 164 int zst_hwflags, /* see z8530var.h */ 165 zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */ 166 167 u_int zst_r_hiwat, 168 zst_r_lowat; 169 u_char *volatile zst_rbget, 170 *volatile zst_rbput; 171 volatile u_int zst_rbavail; 172 u_char *zst_rbuf, 173 *zst_ebuf; 174 175 /* 176 * The transmit byte count and address are used for pseudo-DMA 177 * output in the hardware interrupt code. PDMA can be suspended 178 * to get pending changes done; heldtbc is used for this. It can 179 * also be stopped for ^S; this sets TS_TTSTOP in tp->t_state. 180 */ 181 u_char *zst_tba; /* transmit buffer address */ 182 u_int zst_tbc, /* transmit byte count */ 183 zst_heldtbc; /* held tbc while xmission stopped */ 184 185 /* Flags to communicate with zstty_softint() */ 186 volatile u_char zst_rx_flags, /* receiver blocked */ 187 #define RX_TTY_BLOCKED 0x01 188 #define RX_TTY_OVERFLOWED 0x02 189 #define RX_IBUF_BLOCKED 0x04 190 #define RX_IBUF_OVERFLOWED 0x08 191 #define RX_ANY_BLOCK 0x0f 192 zst_tx_busy, /* working on an output chunk */ 193 zst_tx_done, /* done with one output chunk */ 194 zst_tx_stopped, /* H/W level stop (lost CTS) */ 195 zst_st_check, /* got a status interrupt */ 196 zst_rx_ready; 197 198 /* PPS signal on DCD, with or without inkernel clock disciplining */ 199 u_char zst_ppsmask; /* pps signal mask */ 200 u_char zst_ppsassert; /* pps leading edge */ 201 u_char zst_ppsclear; /* pps trailing edge */ 202 pps_info_t ppsinfo; 203 pps_params_t ppsparam; 204 }; 205 206 /* Macros to clear/set/test flags. */ 207 #define SET(t, f) (t) |= (f) 208 #define CLR(t, f) (t) &= ~(f) 209 #define ISSET(t, f) ((t) & (f)) 210 211 /* Definition of the driver for autoconfig. */ 212 static int zstty_match(struct device *, struct cfdata *, void *); 213 static void zstty_attach(struct device *, struct device *, void *); 214 215 struct cfattach zstty_ca = { 216 sizeof(struct zstty_softc), zstty_match, zstty_attach 217 }; 218 219 extern struct cfdriver zstty_cd; 220 221 struct zsops zsops_tty; 222 223 /* Routines called from other code. */ 224 cdev_decl(zs); /* open, close, read, write, ioctl, stop, ... */ 225 226 static void zs_shutdown __P((struct zstty_softc *)); 227 static void zsstart __P((struct tty *)); 228 static int zsparam __P((struct tty *, struct termios *)); 229 static void zs_modem __P((struct zstty_softc *, int)); 230 static void tiocm_to_zs __P((struct zstty_softc *, u_long, int)); 231 static int zs_to_tiocm __P((struct zstty_softc *)); 232 static int zshwiflow __P((struct tty *, int)); 233 static void zs_hwiflow __P((struct zstty_softc *)); 234 static void zs_maskintr __P((struct zstty_softc *)); 235 236 /* Low-level routines. */ 237 static void zstty_rxint __P((struct zs_chanstate *)); 238 static void zstty_stint __P((struct zs_chanstate *, int)); 239 static void zstty_txint __P((struct zs_chanstate *)); 240 static void zstty_softint __P((struct zs_chanstate *)); 241 242 #define ZSUNIT(x) (minor(x) & 0x7ffff) 243 #define ZSDIALOUT(x) (minor(x) & 0x80000) 244 245 /* 246 * zstty_match: how is this zs channel configured? 247 */ 248 int 249 zstty_match(parent, cf, aux) 250 struct device *parent; 251 struct cfdata *cf; 252 void *aux; 253 { 254 struct zsc_attach_args *args = aux; 255 256 /* Exact match is better than wildcard. */ 257 if (cf->cf_loc[ZSCCF_CHANNEL] == args->channel) 258 return 2; 259 260 /* This driver accepts wildcard. */ 261 if (cf->cf_loc[ZSCCF_CHANNEL] == ZSCCF_CHANNEL_DEFAULT) 262 return 1; 263 264 return 0; 265 } 266 267 void 268 zstty_attach(parent, self, aux) 269 struct device *parent, *self; 270 void *aux; 271 272 { 273 struct zsc_softc *zsc = (void *) parent; 274 struct zstty_softc *zst = (void *) self; 275 struct cfdata *cf = self->dv_cfdata; 276 struct zsc_attach_args *args = aux; 277 struct zs_chanstate *cs; 278 struct tty *tp; 279 int channel, s, tty_unit; 280 dev_t dev; 281 char *i, *o; 282 283 callout_init(&zst->zst_diag_ch); 284 cn_init_magic(&zstty_cnm_state); 285 286 tty_unit = zst->zst_dev.dv_unit; 287 channel = args->channel; 288 cs = zsc->zsc_cs[channel]; 289 cs->cs_private = zst; 290 cs->cs_ops = &zsops_tty; 291 292 zst->zst_cs = cs; 293 zst->zst_swflags = cf->cf_flags; /* softcar, etc. */ 294 zst->zst_hwflags = args->hwflags; 295 dev = makedev(zs_major, tty_unit); 296 297 if (zst->zst_swflags) 298 printf(" flags 0x%x", zst->zst_swflags); 299 300 /* 301 * Check whether we serve as a console device. 302 * XXX - split console input/output channels aren't 303 * supported yet on /dev/console 304 */ 305 i = o = NULL; 306 if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) { 307 i = "input"; 308 if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) { 309 args->consdev->cn_dev = dev; 310 cn_tab->cn_pollc = args->consdev->cn_pollc; 311 cn_tab->cn_getc = args->consdev->cn_getc; 312 } 313 cn_tab->cn_dev = dev; 314 /* Set console magic to BREAK */ 315 cn_set_magic("\047\001"); 316 } 317 if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) { 318 o = "output"; 319 if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) { 320 cn_tab->cn_putc = args->consdev->cn_putc; 321 } 322 cn_tab->cn_dev = dev; 323 } 324 if (i != NULL || o != NULL) 325 printf(" (console %s)", i ? (o ? "i/o" : i) : o); 326 327 #ifdef KGDB 328 if (zs_check_kgdb(cs, dev)) { 329 /* 330 * Allow kgdb to "take over" this port. Returns true 331 * if this serial port is in-use by kgdb. 332 */ 333 printf(" (kgdb)\n"); 334 /* 335 * This is the kgdb port (exclusive use) 336 * so skip the normal attach code. 337 */ 338 return; 339 } 340 #endif 341 printf("\n"); 342 343 tp = ttymalloc(); 344 tp->t_dev = dev; 345 tp->t_oproc = zsstart; 346 tp->t_param = zsparam; 347 tp->t_hwiflow = zshwiflow; 348 tty_attach(tp); 349 350 zst->zst_tty = tp; 351 zst->zst_rbuf = malloc(zstty_rbuf_size << 1, M_DEVBUF, M_WAITOK); 352 zst->zst_ebuf = zst->zst_rbuf + (zstty_rbuf_size << 1); 353 /* Disable the high water mark. */ 354 zst->zst_r_hiwat = 0; 355 zst->zst_r_lowat = 0; 356 zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf; 357 zst->zst_rbavail = zstty_rbuf_size; 358 359 /* if there are no enable/disable functions, assume the device 360 is always enabled */ 361 if (!cs->enable) 362 cs->enabled = 1; 363 364 /* 365 * Hardware init 366 */ 367 if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) { 368 /* Call zsparam similar to open. */ 369 struct termios t; 370 371 /* Wait a while for previous console output to complete */ 372 DELAY(10000); 373 374 /* Setup the "new" parameters in t. */ 375 t.c_ispeed = 0; 376 t.c_ospeed = cs->cs_defspeed; 377 t.c_cflag = cs->cs_defcflag; 378 379 s = splzs(); 380 381 /* 382 * Turn on receiver and status interrupts. 383 * We defer the actual write of the register to zsparam(), 384 * but we must make sure status interrupts are turned on by 385 * the time zsparam() reads the initial rr0 state. 386 */ 387 SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE); 388 389 splx(s); 390 391 /* Make sure zsparam will see changes. */ 392 tp->t_ospeed = 0; 393 (void) zsparam(tp, &t); 394 395 s = splzs(); 396 397 /* Make sure DTR is on now. */ 398 zs_modem(zst, 1); 399 400 splx(s); 401 } else if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_NORESET)) { 402 /* Not the console; may need reset. */ 403 int reset; 404 405 reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; 406 407 s = splzs(); 408 409 zs_write_reg(cs, 9, reset); 410 411 /* Will raise DTR in open. */ 412 zs_modem(zst, 0); 413 414 splx(s); 415 } 416 } 417 418 419 /* 420 * Return pointer to our tty. 421 */ 422 struct tty * 423 zstty(dev) 424 dev_t dev; 425 { 426 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev)); 427 428 return (zst->zst_tty); 429 } 430 431 432 void 433 zs_shutdown(zst) 434 struct zstty_softc *zst; 435 { 436 struct zs_chanstate *cs = zst->zst_cs; 437 struct tty *tp = zst->zst_tty; 438 int s; 439 440 s = splzs(); 441 442 /* If we were asserting flow control, then deassert it. */ 443 SET(zst->zst_rx_flags, RX_IBUF_BLOCKED); 444 zs_hwiflow(zst); 445 446 /* Clear any break condition set with TIOCSBRK. */ 447 zs_break(cs, 0); 448 449 /* Turn off PPS capture on last close. */ 450 zst->zst_ppsmask = 0; 451 zst->ppsparam.mode = 0; 452 453 /* 454 * Hang up if necessary. Wait a bit, so the other side has time to 455 * notice even if we immediately open the port again. 456 */ 457 if (ISSET(tp->t_cflag, HUPCL)) { 458 zs_modem(zst, 0); 459 (void) tsleep(cs, TTIPRI, ttclos, hz); 460 } 461 462 /* Turn off interrupts if not the console. */ 463 if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) { 464 CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE); 465 cs->cs_creg[1] = cs->cs_preg[1]; 466 zs_write_reg(cs, 1, cs->cs_creg[1]); 467 } 468 469 /* Call the power management hook. */ 470 if (cs->disable) { 471 #ifdef DIAGNOSTIC 472 if (!cs->enabled) 473 panic("zs_shutdown: not enabled?"); 474 #endif 475 (*cs->disable)(zst->zst_cs); 476 } 477 478 splx(s); 479 } 480 481 /* 482 * Open a zs serial (tty) port. 483 */ 484 int 485 zsopen(dev, flags, mode, p) 486 dev_t dev; 487 int flags; 488 int mode; 489 struct proc *p; 490 { 491 struct zstty_softc *zst; 492 struct zs_chanstate *cs; 493 struct tty *tp; 494 int s, s2; 495 int error; 496 497 zst = device_lookup(&zstty_cd, ZSUNIT(dev)); 498 if (zst == NULL) 499 return (ENXIO); 500 501 tp = zst->zst_tty; 502 cs = zst->zst_cs; 503 504 /* If KGDB took the line, then tp==NULL */ 505 if (tp == NULL) 506 return (EBUSY); 507 508 if (ISSET(tp->t_state, TS_ISOPEN) && 509 ISSET(tp->t_state, TS_XCLUDE) && 510 p->p_ucred->cr_uid != 0) 511 return (EBUSY); 512 513 s = spltty(); 514 515 /* 516 * Do the following iff this is a first open. 517 */ 518 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 519 struct termios t; 520 521 tp->t_dev = dev; 522 523 /* Call the power management hook. */ 524 if (cs->enable) { 525 if ((*cs->enable)(cs)) { 526 splx(s); 527 printf("%s: device enable failed\n", 528 zst->zst_dev.dv_xname); 529 return (EIO); 530 } 531 } 532 533 /* 534 * Initialize the termios status to the defaults. Add in the 535 * sticky bits from TIOCSFLAGS. 536 */ 537 t.c_ispeed = 0; 538 t.c_ospeed = cs->cs_defspeed; 539 t.c_cflag = cs->cs_defcflag; 540 if (ISSET(zst->zst_swflags, TIOCFLAG_CLOCAL)) 541 SET(t.c_cflag, CLOCAL); 542 if (ISSET(zst->zst_swflags, TIOCFLAG_CRTSCTS)) 543 SET(t.c_cflag, CRTSCTS); 544 if (ISSET(zst->zst_swflags, TIOCFLAG_CDTRCTS)) 545 SET(t.c_cflag, CDTRCTS); 546 if (ISSET(zst->zst_swflags, TIOCFLAG_MDMBUF)) 547 SET(t.c_cflag, MDMBUF); 548 549 s2 = splzs(); 550 551 /* 552 * Turn on receiver and status interrupts. 553 * We defer the actual write of the register to zsparam(), 554 * but we must make sure status interrupts are turned on by 555 * the time zsparam() reads the initial rr0 state. 556 */ 557 SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE); 558 559 /* Clear PPS capture state on first open. */ 560 zst->zst_ppsmask = 0; 561 zst->ppsparam.mode = 0; 562 563 splx(s2); 564 565 /* Make sure zsparam will see changes. */ 566 tp->t_ospeed = 0; 567 (void) zsparam(tp, &t); 568 569 /* 570 * Note: zsparam has done: cflag, ispeed, ospeed 571 * so we just need to do: iflag, oflag, lflag, cc 572 * For "raw" mode, just leave all zeros. 573 */ 574 if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_RAW)) { 575 tp->t_iflag = TTYDEF_IFLAG; 576 tp->t_oflag = TTYDEF_OFLAG; 577 tp->t_lflag = TTYDEF_LFLAG; 578 } else { 579 tp->t_iflag = 0; 580 tp->t_oflag = 0; 581 tp->t_lflag = 0; 582 } 583 ttychars(tp); 584 ttsetwater(tp); 585 586 s2 = splzs(); 587 588 /* 589 * Turn on DTR. We must always do this, even if carrier is not 590 * present, because otherwise we'd have to use TIOCSDTR 591 * immediately after setting CLOCAL, which applications do not 592 * expect. We always assert DTR while the device is open 593 * unless explicitly requested to deassert it. 594 */ 595 zs_modem(zst, 1); 596 597 /* Clear the input ring, and unblock. */ 598 zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf; 599 zst->zst_rbavail = zstty_rbuf_size; 600 zs_iflush(cs); 601 CLR(zst->zst_rx_flags, RX_ANY_BLOCK); 602 zs_hwiflow(zst); 603 604 splx(s2); 605 } 606 607 splx(s); 608 609 error = ttyopen(tp, ZSDIALOUT(dev), ISSET(flags, O_NONBLOCK)); 610 if (error) 611 goto bad; 612 613 error = (*tp->t_linesw->l_open)(dev, tp); 614 if (error) 615 goto bad; 616 617 return (0); 618 619 bad: 620 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 621 /* 622 * We failed to open the device, and nobody else had it opened. 623 * Clean up the state as appropriate. 624 */ 625 zs_shutdown(zst); 626 } 627 628 return (error); 629 } 630 631 /* 632 * Close a zs serial port. 633 */ 634 int 635 zsclose(dev, flags, mode, p) 636 dev_t dev; 637 int flags; 638 int mode; 639 struct proc *p; 640 { 641 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev)); 642 struct tty *tp = zst->zst_tty; 643 644 /* XXX This is for cons.c. */ 645 if (!ISSET(tp->t_state, TS_ISOPEN)) 646 return 0; 647 648 (*tp->t_linesw->l_close)(tp, flags); 649 ttyclose(tp); 650 651 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 652 /* 653 * Although we got a last close, the device may still be in 654 * use; e.g. if this was the dialout node, and there are still 655 * processes waiting for carrier on the non-dialout node. 656 */ 657 zs_shutdown(zst); 658 } 659 660 return (0); 661 } 662 663 /* 664 * Read/write zs serial port. 665 */ 666 int 667 zsread(dev, uio, flags) 668 dev_t dev; 669 struct uio *uio; 670 int flags; 671 { 672 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev)); 673 struct tty *tp = zst->zst_tty; 674 675 return ((*tp->t_linesw->l_read)(tp, uio, flags)); 676 } 677 678 int 679 zswrite(dev, uio, flags) 680 dev_t dev; 681 struct uio *uio; 682 int flags; 683 { 684 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev)); 685 struct tty *tp = zst->zst_tty; 686 687 return ((*tp->t_linesw->l_write)(tp, uio, flags)); 688 } 689 690 int 691 zspoll(dev, events, p) 692 dev_t dev; 693 int events; 694 struct proc *p; 695 { 696 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev)); 697 struct tty *tp = zst->zst_tty; 698 699 return ((*tp->t_linesw->l_poll)(tp, events, p)); 700 } 701 702 int 703 zsioctl(dev, cmd, data, flag, p) 704 dev_t dev; 705 u_long cmd; 706 caddr_t data; 707 int flag; 708 struct proc *p; 709 { 710 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(dev)); 711 struct zs_chanstate *cs = zst->zst_cs; 712 struct tty *tp = zst->zst_tty; 713 int error; 714 int s; 715 716 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p); 717 if (error >= 0) 718 return (error); 719 720 error = ttioctl(tp, cmd, data, flag, p); 721 if (error >= 0) 722 return (error); 723 724 #ifdef ZS_MD_IOCTL 725 error = ZS_MD_IOCTL; 726 if (error >= 0) 727 return (error); 728 #endif /* ZS_MD_IOCTL */ 729 730 error = 0; 731 732 s = splzs(); 733 734 switch (cmd) { 735 case TIOCSBRK: 736 zs_break(cs, 1); 737 break; 738 739 case TIOCCBRK: 740 zs_break(cs, 0); 741 break; 742 743 case TIOCGFLAGS: 744 *(int *)data = zst->zst_swflags; 745 break; 746 747 case TIOCSFLAGS: 748 error = suser(p->p_ucred, &p->p_acflag); 749 if (error) 750 break; 751 zst->zst_swflags = *(int *)data; 752 break; 753 754 case TIOCSDTR: 755 zs_modem(zst, 1); 756 break; 757 758 case TIOCCDTR: 759 zs_modem(zst, 0); 760 break; 761 762 case TIOCMSET: 763 case TIOCMBIS: 764 case TIOCMBIC: 765 tiocm_to_zs(zst, cmd, *(int *)data); 766 break; 767 768 case TIOCMGET: 769 *(int *)data = zs_to_tiocm(zst); 770 break; 771 772 case PPS_IOC_CREATE: 773 break; 774 775 case PPS_IOC_DESTROY: 776 break; 777 778 case PPS_IOC_GETPARAMS: { 779 pps_params_t *pp; 780 pp = (pps_params_t *)data; 781 *pp = zst->ppsparam; 782 break; 783 } 784 785 case PPS_IOC_SETPARAMS: { 786 pps_params_t *pp; 787 int mode; 788 if (cs->cs_rr0_pps == 0) { 789 error = EINVAL; 790 break; 791 } 792 pp = (pps_params_t *)data; 793 if (pp->mode & ~zsppscap) { 794 error = EINVAL; 795 break; 796 } 797 zst->ppsparam = *pp; 798 /* 799 * compute masks from user-specified timestamp state. 800 */ 801 mode = zst->ppsparam.mode; 802 #ifdef PPS_SYNC 803 if (mode & PPS_HARDPPSONASSERT) { 804 mode |= PPS_CAPTUREASSERT; 805 /* XXX revoke any previous HARDPPS source */ 806 } 807 if (mode & PPS_HARDPPSONCLEAR) { 808 mode |= PPS_CAPTURECLEAR; 809 /* XXX revoke any previous HARDPPS source */ 810 } 811 #endif /* PPS_SYNC */ 812 switch (mode & PPS_CAPTUREBOTH) { 813 case 0: 814 zst->zst_ppsmask = 0; 815 break; 816 817 case PPS_CAPTUREASSERT: 818 zst->zst_ppsmask = ZSRR0_DCD; 819 zst->zst_ppsassert = ZSRR0_DCD; 820 zst->zst_ppsclear = -1; 821 break; 822 823 case PPS_CAPTURECLEAR: 824 zst->zst_ppsmask = ZSRR0_DCD; 825 zst->zst_ppsassert = -1; 826 zst->zst_ppsclear = 0; 827 break; 828 829 case PPS_CAPTUREBOTH: 830 zst->zst_ppsmask = ZSRR0_DCD; 831 zst->zst_ppsassert = ZSRR0_DCD; 832 zst->zst_ppsclear = 0; 833 break; 834 835 default: 836 error = EINVAL; 837 break; 838 } 839 840 /* 841 * Now update interrupts. 842 */ 843 zs_maskintr(zst); 844 /* 845 * If nothing is being transmitted, set up new current values, 846 * else mark them as pending. 847 */ 848 if (!cs->cs_heldchange) { 849 if (zst->zst_tx_busy) { 850 zst->zst_heldtbc = zst->zst_tbc; 851 zst->zst_tbc = 0; 852 cs->cs_heldchange = 1; 853 } else 854 zs_loadchannelregs(cs); 855 } 856 857 break; 858 } 859 860 case PPS_IOC_GETCAP: 861 *(int *)data = zsppscap; 862 break; 863 864 case PPS_IOC_FETCH: { 865 pps_info_t *pi; 866 pi = (pps_info_t *)data; 867 *pi = zst->ppsinfo; 868 break; 869 } 870 871 case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */ 872 if (cs->cs_rr0_pps == 0) { 873 error = EINVAL; 874 break; 875 } 876 /* 877 * Some GPS clocks models use the falling rather than 878 * rising edge as the on-the-second signal. 879 * The old API has no way to specify PPS polarity. 880 */ 881 zst->zst_ppsmask = ZSRR0_DCD; 882 #ifndef PPS_TRAILING_EDGE 883 zst->zst_ppsassert = ZSRR0_DCD; 884 zst->zst_ppsclear = -1; 885 TIMESPEC_TO_TIMEVAL((struct timeval *)data, 886 &zst->ppsinfo.assert_timestamp); 887 #else 888 zst->zst_ppsassert = -1; 889 zst->zst_ppsclear = 01; 890 TIMESPEC_TO_TIMEVAL((struct timeval *)data, 891 &zst->ppsinfo.clear_timestamp); 892 #endif 893 /* 894 * Now update interrupts. 895 */ 896 zs_maskintr(zst); 897 /* 898 * If nothing is being transmitted, set up new current values, 899 * else mark them as pending. 900 */ 901 if (!cs->cs_heldchange) { 902 if (zst->zst_tx_busy) { 903 zst->zst_heldtbc = zst->zst_tbc; 904 zst->zst_tbc = 0; 905 cs->cs_heldchange = 1; 906 } else 907 zs_loadchannelregs(cs); 908 } 909 910 break; 911 912 default: 913 error = ENOTTY; 914 break; 915 } 916 917 splx(s); 918 919 return (error); 920 } 921 922 /* 923 * Start or restart transmission. 924 */ 925 static void 926 zsstart(tp) 927 struct tty *tp; 928 { 929 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev)); 930 struct zs_chanstate *cs = zst->zst_cs; 931 int s; 932 933 s = spltty(); 934 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 935 goto out; 936 if (zst->zst_tx_stopped) 937 goto out; 938 939 if (tp->t_outq.c_cc <= tp->t_lowat) { 940 if (ISSET(tp->t_state, TS_ASLEEP)) { 941 CLR(tp->t_state, TS_ASLEEP); 942 wakeup((caddr_t)&tp->t_outq); 943 } 944 selwakeup(&tp->t_wsel); 945 if (tp->t_outq.c_cc == 0) 946 goto out; 947 } 948 949 /* Grab the first contiguous region of buffer space. */ 950 { 951 u_char *tba; 952 int tbc; 953 954 tba = tp->t_outq.c_cf; 955 tbc = ndqb(&tp->t_outq, 0); 956 957 (void) splzs(); 958 959 zst->zst_tba = tba; 960 zst->zst_tbc = tbc; 961 } 962 963 SET(tp->t_state, TS_BUSY); 964 zst->zst_tx_busy = 1; 965 966 /* Enable transmit completion interrupts if necessary. */ 967 if (!ISSET(cs->cs_preg[1], ZSWR1_TIE)) { 968 SET(cs->cs_preg[1], ZSWR1_TIE); 969 cs->cs_creg[1] = cs->cs_preg[1]; 970 zs_write_reg(cs, 1, cs->cs_creg[1]); 971 } 972 973 /* Output the first character of the contiguous buffer. */ 974 { 975 zs_write_data(cs, *zst->zst_tba); 976 zst->zst_tbc--; 977 zst->zst_tba++; 978 } 979 out: 980 splx(s); 981 return; 982 } 983 984 /* 985 * Stop output, e.g., for ^S or output flush. 986 */ 987 void 988 zsstop(tp, flag) 989 struct tty *tp; 990 int flag; 991 { 992 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev)); 993 int s; 994 995 s = splzs(); 996 if (ISSET(tp->t_state, TS_BUSY)) { 997 /* Stop transmitting at the next chunk. */ 998 zst->zst_tbc = 0; 999 zst->zst_heldtbc = 0; 1000 if (!ISSET(tp->t_state, TS_TTSTOP)) 1001 SET(tp->t_state, TS_FLUSH); 1002 } 1003 splx(s); 1004 } 1005 1006 /* 1007 * Set ZS tty parameters from termios. 1008 * XXX - Should just copy the whole termios after 1009 * making sure all the changes could be done. 1010 */ 1011 static int 1012 zsparam(tp, t) 1013 struct tty *tp; 1014 struct termios *t; 1015 { 1016 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev)); 1017 struct zs_chanstate *cs = zst->zst_cs; 1018 int ospeed, cflag; 1019 u_char tmp3, tmp4, tmp5; 1020 int s, error; 1021 1022 ospeed = t->c_ospeed; 1023 cflag = t->c_cflag; 1024 1025 /* Check requested parameters. */ 1026 if (ospeed < 0) 1027 return (EINVAL); 1028 if (t->c_ispeed && t->c_ispeed != ospeed) 1029 return (EINVAL); 1030 1031 /* 1032 * For the console, always force CLOCAL and !HUPCL, so that the port 1033 * is always active. 1034 */ 1035 if (ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR) || 1036 ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) { 1037 SET(cflag, CLOCAL); 1038 CLR(cflag, HUPCL); 1039 } 1040 1041 /* 1042 * Only whack the UART when params change. 1043 * Some callers need to clear tp->t_ospeed 1044 * to make sure initialization gets done. 1045 */ 1046 if (tp->t_ospeed == ospeed && 1047 tp->t_cflag == cflag) 1048 return (0); 1049 1050 /* 1051 * Call MD functions to deal with changed 1052 * clock modes or H/W flow control modes. 1053 * The BRG divisor is set now. (reg 12,13) 1054 */ 1055 error = zs_set_speed(cs, ospeed); 1056 if (error) 1057 return (error); 1058 error = zs_set_modes(cs, cflag); 1059 if (error) 1060 return (error); 1061 1062 /* 1063 * Block interrupts so that state will not 1064 * be altered until we are done setting it up. 1065 * 1066 * Initial values in cs_preg are set before 1067 * our attach routine is called. The master 1068 * interrupt enable is handled by zsc.c 1069 * 1070 */ 1071 s = splzs(); 1072 1073 /* 1074 * Recalculate which status ints to enable. 1075 */ 1076 zs_maskintr(zst); 1077 1078 /* Recompute character size bits. */ 1079 tmp3 = cs->cs_preg[3]; 1080 tmp5 = cs->cs_preg[5]; 1081 CLR(tmp3, ZSWR3_RXSIZE); 1082 CLR(tmp5, ZSWR5_TXSIZE); 1083 switch (ISSET(cflag, CSIZE)) { 1084 case CS5: 1085 SET(tmp3, ZSWR3_RX_5); 1086 SET(tmp5, ZSWR5_TX_5); 1087 break; 1088 case CS6: 1089 SET(tmp3, ZSWR3_RX_6); 1090 SET(tmp5, ZSWR5_TX_6); 1091 break; 1092 case CS7: 1093 SET(tmp3, ZSWR3_RX_7); 1094 SET(tmp5, ZSWR5_TX_7); 1095 break; 1096 case CS8: 1097 SET(tmp3, ZSWR3_RX_8); 1098 SET(tmp5, ZSWR5_TX_8); 1099 break; 1100 } 1101 cs->cs_preg[3] = tmp3; 1102 cs->cs_preg[5] = tmp5; 1103 1104 /* 1105 * Recompute the stop bits and parity bits. Note that 1106 * zs_set_speed() may have set clock selection bits etc. 1107 * in wr4, so those must preserved. 1108 */ 1109 tmp4 = cs->cs_preg[4]; 1110 CLR(tmp4, ZSWR4_SBMASK | ZSWR4_PARMASK); 1111 if (ISSET(cflag, CSTOPB)) 1112 SET(tmp4, ZSWR4_TWOSB); 1113 else 1114 SET(tmp4, ZSWR4_ONESB); 1115 if (!ISSET(cflag, PARODD)) 1116 SET(tmp4, ZSWR4_EVENP); 1117 if (ISSET(cflag, PARENB)) 1118 SET(tmp4, ZSWR4_PARENB); 1119 cs->cs_preg[4] = tmp4; 1120 1121 /* And copy to tty. */ 1122 tp->t_ispeed = 0; 1123 tp->t_ospeed = ospeed; 1124 tp->t_cflag = cflag; 1125 1126 /* 1127 * If nothing is being transmitted, set up new current values, 1128 * else mark them as pending. 1129 */ 1130 if (!cs->cs_heldchange) { 1131 if (zst->zst_tx_busy) { 1132 zst->zst_heldtbc = zst->zst_tbc; 1133 zst->zst_tbc = 0; 1134 cs->cs_heldchange = 1; 1135 } else 1136 zs_loadchannelregs(cs); 1137 } 1138 1139 /* 1140 * If hardware flow control is disabled, turn off the buffer water 1141 * marks and unblock any soft flow control state. Otherwise, enable 1142 * the water marks. 1143 */ 1144 if (!ISSET(cflag, CHWFLOW)) { 1145 zst->zst_r_hiwat = 0; 1146 zst->zst_r_lowat = 0; 1147 if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) { 1148 CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED); 1149 zst->zst_rx_ready = 1; 1150 cs->cs_softreq = 1; 1151 } 1152 if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) { 1153 CLR(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED); 1154 zs_hwiflow(zst); 1155 } 1156 } else { 1157 zst->zst_r_hiwat = zstty_rbuf_hiwat; 1158 zst->zst_r_lowat = zstty_rbuf_lowat; 1159 } 1160 1161 /* 1162 * Force a recheck of the hardware carrier and flow control status, 1163 * since we may have changed which bits we're looking at. 1164 */ 1165 zstty_stint(cs, 1); 1166 1167 splx(s); 1168 1169 /* 1170 * If hardware flow control is disabled, unblock any hard flow control 1171 * state. 1172 */ 1173 if (!ISSET(cflag, CHWFLOW)) { 1174 if (zst->zst_tx_stopped) { 1175 zst->zst_tx_stopped = 0; 1176 zsstart(tp); 1177 } 1178 } 1179 1180 zstty_softint(cs); 1181 1182 return (0); 1183 } 1184 1185 /* 1186 * Compute interupt enable bits and set in the pending bits. Called both 1187 * in zsparam() and when PPS (pulse per second timing) state changes. 1188 * Must be called at splzs(). 1189 */ 1190 static void 1191 zs_maskintr(zst) 1192 struct zstty_softc *zst; 1193 { 1194 struct zs_chanstate *cs = zst->zst_cs; 1195 int tmp15; 1196 1197 cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd; 1198 if (zst->zst_ppsmask != 0) 1199 cs->cs_rr0_mask |= cs->cs_rr0_pps; 1200 tmp15 = cs->cs_preg[15]; 1201 if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD)) 1202 SET(tmp15, ZSWR15_DCD_IE); 1203 else 1204 CLR(tmp15, ZSWR15_DCD_IE); 1205 if (ISSET(cs->cs_rr0_mask, ZSRR0_CTS)) 1206 SET(tmp15, ZSWR15_CTS_IE); 1207 else 1208 CLR(tmp15, ZSWR15_CTS_IE); 1209 cs->cs_preg[15] = tmp15; 1210 } 1211 1212 1213 /* 1214 * Raise or lower modem control (DTR/RTS) signals. If a character is 1215 * in transmission, the change is deferred. 1216 */ 1217 static void 1218 zs_modem(zst, onoff) 1219 struct zstty_softc *zst; 1220 int onoff; 1221 { 1222 struct zs_chanstate *cs = zst->zst_cs; 1223 1224 if (cs->cs_wr5_dtr == 0) 1225 return; 1226 1227 if (onoff) 1228 SET(cs->cs_preg[5], cs->cs_wr5_dtr); 1229 else 1230 CLR(cs->cs_preg[5], cs->cs_wr5_dtr); 1231 1232 if (!cs->cs_heldchange) { 1233 if (zst->zst_tx_busy) { 1234 zst->zst_heldtbc = zst->zst_tbc; 1235 zst->zst_tbc = 0; 1236 cs->cs_heldchange = 1; 1237 } else 1238 zs_loadchannelregs(cs); 1239 } 1240 } 1241 1242 static void 1243 tiocm_to_zs(zst, how, ttybits) 1244 struct zstty_softc *zst; 1245 u_long how; 1246 int ttybits; 1247 { 1248 struct zs_chanstate *cs = zst->zst_cs; 1249 u_char zsbits; 1250 1251 zsbits = 0; 1252 if (ISSET(ttybits, TIOCM_DTR)) 1253 SET(zsbits, ZSWR5_DTR); 1254 if (ISSET(ttybits, TIOCM_RTS)) 1255 SET(zsbits, ZSWR5_RTS); 1256 1257 switch (how) { 1258 case TIOCMBIC: 1259 CLR(cs->cs_preg[5], zsbits); 1260 break; 1261 1262 case TIOCMBIS: 1263 SET(cs->cs_preg[5], zsbits); 1264 break; 1265 1266 case TIOCMSET: 1267 CLR(cs->cs_preg[5], ZSWR5_RTS | ZSWR5_DTR); 1268 SET(cs->cs_preg[5], zsbits); 1269 break; 1270 } 1271 1272 if (!cs->cs_heldchange) { 1273 if (zst->zst_tx_busy) { 1274 zst->zst_heldtbc = zst->zst_tbc; 1275 zst->zst_tbc = 0; 1276 cs->cs_heldchange = 1; 1277 } else 1278 zs_loadchannelregs(cs); 1279 } 1280 } 1281 1282 static int 1283 zs_to_tiocm(zst) 1284 struct zstty_softc *zst; 1285 { 1286 struct zs_chanstate *cs = zst->zst_cs; 1287 u_char zsbits; 1288 int ttybits = 0; 1289 1290 zsbits = cs->cs_preg[5]; 1291 if (ISSET(zsbits, ZSWR5_DTR)) 1292 SET(ttybits, TIOCM_DTR); 1293 if (ISSET(zsbits, ZSWR5_RTS)) 1294 SET(ttybits, TIOCM_RTS); 1295 1296 zsbits = cs->cs_rr0; 1297 if (ISSET(zsbits, ZSRR0_DCD)) 1298 SET(ttybits, TIOCM_CD); 1299 if (ISSET(zsbits, ZSRR0_CTS)) 1300 SET(ttybits, TIOCM_CTS); 1301 1302 return (ttybits); 1303 } 1304 1305 /* 1306 * Try to block or unblock input using hardware flow-control. 1307 * This is called by kern/tty.c if MDMBUF|CRTSCTS is set, and 1308 * if this function returns non-zero, the TS_TBLOCK flag will 1309 * be set or cleared according to the "block" arg passed. 1310 */ 1311 int 1312 zshwiflow(tp, block) 1313 struct tty *tp; 1314 int block; 1315 { 1316 struct zstty_softc *zst = device_lookup(&zstty_cd, ZSUNIT(tp->t_dev)); 1317 struct zs_chanstate *cs = zst->zst_cs; 1318 int s; 1319 1320 if (cs->cs_wr5_rts == 0) 1321 return (0); 1322 1323 s = splzs(); 1324 if (block) { 1325 if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) { 1326 SET(zst->zst_rx_flags, RX_TTY_BLOCKED); 1327 zs_hwiflow(zst); 1328 } 1329 } else { 1330 if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) { 1331 CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED); 1332 zst->zst_rx_ready = 1; 1333 cs->cs_softreq = 1; 1334 } 1335 if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) { 1336 CLR(zst->zst_rx_flags, RX_TTY_BLOCKED); 1337 zs_hwiflow(zst); 1338 } 1339 } 1340 splx(s); 1341 return (1); 1342 } 1343 1344 /* 1345 * Internal version of zshwiflow 1346 * called at splzs 1347 */ 1348 static void 1349 zs_hwiflow(zst) 1350 struct zstty_softc *zst; 1351 { 1352 struct zs_chanstate *cs = zst->zst_cs; 1353 1354 if (cs->cs_wr5_rts == 0) 1355 return; 1356 1357 if (ISSET(zst->zst_rx_flags, RX_ANY_BLOCK)) { 1358 CLR(cs->cs_preg[5], cs->cs_wr5_rts); 1359 CLR(cs->cs_creg[5], cs->cs_wr5_rts); 1360 } else { 1361 SET(cs->cs_preg[5], cs->cs_wr5_rts); 1362 SET(cs->cs_creg[5], cs->cs_wr5_rts); 1363 } 1364 zs_write_reg(cs, 5, cs->cs_creg[5]); 1365 } 1366 1367 1368 /**************************************************************** 1369 * Interface to the lower layer (zscc) 1370 ****************************************************************/ 1371 1372 #define integrate static inline 1373 integrate void zstty_rxsoft __P((struct zstty_softc *, struct tty *)); 1374 integrate void zstty_txsoft __P((struct zstty_softc *, struct tty *)); 1375 integrate void zstty_stsoft __P((struct zstty_softc *, struct tty *)); 1376 static void zstty_diag __P((void *)); 1377 1378 /* 1379 * receiver ready interrupt. 1380 * called at splzs 1381 */ 1382 static void 1383 zstty_rxint(cs) 1384 struct zs_chanstate *cs; 1385 { 1386 struct zstty_softc *zst = cs->cs_private; 1387 u_char *put, *end; 1388 u_int cc; 1389 u_char rr0, rr1, c; 1390 1391 end = zst->zst_ebuf; 1392 put = zst->zst_rbput; 1393 cc = zst->zst_rbavail; 1394 1395 while (cc > 0) { 1396 /* 1397 * First read the status, because reading the received char 1398 * destroys the status of this char. 1399 */ 1400 rr1 = zs_read_reg(cs, 1); 1401 c = zs_read_data(cs); 1402 1403 if (ISSET(rr1, ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) { 1404 /* Clear the receive error. */ 1405 zs_write_csr(cs, ZSWR0_RESET_ERRORS); 1406 } 1407 1408 cn_check_magic(zst->zst_tty->t_dev, c, zstty_cnm_state); 1409 put[0] = c; 1410 put[1] = rr1; 1411 put += 2; 1412 if (put >= end) 1413 put = zst->zst_rbuf; 1414 cc--; 1415 1416 rr0 = zs_read_csr(cs); 1417 if (!ISSET(rr0, ZSRR0_RX_READY)) 1418 break; 1419 } 1420 1421 /* 1422 * Current string of incoming characters ended because 1423 * no more data was available or we ran out of space. 1424 * Schedule a receive event if any data was received. 1425 * If we're out of space, turn off receive interrupts. 1426 */ 1427 zst->zst_rbput = put; 1428 zst->zst_rbavail = cc; 1429 if (!ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) { 1430 zst->zst_rx_ready = 1; 1431 cs->cs_softreq = 1; 1432 } 1433 1434 /* 1435 * See if we are in danger of overflowing a buffer. If 1436 * so, use hardware flow control to ease the pressure. 1437 */ 1438 if (!ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED) && 1439 cc < zst->zst_r_hiwat) { 1440 SET(zst->zst_rx_flags, RX_IBUF_BLOCKED); 1441 zs_hwiflow(zst); 1442 } 1443 1444 /* 1445 * If we're out of space, disable receive interrupts 1446 * until the queue has drained a bit. 1447 */ 1448 if (!cc) { 1449 SET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED); 1450 CLR(cs->cs_preg[1], ZSWR1_RIE); 1451 cs->cs_creg[1] = cs->cs_preg[1]; 1452 zs_write_reg(cs, 1, cs->cs_creg[1]); 1453 } 1454 1455 #if 0 1456 printf("%xH%04d\n", zst->zst_rx_flags, zst->zst_rbavail); 1457 #endif 1458 } 1459 1460 /* 1461 * transmitter ready interrupt. (splzs) 1462 */ 1463 static void 1464 zstty_txint(cs) 1465 struct zs_chanstate *cs; 1466 { 1467 struct zstty_softc *zst = cs->cs_private; 1468 1469 /* 1470 * If we've delayed a parameter change, do it now, and restart 1471 * output. 1472 */ 1473 if (cs->cs_heldchange) { 1474 zs_loadchannelregs(cs); 1475 cs->cs_heldchange = 0; 1476 zst->zst_tbc = zst->zst_heldtbc; 1477 zst->zst_heldtbc = 0; 1478 } 1479 1480 /* Output the next character in the buffer, if any. */ 1481 if (zst->zst_tbc > 0) { 1482 zs_write_data(cs, *zst->zst_tba); 1483 zst->zst_tbc--; 1484 zst->zst_tba++; 1485 } else { 1486 /* Disable transmit completion interrupts if necessary. */ 1487 if (ISSET(cs->cs_preg[1], ZSWR1_TIE)) { 1488 CLR(cs->cs_preg[1], ZSWR1_TIE); 1489 cs->cs_creg[1] = cs->cs_preg[1]; 1490 zs_write_reg(cs, 1, cs->cs_creg[1]); 1491 } 1492 if (zst->zst_tx_busy) { 1493 zst->zst_tx_busy = 0; 1494 zst->zst_tx_done = 1; 1495 cs->cs_softreq = 1; 1496 } 1497 } 1498 } 1499 1500 /* 1501 * status change interrupt. (splzs) 1502 */ 1503 static void 1504 zstty_stint(cs, force) 1505 struct zs_chanstate *cs; 1506 int force; 1507 { 1508 struct zstty_softc *zst = cs->cs_private; 1509 u_char rr0, delta; 1510 1511 rr0 = zs_read_csr(cs); 1512 zs_write_csr(cs, ZSWR0_RESET_STATUS); 1513 1514 /* 1515 * Check here for console break, so that we can abort 1516 * even when interrupts are locking up the machine. 1517 */ 1518 if (ISSET(rr0, ZSRR0_BREAK)) 1519 cn_check_magic(zst->zst_tty->t_dev, CNC_BREAK, zstty_cnm_state); 1520 1521 if (!force) 1522 delta = rr0 ^ cs->cs_rr0; 1523 else 1524 delta = cs->cs_rr0_mask; 1525 cs->cs_rr0 = rr0; 1526 1527 if (ISSET(delta, cs->cs_rr0_mask)) { 1528 SET(cs->cs_rr0_delta, delta); 1529 1530 /* 1531 * Pulse-per-second clock signal on edge of DCD? 1532 */ 1533 if (ISSET(delta, zst->zst_ppsmask)) { 1534 struct timeval tv; 1535 if (ISSET(rr0, zst->zst_ppsmask) == zst->zst_ppsassert) { 1536 /* XXX nanotime() */ 1537 microtime(&tv); 1538 TIMEVAL_TO_TIMESPEC(&tv, 1539 &zst->ppsinfo.assert_timestamp); 1540 if (zst->ppsparam.mode & PPS_OFFSETASSERT) { 1541 timespecadd(&zst->ppsinfo.assert_timestamp, 1542 &zst->ppsparam.assert_offset, 1543 &zst->ppsinfo.assert_timestamp); 1544 } 1545 1546 #ifdef PPS_SYNC 1547 if (zst->ppsparam.mode & PPS_HARDPPSONASSERT) 1548 hardpps(&tv, tv.tv_usec); 1549 #endif 1550 zst->ppsinfo.assert_sequence++; 1551 zst->ppsinfo.current_mode = zst->ppsparam.mode; 1552 } else if (ISSET(rr0, zst->zst_ppsmask) == 1553 zst->zst_ppsclear) { 1554 /* XXX nanotime() */ 1555 microtime(&tv); 1556 TIMEVAL_TO_TIMESPEC(&tv, 1557 &zst->ppsinfo.clear_timestamp); 1558 if (zst->ppsparam.mode & PPS_OFFSETCLEAR) { 1559 timespecadd(&zst->ppsinfo.clear_timestamp, 1560 &zst->ppsparam.clear_offset, 1561 &zst->ppsinfo.clear_timestamp); 1562 } 1563 1564 #ifdef PPS_SYNC 1565 if (zst->ppsparam.mode & PPS_HARDPPSONCLEAR) 1566 hardpps(&tv, tv.tv_usec); 1567 #endif 1568 zst->ppsinfo.clear_sequence++; 1569 zst->ppsinfo.current_mode = zst->ppsparam.mode; 1570 } 1571 } 1572 1573 /* 1574 * Stop output immediately if we lose the output 1575 * flow control signal or carrier detect. 1576 */ 1577 if (ISSET(~rr0, cs->cs_rr0_mask)) { 1578 zst->zst_tbc = 0; 1579 zst->zst_heldtbc = 0; 1580 } 1581 1582 zst->zst_st_check = 1; 1583 cs->cs_softreq = 1; 1584 } 1585 } 1586 1587 void 1588 zstty_diag(arg) 1589 void *arg; 1590 { 1591 struct zstty_softc *zst = arg; 1592 int overflows, floods; 1593 int s; 1594 1595 s = splzs(); 1596 overflows = zst->zst_overflows; 1597 zst->zst_overflows = 0; 1598 floods = zst->zst_floods; 1599 zst->zst_floods = 0; 1600 zst->zst_errors = 0; 1601 splx(s); 1602 1603 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", 1604 zst->zst_dev.dv_xname, 1605 overflows, overflows == 1 ? "" : "s", 1606 floods, floods == 1 ? "" : "s"); 1607 } 1608 1609 integrate void 1610 zstty_rxsoft(zst, tp) 1611 struct zstty_softc *zst; 1612 struct tty *tp; 1613 { 1614 struct zs_chanstate *cs = zst->zst_cs; 1615 int (*rint) __P((int c, struct tty *tp)) = tp->t_linesw->l_rint; 1616 u_char *get, *end; 1617 u_int cc, scc; 1618 u_char rr1; 1619 int code; 1620 int s; 1621 1622 end = zst->zst_ebuf; 1623 get = zst->zst_rbget; 1624 scc = cc = zstty_rbuf_size - zst->zst_rbavail; 1625 1626 if (cc == zstty_rbuf_size) { 1627 zst->zst_floods++; 1628 if (zst->zst_errors++ == 0) 1629 callout_reset(&zst->zst_diag_ch, 60 * hz, 1630 zstty_diag, zst); 1631 } 1632 1633 /* If not yet open, drop the entire buffer content here */ 1634 if (!ISSET(tp->t_state, TS_ISOPEN)) { 1635 get += cc << 1; 1636 if (get >= end) 1637 get -= zstty_rbuf_size << 1; 1638 cc = 0; 1639 } 1640 while (cc) { 1641 code = get[0]; 1642 rr1 = get[1]; 1643 if (ISSET(rr1, ZSRR1_DO | ZSRR1_FE | ZSRR1_PE)) { 1644 if (ISSET(rr1, ZSRR1_DO)) { 1645 zst->zst_overflows++; 1646 if (zst->zst_errors++ == 0) 1647 callout_reset(&zst->zst_diag_ch, 1648 60 * hz, zstty_diag, zst); 1649 } 1650 if (ISSET(rr1, ZSRR1_FE)) 1651 SET(code, TTY_FE); 1652 if (ISSET(rr1, ZSRR1_PE)) 1653 SET(code, TTY_PE); 1654 } 1655 if ((*rint)(code, tp) == -1) { 1656 /* 1657 * The line discipline's buffer is out of space. 1658 */ 1659 if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) { 1660 /* 1661 * We're either not using flow control, or the 1662 * line discipline didn't tell us to block for 1663 * some reason. Either way, we have no way to 1664 * know when there's more space available, so 1665 * just drop the rest of the data. 1666 */ 1667 get += cc << 1; 1668 if (get >= end) 1669 get -= zstty_rbuf_size << 1; 1670 cc = 0; 1671 } else { 1672 /* 1673 * Don't schedule any more receive processing 1674 * until the line discipline tells us there's 1675 * space available (through comhwiflow()). 1676 * Leave the rest of the data in the input 1677 * buffer. 1678 */ 1679 SET(zst->zst_rx_flags, RX_TTY_OVERFLOWED); 1680 } 1681 break; 1682 } 1683 get += 2; 1684 if (get >= end) 1685 get = zst->zst_rbuf; 1686 cc--; 1687 } 1688 1689 if (cc != scc) { 1690 zst->zst_rbget = get; 1691 s = splzs(); 1692 cc = zst->zst_rbavail += scc - cc; 1693 /* Buffers should be ok again, release possible block. */ 1694 if (cc >= zst->zst_r_lowat) { 1695 if (ISSET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED)) { 1696 CLR(zst->zst_rx_flags, RX_IBUF_OVERFLOWED); 1697 SET(cs->cs_preg[1], ZSWR1_RIE); 1698 cs->cs_creg[1] = cs->cs_preg[1]; 1699 zs_write_reg(cs, 1, cs->cs_creg[1]); 1700 } 1701 if (ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED)) { 1702 CLR(zst->zst_rx_flags, RX_IBUF_BLOCKED); 1703 zs_hwiflow(zst); 1704 } 1705 } 1706 splx(s); 1707 } 1708 1709 #if 0 1710 printf("%xS%04d\n", zst->zst_rx_flags, zst->zst_rbavail); 1711 #endif 1712 } 1713 1714 integrate void 1715 zstty_txsoft(zst, tp) 1716 struct zstty_softc *zst; 1717 struct tty *tp; 1718 { 1719 1720 CLR(tp->t_state, TS_BUSY); 1721 if (ISSET(tp->t_state, TS_FLUSH)) 1722 CLR(tp->t_state, TS_FLUSH); 1723 else 1724 ndflush(&tp->t_outq, (int)(zst->zst_tba - tp->t_outq.c_cf)); 1725 (*tp->t_linesw->l_start)(tp); 1726 } 1727 1728 integrate void 1729 zstty_stsoft(zst, tp) 1730 struct zstty_softc *zst; 1731 struct tty *tp; 1732 { 1733 struct zs_chanstate *cs = zst->zst_cs; 1734 u_char rr0, delta; 1735 int s; 1736 1737 s = splzs(); 1738 rr0 = cs->cs_rr0; 1739 delta = cs->cs_rr0_delta; 1740 cs->cs_rr0_delta = 0; 1741 splx(s); 1742 1743 if (ISSET(delta, cs->cs_rr0_dcd)) { 1744 /* 1745 * Inform the tty layer that carrier detect changed. 1746 */ 1747 (void) (*tp->t_linesw->l_modem)(tp, ISSET(rr0, ZSRR0_DCD)); 1748 } 1749 1750 if (ISSET(delta, cs->cs_rr0_cts)) { 1751 /* Block or unblock output according to flow control. */ 1752 if (ISSET(rr0, cs->cs_rr0_cts)) { 1753 zst->zst_tx_stopped = 0; 1754 (*tp->t_linesw->l_start)(tp); 1755 } else { 1756 zst->zst_tx_stopped = 1; 1757 } 1758 } 1759 } 1760 1761 /* 1762 * Software interrupt. Called at zssoft 1763 * 1764 * The main job to be done here is to empty the input ring 1765 * by passing its contents up to the tty layer. The ring is 1766 * always emptied during this operation, therefore the ring 1767 * must not be larger than the space after "high water" in 1768 * the tty layer, or the tty layer might drop our input. 1769 * 1770 * Note: an "input blockage" condition is assumed to exist if 1771 * EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set. 1772 */ 1773 static void 1774 zstty_softint(cs) 1775 struct zs_chanstate *cs; 1776 { 1777 struct zstty_softc *zst = cs->cs_private; 1778 struct tty *tp = zst->zst_tty; 1779 int s; 1780 1781 s = spltty(); 1782 1783 if (zst->zst_rx_ready) { 1784 zst->zst_rx_ready = 0; 1785 zstty_rxsoft(zst, tp); 1786 } 1787 1788 if (zst->zst_st_check) { 1789 zst->zst_st_check = 0; 1790 zstty_stsoft(zst, tp); 1791 } 1792 1793 if (zst->zst_tx_done) { 1794 zst->zst_tx_done = 0; 1795 zstty_txsoft(zst, tp); 1796 } 1797 1798 splx(s); 1799 } 1800 1801 struct zsops zsops_tty = { 1802 zstty_rxint, /* receive char available */ 1803 zstty_stint, /* external/status */ 1804 zstty_txint, /* xmit buffer empty */ 1805 zstty_softint, /* process software interrupt */ 1806 }; 1807