1 /* $OpenBSD: z8530tty.c,v 1.23 2010/07/02 17:27:01 nicm Exp $ */ 2 /* $NetBSD: z8530tty.c,v 1.13 1996/10/16 20:42:14 gwr Exp $ */ 3 4 /* 5 * Copyright (c) 1994 Gordon W. Ross 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This software was developed by the Computer Systems Engineering group 10 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 11 * contributed to Berkeley. 12 * 13 * All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Lawrence Berkeley Laboratory. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 1. Redistributions of source code must retain the above copyright 22 * notice, this list of conditions and the following disclaimer. 23 * 2. Redistributions in binary form must reproduce the above copyright 24 * notice, this list of conditions and the following disclaimer in the 25 * documentation and/or other materials provided with the distribution. 26 * 3. Neither the name of the University nor the names of its contributors 27 * may be used to endorse or promote products derived from this software 28 * without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 * SUCH DAMAGE. 41 * 42 * @(#)zs.c 8.1 (Berkeley) 7/19/93 43 */ 44 45 /* 46 * Zilog Z8530 Dual UART driver (tty interface) 47 * 48 * This is the "slave" driver that will be attached to 49 * the "zsc" driver for plain "tty" async. serial lines. 50 * 51 * Credits, history: 52 * 53 * The original version of this code was the sparc/dev/zs.c driver 54 * as distributed with the Berkeley 4.4 Lite release. Since then, 55 * Gordon Ross reorganized the code into the current parent/child 56 * driver scheme, separating the Sun keyboard and mouse support 57 * into independent child drivers. 58 * 59 * RTS/CTS flow-control support was a collaboration of: 60 * Gordon Ross <gwr@netbsd.org>, 61 * Bill Studenmund <wrstuden@loki.stanford.edu> 62 * Ian Dall <Ian.Dall@dsto.defence.gov.au> 63 */ 64 65 #include <sys/param.h> 66 #include <sys/systm.h> 67 #include <sys/proc.h> 68 #include <sys/device.h> 69 #include <sys/conf.h> 70 #include <sys/file.h> 71 #include <sys/ioctl.h> 72 #include <sys/malloc.h> 73 #include <sys/tty.h> 74 #include <sys/time.h> 75 #include <sys/kernel.h> 76 #include <sys/syslog.h> 77 78 #include <dev/ic/z8530reg.h> 79 #include <machine/z8530var.h> 80 81 #ifdef KGDB 82 extern int zs_check_kgdb(); 83 #endif 84 85 /* 86 * Allow the MD var.h to override the default CFLAG so that 87 * console messages during boot come out with correct parity. 88 */ 89 #ifndef ZSTTY_DEF_CFLAG 90 #define ZSTTY_DEF_CFLAG TTYDEF_CFLAG 91 #endif 92 93 /* 94 * How many input characters we can buffer. 95 * The port-specific var.h may override this. 96 * Note: must be a power of two! 97 */ 98 #ifndef ZSTTY_RING_SIZE 99 #define ZSTTY_RING_SIZE 2048 100 #endif 101 102 /* 103 * Make this an option variable one can patch. 104 * But be warned: this must be a power of 2! 105 */ 106 int zstty_rbuf_size = ZSTTY_RING_SIZE; 107 108 /* This should usually be 3/4 of ZSTTY_RING_SIZE */ 109 int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE - (ZSTTY_RING_SIZE >> 2)); 110 111 struct zstty_softc { 112 struct device zst_dev; /* required first: base device */ 113 struct tty *zst_tty; 114 struct zs_chanstate *zst_cs; 115 116 int zst_hwflags; /* see z8530var.h */ 117 int zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */ 118 119 /* 120 * Printing an overrun error message often takes long enough to 121 * cause another overrun, so we only print one per second. 122 */ 123 long zst_rotime; /* time of last ring overrun */ 124 long zst_fotime; /* time of last fifo overrun */ 125 126 /* 127 * The receive ring buffer. 128 */ 129 int zst_rbget; /* ring buffer `get' index */ 130 volatile int zst_rbput; /* ring buffer `put' index */ 131 int zst_ringmask; 132 int zst_rbhiwat; 133 134 u_short *zst_rbuf; /* rr1, data pairs */ 135 136 /* 137 * The transmit byte count and address are used for pseudo-DMA 138 * output in the hardware interrupt code. PDMA can be suspended 139 * to get pending changes done; heldtbc is used for this. It can 140 * also be stopped for ^S; this sets TS_TTSTOP in tp->t_state. 141 */ 142 int zst_tbc; /* transmit byte count */ 143 caddr_t zst_tba; /* transmit buffer address */ 144 int zst_heldtbc; /* held tbc while xmission stopped */ 145 146 /* Flags to communicate with zstty_softint() */ 147 volatile char zst_rx_blocked; /* input block at ring */ 148 volatile char zst_rx_overrun; /* ring overrun */ 149 volatile char zst_tx_busy; /* working on an output chunk */ 150 volatile char zst_tx_done; /* done with one output chunk */ 151 volatile char zst_tx_stopped; /* H/W level stop (lost CTS) */ 152 volatile char zst_st_check; /* got a status interrupt */ 153 char pad[2]; 154 }; 155 156 157 /* Definition of the driver for autoconfig. */ 158 static int zstty_match(struct device *, void *, void *); 159 static void zstty_attach(struct device *, struct device *, void *); 160 161 struct cfattach zstty_ca = { 162 sizeof(struct zstty_softc), zstty_match, zstty_attach 163 }; 164 165 struct cfdriver zstty_cd = { 166 NULL, "zstty", DV_TTY 167 }; 168 169 struct zsops zsops_tty; 170 171 /* Routines called from other code. */ 172 cdev_decl(zs); /* open, close, read, write, ioctl, stop, ... */ 173 174 static void zsstart(struct tty *); 175 static int zsparam(struct tty *, struct termios *); 176 static void zs_modem(struct zstty_softc *zst, int onoff); 177 static int zshwiflow(struct tty *, int); 178 static void zs_hwiflow(struct zstty_softc *, int); 179 static void zstty_rxint(register struct zs_chanstate *); 180 static void zstty_txint(register struct zs_chanstate *); 181 static void zstty_stint(register struct zs_chanstate *); 182 static void zstty_softint(struct zs_chanstate *); 183 static void zsoverrun(struct zstty_softc *, long *, char *); 184 /* 185 * zstty_match: how is this zs channel configured? 186 */ 187 int 188 zstty_match(parent, match, aux) 189 struct device *parent; 190 void *match, *aux; 191 { 192 struct cfdata *cf = match; 193 struct zsc_attach_args *args = aux; 194 195 /* Exact match is better than wildcard. */ 196 if (cf->cf_loc[0] == args->channel) 197 return 2; 198 199 /* This driver accepts wildcard. */ 200 if (cf->cf_loc[0] == -1) 201 return 1; 202 203 return 0; 204 } 205 206 void 207 zstty_attach(parent, self, aux) 208 struct device *parent, *self; 209 void *aux; 210 211 { 212 struct zsc_softc *zsc = (void *) parent; 213 struct zstty_softc *zst = (void *) self; 214 struct zsc_attach_args *args = aux; 215 struct zs_chanstate *cs; 216 struct cfdata *cf; 217 struct tty *tp; 218 int channel, tty_unit; 219 dev_t dev; 220 221 cf = zst->zst_dev.dv_cfdata; 222 tty_unit = zst->zst_dev.dv_unit; 223 channel = args->channel; 224 cs = &zsc->zsc_cs[channel]; 225 cs->cs_private = zst; 226 cs->cs_ops = &zsops_tty; 227 228 zst->zst_cs = cs; 229 zst->zst_swflags = cf->cf_flags; /* softcar, etc. */ 230 zst->zst_hwflags = args->hwflags; 231 dev = makedev(ZSTTY_MAJOR, tty_unit); 232 233 if (zst->zst_swflags) 234 printf(" flags 0x%x", zst->zst_swflags); 235 236 if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE) 237 printf(": console"); 238 else { 239 #ifdef KGDB 240 /* 241 * Allow kgdb to "take over" this port. If this port is 242 * NOT the kgdb port, zs_check_kgdb() will return zero. 243 * If it IS the kgdb port, it will print "kgdb,...\n" 244 * and then return non-zero. 245 */ 246 if (zs_check_kgdb(cs, dev)) { 247 /* 248 * This is the kgdb port (exclusive use) 249 * so skip the normal attach code. 250 */ 251 return; 252 } 253 #endif 254 } 255 printf("\n"); 256 257 tp = ttymalloc(0); 258 tp->t_dev = dev; 259 tp->t_oproc = zsstart; 260 tp->t_param = zsparam; 261 tp->t_hwiflow = zshwiflow; 262 263 zst->zst_tty = tp; 264 zst->zst_rbhiwat = zstty_rbuf_size; /* impossible value */ 265 zst->zst_ringmask = zstty_rbuf_size - 1; 266 zst->zst_rbuf = malloc(zstty_rbuf_size * sizeof(zst->zst_rbuf[0]), 267 M_DEVBUF, M_WAITOK); 268 269 /* 270 * Hardware init 271 */ 272 if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE) { 273 /* This unit is the console. */ 274 zst->zst_swflags |= TIOCFLAG_SOFTCAR; 275 /* Call _param so interrupts get enabled. */ 276 cs->cs_defspeed = zs_getspeed(cs); 277 tp->t_ispeed = cs->cs_defspeed; 278 tp->t_ospeed = cs->cs_defspeed; 279 tp->t_cflag = ZSTTY_DEF_CFLAG; 280 (void) zsparam(tp, &tp->t_termios); 281 } else { 282 /* Not the console; may need reset. */ 283 int reset, s; 284 reset = (channel == 0) ? 285 ZSWR9_A_RESET : ZSWR9_B_RESET; 286 s = splzs(); 287 zs_write_reg(cs, 9, reset); 288 splx(s); 289 } 290 291 /* 292 * Initialize state of modem control lines (DTR). 293 * If softcar is set, turn on DTR now and leave it. 294 * otherwise, turn off DTR now, and raise in open. 295 * (Keeps modem from answering too early.) 296 */ 297 zs_modem(zst, (zst->zst_swflags & TIOCFLAG_SOFTCAR) ? 1 : 0); 298 } 299 300 301 /* 302 * Return pointer to our tty. 303 */ 304 struct tty * 305 zstty(dev) 306 dev_t dev; 307 { 308 struct zstty_softc *zst; 309 int unit = minor(dev); 310 311 #ifdef DIAGNOSTIC 312 if (unit >= zstty_cd.cd_ndevs) 313 panic("zstty"); 314 #endif 315 zst = zstty_cd.cd_devs[unit]; 316 return (zst->zst_tty); 317 } 318 319 320 /* 321 * Open a zs serial (tty) port. 322 */ 323 int 324 zsopen(dev, flags, mode, p) 325 dev_t dev; 326 int flags; 327 int mode; 328 struct proc *p; 329 { 330 register struct tty *tp; 331 register struct zs_chanstate *cs; 332 struct zstty_softc *zst; 333 int error, s, unit; 334 335 unit = minor(dev); 336 if (unit >= zstty_cd.cd_ndevs) 337 return (ENXIO); 338 zst = zstty_cd.cd_devs[unit]; 339 if (zst == NULL) 340 return (ENXIO); 341 tp = zst->zst_tty; 342 cs = zst->zst_cs; 343 344 /* If KGDB took the line, then tp==NULL */ 345 if (tp == NULL) 346 return (EBUSY); 347 348 /* It's simpler to do this up here. */ 349 if (((tp->t_state & (TS_ISOPEN | TS_XCLUDE)) 350 == (TS_ISOPEN | TS_XCLUDE)) 351 && (suser(p, 0) != 0) ) 352 { 353 return (EBUSY); 354 } 355 356 s = spltty(); 357 358 if ((tp->t_state & TS_ISOPEN) == 0) { 359 /* First open. */ 360 ttychars(tp); 361 tp->t_iflag = TTYDEF_IFLAG; 362 tp->t_oflag = TTYDEF_OFLAG; 363 tp->t_cflag = ZSTTY_DEF_CFLAG; 364 if (zst->zst_swflags & TIOCFLAG_CLOCAL) 365 tp->t_cflag |= CLOCAL; 366 if (zst->zst_swflags & TIOCFLAG_CRTSCTS) 367 tp->t_cflag |= CRTSCTS; 368 if (zst->zst_swflags & TIOCFLAG_MDMBUF) 369 tp->t_cflag |= MDMBUF; 370 tp->t_lflag = TTYDEF_LFLAG; 371 tp->t_ispeed = tp->t_ospeed = cs->cs_defspeed; 372 (void) zsparam(tp, &tp->t_termios); 373 ttsetwater(tp); 374 /* Flush any pending input. */ 375 zst->zst_rbget = zst->zst_rbput; 376 zs_iflush(cs); /* XXX */ 377 /* Turn on DTR */ 378 zs_modem(zst, 1); 379 if (zst->zst_swflags & TIOCFLAG_SOFTCAR) { 380 tp->t_state |= TS_CARR_ON; 381 } 382 } 383 error = 0; 384 385 /* Wait for carrier. */ 386 for (;;) { 387 388 /* Might never get status intr if carrier already on. */ 389 cs->cs_rr0 = zs_read_csr(cs); 390 if (cs->cs_rr0 & ZSRR0_DCD) { 391 tp->t_state |= TS_CARR_ON; 392 break; 393 } 394 395 if ((tp->t_state & TS_CARR_ON) || 396 (tp->t_cflag & CLOCAL) || 397 (flags & O_NONBLOCK) ) 398 { 399 break; 400 } 401 402 tp->t_state |= TS_WOPEN; 403 error = ttysleep(tp, (caddr_t)&tp->t_rawq, 404 TTIPRI | PCATCH, ttopen, 0); 405 if (error) { 406 if ((tp->t_state & TS_ISOPEN) == 0) { 407 /* Never get here with softcar */ 408 zs_modem(zst, 0); 409 tp->t_state &= ~TS_WOPEN; 410 ttwakeup(tp); 411 } 412 break; 413 } 414 } 415 416 splx(s); 417 418 if (error == 0) 419 error = linesw[tp->t_line].l_open(dev, tp, p); 420 421 return (error); 422 } 423 424 /* 425 * Close a zs serial port. 426 */ 427 int 428 zsclose(dev, flags, mode, p) 429 dev_t dev; 430 int flags; 431 int mode; 432 struct proc *p; 433 { 434 struct zstty_softc *zst; 435 register struct zs_chanstate *cs; 436 register struct tty *tp; 437 int hup; 438 439 zst = zstty_cd.cd_devs[minor(dev)]; 440 cs = zst->zst_cs; 441 tp = zst->zst_tty; 442 443 /* XXX This is for cons.c. */ 444 if ((tp->t_state & TS_ISOPEN) == 0) 445 return 0; 446 447 (*linesw[tp->t_line].l_close)(tp, flags, p); 448 hup = tp->t_cflag & HUPCL; 449 if (zst->zst_swflags & TIOCFLAG_SOFTCAR) 450 hup = 0; 451 if (hup) { 452 zs_modem(zst, 0); 453 /* hold low for 1 second */ 454 (void) tsleep((caddr_t)cs, TTIPRI, ttclos, hz); 455 } 456 if (cs->cs_creg[5] & ZSWR5_BREAK) { 457 zs_break(cs, 0); 458 } 459 /* XXX - turn off interrupts? */ 460 461 ttyclose(tp); 462 return (0); 463 } 464 465 /* 466 * Read/write zs serial port. 467 */ 468 int 469 zsread(dev, uio, flags) 470 dev_t dev; 471 struct uio *uio; 472 int flags; 473 { 474 register struct zstty_softc *zst; 475 register struct tty *tp; 476 477 zst = zstty_cd.cd_devs[minor(dev)]; 478 tp = zst->zst_tty; 479 return (linesw[tp->t_line].l_read(tp, uio, flags)); 480 } 481 482 int 483 zswrite(dev, uio, flags) 484 dev_t dev; 485 struct uio *uio; 486 int flags; 487 { 488 register struct zstty_softc *zst; 489 register struct tty *tp; 490 491 zst = zstty_cd.cd_devs[minor(dev)]; 492 tp = zst->zst_tty; 493 return (linesw[tp->t_line].l_write(tp, uio, flags)); 494 } 495 496 #define TIOCFLAG_ALL (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | \ 497 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF ) 498 499 int 500 zsioctl(dev, cmd, data, flag, p) 501 dev_t dev; 502 u_long cmd; 503 caddr_t data; 504 int flag; 505 struct proc *p; 506 { 507 register struct zstty_softc *zst; 508 register struct zs_chanstate *cs; 509 register struct tty *tp; 510 register int error, tmp; 511 512 zst = zstty_cd.cd_devs[minor(dev)]; 513 cs = zst->zst_cs; 514 tp = zst->zst_tty; 515 516 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 517 if (error >= 0) 518 return (error); 519 error = ttioctl(tp, cmd, data, flag, p); 520 if (error >= 0) 521 return (error); 522 523 switch (cmd) { 524 525 case TIOCSBRK: 526 zs_break(cs, 1); 527 break; 528 529 case TIOCCBRK: 530 zs_break(cs, 0); 531 break; 532 533 case TIOCGFLAGS: 534 *(int *)data = zst->zst_swflags; 535 break; 536 537 case TIOCSFLAGS: 538 error = suser(p, 0); 539 if (error != 0) 540 return (EPERM); 541 tmp = *(int *)data; 542 /* Check for random bits... */ 543 if (tmp & ~TIOCFLAG_ALL) 544 return(EINVAL); 545 /* Silently enforce softcar on the console. */ 546 if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE) 547 tmp |= TIOCFLAG_SOFTCAR; 548 /* These flags take effect during open. */ 549 zst->zst_swflags = tmp; 550 break; 551 552 case TIOCSDTR: 553 zs_modem(zst, 1); 554 break; 555 556 case TIOCCDTR: 557 zs_modem(zst, 0); 558 break; 559 560 case TIOCMSET: 561 case TIOCMBIS: 562 case TIOCMBIC: 563 case TIOCMGET: 564 default: 565 return (ENOTTY); 566 } 567 return (0); 568 } 569 570 /* 571 * Start or restart transmission. 572 */ 573 static void 574 zsstart(tp) 575 register struct tty *tp; 576 { 577 register struct zstty_softc *zst; 578 register struct zs_chanstate *cs; 579 register int s, nch; 580 581 zst = zstty_cd.cd_devs[minor(tp->t_dev)]; 582 cs = zst->zst_cs; 583 584 s = spltty(); 585 586 /* 587 * If currently active or delaying, no need to do anything. 588 */ 589 if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) 590 goto out; 591 592 /* 593 * If under CRTSCTS hfc and halted, do nothing 594 */ 595 if (tp->t_cflag & CRTSCTS) 596 if (zst->zst_tx_stopped) 597 goto out; 598 599 /* 600 * If there are sleepers, and output has drained below low 601 * water mark, awaken. 602 */ 603 ttwakeupwr(tp); 604 605 nch = ndqb(&tp->t_outq, 0); /* XXX */ 606 (void) splzs(); 607 608 if (nch) { 609 register char *p = tp->t_outq.c_cf; 610 611 /* mark busy, enable tx done interrupts, & send first byte */ 612 tp->t_state |= TS_BUSY; 613 zst->zst_tx_busy = 1; 614 cs->cs_preg[1] |= ZSWR1_TIE; 615 cs->cs_creg[1] = cs->cs_preg[1]; 616 zs_write_reg(cs, 1, cs->cs_creg[1]); 617 zs_write_data(cs, *p); 618 zst->zst_tba = p + 1; 619 zst->zst_tbc = nch - 1; 620 } else { 621 /* 622 * Nothing to send, turn off transmit done interrupts. 623 * This is useful if something is doing polled output. 624 */ 625 cs->cs_preg[1] &= ~ZSWR1_TIE; 626 cs->cs_creg[1] = cs->cs_preg[1]; 627 zs_write_reg(cs, 1, cs->cs_creg[1]); 628 } 629 out: 630 splx(s); 631 } 632 633 /* 634 * Stop output, e.g., for ^S or output flush. 635 */ 636 int 637 zsstop(tp, flag) 638 struct tty *tp; 639 int flag; 640 { 641 register struct zstty_softc *zst; 642 register struct zs_chanstate *cs; 643 register int s; 644 645 zst = zstty_cd.cd_devs[minor(tp->t_dev)]; 646 cs = zst->zst_cs; 647 648 s = splzs(); 649 if (tp->t_state & TS_BUSY) { 650 /* 651 * Device is transmitting; must stop it. 652 * Also clear _heldtbc to prevent any 653 * flow-control event from resuming. 654 */ 655 zst->zst_tbc = 0; 656 zst->zst_heldtbc = 0; 657 if ((tp->t_state & TS_TTSTOP) == 0) 658 tp->t_state |= TS_FLUSH; 659 } 660 splx(s); 661 return (0); 662 } 663 664 /* 665 * Set ZS tty parameters from termios. 666 * XXX - Should just copy the whole termios after 667 * making sure all the changes could be done. 668 * XXX - Only whack the UART when params change... 669 */ 670 static int 671 zsparam(tp, t) 672 register struct tty *tp; 673 register struct termios *t; 674 { 675 register struct zstty_softc *zst; 676 register struct zs_chanstate *cs; 677 register int s, bps, cflag, tconst; 678 u_char tmp3, tmp4, tmp5; 679 680 zst = zstty_cd.cd_devs[minor(tp->t_dev)]; 681 cs = zst->zst_cs; 682 683 /* XXX: Need to use an MD function for this. */ 684 bps = t->c_ospeed; 685 if (bps < 0 || (t->c_ispeed && t->c_ispeed != bps)) 686 return (EINVAL); 687 if (bps == 0) { 688 /* stty 0 => drop DTR and RTS */ 689 zs_modem(zst, 0); 690 return (0); 691 } 692 tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps); 693 if (tconst < 0) 694 return (EINVAL); 695 696 /* Convert back to make sure we can do it. */ 697 bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst); 698 if (bps != t->c_ospeed) 699 return (EINVAL); 700 tp->t_ispeed = tp->t_ospeed = bps; 701 702 cflag = t->c_cflag; 703 tp->t_cflag = cflag; 704 705 /* 706 * Block interrupts so that state will not 707 * be altered until we are done setting it up. 708 */ 709 s = splzs(); 710 711 /* 712 * Initial values in cs_preg are set before 713 * our attach routine is called. The master 714 * interrupt enable is handled by zsc.c 715 */ 716 717 cs->cs_preg[12] = tconst; 718 cs->cs_preg[13] = tconst >> 8; 719 720 switch (cflag & CSIZE) { 721 case CS5: 722 tmp3 = ZSWR3_RX_5; 723 tmp5 = ZSWR5_TX_5; 724 break; 725 case CS6: 726 tmp3 = ZSWR3_RX_6; 727 tmp5 = ZSWR5_TX_6; 728 break; 729 case CS7: 730 tmp3 = ZSWR3_RX_7; 731 tmp5 = ZSWR5_TX_7; 732 break; 733 case CS8: 734 default: 735 tmp3 = ZSWR3_RX_8; 736 tmp5 = ZSWR5_TX_8; 737 break; 738 } 739 740 cs->cs_preg[3] = tmp3 | ZSWR3_RX_ENABLE; 741 cs->cs_preg[5] = tmp5 | ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS; 742 743 tmp4 = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB); 744 if ((cflag & PARODD) == 0) 745 tmp4 |= ZSWR4_EVENP; 746 if (cflag & PARENB) 747 tmp4 |= ZSWR4_PARENB; 748 cs->cs_preg[4] = tmp4; 749 750 /* 751 * Output hardware flow control on the chip is horrendous: 752 * if carrier detect drops, the receiver is disabled. 753 * Therefore, NEVER set the HFC bit, and instead use 754 * the status interrupts to detect CTS changes. 755 */ 756 if (cflag & CRTSCTS) { 757 zst->zst_rbhiwat = zstty_rbuf_hiwat; 758 cs->cs_preg[15] |= ZSWR15_CTS_IE; 759 } else { 760 zst->zst_rbhiwat = zstty_rbuf_size; /* impossible value */ 761 cs->cs_preg[15] &= ~ZSWR15_CTS_IE; 762 } 763 764 /* 765 * If nothing is being transmitted, set up new current values, 766 * else mark them as pending. 767 */ 768 if (cs->cs_heldchange == 0) { 769 if (zst->zst_tx_busy) { 770 zst->zst_heldtbc = zst->zst_tbc; 771 zst->zst_tbc = 0; 772 cs->cs_heldchange = 0xFF; /* XXX */ 773 } else { 774 zs_loadchannelregs(cs); 775 } 776 } 777 splx(s); 778 return (0); 779 } 780 781 /* 782 * Raise or lower modem control (DTR/RTS) signals. If a character is 783 * in transmission, the change is deferred. 784 */ 785 static void 786 zs_modem(zst, onoff) 787 struct zstty_softc *zst; 788 int onoff; 789 { 790 struct zs_chanstate *cs; 791 struct tty *tp; 792 int s, bis, and; 793 794 cs = zst->zst_cs; 795 tp = zst->zst_tty; 796 797 if (onoff) { 798 bis = ZSWR5_DTR | ZSWR5_RTS; 799 and = ~0; 800 } else { 801 bis = 0; 802 and = ~(ZSWR5_DTR | ZSWR5_RTS); 803 } 804 s = splzs(); 805 cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and; 806 if (cs->cs_heldchange == 0) { 807 if (zst->zst_tx_busy) { 808 zst->zst_heldtbc = zst->zst_tbc; 809 zst->zst_tbc = 0; 810 cs->cs_heldchange = (1<<5); 811 } else { 812 cs->cs_creg[5] = cs->cs_preg[5]; 813 zs_write_reg(cs, 5, cs->cs_creg[5]); 814 } 815 } 816 splx(s); 817 } 818 819 /* 820 * Try to block or unblock input using hardware flow-control. 821 * This is called by kern/tty.c if MDMBUF|CRTSCTS is set, and 822 * if this function returns non-zero, the TS_TBLOCK flag will 823 * be set or cleared according to the "stop" arg passed. 824 */ 825 int 826 zshwiflow(tp, stop) 827 struct tty *tp; 828 int stop; 829 { 830 register struct zstty_softc *zst; 831 int s; 832 833 zst = zstty_cd.cd_devs[minor(tp->t_dev)]; 834 835 s = splzs(); 836 if (stop) { 837 /* 838 * The tty layer is asking us to block input. 839 * If we already did it, just return TRUE. 840 */ 841 if (zst->zst_rx_blocked) 842 goto out; 843 zst->zst_rx_blocked = 1; 844 } else { 845 /* 846 * The tty layer is asking us to resume input. 847 * The input ring is always empty by now. 848 */ 849 zst->zst_rx_blocked = 0; 850 } 851 zs_hwiflow(zst, stop); 852 out: 853 splx(s); 854 return 1; 855 } 856 857 /* 858 * Internal version of zshwiflow 859 * called at splzs 860 */ 861 static void 862 zs_hwiflow(zst, stop) 863 register struct zstty_softc *zst; 864 int stop; 865 { 866 register struct zs_chanstate *cs; 867 register struct tty *tp; 868 register int bis, and; 869 870 cs = zst->zst_cs; 871 tp = zst->zst_tty; 872 873 if (stop) { 874 /* Block input (Lower RTS) */ 875 bis = 0; 876 and = ~ZSWR5_RTS; 877 } else { 878 /* Unblock input (Raise RTS) */ 879 bis = ZSWR5_RTS; 880 and = ~0; 881 } 882 883 cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and; 884 if (cs->cs_heldchange == 0) { 885 if (zst->zst_tx_busy) { 886 zst->zst_heldtbc = zst->zst_tbc; 887 zst->zst_tbc = 0; 888 cs->cs_heldchange = (1<<5); 889 } else { 890 cs->cs_creg[5] = cs->cs_preg[5]; 891 zs_write_reg(cs, 5, cs->cs_creg[5]); 892 } 893 } 894 } 895 896 897 /**************************************************************** 898 * Interface to the lower layer (zscc) 899 ****************************************************************/ 900 901 902 /* 903 * receiver ready interrupt. 904 * called at splzs 905 */ 906 static void 907 zstty_rxint(cs) 908 register struct zs_chanstate *cs; 909 { 910 register struct zstty_softc *zst; 911 register int cc, put, put_next, ringmask; 912 register u_char c, rr0, rr1; 913 register u_short ch_rr1; 914 915 zst = cs->cs_private; 916 put = zst->zst_rbput; 917 ringmask = zst->zst_ringmask; 918 919 nextchar: 920 921 /* 922 * First read the status, because reading the received char 923 * destroys the status of this char. 924 */ 925 rr1 = zs_read_reg(cs, 1); 926 c = zs_read_data(cs); 927 ch_rr1 = (c << 8) | rr1; 928 929 if (ch_rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) { 930 /* Clear the receive error. */ 931 zs_write_csr(cs, ZSWR0_RESET_ERRORS); 932 } 933 934 /* XXX: Check for the stop character? */ 935 936 zst->zst_rbuf[put] = ch_rr1; 937 put_next = (put + 1) & ringmask; 938 939 /* Would overrun if increment makes (put==get). */ 940 if (put_next == zst->zst_rbget) { 941 zst->zst_rx_overrun = 1; 942 } else { 943 /* OK, really increment. */ 944 put = put_next; 945 } 946 947 /* Keep reading until the FIFO is empty. */ 948 rr0 = zs_read_csr(cs); 949 if (rr0 & ZSRR0_RX_READY) 950 goto nextchar; 951 952 /* Done reading. */ 953 zst->zst_rbput = put; 954 955 /* 956 * If ring is getting too full, try to block input. 957 */ 958 cc = put - zst->zst_rbget; 959 if (cc < 0) 960 cc += zstty_rbuf_size; 961 if ((cc > zst->zst_rbhiwat) && (zst->zst_rx_blocked == 0)) { 962 zst->zst_rx_blocked = 1; 963 zs_hwiflow(zst, 1); 964 } 965 966 /* Ask for softint() call. */ 967 cs->cs_softreq = 1; 968 } 969 970 /* 971 * transmitter ready interrupt. (splzs) 972 */ 973 static void 974 zstty_txint(cs) 975 register struct zs_chanstate *cs; 976 { 977 register struct zstty_softc *zst; 978 register int count; 979 980 zst = cs->cs_private; 981 982 /* 983 * If we suspended output for a "held" change, 984 * then handle that now and resume. 985 * Do flow-control changes ASAP. 986 * When the only change is for flow control, 987 * avoid hitting other registers, because that 988 * often makes the stupid zs drop input... 989 */ 990 if (cs->cs_heldchange) { 991 if (cs->cs_heldchange == (1<<5)) { 992 /* Avoid whacking the chip... */ 993 cs->cs_creg[5] = cs->cs_preg[5]; 994 zs_write_reg(cs, 5, cs->cs_creg[5]); 995 } else 996 zs_loadchannelregs(cs); 997 cs->cs_heldchange = 0; 998 count = zst->zst_heldtbc; 999 } else 1000 count = zst->zst_tbc; 1001 1002 /* 1003 * If our transmit buffer still has data, 1004 * just send the next character. 1005 */ 1006 if (count > 0) { 1007 /* Send the next char. */ 1008 zst->zst_tbc = --count; 1009 zs_write_data(cs, *zst->zst_tba); 1010 zst->zst_tba++; 1011 return; 1012 } 1013 1014 zs_write_csr(cs, ZSWR0_RESET_TXINT); 1015 1016 /* Ask the softint routine for more output. */ 1017 zst->zst_tx_busy = 0; 1018 zst->zst_tx_done = 1; 1019 cs->cs_softreq = 1; 1020 } 1021 1022 /* 1023 * status change interrupt. (splzs) 1024 */ 1025 static void 1026 zstty_stint(cs) 1027 register struct zs_chanstate *cs; 1028 { 1029 register struct zstty_softc *zst; 1030 register struct tty *tp; 1031 register u_char rr0; 1032 1033 zst = cs->cs_private; 1034 tp = zst->zst_tty; 1035 1036 rr0 = zs_read_csr(cs); 1037 zs_write_csr(cs, ZSWR0_RESET_STATUS); 1038 1039 /* 1040 * Check here for console break, so that we can abort 1041 * even when interrupts are locking up the machine. 1042 */ 1043 if ((rr0 & ZSRR0_BREAK) && 1044 (zst->zst_hwflags & ZS_HWFLAG_CONSOLE)) 1045 { 1046 zs_abort(); 1047 return; 1048 } 1049 1050 /* 1051 * Need to handle CTS output flow control here. 1052 * Output remains stopped as long as either the 1053 * zst_tx_stopped or TS_TTSTOP flag is set. 1054 * Never restart here; the softint routine will 1055 * do that after things are ready to move. 1056 */ 1057 if (((rr0 & ZSRR0_CTS) == 0) && (tp->t_cflag & CRTSCTS)) { 1058 zst->zst_tbc = 0; 1059 zst->zst_heldtbc = 0; 1060 zst->zst_tx_stopped = 1; 1061 } 1062 1063 /* 1064 * We have to accumulate status line changes here. 1065 * Otherwise, if we get multiple status interrupts 1066 * before the softint runs, we could fail to notice 1067 * some status line changes in the softint routine. 1068 * Fix from Bill Studenmund, October 1996. 1069 */ 1070 cs->cs_rr0_delta |= (cs->cs_rr0 ^ rr0); 1071 1072 ttytstamp(tp, cs->cs_rr0 & ZSRR0_CTS, rr0 & ZSRR0_CTS, 1073 cs->cs_rr0 & ZSRR0_DCD, rr0 & ZSRR0_DCD); 1074 1075 cs->cs_rr0 = rr0; 1076 zst->zst_st_check = 1; 1077 1078 /* Ask for softint() call. */ 1079 cs->cs_softreq = 1; 1080 } 1081 1082 /* 1083 * Print out a ring or fifo overrun error message. 1084 */ 1085 static void 1086 zsoverrun(zst, ptime, what) 1087 struct zstty_softc *zst; 1088 long *ptime; 1089 char *what; 1090 { 1091 1092 if (*ptime != time_second) { 1093 *ptime = time_second; 1094 log(LOG_WARNING, "%s: %s overrun\n", 1095 zst->zst_dev.dv_xname, what); 1096 } 1097 } 1098 1099 /* 1100 * Software interrupt. Called at zssoft 1101 * 1102 * The main job to be done here is to empty the input ring 1103 * by passing its contents up to the tty layer. The ring is 1104 * always emptied during this operation, therefore the ring 1105 * must not be larger than the space after "high water" in 1106 * the tty layer, or the tty layer might drop our input. 1107 * 1108 * Note: an "input blockage" condition is assumed to exist if 1109 * EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set. 1110 */ 1111 static void 1112 zstty_softint(cs) 1113 struct zs_chanstate *cs; 1114 { 1115 register struct zstty_softc *zst; 1116 register struct linesw *line; 1117 register struct tty *tp; 1118 register int get, c, s; 1119 int ringmask, overrun; 1120 register u_short ring_data; 1121 register u_char rr0, delta; 1122 1123 zst = cs->cs_private; 1124 tp = zst->zst_tty; 1125 line = &linesw[tp->t_line]; 1126 ringmask = zst->zst_ringmask; 1127 overrun = 0; 1128 1129 /* 1130 * Raise to tty priority while servicing the ring. 1131 */ 1132 s = spltty(); 1133 1134 if (zst->zst_rx_overrun) { 1135 zst->zst_rx_overrun = 0; 1136 zsoverrun(zst, &zst->zst_rotime, "ring"); 1137 } 1138 1139 /* 1140 * Copy data from the receive ring into the tty layer. 1141 */ 1142 get = zst->zst_rbget; 1143 while (get != zst->zst_rbput) { 1144 ring_data = zst->zst_rbuf[get]; 1145 get = (get + 1) & ringmask; 1146 1147 if (ring_data & ZSRR1_DO) 1148 overrun++; 1149 /* low byte of ring_data is rr1 */ 1150 c = (ring_data >> 8) & 0xff; 1151 if (ring_data & ZSRR1_FE) 1152 c |= TTY_FE; 1153 if (ring_data & ZSRR1_PE) 1154 c |= TTY_PE; 1155 1156 line->l_rint(c, tp); 1157 } 1158 zst->zst_rbget = get; 1159 1160 /* 1161 * If the overrun flag is set now, it was set while 1162 * copying char/status pairs from the ring, which 1163 * means this was a hardware (fifo) overrun. 1164 */ 1165 if (overrun) { 1166 zsoverrun(zst, &zst->zst_fotime, "fifo"); 1167 } 1168 1169 /* 1170 * We have emptied the input ring. Maybe unblock input. 1171 * Note: an "input blockage" condition is assumed to exist 1172 * when EITHER zst_rx_blocked or the TS_TBLOCK flag is set, 1173 * so unblock here ONLY if TS_TBLOCK has not been set. 1174 */ 1175 if (zst->zst_rx_blocked && ((tp->t_state & TS_TBLOCK) == 0)) { 1176 (void) splzs(); 1177 zst->zst_rx_blocked = 0; 1178 zs_hwiflow(zst, 0); /* unblock input */ 1179 (void) spltty(); 1180 } 1181 1182 /* 1183 * Do any deferred work for status interrupts. 1184 * The rr0 was saved in the h/w interrupt to 1185 * avoid another splzs in here. 1186 */ 1187 if (zst->zst_st_check) { 1188 zst->zst_st_check = 0; 1189 1190 rr0 = cs->cs_rr0; 1191 delta = cs->cs_rr0_delta; 1192 cs->cs_rr0_delta = 0; 1193 if (delta & ZSRR0_DCD) { 1194 c = ((rr0 & ZSRR0_DCD) != 0); 1195 if (line->l_modem(tp, c) == 0) 1196 zs_modem(zst, c); 1197 } 1198 if ((delta & ZSRR0_CTS) && (tp->t_cflag & CRTSCTS)) { 1199 /* 1200 * Only do restart here. Stop is handled 1201 * at the h/w interrupt level. 1202 */ 1203 if (rr0 & ZSRR0_CTS) { 1204 zst->zst_tx_stopped = 0; 1205 tp->t_state &= ~TS_TTSTOP; 1206 (*line->l_start)(tp); 1207 } 1208 } 1209 } 1210 1211 if (zst->zst_tx_done) { 1212 zst->zst_tx_done = 0; 1213 tp->t_state &= ~TS_BUSY; 1214 if (tp->t_state & TS_FLUSH) 1215 tp->t_state &= ~TS_FLUSH; 1216 else 1217 ndflush(&tp->t_outq, zst->zst_tba - 1218 (caddr_t) tp->t_outq.c_cf); 1219 line->l_start(tp); 1220 } 1221 1222 splx(s); 1223 } 1224 1225 struct zsops zsops_tty = { 1226 zstty_rxint, /* receive char available */ 1227 zstty_stint, /* external/status */ 1228 zstty_txint, /* xmit buffer empty */ 1229 zstty_softint, /* process software interrupt */ 1230 }; 1231 1232