1 /* $OpenBSD: com.c,v 1.177 2023/05/23 16:39:29 denis 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; 150 151 /* force access to id reg */ 152 bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS); 153 bus_space_write_1(iot, ioh, com_iir, 0); 154 for (i = 0; i < 32; i++) { 155 if ((bus_space_read_1(iot, ioh, com_lcr) != LCR_8BITS) || 156 (bus_space_read_1(iot, ioh, com_iir) & 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 = 1; 1170 1171 if (comconsaddr == 0) 1172 return; 1173 1174 if (bus_space_map(comconsiot, comconsaddr, COM_NPORTS, 0, &ioh)) 1175 return; 1176 /* XXX Some com@acpi devices will fail the comprobe1() check */ 1177 if (comcons_reg_width != 4) 1178 found = comprobe1(comconsiot, ioh); 1179 bus_space_unmap(comconsiot, ioh, COM_NPORTS); 1180 if (!found) 1181 return; 1182 1183 /* Locate the major number. */ 1184 for (commajor = 0; commajor < nchrdev; commajor++) 1185 if (cdevsw[commajor].d_open == comopen) 1186 break; 1187 1188 /* Initialize required fields. */ 1189 cp->cn_dev = makedev(commajor, comconsunit); 1190 cp->cn_pri = CN_HIGHPRI; 1191 } 1192 1193 void 1194 comcninit(struct consdev *cp) 1195 { 1196 if (bus_space_map(comconsiot, comconsaddr, COM_NPORTS, 0, &comconsioh)) 1197 panic("comcninit: mapping failed"); 1198 1199 if (comconsfreq == 0) 1200 comconsfreq = COM_FREQ; 1201 1202 cominit(comconsiot, comconsioh, comconsrate, comconsfreq); 1203 } 1204 1205 int 1206 comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, 1207 int frequency, tcflag_t cflag) 1208 { 1209 static struct consdev comcons = { 1210 NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL, 1211 NODEV, CN_LOWPRI 1212 }; 1213 1214 #ifndef __sparc64__ 1215 if (bus_space_map(iot, iobase, COM_NPORTS, 0, &comconsioh)) 1216 return ENOMEM; 1217 #endif 1218 1219 cominit(iot, comconsioh, rate, frequency); 1220 1221 cn_tab = &comcons; 1222 1223 comconsiot = iot; 1224 comconsaddr = iobase; 1225 comconscflag = cflag; 1226 comconsfreq = frequency; 1227 comconsrate = rate; 1228 1229 return (0); 1230 } 1231 1232 int 1233 comcngetc(dev_t dev) 1234 { 1235 int s = splhigh(); 1236 u_char stat, c; 1237 1238 /* Block until a character becomes available. */ 1239 while (!ISSET(stat = comcn_read_reg(com_lsr), LSR_RXRDY)) 1240 continue; 1241 1242 c = comcn_read_reg(com_data); 1243 1244 /* Clear any interrupts generated by this transmission. */ 1245 stat = comcn_read_reg(com_iir); 1246 splx(s); 1247 return (c); 1248 } 1249 1250 /* 1251 * Console kernel output character routine. 1252 */ 1253 void 1254 comcnputc(dev_t dev, int c) 1255 { 1256 int s = spltty(); 1257 int timo; 1258 1259 /* Wait for any pending transmission to finish. */ 1260 timo = 2000; 1261 while (!ISSET(comcn_read_reg(com_lsr), LSR_TXRDY) && --timo) 1262 delay(1); 1263 1264 comcn_write_reg(com_data, (u_int8_t)(c & 0xff)); 1265 bus_space_barrier(comconsiot, comconsioh, 0, 1266 COM_NPORTS << comcons_reg_shift, 1267 (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)); 1268 1269 /* Wait for this transmission to complete. */ 1270 timo = 2000; 1271 while (!ISSET(comcn_read_reg(com_lsr), LSR_TXRDY) && --timo) 1272 delay(1); 1273 1274 splx(s); 1275 } 1276 1277 void 1278 comcnpollc(dev_t dev, int on) 1279 { 1280 } 1281 #endif /* COM_CONSOLE */ 1282 1283 void com_enable_debugport(struct com_softc *); 1284 void com_fifo_probe(struct com_softc *); 1285 1286 #ifdef COM_CONSOLE 1287 void 1288 com_enable_debugport(struct com_softc *sc) 1289 { 1290 int s; 1291 1292 /* Turn on line break interrupt, set carrier. */ 1293 s = splhigh(); 1294 SET(sc->sc_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE); 1295 com_write_reg(sc, com_mcr, sc->sc_mcr); 1296 1297 splx(s); 1298 } 1299 #endif /* COM_CONSOLE */ 1300 1301 void 1302 com_attach_subr(struct com_softc *sc) 1303 { 1304 int probe = 0; 1305 u_int8_t lcr, fifo; 1306 u_int32_t cpr; 1307 1308 sc->sc_ier = 0; 1309 /* disable interrupts */ 1310 com_write_reg(sc, com_ier, sc->sc_ier); 1311 1312 #ifdef COM_CONSOLE 1313 if (sc->sc_iot == comconsiot && sc->sc_iobase == comconsaddr) { 1314 comconsattached = 1; 1315 delay(10000); /* wait for output to finish */ 1316 SET(sc->sc_hwflags, COM_HW_CONSOLE); 1317 SET(sc->sc_swflags, COM_SW_SOFTCAR); 1318 } 1319 #endif 1320 1321 /* 1322 * Probe for all known forms of UART. 1323 */ 1324 lcr = com_read_reg(sc, com_lcr); 1325 com_write_reg(sc, com_lcr, LCR_EFR); 1326 com_write_reg(sc, com_efr, 0); 1327 com_write_reg(sc, com_lcr, 0); 1328 1329 com_write_reg(sc, com_fifo, FIFO_ENABLE); 1330 delay(100); 1331 1332 /* 1333 * Skip specific probes if attachment code knows it already. 1334 */ 1335 if (sc->sc_uarttype == COM_UART_UNKNOWN) { 1336 switch (com_read_reg(sc, com_iir) >> 6) { 1337 case 0: 1338 sc->sc_uarttype = COM_UART_16450; 1339 break; 1340 case 2: 1341 sc->sc_uarttype = COM_UART_16550; 1342 break; 1343 case 3: 1344 sc->sc_uarttype = COM_UART_16550A; 1345 break; 1346 default: 1347 sc->sc_uarttype = COM_UART_UNKNOWN; 1348 break; 1349 } 1350 probe = 1; 1351 } 1352 1353 /* Probe for ST16650s */ 1354 if (probe && sc->sc_uarttype == COM_UART_16550A) { 1355 com_write_reg(sc, com_lcr, lcr | LCR_DLAB); 1356 if (com_read_reg(sc, com_efr) == 0) { 1357 com_write_reg(sc, com_efr, EFR_CTS); 1358 if (com_read_reg(sc, com_efr) != 0) 1359 sc->sc_uarttype = COM_UART_ST16650; 1360 com_write_reg(sc, com_efr, 0); 1361 } else { 1362 com_write_reg(sc, com_lcr, LCR_EFR); 1363 if (com_read_reg(sc, com_efr) == 0) 1364 sc->sc_uarttype = COM_UART_ST16650V2; 1365 } 1366 } 1367 1368 #if 0 /* until com works with large FIFOs */ 1369 /* Probe for XR16850s */ 1370 if (probe && sc->sc_uarttype == COM_UART_ST16650V2) { 1371 u_int8_t dlbl, dlbh; 1372 1373 /* Enable latch access and get the current values. */ 1374 com_write_reg(sc, com_lcr, lcr | LCR_DLAB); 1375 dlbl = com_read_reg(sc, com_dlbl); 1376 dlbh = com_read_reg(sc, com_dlbh); 1377 1378 /* Zero out the latch divisors */ 1379 com_write_reg(sc, com_dlbl, 0); 1380 com_write_reg(sc, com_dlbh, 0); 1381 1382 if (com_read_reg(sc, com_dlbh) == 0x10) { 1383 sc->sc_uarttype = COM_UART_XR16850; 1384 sc->sc_uartrev = com_read_reg(sc, com_dlbl); 1385 } 1386 1387 /* Reset to original. */ 1388 com_write_reg(sc, com_dlbl, dlbl); 1389 com_write_reg(sc, com_dlbh, dlbh); 1390 } 1391 #endif 1392 1393 /* Probe for TI16750s */ 1394 if (probe && sc->sc_uarttype == COM_UART_16550A) { 1395 com_write_reg(sc, com_lcr, lcr | LCR_DLAB); 1396 com_write_reg(sc, com_fifo, 1397 FIFO_ENABLE | FIFO_ENABLE_64BYTE); 1398 if ((com_read_reg(sc, com_iir) >> 5) == 7) { 1399 #if 0 1400 com_write_reg(sc, com_lcr, 0); 1401 if ((com_read_reg(sc, com_iir) >> 5) == 6) 1402 #endif 1403 sc->sc_uarttype = COM_UART_TI16750; 1404 } 1405 com_write_reg(sc, com_fifo, FIFO_ENABLE); 1406 } 1407 1408 /* Reset the LCR (latch access is probably enabled). */ 1409 com_write_reg(sc, com_lcr, lcr); 1410 1411 /* Probe for 8250 */ 1412 if (probe && sc->sc_uarttype == COM_UART_16450) { 1413 u_int8_t scr0, scr1, scr2; 1414 1415 scr0 = com_read_reg(sc, com_scratch); 1416 com_write_reg(sc, com_scratch, 0xa5); 1417 scr1 = com_read_reg(sc, com_scratch); 1418 com_write_reg(sc, com_scratch, 0x5a); 1419 scr2 = com_read_reg(sc, com_scratch); 1420 com_write_reg(sc, com_scratch, scr0); 1421 1422 if ((scr1 != 0xa5) || (scr2 != 0x5a)) 1423 sc->sc_uarttype = COM_UART_8250; 1424 } 1425 1426 /* 1427 * Print UART type and initialize ourself. 1428 */ 1429 switch (sc->sc_uarttype) { 1430 case COM_UART_UNKNOWN: 1431 printf(": unknown uart\n"); 1432 break; 1433 case COM_UART_8250: 1434 printf(": ns8250, no fifo\n"); 1435 break; 1436 case COM_UART_16450: 1437 printf(": ns16450, no fifo\n"); 1438 break; 1439 case COM_UART_16550: 1440 printf(": ns16550, no working fifo\n"); 1441 break; 1442 case COM_UART_16550A: 1443 if (sc->sc_fifolen == 0) 1444 sc->sc_fifolen = 16; 1445 printf(": ns16550a, %d byte fifo\n", sc->sc_fifolen); 1446 SET(sc->sc_hwflags, COM_HW_FIFO); 1447 break; 1448 case COM_UART_ST16650: 1449 printf(": st16650, no working fifo\n"); 1450 break; 1451 case COM_UART_ST16650V2: 1452 if (sc->sc_fifolen == 0) 1453 sc->sc_fifolen = 32; 1454 printf(": st16650, %d byte fifo\n", sc->sc_fifolen); 1455 SET(sc->sc_hwflags, COM_HW_FIFO); 1456 break; 1457 case COM_UART_ST16C654: 1458 printf(": st16c654, 64 byte fifo\n"); 1459 SET(sc->sc_hwflags, COM_HW_FIFO); 1460 sc->sc_fifolen = 64; 1461 break; 1462 case COM_UART_TI16750: 1463 printf(": ti16750, 64 byte fifo\n"); 1464 SET(sc->sc_hwflags, COM_HW_FIFO); 1465 sc->sc_fifolen = 64; 1466 break; 1467 #if 0 1468 case COM_UART_XR16850: 1469 printf(": xr16850 (rev %d), 128 byte fifo\n", sc->sc_uartrev); 1470 SET(sc->sc_hwflags, COM_HW_FIFO); 1471 sc->sc_fifolen = 128; 1472 break; 1473 #ifdef COM_UART_OX16C950 1474 case COM_UART_OX16C950: 1475 printf(": ox16c950 (rev %d), 128 byte fifo\n", sc->sc_uartrev); 1476 SET(sc->sc_hwflags, COM_HW_FIFO); 1477 sc->sc_fifolen = 128; 1478 break; 1479 #endif 1480 #endif 1481 case COM_UART_XR17V35X: 1482 printf(": xr17v35x, 256 byte fifo\n"); 1483 SET(sc->sc_hwflags, COM_HW_FIFO); 1484 sc->sc_fifolen = 256; 1485 break; 1486 case COM_UART_DW_APB: 1487 printf(": dw16550"); 1488 SET(sc->sc_hwflags, COM_HW_FIFO); 1489 cpr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, com_cpr << 2); 1490 sc->sc_fifolen = CPR_FIFO_MODE(cpr) * 16; 1491 if (sc->sc_fifolen) { 1492 printf(", %d byte fifo\n", sc->sc_fifolen); 1493 } else { 1494 printf("\n"); 1495 /* 1496 * The DW-APB configuration on the Allwinner H6 SoC 1497 * does not provide the CPR register and will be 1498 * detected as having no FIFO. But it does have a 1499 * 256-byte FIFO and with the FIFO disabled the 1500 * LSR_RXRDY bit remains set even if the input 1501 * buffer is empty. As a workaround, treat as a 1502 * 1-byte FIFO. 1503 */ 1504 sc->sc_fifolen = 1; 1505 } 1506 break; 1507 default: 1508 panic("comattach: bad fifo type"); 1509 } 1510 1511 #ifdef COM_CONSOLE 1512 if (!ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) 1513 #endif 1514 if (sc->sc_fifolen < 256) 1515 com_fifo_probe(sc); 1516 1517 if (sc->sc_fifolen == 0) { 1518 CLR(sc->sc_hwflags, COM_HW_FIFO); 1519 sc->sc_fifolen = 1; 1520 } 1521 1522 /* clear and disable fifo */ 1523 /* DW-APB UART cannot turn off FIFO here (ddb will not work) */ 1524 fifo = (sc->sc_uarttype == COM_UART_DW_APB) ? 1525 (FIFO_ENABLE | FIFO_TRIGGER_1) : 0; 1526 com_write_reg(sc, com_fifo, fifo | FIFO_RCV_RST | FIFO_XMT_RST); 1527 if (ISSET(com_read_reg(sc, com_lsr), LSR_RXRDY)) 1528 (void)com_read_reg(sc, com_data); 1529 com_write_reg(sc, com_fifo, fifo); 1530 1531 sc->sc_mcr = 0; 1532 com_write_reg(sc, com_mcr, sc->sc_mcr); 1533 1534 #ifdef COM_CONSOLE 1535 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 1536 int maj; 1537 1538 /* locate the major number */ 1539 for (maj = 0; maj < nchrdev; maj++) 1540 if (cdevsw[maj].d_open == comopen) 1541 break; 1542 1543 KASSERT(maj < nchrdev); 1544 cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit); 1545 1546 printf("%s: console\n", sc->sc_dev.dv_xname); 1547 } 1548 #endif 1549 1550 timeout_set(&sc->sc_diag_tmo, comdiag, sc); 1551 timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc); 1552 sc->sc_si = softintr_establish(IPL_TTY, comsoft, sc); 1553 if (sc->sc_si == NULL) 1554 panic("%s: can't establish soft interrupt", 1555 sc->sc_dev.dv_xname); 1556 1557 /* 1558 * If there are no enable/disable functions, assume the device 1559 * is always enabled. 1560 */ 1561 if (!sc->enable) 1562 sc->enabled = 1; 1563 1564 #ifdef COM_CONSOLE 1565 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) 1566 com_enable_debugport(sc); 1567 #endif 1568 } 1569 1570 void 1571 com_fifo_probe(struct com_softc *sc) 1572 { 1573 u_int8_t fifo, ier; 1574 int timo, len; 1575 1576 if (!ISSET(sc->sc_hwflags, COM_HW_FIFO)) 1577 return; 1578 1579 ier = 0; 1580 com_write_reg(sc, com_ier, ier); 1581 com_write_reg(sc, com_lcr, LCR_DLAB); 1582 com_write_reg(sc, com_dlbl, 3); 1583 com_write_reg(sc, com_dlbh, 0); 1584 com_write_reg(sc, com_lcr, LCR_PNONE | LCR_8BITS); 1585 com_write_reg(sc, com_mcr, MCR_LOOPBACK); 1586 1587 fifo = FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST; 1588 if (sc->sc_uarttype == COM_UART_TI16750) 1589 fifo |= FIFO_ENABLE_64BYTE; 1590 1591 com_write_reg(sc, com_fifo, fifo); 1592 1593 for (len = 0; len < 256; len++) { 1594 com_write_reg(sc, com_data, (len + 1)); 1595 timo = 2000; 1596 while (!ISSET(com_read_reg(sc, com_lsr), 1597 LSR_TXRDY) && --timo) 1598 delay(1); 1599 if (!timo) 1600 break; 1601 } 1602 1603 delay(100); 1604 1605 for (len = 0; len < 256; len++) { 1606 timo = 2000; 1607 while (!ISSET(com_read_reg(sc, com_lsr), 1608 LSR_RXRDY) && --timo) 1609 delay(1); 1610 if (!timo || com_read_reg(sc, com_data) != (len + 1)) 1611 break; 1612 } 1613 1614 /* For safety, always use the smaller value. */ 1615 if (sc->sc_fifolen > len) { 1616 printf("%s: probed fifo depth: %d bytes\n", 1617 sc->sc_dev.dv_xname, len); 1618 sc->sc_fifolen = len; 1619 } 1620 } 1621 1622 uint8_t 1623 com_read_reg(struct com_softc *sc, bus_size_t reg) 1624 { 1625 reg <<= sc->sc_reg_shift; 1626 1627 if (sc->sc_reg_width == 4) 1628 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg); 1629 else 1630 return bus_space_read_1(sc->sc_iot, sc->sc_ioh, reg); 1631 } 1632 1633 void 1634 com_write_reg(struct com_softc *sc, bus_size_t reg, uint8_t value) 1635 { 1636 reg <<= sc->sc_reg_shift; 1637 1638 if (sc->sc_reg_width == 4) 1639 bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, value); 1640 else 1641 bus_space_write_1(sc->sc_iot, sc->sc_ioh, reg, value); 1642 } 1643 1644 #ifdef COM_CONSOLE 1645 1646 u_char comcons_reg_width; 1647 u_char comcons_reg_shift; 1648 1649 uint8_t 1650 comcn_read_reg(bus_size_t reg) 1651 { 1652 reg <<= comcons_reg_shift; 1653 1654 if (comcons_reg_width == 4) 1655 return bus_space_read_4(comconsiot, comconsioh, reg); 1656 else 1657 return bus_space_read_1(comconsiot, comconsioh, reg); 1658 } 1659 1660 void 1661 comcn_write_reg(bus_size_t reg, uint8_t value) 1662 { 1663 reg <<= comcons_reg_shift; 1664 1665 if (comcons_reg_width == 4) 1666 bus_space_write_4(comconsiot, comconsioh, reg, value); 1667 else 1668 bus_space_write_1(comconsiot, comconsioh, reg, value); 1669 } 1670 1671 #endif 1672