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