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