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