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