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