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