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