1 /* $OpenBSD: com.c,v 1.91 2003/07/15 03:15:58 jason Exp $ */ 2 /* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */ 3 4 /* 5 * Copyright (c) 1997 - 1999, Jason Downs. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS 17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 /*- 29 * Copyright (c) 1993, 1994, 1995, 1996 30 * Charles M. Hannum. All rights reserved. 31 * Copyright (c) 1991 The Regents of the University of California. 32 * All rights reserved. 33 * 34 * Redistribution and use in source and binary forms, with or without 35 * modification, are permitted provided that the following conditions 36 * are met: 37 * 1. Redistributions of source code must retain the above copyright 38 * notice, this list of conditions and the following disclaimer. 39 * 2. Redistributions in binary form must reproduce the above copyright 40 * notice, this list of conditions and the following disclaimer in the 41 * documentation and/or other materials provided with the distribution. 42 * 3. Neither the name of the University nor the names of its contributors 43 * may be used to endorse or promote products derived from this software 44 * without specific prior written permission. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 * 58 * @(#)com.c 7.5 (Berkeley) 5/16/91 59 */ 60 61 /* 62 * COM driver, based on HP dca driver 63 * uses National Semiconductor NS16450/NS16550AF UART 64 */ 65 #include <sys/param.h> 66 #include <sys/systm.h> 67 #include <sys/ioctl.h> 68 #include <sys/select.h> 69 #include <sys/tty.h> 70 #include <sys/proc.h> 71 #include <sys/user.h> 72 #include <sys/conf.h> 73 #include <sys/file.h> 74 #include <sys/uio.h> 75 #include <sys/kernel.h> 76 #include <sys/syslog.h> 77 #include <sys/types.h> 78 #include <sys/device.h> 79 #include <sys/vnode.h> 80 #ifdef DDB 81 #include <ddb/db_var.h> 82 #endif 83 84 #include <machine/bus.h> 85 #include <machine/intr.h> 86 87 #include <dev/cons.h> 88 89 #include <dev/ic/comreg.h> 90 #include <dev/ic/comvar.h> 91 #include <dev/ic/ns16550reg.h> 92 #define com_lcr com_cfcr 93 94 #include "com.h" 95 96 /* XXX: These belong elsewhere */ 97 cdev_decl(com); 98 99 static u_char tiocm_xxx2mcr(int); 100 101 void compwroff(struct com_softc *); 102 void com_enable_debugport(struct com_softc *); 103 104 struct cfdriver com_cd = { 105 NULL, "com", DV_TTY 106 }; 107 108 int comdefaultrate = TTYDEF_SPEED; 109 int comconsinit; 110 int comconsaddr; 111 int comconsattached; 112 bus_space_tag_t comconsiot; 113 bus_space_handle_t comconsioh; 114 tcflag_t comconscflag = TTYDEF_CFLAG; 115 116 int commajor; 117 118 #ifdef KGDB 119 #include <sys/kgdb.h> 120 121 int com_kgdb_addr; 122 bus_space_tag_t com_kgdb_iot; 123 bus_space_handle_t com_kgdb_ioh; 124 125 int com_kgdb_getc(void *); 126 void com_kgdb_putc(void *, int); 127 #endif /* KGDB */ 128 129 #define DEVUNIT(x) (minor(x) & 0x7f) 130 #define DEVCUA(x) (minor(x) & 0x80) 131 132 int 133 comspeed(freq, speed) 134 long freq; 135 long speed; 136 { 137 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */ 138 139 int x, err; 140 141 if (speed == 0) 142 return 0; 143 if (speed < 0) 144 return -1; 145 x = divrnd((freq / 16), speed); 146 if (x <= 0) 147 return -1; 148 err = divrnd((freq / 16) * 1000, speed * x) - 1000; 149 if (err < 0) 150 err = -err; 151 if (err > COM_TOLERANCE) 152 return -1; 153 return x; 154 155 #undef divrnd 156 } 157 158 int 159 comprobe1(iot, ioh) 160 bus_space_tag_t iot; 161 bus_space_handle_t ioh; 162 { 163 int i, k; 164 165 /* force access to id reg */ 166 bus_space_write_1(iot, ioh, com_lcr, 0); 167 bus_space_write_1(iot, ioh, com_iir, 0); 168 for (i = 0; i < 32; i++) { 169 k = bus_space_read_1(iot, ioh, com_iir); 170 if (k & 0x38) { 171 bus_space_read_1(iot, ioh, com_data); /* cleanup */ 172 } else 173 break; 174 } 175 if (i >= 32) 176 return 0; 177 178 return 1; 179 } 180 181 void 182 com_attach_subr(sc) 183 struct com_softc *sc; 184 { 185 bus_space_tag_t iot = sc->sc_iot; 186 bus_space_handle_t ioh = sc->sc_ioh; 187 u_int8_t lcr; 188 189 sc->sc_ier = 0; 190 /* disable interrupts */ 191 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier); 192 193 if (sc->sc_iobase == comconsaddr) { 194 comconsattached = 1; 195 196 /* 197 * Need to reset baud rate, etc. of next print so reset 198 * comconsinit. Also make sure console is always "hardwired". 199 */ 200 delay(10000); /* wait for output to finish */ 201 SET(sc->sc_hwflags, COM_HW_CONSOLE); 202 SET(sc->sc_swflags, COM_SW_SOFTCAR); 203 } 204 205 /* 206 * Probe for all known forms of UART. 207 */ 208 lcr = bus_space_read_1(iot, ioh, com_lcr); 209 bus_space_write_1(iot, ioh, com_lcr, 0xbf); 210 bus_space_write_1(iot, ioh, com_efr, 0); 211 bus_space_write_1(iot, ioh, com_lcr, 0); 212 213 bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE); 214 delay(100); 215 216 switch(bus_space_read_1(iot, ioh, com_iir) >> 6) { 217 case 0: 218 sc->sc_uarttype = COM_UART_16450; 219 break; 220 case 2: 221 sc->sc_uarttype = COM_UART_16550; 222 break; 223 case 3: 224 sc->sc_uarttype = COM_UART_16550A; 225 break; 226 default: 227 sc->sc_uarttype = COM_UART_UNKNOWN; 228 break; 229 } 230 231 if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */ 232 bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB); 233 if (bus_space_read_1(iot, ioh, com_efr) == 0) { 234 sc->sc_uarttype = COM_UART_ST16650; 235 } else { 236 bus_space_write_1(iot, ioh, com_lcr, 0xbf); 237 if (bus_space_read_1(iot, ioh, com_efr) == 0) 238 sc->sc_uarttype = COM_UART_ST16650V2; 239 } 240 } 241 242 if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for TI16750s */ 243 bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB); 244 bus_space_write_1(iot, ioh, com_fifo, 245 FIFO_ENABLE | FIFO_ENABLE_64BYTE); 246 if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 7) { 247 #if 0 248 bus_space_write_1(iot, ioh, com_lcr, 0); 249 if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 6) 250 #endif 251 sc->sc_uarttype = COM_UART_TI16750; 252 } 253 bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE); 254 } 255 bus_space_write_1(iot, ioh, com_lcr, lcr); 256 if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */ 257 u_int8_t scr0, scr1, scr2; 258 259 scr0 = bus_space_read_1(iot, ioh, com_scratch); 260 bus_space_write_1(iot, ioh, com_scratch, 0xa5); 261 scr1 = bus_space_read_1(iot, ioh, com_scratch); 262 bus_space_write_1(iot, ioh, com_scratch, 0x5a); 263 scr2 = bus_space_read_1(iot, ioh, com_scratch); 264 bus_space_write_1(iot, ioh, com_scratch, scr0); 265 266 if ((scr1 != 0xa5) || (scr2 != 0x5a)) 267 sc->sc_uarttype = COM_UART_8250; 268 } 269 270 /* 271 * Print UART type and initialize ourself. 272 */ 273 sc->sc_fifolen = 1; /* default */ 274 switch (sc->sc_uarttype) { 275 case COM_UART_UNKNOWN: 276 printf(": unknown uart\n"); 277 break; 278 case COM_UART_8250: 279 printf(": ns8250, no fifo\n"); 280 break; 281 case COM_UART_16450: 282 printf(": ns16450, no fifo\n"); 283 break; 284 case COM_UART_16550: 285 printf(": ns16550, no working fifo\n"); 286 break; 287 case COM_UART_16550A: 288 printf(": ns16550a, 16 byte fifo\n"); 289 SET(sc->sc_hwflags, COM_HW_FIFO); 290 sc->sc_fifolen = 16; 291 break; 292 case COM_UART_ST16650: 293 printf(": st16650, no working fifo\n"); 294 break; 295 case COM_UART_ST16650V2: 296 printf(": st16650, 32 byte fifo\n"); 297 SET(sc->sc_hwflags, COM_HW_FIFO); 298 sc->sc_fifolen = 32; 299 break; 300 case COM_UART_TI16750: 301 printf(": ti16750, 64 byte fifo\n"); 302 SET(sc->sc_hwflags, COM_HW_FIFO); 303 sc->sc_fifolen = 64; 304 break; 305 default: 306 panic("comattach: bad fifo type"); 307 } 308 309 /* clear and disable fifo */ 310 bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST); 311 (void)bus_space_read_1(iot, ioh, com_data); 312 bus_space_write_1(iot, ioh, com_fifo, 0); 313 314 sc->sc_mcr = 0; 315 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 316 317 #ifdef KGDB 318 /* 319 * Allow kgdb to "take over" this port. If this is 320 * the kgdb device, it has exclusive use. 321 */ 322 323 if (iot == com_kgdb_iot && sc->sc_iobase == com_kgdb_addr && 324 !ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 325 printf("%s: kgdb\n", sc->sc_dev.dv_xname); 326 SET(sc->sc_hwflags, COM_HW_KGDB); 327 } 328 #endif /* KGDB */ 329 330 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 331 int maj; 332 333 /* locate the major number */ 334 for (maj = 0; maj < nchrdev; maj++) 335 if (cdevsw[maj].d_open == comopen) 336 break; 337 338 if (maj < nchrdev && cn_tab->cn_dev == NODEV) 339 cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit); 340 341 printf("%s: console\n", sc->sc_dev.dv_xname); 342 } 343 344 timeout_set(&sc->sc_diag_tmo, comdiag, sc); 345 timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc); 346 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 347 sc->sc_si = softintr_establish(IPL_TTY, compoll, sc); 348 if (sc->sc_si == NULL) 349 panic("%s: can't establish soft interrupt.", sc->sc_dev.dv_xname); 350 #else 351 timeout_set(&sc->sc_poll_tmo, compoll, sc); 352 #endif 353 354 /* 355 * If there are no enable/disable functions, assume the device 356 * is always enabled. 357 */ 358 if (!sc->enable) 359 sc->enabled = 1; 360 361 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE|COM_HW_KGDB)) 362 com_enable_debugport(sc); 363 } 364 365 void 366 com_enable_debugport(sc) 367 struct com_softc *sc; 368 { 369 int s; 370 371 /* Turn on line break interrupt, set carrier. */ 372 s = splhigh(); 373 #ifdef KGDB 374 SET(sc->sc_ier, IER_ERXRDY); 375 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier); 376 #endif 377 SET(sc->sc_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE); 378 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr); 379 380 splx(s); 381 } 382 383 int 384 com_detach(self, flags) 385 struct device *self; 386 int flags; 387 { 388 struct com_softc *sc = (struct com_softc *)self; 389 int maj, mn; 390 391 /* locate the major number */ 392 for (maj = 0; maj < nchrdev; maj++) 393 if (cdevsw[maj].d_open == comopen) 394 break; 395 396 /* Nuke the vnodes for any open instances. */ 397 mn = self->dv_unit; 398 vdevgone(maj, mn, mn, VCHR); 399 400 /* XXX a symbolic constant for the cua bit would be nicer. */ 401 mn |= 0x80; 402 vdevgone(maj, mn, mn, VCHR); 403 404 /* Detach and free the tty. */ 405 if (sc->sc_tty) { 406 tty_detach(sc->sc_tty); 407 ttyfree(sc->sc_tty); 408 } 409 410 timeout_del(&sc->sc_dtr_tmo); 411 timeout_del(&sc->sc_diag_tmo); 412 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 413 softintr_disestablish(sc->sc_si); 414 #else 415 timeout_del(&sc->sc_poll_tmo); 416 #endif 417 418 return (0); 419 } 420 421 int 422 com_activate(self, act) 423 struct device *self; 424 enum devact act; 425 { 426 struct com_softc *sc = (struct com_softc *)self; 427 int s, rv = 0; 428 429 s = spltty(); 430 switch (act) { 431 case DVACT_ACTIVATE: 432 rv = EOPNOTSUPP; 433 break; 434 435 case DVACT_DEACTIVATE: 436 #ifdef KGDB 437 if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) { 438 #else 439 if (sc->sc_hwflags & COM_HW_CONSOLE) { 440 #endif /* KGDB */ 441 rv = EBUSY; 442 break; 443 } 444 445 if (sc->disable != NULL && sc->enabled != 0) { 446 (*sc->disable)(sc); 447 sc->enabled = 0; 448 } 449 break; 450 } 451 splx(s); 452 return (rv); 453 } 454 455 int 456 comopen(dev, flag, mode, p) 457 dev_t dev; 458 int flag, mode; 459 struct proc *p; 460 { 461 int unit = DEVUNIT(dev); 462 struct com_softc *sc; 463 bus_space_tag_t iot; 464 bus_space_handle_t ioh; 465 struct tty *tp; 466 int s; 467 int error = 0; 468 469 if (unit >= com_cd.cd_ndevs) 470 return ENXIO; 471 sc = com_cd.cd_devs[unit]; 472 if (!sc) 473 return ENXIO; 474 475 #ifdef KGDB 476 /* 477 * If this is the kgdb port, no other use is permitted. 478 */ 479 if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) 480 return (EBUSY); 481 #endif /* KGDB */ 482 483 s = spltty(); 484 if (!sc->sc_tty) { 485 tp = sc->sc_tty = ttymalloc(); 486 tty_attach(tp); 487 } else 488 tp = sc->sc_tty; 489 splx(s); 490 491 tp->t_oproc = comstart; 492 tp->t_param = comparam; 493 tp->t_dev = dev; 494 if (!ISSET(tp->t_state, TS_ISOPEN)) { 495 SET(tp->t_state, TS_WOPEN); 496 ttychars(tp); 497 tp->t_iflag = TTYDEF_IFLAG; 498 tp->t_oflag = TTYDEF_OFLAG; 499 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) 500 tp->t_cflag = comconscflag; 501 else 502 tp->t_cflag = TTYDEF_CFLAG; 503 if (ISSET(sc->sc_swflags, COM_SW_CLOCAL)) 504 SET(tp->t_cflag, CLOCAL); 505 if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS)) 506 SET(tp->t_cflag, CRTSCTS); 507 if (ISSET(sc->sc_swflags, COM_SW_MDMBUF)) 508 SET(tp->t_cflag, MDMBUF); 509 tp->t_lflag = TTYDEF_LFLAG; 510 tp->t_ispeed = tp->t_ospeed = comdefaultrate; 511 512 s = spltty(); 513 514 sc->sc_initialize = 1; 515 comparam(tp, &tp->t_termios); 516 ttsetwater(tp); 517 518 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS 519 timeout_add(&sc->sc_poll_tmo, 1); 520 #endif 521 522 sc->sc_ibufp = sc->sc_ibuf = sc->sc_ibufs[0]; 523 sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER; 524 sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE; 525 526 iot = sc->sc_iot; 527 ioh = sc->sc_ioh; 528 529 /* 530 * Wake up the sleepy heads. 531 */ 532 switch (sc->sc_uarttype) { 533 case COM_UART_ST16650: 534 case COM_UART_ST16650V2: 535 bus_space_write_1(iot, ioh, com_lcr, 0xbf); 536 bus_space_write_1(iot, ioh, com_efr, EFR_ECB); 537 bus_space_write_1(iot, ioh, com_ier, 0); 538 bus_space_write_1(iot, ioh, com_efr, 0); 539 bus_space_write_1(iot, ioh, com_lcr, 0); 540 break; 541 case COM_UART_TI16750: 542 bus_space_write_1(iot, ioh, com_ier, 0); 543 break; 544 } 545 546 if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) { 547 u_int8_t fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST; 548 u_int8_t lcr; 549 550 if (tp->t_ispeed <= 1200) 551 fifo |= FIFO_TRIGGER_1; 552 else 553 fifo |= FIFO_TRIGGER_8; 554 if (sc->sc_uarttype == COM_UART_TI16750) { 555 fifo |= FIFO_ENABLE_64BYTE; 556 lcr = bus_space_read_1(iot, ioh, com_lcr); 557 bus_space_write_1(iot, ioh, com_lcr, 558 lcr | LCR_DLAB); 559 } 560 561 /* 562 * (Re)enable and drain FIFOs. 563 * 564 * Certain SMC chips cause problems if the FIFOs are 565 * enabled while input is ready. Turn off the FIFO 566 * if necessary to clear the input. Test the input 567 * ready bit after enabling the FIFOs to handle races 568 * between enabling and fresh input. 569 * 570 * Set the FIFO threshold based on the receive speed. 571 */ 572 for (;;) { 573 bus_space_write_1(iot, ioh, com_fifo, 0); 574 delay(100); 575 (void) bus_space_read_1(iot, ioh, com_data); 576 bus_space_write_1(iot, ioh, com_fifo, fifo | 577 FIFO_RCV_RST | FIFO_XMT_RST); 578 delay(100); 579 if(!ISSET(bus_space_read_1(iot, ioh, 580 com_lsr), LSR_RXRDY)) 581 break; 582 } 583 if (sc->sc_uarttype == COM_UART_TI16750) 584 bus_space_write_1(iot, ioh, com_lcr, lcr); 585 } 586 587 /* flush any pending I/O */ 588 while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)) 589 (void) bus_space_read_1(iot, ioh, com_data); 590 /* you turn me on, baby */ 591 sc->sc_mcr = MCR_DTR | MCR_RTS; 592 if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN)) 593 SET(sc->sc_mcr, MCR_IENABLE); 594 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 595 sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC; 596 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier); 597 598 sc->sc_msr = bus_space_read_1(iot, ioh, com_msr); 599 if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || DEVCUA(dev) || 600 ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF)) 601 SET(tp->t_state, TS_CARR_ON); 602 else 603 CLR(tp->t_state, TS_CARR_ON); 604 } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) 605 return EBUSY; 606 else 607 s = spltty(); 608 609 if (DEVCUA(dev)) { 610 if (ISSET(tp->t_state, TS_ISOPEN)) { 611 /* Ah, but someone already is dialed in... */ 612 splx(s); 613 return EBUSY; 614 } 615 sc->sc_cua = 1; /* We go into CUA mode */ 616 } else { 617 /* tty (not cua) device; wait for carrier if necessary */ 618 if (ISSET(flag, O_NONBLOCK)) { 619 if (sc->sc_cua) { 620 /* Opening TTY non-blocking... but the CUA is busy */ 621 splx(s); 622 return EBUSY; 623 } 624 } else { 625 while (sc->sc_cua || 626 (!ISSET(tp->t_cflag, CLOCAL) && 627 !ISSET(tp->t_state, TS_CARR_ON))) { 628 SET(tp->t_state, TS_WOPEN); 629 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0); 630 /* 631 * If TS_WOPEN has been reset, that means the cua device 632 * has been closed. We don't want to fail in that case, 633 * so just go around again. 634 */ 635 if (error && ISSET(tp->t_state, TS_WOPEN)) { 636 CLR(tp->t_state, TS_WOPEN); 637 if (!sc->sc_cua && !ISSET(tp->t_state, TS_ISOPEN)) 638 compwroff(sc); 639 splx(s); 640 return error; 641 } 642 } 643 } 644 } 645 splx(s); 646 647 return (*linesw[tp->t_line].l_open)(dev, tp); 648 } 649 650 int 651 comclose(dev, flag, mode, p) 652 dev_t dev; 653 int flag, mode; 654 struct proc *p; 655 { 656 int unit = DEVUNIT(dev); 657 struct com_softc *sc = com_cd.cd_devs[unit]; 658 bus_space_tag_t iot = sc->sc_iot; 659 bus_space_handle_t ioh = sc->sc_ioh; 660 struct tty *tp = sc->sc_tty; 661 int s; 662 663 /* XXX This is for cons.c. */ 664 if (!ISSET(tp->t_state, TS_ISOPEN)) 665 return 0; 666 667 (*linesw[tp->t_line].l_close)(tp, flag); 668 s = spltty(); 669 if (ISSET(tp->t_state, TS_WOPEN)) { 670 /* tty device is waiting for carrier; drop dtr then re-raise */ 671 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS); 672 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 673 timeout_add(&sc->sc_dtr_tmo, hz * 2); 674 } else { 675 /* no one else waiting; turn off the uart */ 676 compwroff(sc); 677 } 678 CLR(tp->t_state, TS_BUSY | TS_FLUSH); 679 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS 680 timeout_del(&sc->sc_poll_tmo); 681 #endif 682 sc->sc_cua = 0; 683 splx(s); 684 ttyclose(tp); 685 686 #ifdef notyet /* XXXX */ 687 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 688 ttyfree(tp); 689 sc->sc_tty = 0; 690 } 691 #endif 692 return 0; 693 } 694 695 void 696 compwroff(sc) 697 struct com_softc *sc; 698 { 699 bus_space_tag_t iot = sc->sc_iot; 700 bus_space_handle_t ioh = sc->sc_ioh; 701 struct tty *tp = sc->sc_tty; 702 703 CLR(sc->sc_lcr, LCR_SBREAK); 704 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); 705 bus_space_write_1(iot, ioh, com_ier, 0); 706 if (ISSET(tp->t_cflag, HUPCL) && 707 !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) { 708 /* XXX perhaps only clear DTR */ 709 sc->sc_mcr = 0; 710 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 711 } 712 713 /* 714 * Turn FIFO off; enter sleep mode if possible. 715 */ 716 bus_space_write_1(iot, ioh, com_fifo, 0); 717 delay(100); 718 (void) bus_space_read_1(iot, ioh, com_data); 719 delay(100); 720 bus_space_write_1(iot, ioh, com_fifo, 721 FIFO_RCV_RST | FIFO_XMT_RST); 722 723 switch (sc->sc_uarttype) { 724 case COM_UART_ST16650: 725 case COM_UART_ST16650V2: 726 bus_space_write_1(iot, ioh, com_lcr, 0xbf); 727 bus_space_write_1(iot, ioh, com_efr, EFR_ECB); 728 bus_space_write_1(iot, ioh, com_ier, IER_SLEEP); 729 bus_space_write_1(iot, ioh, com_lcr, 0); 730 break; 731 case COM_UART_TI16750: 732 bus_space_write_1(iot, ioh, com_ier, IER_SLEEP); 733 break; 734 } 735 } 736 737 void 738 com_raisedtr(arg) 739 void *arg; 740 { 741 struct com_softc *sc = arg; 742 743 SET(sc->sc_mcr, MCR_DTR | MCR_RTS); 744 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr); 745 } 746 747 int 748 comread(dev, uio, flag) 749 dev_t dev; 750 struct uio *uio; 751 int flag; 752 { 753 struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)]; 754 struct tty *tp = sc->sc_tty; 755 756 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 757 } 758 759 int 760 comwrite(dev, uio, flag) 761 dev_t dev; 762 struct uio *uio; 763 int flag; 764 { 765 struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)]; 766 struct tty *tp = sc->sc_tty; 767 768 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 769 } 770 771 struct tty * 772 comtty(dev) 773 dev_t dev; 774 { 775 struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)]; 776 struct tty *tp = sc->sc_tty; 777 778 return (tp); 779 } 780 781 static u_char 782 tiocm_xxx2mcr(data) 783 int data; 784 { 785 u_char m = 0; 786 787 if (ISSET(data, TIOCM_DTR)) 788 SET(m, MCR_DTR); 789 if (ISSET(data, TIOCM_RTS)) 790 SET(m, MCR_RTS); 791 return m; 792 } 793 794 int 795 comioctl(dev, cmd, data, flag, p) 796 dev_t dev; 797 u_long cmd; 798 caddr_t data; 799 int flag; 800 struct proc *p; 801 { 802 int unit = DEVUNIT(dev); 803 struct com_softc *sc = com_cd.cd_devs[unit]; 804 struct tty *tp = sc->sc_tty; 805 bus_space_tag_t iot = sc->sc_iot; 806 bus_space_handle_t ioh = sc->sc_ioh; 807 int error; 808 809 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 810 if (error >= 0) 811 return error; 812 error = ttioctl(tp, cmd, data, flag, p); 813 if (error >= 0) 814 return error; 815 816 switch (cmd) { 817 case TIOCSBRK: 818 SET(sc->sc_lcr, LCR_SBREAK); 819 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); 820 break; 821 case TIOCCBRK: 822 CLR(sc->sc_lcr, LCR_SBREAK); 823 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr); 824 break; 825 case TIOCSDTR: 826 SET(sc->sc_mcr, sc->sc_dtr); 827 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 828 break; 829 case TIOCCDTR: 830 CLR(sc->sc_mcr, sc->sc_dtr); 831 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 832 break; 833 case TIOCMSET: 834 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS); 835 case TIOCMBIS: 836 SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data)); 837 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 838 break; 839 case TIOCMBIC: 840 CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data)); 841 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 842 break; 843 case TIOCMGET: { 844 u_char m; 845 int bits = 0; 846 847 m = sc->sc_mcr; 848 if (ISSET(m, MCR_DTR)) 849 SET(bits, TIOCM_DTR); 850 if (ISSET(m, MCR_RTS)) 851 SET(bits, TIOCM_RTS); 852 m = sc->sc_msr; 853 if (ISSET(m, MSR_DCD)) 854 SET(bits, TIOCM_CD); 855 if (ISSET(m, MSR_CTS)) 856 SET(bits, TIOCM_CTS); 857 if (ISSET(m, MSR_DSR)) 858 SET(bits, TIOCM_DSR); 859 if (ISSET(m, MSR_RI | MSR_TERI)) 860 SET(bits, TIOCM_RI); 861 if (bus_space_read_1(iot, ioh, com_ier)) 862 SET(bits, TIOCM_LE); 863 *(int *)data = bits; 864 break; 865 } 866 case TIOCGFLAGS: { 867 int driverbits, userbits = 0; 868 869 driverbits = sc->sc_swflags; 870 if (ISSET(driverbits, COM_SW_SOFTCAR)) 871 SET(userbits, TIOCFLAG_SOFTCAR); 872 if (ISSET(driverbits, COM_SW_CLOCAL)) 873 SET(userbits, TIOCFLAG_CLOCAL); 874 if (ISSET(driverbits, COM_SW_CRTSCTS)) 875 SET(userbits, TIOCFLAG_CRTSCTS); 876 if (ISSET(driverbits, COM_SW_MDMBUF)) 877 SET(userbits, TIOCFLAG_MDMBUF); 878 if (ISSET(driverbits, COM_SW_PPS)) 879 SET(userbits, TIOCFLAG_PPS); 880 881 *(int *)data = userbits; 882 break; 883 } 884 case TIOCSFLAGS: { 885 int userbits, driverbits = 0; 886 887 error = suser(p->p_ucred, &p->p_acflag); 888 if (error != 0) 889 return(EPERM); 890 891 userbits = *(int *)data; 892 if (ISSET(userbits, TIOCFLAG_SOFTCAR) || 893 ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) 894 SET(driverbits, COM_SW_SOFTCAR); 895 if (ISSET(userbits, TIOCFLAG_CLOCAL)) 896 SET(driverbits, COM_SW_CLOCAL); 897 if (ISSET(userbits, TIOCFLAG_CRTSCTS)) 898 SET(driverbits, COM_SW_CRTSCTS); 899 if (ISSET(userbits, TIOCFLAG_MDMBUF)) 900 SET(driverbits, COM_SW_MDMBUF); 901 if (ISSET(userbits, TIOCFLAG_PPS)) 902 SET(driverbits, COM_SW_PPS); 903 904 sc->sc_swflags = driverbits; 905 break; 906 } 907 default: 908 return ENOTTY; 909 } 910 911 return 0; 912 } 913 914 /* already called at spltty */ 915 int 916 comparam(tp, t) 917 struct tty *tp; 918 struct termios *t; 919 { 920 struct com_softc *sc = com_cd.cd_devs[DEVUNIT(tp->t_dev)]; 921 bus_space_tag_t iot = sc->sc_iot; 922 bus_space_handle_t ioh = sc->sc_ioh; 923 int ospeed = comspeed(sc->sc_frequency, t->c_ospeed); 924 u_char lcr; 925 tcflag_t oldcflag; 926 927 /* check requested parameters */ 928 if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed)) 929 return EINVAL; 930 931 lcr = ISSET(sc->sc_lcr, LCR_SBREAK); 932 933 switch (ISSET(t->c_cflag, CSIZE)) { 934 case CS5: 935 SET(lcr, LCR_5BITS); 936 break; 937 case CS6: 938 SET(lcr, LCR_6BITS); 939 break; 940 case CS7: 941 SET(lcr, LCR_7BITS); 942 break; 943 case CS8: 944 SET(lcr, LCR_8BITS); 945 break; 946 } 947 if (ISSET(t->c_cflag, PARENB)) { 948 SET(lcr, LCR_PENAB); 949 if (!ISSET(t->c_cflag, PARODD)) 950 SET(lcr, LCR_PEVEN); 951 } 952 if (ISSET(t->c_cflag, CSTOPB)) 953 SET(lcr, LCR_STOPB); 954 955 sc->sc_lcr = lcr; 956 957 if (ospeed == 0) { 958 CLR(sc->sc_mcr, MCR_DTR); 959 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 960 } 961 962 /* 963 * Set the FIFO threshold based on the receive speed, if we are 964 * changing it. 965 */ 966 if (sc->sc_initialize || (tp->t_ispeed != t->c_ispeed)) { 967 sc->sc_initialize = 0; 968 969 if (ospeed != 0) { 970 /* 971 * Make sure the transmit FIFO is empty before 972 * proceeding. If we don't do this, some revisions 973 * of the UART will hang. Interestingly enough, 974 * even if we do this while the last character is 975 * still being pushed out, they don't hang. This 976 * seems good enough. 977 */ 978 while (ISSET(tp->t_state, TS_BUSY)) { 979 int error; 980 981 ++sc->sc_halt; 982 error = ttysleep(tp, &tp->t_outq, 983 TTOPRI | PCATCH, "comprm", 0); 984 --sc->sc_halt; 985 if (error) { 986 comstart(tp); 987 return (error); 988 } 989 } 990 991 bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB); 992 bus_space_write_1(iot, ioh, com_dlbl, ospeed); 993 bus_space_write_1(iot, ioh, com_dlbh, ospeed >> 8); 994 bus_space_write_1(iot, ioh, com_lcr, lcr); 995 SET(sc->sc_mcr, MCR_DTR); 996 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 997 } else 998 bus_space_write_1(iot, ioh, com_lcr, lcr); 999 1000 if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) { 1001 if (sc->sc_uarttype == COM_UART_TI16750) { 1002 bus_space_write_1(iot, ioh, com_lcr, 1003 lcr | LCR_DLAB); 1004 bus_space_write_1(iot, ioh, com_fifo, 1005 FIFO_ENABLE | FIFO_ENABLE_64BYTE | 1006 (t->c_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8)); 1007 bus_space_write_1(iot, ioh, com_lcr, lcr); 1008 } else 1009 bus_space_write_1(iot, ioh, com_fifo, 1010 FIFO_ENABLE | 1011 (t->c_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8)); 1012 } 1013 } else 1014 bus_space_write_1(iot, ioh, com_lcr, lcr); 1015 1016 /* When not using CRTSCTS, RTS follows DTR. */ 1017 if (!ISSET(t->c_cflag, CRTSCTS)) { 1018 if (ISSET(sc->sc_mcr, MCR_DTR)) { 1019 if (!ISSET(sc->sc_mcr, MCR_RTS)) { 1020 SET(sc->sc_mcr, MCR_RTS); 1021 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 1022 } 1023 } else { 1024 if (ISSET(sc->sc_mcr, MCR_RTS)) { 1025 CLR(sc->sc_mcr, MCR_RTS); 1026 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 1027 } 1028 } 1029 sc->sc_dtr = MCR_DTR | MCR_RTS; 1030 } else 1031 sc->sc_dtr = MCR_DTR; 1032 1033 /* and copy to tty */ 1034 tp->t_ispeed = t->c_ispeed; 1035 tp->t_ospeed = t->c_ospeed; 1036 oldcflag = tp->t_cflag; 1037 tp->t_cflag = t->c_cflag; 1038 1039 /* 1040 * If DCD is off and MDMBUF is changed, ask the tty layer if we should 1041 * stop the device. 1042 */ 1043 if (!ISSET(sc->sc_msr, MSR_DCD) && 1044 !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) && 1045 ISSET(oldcflag, MDMBUF) != ISSET(tp->t_cflag, MDMBUF) && 1046 (*linesw[tp->t_line].l_modem)(tp, 0) == 0) { 1047 CLR(sc->sc_mcr, sc->sc_dtr); 1048 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 1049 } 1050 1051 /* Just to be sure... */ 1052 comstart(tp); 1053 return 0; 1054 } 1055 1056 void 1057 comstart(tp) 1058 struct tty *tp; 1059 { 1060 struct com_softc *sc = com_cd.cd_devs[DEVUNIT(tp->t_dev)]; 1061 bus_space_tag_t iot = sc->sc_iot; 1062 bus_space_handle_t ioh = sc->sc_ioh; 1063 int s; 1064 1065 s = spltty(); 1066 if (ISSET(tp->t_state, TS_BUSY)) 1067 goto out; 1068 if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP) || sc->sc_halt > 0) 1069 goto stopped; 1070 if (ISSET(tp->t_cflag, CRTSCTS) && !ISSET(sc->sc_msr, MSR_CTS)) 1071 goto stopped; 1072 if (tp->t_outq.c_cc <= tp->t_lowat) { 1073 if (ISSET(tp->t_state, TS_ASLEEP)) { 1074 CLR(tp->t_state, TS_ASLEEP); 1075 wakeup(&tp->t_outq); 1076 } 1077 if (tp->t_outq.c_cc == 0) 1078 goto stopped; 1079 selwakeup(&tp->t_wsel); 1080 } 1081 SET(tp->t_state, TS_BUSY); 1082 1083 /* Enable transmit completion interrupts. */ 1084 if (!ISSET(sc->sc_ier, IER_ETXRDY)) { 1085 SET(sc->sc_ier, IER_ETXRDY); 1086 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier); 1087 } 1088 1089 if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) { 1090 u_char buffer[64]; /* XXX: largest fifo */ 1091 1092 int n = q_to_b(&tp->t_outq, buffer, sc->sc_fifolen); 1093 int i; 1094 1095 for (i = 0; i < n; i++) { 1096 bus_space_write_1(iot, ioh, com_data, buffer[i]); 1097 } 1098 } else 1099 bus_space_write_1(iot, ioh, com_data, getc(&tp->t_outq)); 1100 out: 1101 splx(s); 1102 return; 1103 stopped: 1104 if (ISSET(sc->sc_ier, IER_ETXRDY)) { 1105 CLR(sc->sc_ier, IER_ETXRDY); 1106 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier); 1107 } 1108 splx(s); 1109 } 1110 1111 /* 1112 * Stop output on a line. 1113 */ 1114 int 1115 comstop(tp, flag) 1116 struct tty *tp; 1117 int flag; 1118 { 1119 int s; 1120 1121 s = spltty(); 1122 if (ISSET(tp->t_state, TS_BUSY)) 1123 if (!ISSET(tp->t_state, TS_TTSTOP)) 1124 SET(tp->t_state, TS_FLUSH); 1125 splx(s); 1126 return 0; 1127 } 1128 1129 void 1130 comdiag(arg) 1131 void *arg; 1132 { 1133 struct com_softc *sc = arg; 1134 int overflows, floods; 1135 int s; 1136 1137 s = spltty(); 1138 sc->sc_errors = 0; 1139 overflows = sc->sc_overflows; 1140 sc->sc_overflows = 0; 1141 floods = sc->sc_floods; 1142 sc->sc_floods = 0; 1143 splx(s); 1144 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf overflow%s\n", 1145 sc->sc_dev.dv_xname, 1146 overflows, overflows == 1 ? "" : "s", 1147 floods, floods == 1 ? "" : "s"); 1148 } 1149 1150 void 1151 compoll(arg) 1152 void *arg; 1153 { 1154 struct com_softc *sc = (struct com_softc *)arg; 1155 struct tty *tp; 1156 register u_char *ibufp; 1157 u_char *ibufend; 1158 register int c; 1159 int s; 1160 static int lsrmap[8] = { 1161 0, TTY_PE, 1162 TTY_FE, TTY_PE|TTY_FE, 1163 TTY_FE, TTY_PE|TTY_FE, 1164 TTY_FE, TTY_PE|TTY_FE 1165 }; 1166 1167 if (sc == NULL || sc->sc_ibufp == sc->sc_ibuf) 1168 goto out; 1169 1170 tp = sc->sc_tty; 1171 1172 s = spltty(); 1173 1174 ibufp = sc->sc_ibuf; 1175 ibufend = sc->sc_ibufp; 1176 1177 if (ibufp == ibufend) { 1178 splx(s); 1179 goto out; 1180 } 1181 1182 sc->sc_ibufp = sc->sc_ibuf = (ibufp == sc->sc_ibufs[0]) ? 1183 sc->sc_ibufs[1] : sc->sc_ibufs[0]; 1184 sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER; 1185 sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE; 1186 1187 if (tp == NULL || !ISSET(tp->t_state, TS_ISOPEN)) { 1188 splx(s); 1189 goto out; 1190 } 1191 1192 if (ISSET(tp->t_cflag, CRTSCTS) && 1193 !ISSET(sc->sc_mcr, MCR_RTS)) { 1194 /* XXX */ 1195 SET(sc->sc_mcr, MCR_RTS); 1196 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, 1197 sc->sc_mcr); 1198 } 1199 1200 splx(s); 1201 1202 while (ibufp < ibufend) { 1203 c = *ibufp++; 1204 if (ISSET(*ibufp, LSR_OE)) { 1205 sc->sc_overflows++; 1206 if (sc->sc_errors++ == 0) 1207 timeout_add(&sc->sc_diag_tmo, 60 * hz); 1208 } 1209 /* This is ugly, but fast. */ 1210 c |= lsrmap[(*ibufp++ & (LSR_BI|LSR_FE|LSR_PE)) >> 2]; 1211 (*linesw[tp->t_line].l_rint)(c, tp); 1212 } 1213 1214 out: 1215 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS 1216 timeout_add(&sc->sc_poll_tmo, 1); 1217 #else 1218 ; 1219 #endif 1220 } 1221 1222 #ifdef KGDB 1223 1224 /* 1225 * If a line break is set, or data matches one of the characters 1226 * gdb uses to signal a connection, then start up kgdb. Just gobble 1227 * any other data. Done in a stand alone function because comintr 1228 * does tty stuff and we don't have one. 1229 */ 1230 1231 int 1232 kgdbintr(arg) 1233 void *arg; 1234 { 1235 struct com_softc *sc = arg; 1236 bus_space_tag_t iot = sc->sc_iot; 1237 bus_space_handle_t ioh = sc->sc_ioh; 1238 u_char lsr, data, msr, delta; 1239 1240 if (!ISSET(sc->sc_hwflags, COM_HW_KGDB)) 1241 return(0); 1242 1243 for (;;) { 1244 lsr = bus_space_read_1(iot, ioh, com_lsr); 1245 if (ISSET(lsr, LSR_RXRDY)) { 1246 do { 1247 data = bus_space_read_1(iot, ioh, com_data); 1248 if (data == 3 || data == '$' || data == '+' || 1249 ISSET(lsr, LSR_BI)) { 1250 kgdb_connect(1); 1251 data = 0; 1252 } 1253 lsr = bus_space_read_1(iot, ioh, com_lsr); 1254 } while (ISSET(lsr, LSR_RXRDY)); 1255 1256 } 1257 if (ISSET(lsr, LSR_BI|LSR_FE|LSR_PE|LSR_OE)) 1258 printf("weird lsr %02x\n", lsr); 1259 1260 msr = bus_space_read_1(iot, ioh, com_msr); 1261 1262 if (msr != sc->sc_msr) { 1263 delta = msr ^ sc->sc_msr; 1264 sc->sc_msr = msr; 1265 if (ISSET(delta, MSR_DCD)) { 1266 if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) { 1267 CLR(sc->sc_mcr, sc->sc_dtr); 1268 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 1269 } 1270 } 1271 } 1272 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND)) 1273 return (1); 1274 } 1275 } 1276 #endif /* KGDB */ 1277 1278 int 1279 comintr(arg) 1280 void *arg; 1281 { 1282 struct com_softc *sc = arg; 1283 bus_space_tag_t iot = sc->sc_iot; 1284 bus_space_handle_t ioh = sc->sc_ioh; 1285 struct tty *tp; 1286 u_char lsr, data, msr, delta; 1287 1288 if (!sc->sc_tty) 1289 return (0); /* can't do squat. */ 1290 1291 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND)) 1292 return (0); 1293 1294 tp = sc->sc_tty; 1295 1296 for (;;) { 1297 lsr = bus_space_read_1(iot, ioh, com_lsr); 1298 1299 if (ISSET(lsr, LSR_RXRDY)) { 1300 register u_char *p = sc->sc_ibufp; 1301 1302 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 1303 softintr_schedule(sc->sc_si); 1304 #endif 1305 do { 1306 data = bus_space_read_1(iot, ioh, com_data); 1307 if (ISSET(lsr, LSR_BI)) { 1308 #ifdef DDB 1309 if (ISSET(sc->sc_hwflags, 1310 COM_HW_CONSOLE)) { 1311 if (db_console) 1312 Debugger(); 1313 goto next; 1314 } 1315 #endif 1316 data = 0; 1317 } 1318 if (p >= sc->sc_ibufend) { 1319 sc->sc_floods++; 1320 if (sc->sc_errors++ == 0) 1321 timeout_add(&sc->sc_diag_tmo, 60 * hz); 1322 } else { 1323 *p++ = data; 1324 *p++ = lsr; 1325 if (p == sc->sc_ibufhigh && 1326 ISSET(tp->t_cflag, CRTSCTS)) { 1327 /* XXX */ 1328 CLR(sc->sc_mcr, MCR_RTS); 1329 bus_space_write_1(iot, ioh, com_mcr, 1330 sc->sc_mcr); 1331 } 1332 } 1333 #ifdef DDB 1334 next: 1335 #endif 1336 lsr = bus_space_read_1(iot, ioh, com_lsr); 1337 } while (ISSET(lsr, LSR_RXRDY)); 1338 1339 sc->sc_ibufp = p; 1340 } 1341 msr = bus_space_read_1(iot, ioh, com_msr); 1342 1343 if (msr != sc->sc_msr) { 1344 delta = msr ^ sc->sc_msr; 1345 sc->sc_msr = msr; 1346 if (ISSET(delta, MSR_DCD)) { 1347 if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR) && 1348 (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)) == 0) { 1349 CLR(sc->sc_mcr, sc->sc_dtr); 1350 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); 1351 } 1352 } 1353 if (ISSET(delta & msr, MSR_CTS) && 1354 ISSET(tp->t_cflag, CRTSCTS)) { 1355 /* the line is up and we want to do rts/cts flow control */ 1356 (*linesw[tp->t_line].l_start)(tp); 1357 } 1358 } 1359 1360 if (ISSET(lsr, LSR_TXRDY) && ISSET(tp->t_state, TS_BUSY)) { 1361 CLR(tp->t_state, TS_BUSY | TS_FLUSH); 1362 if (sc->sc_halt > 0) 1363 wakeup(&tp->t_outq); 1364 (*linesw[tp->t_line].l_start)(tp); 1365 } 1366 1367 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND)) 1368 return (1); 1369 } 1370 } 1371 1372 /* 1373 * Following are all routines needed for COM to act as console 1374 */ 1375 1376 #if defined(arc) 1377 #undef CONADDR 1378 extern int CONADDR; 1379 #endif 1380 1381 /* 1382 * The following functions are polled getc and putc routines, shared 1383 * by the console and kgdb glue. 1384 */ 1385 1386 int 1387 com_common_getc(iot, ioh) 1388 bus_space_tag_t iot; 1389 bus_space_handle_t ioh; 1390 { 1391 int s = splhigh(); 1392 u_char stat, c; 1393 1394 /* block until a character becomes available */ 1395 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)) 1396 continue; 1397 1398 c = bus_space_read_1(iot, ioh, com_data); 1399 /* clear any interrupts generated by this transmission */ 1400 stat = bus_space_read_1(iot, ioh, com_iir); 1401 splx(s); 1402 return (c); 1403 } 1404 1405 void 1406 com_common_putc(iot, ioh, c) 1407 bus_space_tag_t iot; 1408 bus_space_handle_t ioh; 1409 int c; 1410 { 1411 int s = spltty(); 1412 int timo; 1413 1414 /* wait for any pending transmission to finish */ 1415 timo = 2000; 1416 while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo) 1417 delay(1); 1418 1419 bus_space_write_1(iot, ioh, com_data, c); 1420 bus_space_barrier(iot, ioh, 0, COM_NPORTS, 1421 (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)); 1422 1423 /* wait for this transmission to complete */ 1424 timo = 2000; 1425 while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo) 1426 delay(1); 1427 1428 splx(s); 1429 } 1430 1431 /* 1432 * Following are all routines needed for COM to act as console 1433 */ 1434 void 1435 cominit(iot, ioh, rate) 1436 bus_space_tag_t iot; 1437 bus_space_handle_t ioh; 1438 int rate; 1439 { 1440 int s = splhigh(); 1441 u_char stat; 1442 1443 bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB); 1444 rate = comspeed(COM_FREQ, rate); /* XXX not comdefaultrate? */ 1445 bus_space_write_1(iot, ioh, com_dlbl, rate); 1446 bus_space_write_1(iot, ioh, com_dlbh, rate >> 8); 1447 bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS); 1448 bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS); 1449 bus_space_write_1(iot, ioh, com_ier, 0); /* Make sure they are off */ 1450 bus_space_write_1(iot, ioh, com_fifo, 1451 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1); 1452 stat = bus_space_read_1(iot, ioh, com_iir); 1453 splx(s); 1454 } 1455 1456 void 1457 comcnprobe(cp) 1458 struct consdev *cp; 1459 { 1460 /* XXX NEEDS TO BE FIXED XXX */ 1461 #if defined(arc) 1462 bus_space_tag_t iot = &arc_bus_io; 1463 #elif defined(hppa) 1464 bus_space_tag_t iot = &hppa_bustag; 1465 #else 1466 bus_space_tag_t iot = 0; 1467 #endif 1468 bus_space_handle_t ioh; 1469 int found; 1470 1471 if(CONADDR == 0) { 1472 cp->cn_pri = CN_DEAD; 1473 return; 1474 } 1475 1476 comconsiot = iot; 1477 if (bus_space_map(iot, CONADDR, COM_NPORTS, 0, &ioh)) { 1478 cp->cn_pri = CN_DEAD; 1479 return; 1480 } 1481 #ifdef __hppa__ 1482 found = 1; 1483 #else 1484 found = comprobe1(iot, ioh); 1485 #endif 1486 bus_space_unmap(iot, ioh, COM_NPORTS); 1487 if (!found) { 1488 cp->cn_pri = CN_DEAD; 1489 return; 1490 } 1491 1492 /* locate the major number */ 1493 for (commajor = 0; commajor < nchrdev; commajor++) 1494 if (cdevsw[commajor].d_open == comopen) 1495 break; 1496 1497 /* initialize required fields */ 1498 cp->cn_dev = makedev(commajor, CONUNIT); 1499 cp->cn_pri = CN_REMOTE; 1500 } 1501 1502 void 1503 comcninit(cp) 1504 struct consdev *cp; 1505 { 1506 comconsaddr = CONADDR; 1507 1508 if (bus_space_map(comconsiot, comconsaddr, COM_NPORTS, 0, &comconsioh)) 1509 panic("comcninit: mapping failed"); 1510 1511 cominit(comconsiot, comconsioh, comdefaultrate); 1512 comconsinit = 0; 1513 } 1514 1515 1516 int 1517 comcnattach(iot, iobase, rate, frequency, cflag) 1518 bus_space_tag_t iot; 1519 int iobase; 1520 int rate, frequency; 1521 tcflag_t cflag; 1522 { 1523 static struct consdev comcons = { 1524 NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL, 1525 NODEV, CN_NORMAL 1526 }; 1527 1528 #ifndef __sparc64__ 1529 if (bus_space_map(iot, iobase, COM_NPORTS, 0, &comconsioh)) 1530 return ENOMEM; 1531 #endif 1532 1533 cominit(iot, comconsioh, rate); 1534 1535 cn_tab = &comcons; 1536 1537 comconsiot = iot; 1538 comconsaddr = iobase; 1539 comconscflag = cflag; 1540 1541 return (0); 1542 } 1543 1544 int 1545 comcngetc(dev) 1546 dev_t dev; 1547 { 1548 return (com_common_getc(comconsiot, comconsioh)); 1549 } 1550 1551 /* 1552 * Console kernel output character routine. 1553 */ 1554 void 1555 comcnputc(dev, c) 1556 dev_t dev; 1557 int c; 1558 { 1559 com_common_putc(comconsiot, comconsioh, c); 1560 } 1561 1562 void 1563 comcnpollc(dev, on) 1564 dev_t dev; 1565 int on; 1566 { 1567 1568 } 1569 1570 #ifdef KGDB 1571 int 1572 com_kgdb_attach(iot, iobase, rate, frequency, cflag) 1573 bus_space_tag_t iot; 1574 int iobase; 1575 int rate, frequency; 1576 tcflag_t cflag; 1577 { 1578 if (iot == comconsiot && iobase == comconsaddr) { 1579 return (EBUSY); /* cannot share with console */ 1580 } 1581 1582 com_kgdb_iot = iot; 1583 com_kgdb_addr = iobase; 1584 1585 if (bus_space_map(com_kgdb_iot, com_kgdb_addr, COM_NPORTS, 0, 1586 &com_kgdb_ioh)) 1587 panic("com_kgdb_attach: mapping failed"); 1588 1589 /* XXX We currently don't respect KGDBMODE? */ 1590 cominit(com_kgdb_iot, com_kgdb_ioh, rate); 1591 1592 kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL); 1593 kgdb_dev = 123; /* unneeded, only to satisfy some tests */ 1594 1595 return (0); 1596 } 1597 1598 /* ARGSUSED */ 1599 int 1600 com_kgdb_getc(arg) 1601 void *arg; 1602 { 1603 1604 return (com_common_getc(com_kgdb_iot, com_kgdb_ioh)); 1605 } 1606 1607 /* ARGSUSED */ 1608 void 1609 com_kgdb_putc(arg, c) 1610 void *arg; 1611 int c; 1612 { 1613 1614 return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c)); 1615 } 1616 #endif /* KGDB */ 1617