1 /* $NetBSD: com.c,v 1.129 1997/12/16 22:52:37 mycroft Exp $ */ 2 3 /*- 4 * Copyright (c) 1993, 1994, 1995, 1996, 1997 5 * Charles M. Hannum. All rights reserved. 6 * 7 * Interrupt processing and hardware flow control partly based on code from 8 * Onno van der Linden and Gordon Ross. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by Charles M. Hannum. 21 * 4. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /* 37 * Copyright (c) 1991 The Regents of the University of California. 38 * All rights reserved. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. All advertising materials mentioning features or use of this software 49 * must display the following acknowledgement: 50 * This product includes software developed by the University of 51 * California, Berkeley and its contributors. 52 * 4. Neither the name of the University nor the names of its contributors 53 * may be used to endorse or promote products derived from this software 54 * without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 * SUCH DAMAGE. 67 * 68 * @(#)com.c 7.5 (Berkeley) 5/16/91 69 */ 70 71 /* 72 * COM driver, uses National Semiconductor NS16450/NS16550AF UART 73 * Supports automatic hardware flow control on StarTech ST16C650A UART 74 */ 75 76 #include "rnd.h" 77 #if NRND > 0 && defined(RND_COM) 78 #include <sys/rnd.h> 79 #endif 80 81 #include <sys/param.h> 82 #include <sys/systm.h> 83 #include <sys/ioctl.h> 84 #include <sys/select.h> 85 #include <sys/tty.h> 86 #include <sys/proc.h> 87 #include <sys/user.h> 88 #include <sys/conf.h> 89 #include <sys/file.h> 90 #include <sys/uio.h> 91 #include <sys/kernel.h> 92 #include <sys/syslog.h> 93 #include <sys/types.h> 94 #include <sys/device.h> 95 #include <sys/malloc.h> 96 97 #include <machine/intr.h> 98 #include <machine/bus.h> 99 100 #include <dev/ic/comreg.h> 101 #include <dev/ic/comvar.h> 102 #include <dev/ic/ns16550reg.h> 103 #include <dev/ic/st16650reg.h> 104 #ifdef COM_HAYESP 105 #include <dev/ic/hayespreg.h> 106 #endif 107 #define com_lcr com_cfcr 108 #include <dev/cons.h> 109 110 #include "com.h" 111 112 #ifdef COM_HAYESP 113 int comprobeHAYESP __P((bus_space_handle_t hayespioh, struct com_softc *sc)); 114 #endif 115 116 #if defined(DDB) || defined(KGDB) 117 static void com_enable_debugport __P((struct com_softc *)); 118 #endif 119 void com_attach_subr __P((struct com_softc *sc)); 120 int comspeed __P((long, long)); 121 static u_char cflag2lcr __P((tcflag_t)); 122 int comparam __P((struct tty *, struct termios *)); 123 void comstart __P((struct tty *)); 124 void comstop __P((struct tty *, int)); 125 int comhwiflow __P((struct tty *, int)); 126 127 void com_loadchannelregs __P((struct com_softc *)); 128 void com_hwiflow __P((struct com_softc *)); 129 void com_break __P((struct com_softc *, int)); 130 void com_modem __P((struct com_softc *, int)); 131 void com_iflush __P((struct com_softc *)); 132 133 int com_common_getc __P((bus_space_tag_t, bus_space_handle_t)); 134 void com_common_putc __P((bus_space_tag_t, bus_space_handle_t, int)); 135 136 /* XXX: These belong elsewhere */ 137 cdev_decl(com); 138 bdev_decl(com); 139 140 int comcngetc __P((dev_t)); 141 void comcnputc __P((dev_t, int)); 142 void comcnpollc __P((dev_t, int)); 143 144 #define integrate static inline 145 #ifdef __GENERIC_SOFT_INTERRUPTS 146 void comsoft __P((void *)); 147 #else 148 #ifndef alpha 149 void comsoft __P((void)); 150 #else 151 void comsoft __P((void *)); 152 #endif 153 #endif 154 integrate void com_rxsoft __P((struct com_softc *, struct tty *)); 155 integrate void com_txsoft __P((struct com_softc *, struct tty *)); 156 integrate void com_stsoft __P((struct com_softc *, struct tty *)); 157 integrate void com_schedrx __P((struct com_softc *)); 158 void comdiag __P((void *)); 159 160 161 struct cfdriver com_cd = { 162 NULL, "com", DV_TTY 163 }; 164 165 /* 166 * Make this an option variable one can patch. 167 * But be warned: this must be a power of 2! 168 */ 169 u_int com_rbuf_size = COM_RING_SIZE; 170 171 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ 172 u_int com_rbuf_hiwat = (COM_RING_SIZE * 1) / 4; 173 u_int com_rbuf_lowat = (COM_RING_SIZE * 3) / 4; 174 175 static int comconsaddr; 176 static bus_space_tag_t comconstag; 177 static bus_space_handle_t comconsioh; 178 static int comconsattached; 179 static int comconsrate; 180 static tcflag_t comconscflag; 181 182 static u_char tiocm_xxx2mcr __P((int)); 183 184 #ifndef __GENERIC_SOFT_INTERRUPTS 185 #ifdef alpha 186 volatile int com_softintr_scheduled; 187 #endif 188 #endif 189 190 #ifdef KGDB 191 #include <sys/kgdb.h> 192 193 static int com_kgdb_addr; 194 static bus_space_tag_t com_kgdb_iot; 195 static bus_space_handle_t com_kgdb_ioh; 196 static int com_kgdb_attached; 197 198 int com_kgdb_getc __P((void *)); 199 void com_kgdb_putc __P((void *, int)); 200 #endif /* KGDB */ 201 202 #define COMUNIT(x) (minor(x)) 203 204 int 205 comspeed(speed, frequency) 206 long speed, frequency; 207 { 208 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */ 209 210 int x, err; 211 212 #if 0 213 if (speed == 0) 214 return (0); 215 #endif 216 if (speed <= 0) 217 return (-1); 218 x = divrnd(frequency / 16, speed); 219 if (x <= 0) 220 return (-1); 221 err = divrnd(((quad_t)frequency) * 1000 / 16, speed * x) - 1000; 222 if (err < 0) 223 err = -err; 224 if (err > COM_TOLERANCE) 225 return (-1); 226 return (x); 227 228 #undef divrnd(n, q) 229 } 230 231 #ifdef COM_DEBUG 232 int com_debug = 0; 233 234 void comstatus __P((struct com_softc *, char *)); 235 void 236 comstatus(sc, str) 237 struct com_softc *sc; 238 char *str; 239 { 240 struct tty *tp = sc->sc_tty; 241 242 printf("%s: %s %sclocal %sdcd %sts_carr_on %sdtr %stx_stopped\n", 243 sc->sc_dev.dv_xname, str, 244 ISSET(tp->t_cflag, CLOCAL) ? "+" : "-", 245 ISSET(sc->sc_msr, MSR_DCD) ? "+" : "-", 246 ISSET(tp->t_state, TS_CARR_ON) ? "+" : "-", 247 ISSET(sc->sc_mcr, MCR_DTR) ? "+" : "-", 248 sc->sc_tx_stopped ? "+" : "-"); 249 250 printf("%s: %s %scrtscts %scts %sts_ttstop %srts %xrx_flags\n", 251 sc->sc_dev.dv_xname, str, 252 ISSET(tp->t_cflag, CRTSCTS) ? "+" : "-", 253 ISSET(sc->sc_msr, MSR_CTS) ? "+" : "-", 254 ISSET(tp->t_state, TS_TTSTOP) ? "+" : "-", 255 ISSET(sc->sc_mcr, MCR_RTS) ? "+" : "-", 256 sc->sc_rx_flags); 257 } 258 #endif 259 260 int 261 comprobe1(iot, ioh, iobase) 262 bus_space_tag_t iot; 263 bus_space_handle_t ioh; 264 int iobase; 265 { 266 267 /* force access to id reg */ 268 bus_space_write_1(iot, ioh, com_lcr, 0); 269 bus_space_write_1(iot, ioh, com_iir, 0); 270 if (bus_space_read_1(iot, ioh, com_iir) & 0x38) 271 return (0); 272 273 return (1); 274 } 275 276 #ifdef COM_HAYESP 277 int 278 comprobeHAYESP(hayespioh, sc) 279 bus_space_handle_t hayespioh; 280 struct com_softc *sc; 281 { 282 char val, dips; 283 int combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; 284 bus_space_tag_t iot = sc->sc_iot; 285 286 /* 287 * Hayes ESP cards have two iobases. One is for compatibility with 288 * 16550 serial chips, and at the same ISA PC base addresses. The 289 * other is for ESP-specific enhanced features, and lies at a 290 * different addressing range entirely (0x140, 0x180, 0x280, or 0x300). 291 */ 292 293 /* Test for ESP signature */ 294 if ((bus_space_read_1(iot, hayespioh, 0) & 0xf3) == 0) 295 return (0); 296 297 /* 298 * ESP is present at ESP enhanced base address; unknown com port 299 */ 300 301 /* Get the dip-switch configurations */ 302 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS); 303 dips = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1); 304 305 /* Determine which com port this ESP card services: bits 0,1 of */ 306 /* dips is the port # (0-3); combaselist[val] is the com_iobase */ 307 if (sc->sc_iobase != combaselist[dips & 0x03]) 308 return (0); 309 310 printf(": ESP"); 311 312 /* Check ESP Self Test bits. */ 313 /* Check for ESP version 2.0: bits 4,5,6 == 010 */ 314 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETTEST); 315 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1); /* Clear reg1 */ 316 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS2); 317 if ((val & 0x70) < 0x20) { 318 printf("-old (%o)", val & 0x70); 319 /* we do not support the necessary features */ 320 return (0); 321 } 322 323 /* Check for ability to emulate 16550: bit 8 == 1 */ 324 if ((dips & 0x80) == 0) { 325 printf(" slave"); 326 /* XXX Does slave really mean no 16550 support?? */ 327 return (0); 328 } 329 330 /* 331 * If we made it this far, we are a full-featured ESP v2.0 (or 332 * better), at the correct com port address. 333 */ 334 335 SET(sc->sc_hwflags, COM_HW_HAYESP); 336 printf(", 1024 byte fifo\n"); 337 return (1); 338 } 339 #endif 340 341 #if defined(DDB) || defined(KGDB) 342 static void 343 com_enable_debugport(sc) 344 struct com_softc *sc; 345 { 346 int s; 347 348 /* Turn on line break interrupt, set carrier. */ 349 s = splserial(); 350 sc->sc_ier = IER_ERXRDY; 351 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier); 352 SET(sc->sc_mcr, MCR_DTR | MCR_RTS); 353 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr); 354 splx(s); 355 } 356 #endif 357 358 void 359 com_attach_subr(sc) 360 struct com_softc *sc; 361 { 362 int iobase = sc->sc_iobase; 363 bus_space_tag_t iot = sc->sc_iot; 364 bus_space_handle_t ioh = sc->sc_ioh; 365 struct tty *tp; 366 #ifdef COM16650 367 u_int8_t lcr; 368 #endif 369 #ifdef COM_HAYESP 370 int hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 }; 371 int *hayespp; 372 #endif 373 374 /* Disable interrupts before configuring the device. */ 375 sc->sc_ier = 0; 376 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier); 377 378 if (iot == comconstag && iobase == comconsaddr) { 379 comconsattached = 1; 380 381 /* Make sure the console is always "hardwired". */ 382 delay(1000); /* wait for output to finish */ 383 SET(sc->sc_hwflags, COM_HW_CONSOLE); 384 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); 385 } 386 387 #ifdef COM_HAYESP 388 /* Look for a Hayes ESP board. */ 389 for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) { 390 bus_space_handle_t hayespioh; 391 392 #define HAYESP_NPORTS 8 /* XXX XXX XXX ??? ??? ??? */ 393 if (bus_space_map(iot, *hayespp, HAYESP_NPORTS, 0, &hayespioh)) 394 continue; 395 if (comprobeHAYESP(hayespioh, sc)) { 396 sc->sc_hayespioh = hayespioh; 397 sc->sc_fifolen = 1024; 398 399 /* Set 16550 compatibility mode */ 400 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETMODE); 401 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, 402 HAYESP_MODE_FIFO|HAYESP_MODE_RTS| 403 HAYESP_MODE_SCALE); 404 405 /* Set RTS/CTS flow control */ 406 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETFLOWTYPE); 407 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, HAYESP_FLOW_RTS); 408 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, HAYESP_FLOW_CTS); 409 410 /* Set flow control levels */ 411 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETRXFLOW); 412 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, 413 HAYESP_HIBYTE(HAYESP_RXHIWMARK)); 414 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, 415 HAYESP_LOBYTE(HAYESP_RXHIWMARK)); 416 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, 417 HAYESP_HIBYTE(HAYESP_RXLOWMARK)); 418 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, 419 HAYESP_LOBYTE(HAYESP_RXLOWMARK)); 420 421 break; 422 } 423 bus_space_unmap(iot, hayespioh, HAYESP_NPORTS); 424 } 425 /* No ESP; look for other things. */ 426 if (*hayespp == 0) { 427 #endif 428 sc->sc_fifolen = 1; 429 /* look for a NS 16550AF UART with FIFOs */ 430 bus_space_write_1(iot, ioh, com_fifo, 431 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14); 432 delay(100); 433 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_FIFO_MASK) 434 == IIR_FIFO_MASK) 435 if (ISSET(bus_space_read_1(iot, ioh, com_fifo), FIFO_TRIGGER_14) 436 == FIFO_TRIGGER_14) { 437 SET(sc->sc_hwflags, COM_HW_FIFO); 438 439 #ifdef COM16650 440 /* 441 * IIR changes into the EFR if LCR is set to LCR_EERS 442 * on 16650s. We also know IIR != 0 at this point. 443 * Write 0 into the EFR, and read it. If the result 444 * is 0, we have a 16650. 445 * 446 * Older 16650s were broken; the test to detect them 447 * is taken from the Linux driver. Apparently 448 * setting DLAB enable gives access to the EFR on 449 * these chips. 450 */ 451 lcr = bus_space_read_1(iot, ioh, com_lcr); 452 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS); 453 bus_space_write_1(iot, ioh, com_efr, 0); 454 if (bus_space_read_1(iot, ioh, com_efr) == 0) { 455 bus_space_write_1(iot, ioh, com_lcr, 456 lcr | LCR_DLAB); 457 if (bus_space_read_1(iot, ioh, com_efr) == 0) { 458 CLR(sc->sc_hwflags, COM_HW_FIFO); 459 sc->sc_fifolen = 0; 460 } else { 461 SET(sc->sc_hwflags, COM_HW_FLOW); 462 sc->sc_fifolen = 32; 463 } 464 } else 465 #endif 466 sc->sc_fifolen = 16; 467 468 #ifdef COM16650 469 bus_space_write_1(iot, ioh, com_lcr, lcr); 470 if (sc->sc_fifolen == 0) 471 printf(": st16650, broken fifo\n"); 472 else if (sc->sc_fifolen == 32) 473 printf(": st16650a, working fifo\n"); 474 else 475 #endif 476 printf(": ns16550a, working fifo\n"); 477 } else 478 printf(": ns16550, broken fifo\n"); 479 else 480 printf(": ns8250 or ns16450, no fifo\n"); 481 bus_space_write_1(iot, ioh, com_fifo, 0); 482 #ifdef COM_HAYESP 483 } 484 #endif 485 486 tp = ttymalloc(); 487 tp->t_oproc = comstart; 488 tp->t_param = comparam; 489 tp->t_hwiflow = comhwiflow; 490 tty_attach(tp); 491 492 sc->sc_tty = tp; 493 sc->sc_rbuf = malloc(com_rbuf_size << 1, M_DEVBUF, M_WAITOK); 494 sc->sc_ebuf = sc->sc_rbuf + (com_rbuf_size << 1); 495 496 if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN)) 497 SET(sc->sc_mcr, MCR_IENABLE); 498 499 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 500 int maj; 501 502 /* locate the major number */ 503 for (maj = 0; maj < nchrdev; maj++) 504 if (cdevsw[maj].d_open == comopen) 505 break; 506 507 cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit); 508 #ifdef DDB 509 com_enable_debugport(sc); 510 #endif 511 printf("%s: console\n", sc->sc_dev.dv_xname); 512 } 513 514 #ifdef KGDB 515 /* 516 * Allow kgdb to "take over" this port. If this is 517 * the kgdb device, it has exclusive use. 518 */ 519 if (iot == com_kgdb_iot && iobase == com_kgdb_addr) { 520 com_kgdb_attached = 1; 521 522 SET(sc->sc_hwflags, COM_HW_KGDB); 523 com_enable_debugport(sc); 524 printf("%s: kgdb\n", sc->sc_dev.dv_xname); 525 } 526 #endif 527 528 #ifdef __GENERIC_SOFT_INTERRUPTS 529 sc->sc_si = softintr_establish(IPL_SOFTSERIAL, comsoft, sc); 530 #endif 531 532 #if NRND > 0 && defined(RND_COM) 533 rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname, 534 RND_TYPE_TTY); 535 #endif 536 } 537 538 int 539 comopen(dev, flag, mode, p) 540 dev_t dev; 541 int flag, mode; 542 struct proc *p; 543 { 544 int unit = COMUNIT(dev); 545 struct com_softc *sc; 546 struct tty *tp; 547 int s, s2; 548 int error = 0; 549 550 if (unit >= com_cd.cd_ndevs) 551 return (ENXIO); 552 sc = com_cd.cd_devs[unit]; 553 if (!sc) 554 return (ENXIO); 555 556 #ifdef KGDB 557 /* 558 * If this is the kgdb port, no other use is permitted. 559 */ 560 if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) 561 return (EBUSY); 562 #endif 563 564 tp = sc->sc_tty; 565 566 if (ISSET(tp->t_state, TS_ISOPEN) && 567 ISSET(tp->t_state, TS_XCLUDE) && 568 p->p_ucred->cr_uid != 0) 569 return (EBUSY); 570 571 s = spltty(); 572 573 /* We need to set this early for the benefit of comsoft(). */ 574 SET(tp->t_state, TS_WOPEN); 575 576 /* 577 * Do the following iff this is a first open. 578 */ 579 if (!ISSET(tp->t_state, TS_ISOPEN)) { 580 struct termios t; 581 582 tp->t_dev = dev; 583 584 s2 = splserial(); 585 586 /* Turn on interrupts. */ 587 sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC; 588 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier); 589 590 /* Fetch the current modem control status, needed later. */ 591 sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr); 592 593 splx(s2); 594 595 /* 596 * Initialize the termios status to the defaults. Add in the 597 * sticky bits from TIOCSFLAGS. 598 */ 599 t.c_ispeed = 0; 600 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 601 t.c_ospeed = comconsrate; 602 t.c_cflag = comconscflag; 603 } else { 604 t.c_ospeed = TTYDEF_SPEED; 605 t.c_cflag = TTYDEF_CFLAG; 606 } 607 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) 608 SET(t.c_cflag, CLOCAL); 609 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) 610 SET(t.c_cflag, CRTSCTS); 611 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) 612 SET(t.c_cflag, MDMBUF); 613 /* Make sure comparam() will do something. */ 614 tp->t_ospeed = 0; 615 (void) comparam(tp, &t); 616 tp->t_iflag = TTYDEF_IFLAG; 617 tp->t_oflag = TTYDEF_OFLAG; 618 tp->t_lflag = TTYDEF_LFLAG; 619 ttychars(tp); 620 ttsetwater(tp); 621 622 /* 623 * Turn on DTR. We must always do this, even if carrier is not 624 * present, because otherwise we'd have to use TIOCSDTR 625 * immediately after setting CLOCAL, which applications do not 626 * expect. We always assert DTR while the device is open 627 * unless explicitly requested to deassert it. 628 */ 629 com_modem(sc, 1); 630 631 s2 = splserial(); 632 633 /* Clear the input ring, and unblock. */ 634 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 635 sc->sc_rbavail = com_rbuf_size; 636 com_iflush(sc); 637 CLR(sc->sc_rx_flags, RX_ANY_BLOCK); 638 com_hwiflow(sc); 639 640 #ifdef COM_DEBUG 641 if (com_debug) 642 comstatus(sc, "comopen "); 643 #endif 644 645 splx(s2); 646 } 647 error = 0; 648 649 /* If we're doing a blocking open... */ 650 if (!ISSET(flag, O_NONBLOCK)) 651 /* ...then wait for carrier. */ 652 while (!ISSET(tp->t_state, TS_CARR_ON) && 653 !ISSET(tp->t_cflag, CLOCAL | MDMBUF)) { 654 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 655 ttopen, 0); 656 if (error) { 657 /* 658 * If the open was interrupted and nobody 659 * else has the device open, then hang up. 660 */ 661 if (!ISSET(tp->t_state, TS_ISOPEN)) { 662 com_modem(sc, 0); 663 CLR(tp->t_state, TS_WOPEN); 664 ttwakeup(tp); 665 } 666 break; 667 } 668 SET(tp->t_state, TS_WOPEN); 669 } 670 671 splx(s); 672 if (error == 0) 673 error = (*linesw[tp->t_line].l_open)(dev, tp); 674 return (error); 675 } 676 677 int 678 comclose(dev, flag, mode, p) 679 dev_t dev; 680 int flag, mode; 681 struct proc *p; 682 { 683 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)]; 684 struct tty *tp = sc->sc_tty; 685 int s; 686 687 /* XXX This is for cons.c. */ 688 if (!ISSET(tp->t_state, TS_ISOPEN)) 689 return (0); 690 691 (*linesw[tp->t_line].l_close)(tp, flag); 692 ttyclose(tp); 693 694 s = splserial(); 695 696 /* If we were asserting flow control, then deassert it. */ 697 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); 698 com_hwiflow(sc); 699 700 splx(s); 701 702 /* Clear any break condition set with TIOCSBRK. */ 703 com_break(sc, 0); 704 705 /* 706 * Hang up if necessary. Wait a bit, so the other side has time to 707 * notice even if we immediately open the port again. 708 */ 709 if (ISSET(tp->t_cflag, HUPCL)) { 710 com_modem(sc, 0); 711 (void) tsleep(sc, TTIPRI, ttclos, hz); 712 } 713 714 s = splserial(); 715 716 /* Turn off interrupts. */ 717 #ifdef DDB 718 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) 719 sc->sc_ier = IER_ERXRDY; /* interrupt on break */ 720 else 721 #endif 722 sc->sc_ier = 0; 723 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier); 724 725 splx(s); 726 727 return (0); 728 } 729 730 int 731 comread(dev, uio, flag) 732 dev_t dev; 733 struct uio *uio; 734 int flag; 735 { 736 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)]; 737 struct tty *tp = sc->sc_tty; 738 739 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 740 } 741 742 int 743 comwrite(dev, uio, flag) 744 dev_t dev; 745 struct uio *uio; 746 int flag; 747 { 748 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)]; 749 struct tty *tp = sc->sc_tty; 750 751 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 752 } 753 754 struct tty * 755 comtty(dev) 756 dev_t dev; 757 { 758 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)]; 759 struct tty *tp = sc->sc_tty; 760 761 return (tp); 762 } 763 764 static u_char 765 tiocm_xxx2mcr(data) 766 int data; 767 { 768 u_char m = 0; 769 770 if (ISSET(data, TIOCM_DTR)) 771 SET(m, MCR_DTR); 772 if (ISSET(data, TIOCM_RTS)) 773 SET(m, MCR_RTS); 774 return m; 775 } 776 777 int 778 comioctl(dev, cmd, data, flag, p) 779 dev_t dev; 780 u_long cmd; 781 caddr_t data; 782 int flag; 783 struct proc *p; 784 { 785 struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)]; 786 struct tty *tp = sc->sc_tty; 787 int error; 788 789 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 790 if (error >= 0) 791 return (error); 792 793 error = ttioctl(tp, cmd, data, flag, p); 794 if (error >= 0) 795 return (error); 796 797 switch (cmd) { 798 case TIOCSBRK: 799 com_break(sc, 1); 800 break; 801 802 case TIOCCBRK: 803 com_break(sc, 0); 804 break; 805 806 case TIOCSDTR: 807 com_modem(sc, 1); 808 break; 809 810 case TIOCCDTR: 811 com_modem(sc, 0); 812 break; 813 814 case TIOCGFLAGS: 815 *(int *)data = sc->sc_swflags; 816 break; 817 818 case TIOCSFLAGS: 819 error = suser(p->p_ucred, &p->p_acflag); 820 if (error) 821 return (error); 822 sc->sc_swflags = *(int *)data; 823 break; 824 825 case TIOCMSET: 826 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS); 827 /*FALLTHROUGH*/ 828 829 case TIOCMBIS: 830 SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data)); 831 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr); 832 break; 833 834 case TIOCMBIC: 835 CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data)); 836 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr); 837 break; 838 839 case TIOCMGET: { 840 u_char m; 841 int bits = 0; 842 843 m = sc->sc_mcr; 844 if (ISSET(m, MCR_DTR)) 845 SET(bits, TIOCM_DTR); 846 if (ISSET(m, MCR_RTS)) 847 SET(bits, TIOCM_RTS); 848 m = sc->sc_msr; 849 if (ISSET(m, MSR_DCD)) 850 SET(bits, TIOCM_CD); 851 if (ISSET(m, MSR_CTS)) 852 SET(bits, TIOCM_CTS); 853 if (ISSET(m, MSR_DSR)) 854 SET(bits, TIOCM_DSR); 855 if (ISSET(m, MSR_RI | MSR_TERI)) 856 SET(bits, TIOCM_RI); 857 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_ier)) 858 SET(bits, TIOCM_LE); 859 *(int *)data = bits; 860 break; 861 } 862 default: 863 return (ENOTTY); 864 } 865 866 #ifdef COM_DEBUG 867 if (com_debug) 868 comstatus(sc, "comioctl "); 869 #endif 870 871 return (0); 872 } 873 874 integrate void 875 com_schedrx(sc) 876 struct com_softc *sc; 877 { 878 879 sc->sc_rx_ready = 1; 880 881 /* Wake up the poller. */ 882 #ifdef __GENERIC_SOFT_INTERRUPTS 883 softintr_schedule(sc->sc_si); 884 #else 885 #ifndef alpha 886 setsoftserial(); 887 #else 888 if (!com_softintr_scheduled) { 889 com_softintr_scheduled = 1; 890 timeout(comsoft, NULL, 1); 891 } 892 #endif 893 #endif 894 } 895 896 void 897 com_break(sc, onoff) 898 struct com_softc *sc; 899 int onoff; 900 { 901 int s; 902 903 s = splserial(); 904 if (onoff) 905 SET(sc->sc_lcr, LCR_SBREAK); 906 else 907 CLR(sc->sc_lcr, LCR_SBREAK); 908 909 if (!sc->sc_heldchange) { 910 if (sc->sc_tx_busy) { 911 sc->sc_heldtbc = sc->sc_tbc; 912 sc->sc_tbc = 0; 913 sc->sc_heldchange = 1; 914 } else 915 com_loadchannelregs(sc); 916 } 917 splx(s); 918 } 919 920 void 921 com_modem(sc, onoff) 922 struct com_softc *sc; 923 int onoff; 924 { 925 int s; 926 927 s = splserial(); 928 if (onoff) 929 SET(sc->sc_mcr, sc->sc_mcr_dtr); 930 else 931 CLR(sc->sc_mcr, sc->sc_mcr_dtr); 932 933 if (!sc->sc_heldchange) { 934 if (sc->sc_tx_busy) { 935 sc->sc_heldtbc = sc->sc_tbc; 936 sc->sc_tbc = 0; 937 sc->sc_heldchange = 1; 938 } else 939 com_loadchannelregs(sc); 940 } 941 splx(s); 942 } 943 944 static u_char 945 cflag2lcr(cflag) 946 tcflag_t cflag; 947 { 948 u_char lcr = 0; 949 950 switch (ISSET(cflag, CSIZE)) { 951 case CS5: 952 SET(lcr, LCR_5BITS); 953 break; 954 case CS6: 955 SET(lcr, LCR_6BITS); 956 break; 957 case CS7: 958 SET(lcr, LCR_7BITS); 959 break; 960 case CS8: 961 SET(lcr, LCR_8BITS); 962 break; 963 } 964 if (ISSET(cflag, PARENB)) { 965 SET(lcr, LCR_PENAB); 966 if (!ISSET(cflag, PARODD)) 967 SET(lcr, LCR_PEVEN); 968 } 969 if (ISSET(cflag, CSTOPB)) 970 SET(lcr, LCR_STOPB); 971 972 return (lcr); 973 } 974 975 int 976 comparam(tp, t) 977 struct tty *tp; 978 struct termios *t; 979 { 980 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)]; 981 int ospeed = comspeed(t->c_ospeed, sc->sc_frequency); 982 u_char lcr; 983 int s; 984 985 /* Check requested parameters. */ 986 if (ospeed < 0) 987 return (EINVAL); 988 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) 989 return (EINVAL); 990 991 /* 992 * For the console, always force CLOCAL and !HUPCL, so that the port 993 * is always active. 994 */ 995 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || 996 ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 997 SET(t->c_cflag, CLOCAL); 998 CLR(t->c_cflag, HUPCL); 999 } 1000 1001 /* 1002 * If there were no changes, don't do anything. This avoids dropping 1003 * input and improves performance when all we did was frob things like 1004 * VMIN and VTIME. 1005 */ 1006 if (tp->t_ospeed == t->c_ospeed && 1007 tp->t_cflag == t->c_cflag) 1008 return (0); 1009 1010 lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag); 1011 1012 s = splserial(); 1013 1014 sc->sc_lcr = lcr; 1015 1016 /* 1017 * If we're not in a mode that assumes a connection is present, then 1018 * ignore carrier changes. 1019 */ 1020 if (ISSET(t->c_cflag, CLOCAL | MDMBUF)) 1021 sc->sc_msr_dcd = 0; 1022 else 1023 sc->sc_msr_dcd = MSR_DCD; 1024 /* 1025 * Set the flow control pins depending on the current flow control 1026 * mode. 1027 */ 1028 if (ISSET(t->c_cflag, CRTSCTS)) { 1029 sc->sc_mcr_dtr = MCR_DTR; 1030 sc->sc_mcr_rts = MCR_RTS; 1031 sc->sc_msr_cts = MSR_CTS; 1032 sc->sc_efr = EFR_AUTORTS | EFR_AUTOCTS; 1033 } else if (ISSET(t->c_cflag, MDMBUF)) { 1034 /* 1035 * For DTR/DCD flow control, make sure we don't toggle DTR for 1036 * carrier detection. 1037 */ 1038 sc->sc_mcr_dtr = 0; 1039 sc->sc_mcr_rts = MCR_DTR; 1040 sc->sc_msr_cts = MSR_DCD; 1041 sc->sc_efr = 0; 1042 } else { 1043 /* 1044 * If no flow control, then always set RTS. This will make 1045 * the other side happy if it mistakenly thinks we're doing 1046 * RTS/CTS flow control. 1047 */ 1048 sc->sc_mcr_dtr = MCR_DTR | MCR_RTS; 1049 sc->sc_mcr_rts = 0; 1050 sc->sc_msr_cts = 0; 1051 sc->sc_efr = 0; 1052 if (ISSET(sc->sc_mcr, MCR_DTR)) 1053 SET(sc->sc_mcr, MCR_RTS); 1054 else 1055 CLR(sc->sc_mcr, MCR_RTS); 1056 } 1057 sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd; 1058 1059 #if 0 1060 if (ospeed == 0) 1061 CLR(sc->sc_mcr, sc->sc_mcr_dtr); 1062 else 1063 SET(sc->sc_mcr, sc->sc_mcr_dtr); 1064 #endif 1065 1066 sc->sc_dlbl = ospeed; 1067 sc->sc_dlbh = ospeed >> 8; 1068 1069 /* 1070 * Set the FIFO threshold based on the receive speed. 1071 * 1072 * * If it's a low speed, it's probably a mouse or some other 1073 * interactive device, so set the threshold low. 1074 * * If it's a high speed, trim the trigger level down to prevent 1075 * overflows. 1076 * * Otherwise set it a bit higher. 1077 */ 1078 if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) 1079 sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8; 1080 else if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) 1081 sc->sc_fifo = FIFO_ENABLE | 1082 (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 : 1083 t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4); 1084 else 1085 sc->sc_fifo = 0; 1086 1087 /* And copy to tty. */ 1088 tp->t_ispeed = 0; 1089 tp->t_ospeed = t->c_ospeed; 1090 tp->t_cflag = t->c_cflag; 1091 1092 if (!sc->sc_heldchange) { 1093 if (sc->sc_tx_busy) { 1094 sc->sc_heldtbc = sc->sc_tbc; 1095 sc->sc_tbc = 0; 1096 sc->sc_heldchange = 1; 1097 } else 1098 com_loadchannelregs(sc); 1099 } 1100 1101 if (!ISSET(t->c_cflag, CHWFLOW)) { 1102 /* Disable the high water mark. */ 1103 sc->sc_r_hiwat = 0; 1104 sc->sc_r_lowat = 0; 1105 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { 1106 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1107 com_schedrx(sc); 1108 } 1109 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) { 1110 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED); 1111 com_hwiflow(sc); 1112 } 1113 } else { 1114 sc->sc_r_hiwat = com_rbuf_hiwat; 1115 sc->sc_r_lowat = com_rbuf_lowat; 1116 } 1117 1118 splx(s); 1119 1120 /* 1121 * Update the tty layer's idea of the carrier bit, in case we changed 1122 * CLOCAL or MDMBUF. We don't hang up here; we only do that by 1123 * explicit request. 1124 */ 1125 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(sc->sc_msr, MSR_DCD)); 1126 1127 #ifdef COM_DEBUG 1128 if (com_debug) 1129 comstatus(sc, "comparam "); 1130 #endif 1131 1132 if (!ISSET(t->c_cflag, CHWFLOW)) { 1133 if (sc->sc_tx_stopped) { 1134 sc->sc_tx_stopped = 0; 1135 comstart(tp); 1136 } 1137 } 1138 1139 return (0); 1140 } 1141 1142 void 1143 com_iflush(sc) 1144 struct com_softc *sc; 1145 { 1146 bus_space_tag_t iot = sc->sc_iot; 1147 bus_space_handle_t ioh = sc->sc_ioh; 1148 1149 /* flush any pending I/O */ 1150 while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)) 1151 (void) bus_space_read_1(iot, ioh, com_data); 1152 } 1153 1154 void 1155 com_loadchannelregs(sc) 1156 struct com_softc *sc; 1157 { 1158 bus_space_tag_t iot = sc->sc_iot; 1159 bus_space_handle_t ioh = sc->sc_ioh; 1160 1161 /* XXXXX necessary? */ 1162 com_iflush(sc); 1163 1164 bus_space_write_1(iot, ioh, com_ier, 0); 1165 1166 if (ISSET(sc->sc_hwflags, COM_HW_FLOW)) { 1167 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS); 1168 bus_space_write_1(iot, ioh, com_efr, sc->sc_efr); 1169 } 1170 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr | LCR_DLAB); 1171 bus_space_write_1(iot, ioh, com_dlbl, sc->sc_dlbl); 1172 bus_space_write_1(iot, ioh, com_dlbh, sc->sc_dlbh); 1173 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); 1174 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active = sc->sc_mcr); 1175 bus_space_write_1(iot, ioh, com_fifo, sc->sc_fifo); 1176 1177 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier); 1178 } 1179 1180 int 1181 comhwiflow(tp, block) 1182 struct tty *tp; 1183 int block; 1184 { 1185 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)]; 1186 int s; 1187 1188 if (sc->sc_mcr_rts == 0) 1189 return (0); 1190 1191 s = splserial(); 1192 if (block) { 1193 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1194 SET(sc->sc_rx_flags, RX_TTY_BLOCKED); 1195 com_hwiflow(sc); 1196 } 1197 } else { 1198 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { 1199 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1200 com_schedrx(sc); 1201 } 1202 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1203 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED); 1204 com_hwiflow(sc); 1205 } 1206 } 1207 splx(s); 1208 return (1); 1209 } 1210 1211 /* 1212 * (un)block input via hw flowcontrol 1213 */ 1214 void 1215 com_hwiflow(sc) 1216 struct com_softc *sc; 1217 { 1218 bus_space_tag_t iot = sc->sc_iot; 1219 bus_space_handle_t ioh = sc->sc_ioh; 1220 1221 if (sc->sc_mcr_rts == 0) 1222 return; 1223 1224 if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) { 1225 CLR(sc->sc_mcr, sc->sc_mcr_rts); 1226 CLR(sc->sc_mcr_active, sc->sc_mcr_rts); 1227 } else { 1228 SET(sc->sc_mcr, sc->sc_mcr_rts); 1229 SET(sc->sc_mcr_active, sc->sc_mcr_rts); 1230 } 1231 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active); 1232 } 1233 1234 1235 void 1236 comstart(tp) 1237 struct tty *tp; 1238 { 1239 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)]; 1240 bus_space_tag_t iot = sc->sc_iot; 1241 bus_space_handle_t ioh = sc->sc_ioh; 1242 int s; 1243 1244 s = spltty(); 1245 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 1246 goto out; 1247 if (sc->sc_tx_stopped) 1248 goto out; 1249 1250 if (tp->t_outq.c_cc <= tp->t_lowat) { 1251 if (ISSET(tp->t_state, TS_ASLEEP)) { 1252 CLR(tp->t_state, TS_ASLEEP); 1253 wakeup(&tp->t_outq); 1254 } 1255 selwakeup(&tp->t_wsel); 1256 if (tp->t_outq.c_cc == 0) 1257 goto out; 1258 } 1259 1260 /* Grab the first contiguous region of buffer space. */ 1261 { 1262 u_char *tba; 1263 int tbc; 1264 1265 tba = tp->t_outq.c_cf; 1266 tbc = ndqb(&tp->t_outq, 0); 1267 1268 (void)splserial(); 1269 1270 sc->sc_tba = tba; 1271 sc->sc_tbc = tbc; 1272 } 1273 1274 SET(tp->t_state, TS_BUSY); 1275 sc->sc_tx_busy = 1; 1276 1277 /* Enable transmit completion interrupts if necessary. */ 1278 if (!ISSET(sc->sc_ier, IER_ETXRDY)) { 1279 SET(sc->sc_ier, IER_ETXRDY); 1280 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier); 1281 } 1282 1283 /* Output the first chunk of the contiguous buffer. */ 1284 { 1285 int n; 1286 1287 n = sc->sc_tbc; 1288 if (n > sc->sc_fifolen) 1289 n = sc->sc_fifolen; 1290 bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n); 1291 sc->sc_tbc -= n; 1292 sc->sc_tba += n; 1293 } 1294 out: 1295 splx(s); 1296 return; 1297 } 1298 1299 /* 1300 * Stop output on a line. 1301 */ 1302 void 1303 comstop(tp, flag) 1304 struct tty *tp; 1305 int flag; 1306 { 1307 struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)]; 1308 int s; 1309 1310 s = splserial(); 1311 if (ISSET(tp->t_state, TS_BUSY)) { 1312 /* Stop transmitting at the next chunk. */ 1313 sc->sc_tbc = 0; 1314 sc->sc_heldtbc = 0; 1315 if (!ISSET(tp->t_state, TS_TTSTOP)) 1316 SET(tp->t_state, TS_FLUSH); 1317 } 1318 splx(s); 1319 } 1320 1321 void 1322 comdiag(arg) 1323 void *arg; 1324 { 1325 struct com_softc *sc = arg; 1326 int overflows, floods; 1327 int s; 1328 1329 s = splserial(); 1330 overflows = sc->sc_overflows; 1331 sc->sc_overflows = 0; 1332 floods = sc->sc_floods; 1333 sc->sc_floods = 0; 1334 sc->sc_errors = 0; 1335 splx(s); 1336 1337 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", 1338 sc->sc_dev.dv_xname, 1339 overflows, overflows == 1 ? "" : "s", 1340 floods, floods == 1 ? "" : "s"); 1341 } 1342 1343 integrate void 1344 com_rxsoft(sc, tp) 1345 struct com_softc *sc; 1346 struct tty *tp; 1347 { 1348 int (*rint) __P((int c, struct tty *tp)) = linesw[tp->t_line].l_rint; 1349 u_char *get, *end; 1350 u_int cc, scc; 1351 u_char lsr; 1352 int code; 1353 int s; 1354 1355 end = sc->sc_ebuf; 1356 get = sc->sc_rbget; 1357 scc = cc = com_rbuf_size - sc->sc_rbavail; 1358 1359 if (cc == com_rbuf_size) { 1360 sc->sc_floods++; 1361 if (sc->sc_errors++ == 0) 1362 timeout(comdiag, sc, 60 * hz); 1363 } 1364 1365 while (cc) { 1366 code = get[0]; 1367 lsr = get[1]; 1368 if (ISSET(lsr, LSR_OE | LSR_BI | LSR_FE | LSR_PE)) { 1369 if (ISSET(lsr, LSR_OE)) { 1370 sc->sc_overflows++; 1371 if (sc->sc_errors++ == 0) 1372 timeout(comdiag, sc, 60 * hz); 1373 } 1374 if (ISSET(lsr, LSR_BI | LSR_FE)) 1375 SET(code, TTY_FE); 1376 if (ISSET(lsr, LSR_PE)) 1377 SET(code, TTY_PE); 1378 } 1379 if ((*rint)(code, tp) == -1) { 1380 /* 1381 * The line discipline's buffer is out of space. 1382 */ 1383 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1384 /* 1385 * We're either not using flow control, or the 1386 * line discipline didn't tell us to block for 1387 * some reason. Either way, we have no way to 1388 * know when there's more space available, so 1389 * just drop the rest of the data. 1390 */ 1391 get += cc << 1; 1392 if (get >= end) 1393 get -= com_rbuf_size << 1; 1394 cc = 0; 1395 } else { 1396 /* 1397 * Don't schedule any more receive processing 1398 * until the line discipline tells us there's 1399 * space available (through comhwiflow()). 1400 * Leave the rest of the data in the input 1401 * buffer. 1402 */ 1403 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1404 } 1405 break; 1406 } 1407 get += 2; 1408 if (get >= end) 1409 get = sc->sc_rbuf; 1410 cc--; 1411 } 1412 1413 if (cc != scc) { 1414 sc->sc_rbget = get; 1415 s = splserial(); 1416 cc = sc->sc_rbavail += scc - cc; 1417 /* Buffers should be ok again, release possible block. */ 1418 if (cc >= sc->sc_r_lowat) { 1419 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1420 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1421 SET(sc->sc_ier, IER_ERXRDY); 1422 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier); 1423 } 1424 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { 1425 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1426 com_hwiflow(sc); 1427 } 1428 } 1429 splx(s); 1430 } 1431 } 1432 1433 integrate void 1434 com_txsoft(sc, tp) 1435 struct com_softc *sc; 1436 struct tty *tp; 1437 { 1438 1439 CLR(tp->t_state, TS_BUSY); 1440 if (ISSET(tp->t_state, TS_FLUSH)) 1441 CLR(tp->t_state, TS_FLUSH); 1442 else 1443 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf)); 1444 (*linesw[tp->t_line].l_start)(tp); 1445 } 1446 1447 integrate void 1448 com_stsoft(sc, tp) 1449 struct com_softc *sc; 1450 struct tty *tp; 1451 { 1452 u_char msr, delta; 1453 int s; 1454 1455 s = splserial(); 1456 msr = sc->sc_msr; 1457 delta = sc->sc_msr_delta; 1458 sc->sc_msr_delta = 0; 1459 splx(s); 1460 1461 if (ISSET(delta, sc->sc_msr_dcd)) { 1462 /* 1463 * Inform the tty layer that carrier detect changed. 1464 */ 1465 (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)); 1466 } 1467 1468 if (ISSET(delta, sc->sc_msr_cts)) { 1469 /* Block or unblock output according to flow control. */ 1470 if (ISSET(msr, sc->sc_msr_cts)) { 1471 sc->sc_tx_stopped = 0; 1472 (*linesw[tp->t_line].l_start)(tp); 1473 } else { 1474 sc->sc_tx_stopped = 1; 1475 } 1476 } 1477 1478 #ifdef COM_DEBUG 1479 if (com_debug) 1480 comstatus(sc, "com_stsoft"); 1481 #endif 1482 } 1483 1484 #ifdef __GENERIC_SOFT_INTERRUPTS 1485 void 1486 comsoft(arg) 1487 void *arg; 1488 { 1489 struct com_softc *sc = arg; 1490 struct tty *tp; 1491 1492 { 1493 #else 1494 void 1495 #ifndef alpha 1496 comsoft() 1497 #else 1498 comsoft(arg) 1499 void *arg; 1500 #endif 1501 { 1502 struct com_softc *sc; 1503 struct tty *tp; 1504 int unit; 1505 #ifdef alpha 1506 int s; 1507 1508 s = splsoftserial(); 1509 com_softintr_scheduled = 0; 1510 #endif 1511 1512 for (unit = 0; unit < com_cd.cd_ndevs; unit++) { 1513 sc = com_cd.cd_devs[unit]; 1514 if (sc == NULL) 1515 continue; 1516 1517 tp = sc->sc_tty; 1518 if (tp == NULL || !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN)) 1519 continue; 1520 #endif 1521 tp = sc->sc_tty; 1522 1523 if (sc->sc_rx_ready) { 1524 sc->sc_rx_ready = 0; 1525 com_rxsoft(sc, tp); 1526 } 1527 1528 if (sc->sc_st_check) { 1529 sc->sc_st_check = 0; 1530 com_stsoft(sc, tp); 1531 } 1532 1533 if (sc->sc_tx_done) { 1534 sc->sc_tx_done = 0; 1535 com_txsoft(sc, tp); 1536 } 1537 } 1538 1539 #ifndef __GENERIC_SOFT_INTERRUPTS 1540 #ifdef alpha 1541 splx(s); 1542 #endif 1543 #endif 1544 } 1545 1546 int 1547 comintr(arg) 1548 void *arg; 1549 { 1550 struct com_softc *sc = arg; 1551 bus_space_tag_t iot = sc->sc_iot; 1552 bus_space_handle_t ioh = sc->sc_ioh; 1553 u_char *put, *end; 1554 u_int cc; 1555 u_char lsr, iir; 1556 1557 iir = bus_space_read_1(iot, ioh, com_iir); 1558 if (ISSET(iir, IIR_NOPEND)) 1559 return (0); 1560 1561 end = sc->sc_ebuf; 1562 put = sc->sc_rbput; 1563 cc = sc->sc_rbavail; 1564 1565 do { 1566 u_char msr, delta; 1567 1568 lsr = bus_space_read_1(iot, ioh, com_lsr); 1569 #if defined(DDB) || defined(KGDB) 1570 if (ISSET(lsr, LSR_BI)) { 1571 #ifdef DDB 1572 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 1573 Debugger(); 1574 continue; 1575 } 1576 #endif 1577 #ifdef KGDB 1578 if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) { 1579 kgdb_connect(1); 1580 continue; 1581 } 1582 #endif 1583 } 1584 #endif /* DDB || KGDB */ 1585 1586 if (ISSET(lsr, LSR_RCV_MASK) && 1587 !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1588 while (cc > 0) { 1589 put[0] = bus_space_read_1(iot, ioh, com_data); 1590 put[1] = lsr; 1591 put += 2; 1592 if (put >= end) 1593 put = sc->sc_rbuf; 1594 cc--; 1595 1596 lsr = bus_space_read_1(iot, ioh, com_lsr); 1597 if (!ISSET(lsr, LSR_RCV_MASK)) 1598 break; 1599 } 1600 1601 /* 1602 * Current string of incoming characters ended because 1603 * no more data was available or we ran out of space. 1604 * Schedule a receive event if any data was received. 1605 * If we're out of space, turn off receive interrupts. 1606 */ 1607 sc->sc_rbput = put; 1608 sc->sc_rbavail = cc; 1609 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) 1610 sc->sc_rx_ready = 1; 1611 1612 /* 1613 * See if we are in danger of overflowing a buffer. If 1614 * so, use hardware flow control to ease the pressure. 1615 */ 1616 if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) && 1617 cc < sc->sc_r_hiwat) { 1618 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1619 com_hwiflow(sc); 1620 } 1621 1622 /* 1623 * If we're out of space, disable receive interrupts 1624 * until the queue has drained a bit. 1625 */ 1626 if (!cc) { 1627 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1628 CLR(sc->sc_ier, IER_ERXRDY); 1629 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier); 1630 } 1631 } else { 1632 if ((iir & IIR_IMASK) == IIR_RXRDY) { 1633 bus_space_write_1(iot, ioh, com_ier, 0); 1634 delay(10); 1635 bus_space_write_1(iot, ioh, com_ier,sc->sc_ier); 1636 iir = IIR_NOPEND; 1637 continue; 1638 } 1639 } 1640 1641 msr = bus_space_read_1(iot, ioh, com_msr); 1642 delta = msr ^ sc->sc_msr; 1643 sc->sc_msr = msr; 1644 if (ISSET(delta, sc->sc_msr_mask)) { 1645 SET(sc->sc_msr_delta, delta); 1646 1647 /* 1648 * Stop output immediately if we lose the output 1649 * flow control signal or carrier detect. 1650 */ 1651 if (ISSET(~msr, sc->sc_msr_mask)) { 1652 sc->sc_tbc = 0; 1653 sc->sc_heldtbc = 0; 1654 #ifdef COM_DEBUG 1655 if (com_debug) 1656 comstatus(sc, "comintr "); 1657 #endif 1658 } 1659 1660 sc->sc_st_check = 1; 1661 } 1662 } while (!ISSET((iir = bus_space_read_1(iot, ioh, com_iir)), IIR_NOPEND)); 1663 1664 /* 1665 * Done handling any receive interrupts. See if data can be 1666 * transmitted as well. Schedule tx done event if no data left 1667 * and tty was marked busy. 1668 */ 1669 if (ISSET(lsr, LSR_TXRDY)) { 1670 /* 1671 * If we've delayed a parameter change, do it now, and restart 1672 * output. 1673 */ 1674 if (sc->sc_heldchange) { 1675 com_loadchannelregs(sc); 1676 sc->sc_heldchange = 0; 1677 sc->sc_tbc = sc->sc_heldtbc; 1678 sc->sc_heldtbc = 0; 1679 } 1680 1681 /* Output the next chunk of the contiguous buffer, if any. */ 1682 if (sc->sc_tbc > 0) { 1683 int n; 1684 1685 n = sc->sc_tbc; 1686 if (n > sc->sc_fifolen) 1687 n = sc->sc_fifolen; 1688 bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n); 1689 sc->sc_tbc -= n; 1690 sc->sc_tba += n; 1691 } else { 1692 /* Disable transmit completion interrupts if necessary. */ 1693 if (ISSET(sc->sc_ier, IER_ETXRDY)) { 1694 CLR(sc->sc_ier, IER_ETXRDY); 1695 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier); 1696 } 1697 if (sc->sc_tx_busy) { 1698 sc->sc_tx_busy = 0; 1699 sc->sc_tx_done = 1; 1700 } 1701 } 1702 } 1703 1704 /* Wake up the poller. */ 1705 #ifdef __GENERIC_SOFT_INTERRUPTS 1706 softintr_schedule(sc->sc_si); 1707 #else 1708 #ifndef alpha 1709 setsoftserial(); 1710 #else 1711 if (!com_softintr_scheduled) { 1712 com_softintr_scheduled = 1; 1713 timeout(comsoft, NULL, 1); 1714 } 1715 #endif 1716 #endif 1717 1718 #if NRND > 0 && defined(RND_COM) 1719 rnd_add_uint32(&sc->rnd_source, iir | lsr); 1720 #endif 1721 1722 return (1); 1723 } 1724 1725 /* 1726 * The following functions are polled getc and putc routines, shared 1727 * by the console and kgdb glue. 1728 */ 1729 1730 int 1731 com_common_getc(iot, ioh) 1732 bus_space_tag_t iot; 1733 bus_space_handle_t ioh; 1734 { 1735 int s = splserial(); 1736 u_char stat, c; 1737 1738 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)) 1739 ; 1740 c = bus_space_read_1(iot, ioh, com_data); 1741 stat = bus_space_read_1(iot, ioh, com_iir); 1742 splx(s); 1743 return (c); 1744 } 1745 1746 void 1747 com_common_putc(iot, ioh, c) 1748 bus_space_tag_t iot; 1749 bus_space_handle_t ioh; 1750 int c; 1751 { 1752 int s = splserial(); 1753 u_char stat; 1754 int timo; 1755 1756 /* wait for any pending transmission to finish */ 1757 timo = 50000; 1758 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) 1759 && --timo) 1760 ; 1761 bus_space_write_1(iot, ioh, com_data, c); 1762 /* wait for this transmission to complete */ 1763 timo = 1500000; 1764 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) 1765 && --timo) 1766 ; 1767 /* clear any interrupts generated by this transmission */ 1768 stat = bus_space_read_1(iot, ioh, com_iir); 1769 splx(s); 1770 } 1771 1772 /* 1773 * Initialize UART to known state. 1774 */ 1775 int 1776 cominit(iot, iobase, rate, frequency, cflag, iohp) 1777 bus_space_tag_t iot; 1778 int iobase; 1779 int rate, frequency; 1780 tcflag_t cflag; 1781 bus_space_handle_t *iohp; 1782 { 1783 bus_space_handle_t ioh; 1784 1785 if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh)) 1786 return (ENOMEM); /* ??? */ 1787 1788 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS); 1789 bus_space_write_1(iot, ioh, com_efr, 0); 1790 bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB); 1791 rate = comspeed(rate, frequency); 1792 bus_space_write_1(iot, ioh, com_dlbl, rate); 1793 bus_space_write_1(iot, ioh, com_dlbh, rate >> 8); 1794 bus_space_write_1(iot, ioh, com_lcr, cflag2lcr(cflag)); 1795 bus_space_write_1(iot, ioh, com_mcr, 0); 1796 bus_space_write_1(iot, ioh, com_fifo, 1797 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1); 1798 bus_space_write_1(iot, ioh, com_ier, 0); 1799 1800 *iohp = ioh; 1801 return (0); 1802 } 1803 1804 /* 1805 * Following are all routines needed for COM to act as console 1806 */ 1807 1808 int 1809 comcnattach(iot, iobase, rate, frequency, cflag) 1810 bus_space_tag_t iot; 1811 int iobase; 1812 int rate, frequency; 1813 tcflag_t cflag; 1814 { 1815 int res; 1816 static struct consdev comcons = { 1817 NULL, NULL, comcngetc, comcnputc, comcnpollc, NODEV, CN_NORMAL 1818 }; 1819 1820 res = cominit(iot, iobase, rate, frequency, cflag, &comconsioh); 1821 if (res) 1822 return (res); 1823 1824 cn_tab = &comcons; 1825 1826 comconstag = iot; 1827 comconsaddr = iobase; 1828 comconsrate = rate; 1829 comconscflag = cflag; 1830 1831 return (0); 1832 } 1833 1834 int 1835 comcngetc(dev) 1836 dev_t dev; 1837 { 1838 1839 return (com_common_getc(comconstag, comconsioh)); 1840 } 1841 1842 /* 1843 * Console kernel output character routine. 1844 */ 1845 void 1846 comcnputc(dev, c) 1847 dev_t dev; 1848 int c; 1849 { 1850 1851 com_common_putc(comconstag, comconsioh, c); 1852 } 1853 1854 void 1855 comcnpollc(dev, on) 1856 dev_t dev; 1857 int on; 1858 { 1859 1860 } 1861 1862 #ifdef KGDB 1863 int 1864 com_kgdb_attach(iot, iobase, rate, frequency, cflag) 1865 bus_space_tag_t iot; 1866 int iobase; 1867 int rate, frequency; 1868 tcflag_t cflag; 1869 { 1870 int res; 1871 1872 if (iot == comconstag && iobase == comconsaddr) 1873 return (EBUSY); /* cannot share with console */ 1874 1875 res = cominit(iot, iobase, rate, frequency, cflag, &com_kgdb_ioh); 1876 if (res) 1877 return (res); 1878 1879 kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL); 1880 kgdb_dev = 123; /* unneeded, only to satisfy some tests */ 1881 1882 com_kgdb_iot = iot; 1883 com_kgdb_addr = iobase; 1884 1885 return (0); 1886 } 1887 1888 /* ARGSUSED */ 1889 int 1890 com_kgdb_getc(arg) 1891 void *arg; 1892 { 1893 1894 return (com_common_getc(com_kgdb_iot, com_kgdb_ioh)); 1895 } 1896 1897 /* ARGSUSED */ 1898 void 1899 com_kgdb_putc(arg, c) 1900 void *arg; 1901 int c; 1902 { 1903 1904 return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c)); 1905 } 1906 #endif /* KGDB */ 1907 1908 /* helper function to identify the com ports used by 1909 console or KGDB (and not yet autoconf attached) */ 1910 int 1911 com_is_console(iot, iobase, ioh) 1912 bus_space_tag_t iot; 1913 int iobase; 1914 bus_space_handle_t *ioh; 1915 { 1916 bus_space_handle_t help; 1917 1918 if (!comconsattached && 1919 iot == comconstag && iobase == comconsaddr) 1920 help = comconsioh; 1921 #ifdef KGDB 1922 else if (!com_kgdb_attached && 1923 iot == com_kgdb_iot && iobase == com_kgdb_addr) 1924 help = com_kgdb_ioh; 1925 #endif 1926 else 1927 return (0); 1928 1929 if (ioh) 1930 *ioh = help; 1931 return (1); 1932 } 1933