1 /* $NetBSD: plcom.c,v 1.64 2021/10/20 01:09:49 jmcneill Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 ARM Ltd 5 * 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 * 3. The name of the company may not be used to endorse or promote 16 * products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * Copyright (c) 1998, 1999, 2012 The NetBSD Foundation, Inc. 32 * All rights reserved. 33 * 34 * This code is derived from software contributed to The NetBSD Foundation 35 * by Charles M. Hannum and Nick Hudson. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 47 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 48 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 49 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 50 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 51 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 52 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 53 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 54 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 56 * POSSIBILITY OF SUCH DAMAGE. 57 */ 58 59 /* 60 * Copyright (c) 1991 The Regents of the University of California. 61 * All rights reserved. 62 * 63 * Redistribution and use in source and binary forms, with or without 64 * modification, are permitted provided that the following conditions 65 * are met: 66 * 1. Redistributions of source code must retain the above copyright 67 * notice, this list of conditions and the following disclaimer. 68 * 2. Redistributions in binary form must reproduce the above copyright 69 * notice, this list of conditions and the following disclaimer in the 70 * documentation and/or other materials provided with the distribution. 71 * 3. Neither the name of the University nor the names of its contributors 72 * may be used to endorse or promote products derived from this software 73 * without specific prior written permission. 74 * 75 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 76 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 77 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 78 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 79 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 80 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 81 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 82 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 83 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 84 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 85 * SUCH DAMAGE. 86 * 87 * @(#)com.c 7.5 (Berkeley) 5/16/91 88 */ 89 90 /* 91 * COM driver for the Prime Cell PL010 and PL011 UARTs. Both are is similar to 92 * the 16C550, but have a completely different programmer's model. 93 * Derived from the NS16550AF com driver. 94 */ 95 96 #include <sys/cdefs.h> 97 __KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.64 2021/10/20 01:09:49 jmcneill Exp $"); 98 99 #include "opt_plcom.h" 100 #include "opt_ddb.h" 101 #include "opt_kgdb.h" 102 #include "opt_lockdebug.h" 103 #include "opt_multiprocessor.h" 104 105 /* 106 * Override cnmagic(9) macro before including <sys/systm.h>. 107 * We need to know if cn_check_magic triggered debugger, so set a flag. 108 * Callers of cn_check_magic must declare int cn_trapped = 0; 109 * XXX: this is *ugly*! 110 */ 111 #define cn_trap() \ 112 do { \ 113 console_debugger(); \ 114 cn_trapped = 1; \ 115 } while (/* CONSTCOND */ 0) 116 117 #include <sys/param.h> 118 #include <sys/systm.h> 119 #include <sys/ioctl.h> 120 #include <sys/select.h> 121 #include <sys/tty.h> 122 #include <sys/proc.h> 123 #include <sys/conf.h> 124 #include <sys/file.h> 125 #include <sys/uio.h> 126 #include <sys/kernel.h> 127 #include <sys/syslog.h> 128 #include <sys/types.h> 129 #include <sys/device.h> 130 #include <sys/malloc.h> 131 #include <sys/timepps.h> 132 #include <sys/vnode.h> 133 #include <sys/kauth.h> 134 #include <sys/intr.h> 135 #include <sys/bus.h> 136 #ifdef RND_COM 137 #include <sys/rndsource.h> 138 #endif 139 140 #include <evbarm/dev/plcomreg.h> 141 #include <evbarm/dev/plcomvar.h> 142 143 #include <dev/cons.h> 144 145 static void plcom_enable_debugport (struct plcom_softc *); 146 147 void plcom_config (struct plcom_softc *); 148 void plcom_shutdown (struct plcom_softc *); 149 int pl010comspeed (long, long); 150 int pl011comspeed (long, long); 151 static u_char cflag2lcr (tcflag_t); 152 int plcomparam (struct tty *, struct termios *); 153 void plcomstart (struct tty *); 154 int plcomhwiflow (struct tty *, int); 155 156 void plcom_loadchannelregs (struct plcom_softc *); 157 void plcom_hwiflow (struct plcom_softc *); 158 void plcom_break (struct plcom_softc *, int); 159 void plcom_modem (struct plcom_softc *, int); 160 void tiocm_to_plcom (struct plcom_softc *, u_long, int); 161 int plcom_to_tiocm (struct plcom_softc *); 162 void plcom_iflush (struct plcom_softc *); 163 164 int plcom_common_getc (dev_t, struct plcom_instance *); 165 void plcom_common_putc (dev_t, struct plcom_instance *, int); 166 167 int plcominit (struct plcom_instance *, int, int, tcflag_t); 168 169 dev_type_open(plcomopen); 170 dev_type_close(plcomclose); 171 dev_type_read(plcomread); 172 dev_type_write(plcomwrite); 173 dev_type_ioctl(plcomioctl); 174 dev_type_stop(plcomstop); 175 dev_type_tty(plcomtty); 176 dev_type_poll(plcompoll); 177 178 int plcomcngetc (dev_t); 179 void plcomcnputc (dev_t, int); 180 void plcomcnpollc (dev_t, int); 181 void plcomcnhalt (dev_t); 182 183 #define integrate static inline 184 void plcomsoft (void *); 185 integrate void plcom_rxsoft (struct plcom_softc *, struct tty *); 186 integrate void plcom_txsoft (struct plcom_softc *, struct tty *); 187 integrate void plcom_stsoft (struct plcom_softc *, struct tty *); 188 integrate void plcom_schedrx (struct plcom_softc *); 189 void plcomdiag (void *); 190 191 bool plcom_intstatus(struct plcom_instance *, u_int *); 192 193 extern struct cfdriver plcom_cd; 194 195 const struct cdevsw plcom_cdevsw = { 196 .d_open = plcomopen, 197 .d_close = plcomclose, 198 .d_read = plcomread, 199 .d_write = plcomwrite, 200 .d_ioctl = plcomioctl, 201 .d_stop = plcomstop, 202 .d_tty = plcomtty, 203 .d_poll = plcompoll, 204 .d_mmap = nommap, 205 .d_kqfilter = ttykqfilter, 206 .d_discard = nodiscard, 207 .d_flag = D_TTY 208 }; 209 210 /* 211 * Make this an option variable one can patch. 212 * But be warned: this must be a power of 2! 213 */ 214 u_int plcom_rbuf_size = PLCOM_RING_SIZE; 215 216 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ 217 u_int plcom_rbuf_hiwat = (PLCOM_RING_SIZE * 1) / 4; 218 u_int plcom_rbuf_lowat = (PLCOM_RING_SIZE * 3) / 4; 219 220 static int plcomconsunit = -1; 221 static struct plcom_instance plcomcons_info; 222 223 static int plcomconsattached; 224 static int plcomconsrate; 225 static tcflag_t plcomconscflag; 226 static struct cnm_state plcom_cnm_state; 227 228 static int ppscap = 229 PPS_TSFMT_TSPEC | 230 PPS_CAPTUREASSERT | 231 PPS_CAPTURECLEAR | 232 #ifdef PPS_SYNC 233 PPS_HARDPPSONASSERT | PPS_HARDPPSONCLEAR | 234 #endif /* PPS_SYNC */ 235 PPS_OFFSETASSERT | PPS_OFFSETCLEAR; 236 237 #ifdef KGDB 238 #include <sys/kgdb.h> 239 240 static struct plcom_instance plcomkgdb_info; 241 static int plcom_kgdb_attached; 242 243 int plcom_kgdb_getc (void *); 244 void plcom_kgdb_putc (void *, int); 245 #endif /* KGDB */ 246 247 #define PLCOMDIALOUT_MASK TTDIALOUT_MASK 248 249 #define PLCOMUNIT(x) TTUNIT(x) 250 #define PLCOMDIALOUT(x) TTDIALOUT(x) 251 252 #define PLCOM_ISALIVE(sc) ((sc)->enabled != 0 && \ 253 device_is_active((sc)->sc_dev)) 254 255 #define BR BUS_SPACE_BARRIER_READ 256 #define BW BUS_SPACE_BARRIER_WRITE 257 #define PLCOM_BARRIER(pi, f) \ 258 bus_space_barrier((pi)->pi_iot, (pi)->pi_ioh, 0, (pi)->pi_size, (f)) 259 260 static uint8_t 261 pread1(struct plcom_instance *pi, bus_size_t reg) 262 { 263 if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) 264 return bus_space_read_1(pi->pi_iot, pi->pi_ioh, reg); 265 266 return bus_space_read_4(pi->pi_iot, pi->pi_ioh, reg & -4) >> 267 (8 * (reg & 3)); 268 } 269 int nhcr; 270 static void 271 pwrite1(struct plcom_instance *pi, bus_size_t o, uint8_t val) 272 { 273 if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) { 274 bus_space_write_1(pi->pi_iot, pi->pi_ioh, o, val); 275 } else { 276 const size_t shift = 8 * (o & 3); 277 o &= -4; 278 uint32_t tmp = bus_space_read_4(pi->pi_iot, pi->pi_ioh, o); 279 tmp = (val << shift) | (tmp & ~(0xff << shift)); 280 bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, tmp); 281 } 282 } 283 284 static void 285 pwritem1(struct plcom_instance *pi, bus_size_t o, const uint8_t *datap, 286 bus_size_t count) 287 { 288 if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) { 289 bus_space_write_multi_1(pi->pi_iot, pi->pi_ioh, o, datap, count); 290 } else { 291 KASSERT((o & 3) == 0); 292 while (count--) { 293 bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, *datap++); 294 }; 295 } 296 } 297 298 #define PREAD1(pi, reg) pread1(pi, reg) 299 #define PREAD4(pi, reg) \ 300 bus_space_read_4((pi)->pi_iot, (pi)->pi_ioh, (reg)) 301 302 #define PWRITE1(pi, reg, val) pwrite1(pi, reg, val) 303 #define PWRITEM1(pi, reg, d, c) pwritem1(pi, reg, d, c) 304 #define PWRITE4(pi, reg, val) \ 305 bus_space_write_4((pi)->pi_iot, (pi)->pi_ioh, (reg), (val)) 306 307 int 308 pl010comspeed(long speed, long frequency) 309 { 310 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */ 311 312 int x, err; 313 314 #if 0 315 if (speed == 0) 316 return 0; 317 #endif 318 if (speed <= 0) 319 return -1; 320 x = divrnd(frequency / 16, speed); 321 if (x <= 0) 322 return -1; 323 err = divrnd(((quad_t)frequency) * 1000 / 16, speed * x) - 1000; 324 if (err < 0) 325 err = -err; 326 if (err > PLCOM_TOLERANCE) 327 return -1; 328 return x; 329 330 #undef divrnd 331 } 332 333 int 334 pl011comspeed(long speed, long frequency) 335 { 336 int denom = 16 * speed; 337 int div = frequency / denom; 338 int rem = frequency % denom; 339 340 int ibrd = div << 6; 341 int fbrd = (((8 * rem) / speed) + 1) / 2; 342 343 /* Tolerance? */ 344 return ibrd | fbrd; 345 } 346 347 #ifdef PLCOM_DEBUG 348 int plcom_debug = 0; 349 350 void plcomstatus (struct plcom_softc *, const char *); 351 void 352 plcomstatus(struct plcom_softc *sc, const char *str) 353 { 354 struct tty *tp = sc->sc_tty; 355 356 printf("%s: %s %sclocal %sdcd %sts_carr_on %sdtr %stx_stopped\n", 357 device_xname(sc->sc_dev), str, 358 ISSET(tp->t_cflag, CLOCAL) ? "+" : "-", 359 ISSET(sc->sc_msr, PL01X_MSR_DCD) ? "+" : "-", 360 ISSET(tp->t_state, TS_CARR_ON) ? "+" : "-", 361 ISSET(sc->sc_mcr, PL01X_MCR_DTR) ? "+" : "-", 362 sc->sc_tx_stopped ? "+" : "-"); 363 364 printf("%s: %s %scrtscts %scts %sts_ttstop %srts %xrx_flags\n", 365 device_xname(sc->sc_dev), str, 366 ISSET(tp->t_cflag, CRTSCTS) ? "+" : "-", 367 ISSET(sc->sc_msr, PL01X_MSR_CTS) ? "+" : "-", 368 ISSET(tp->t_state, TS_TTSTOP) ? "+" : "-", 369 ISSET(sc->sc_mcr, PL01X_MCR_RTS) ? "+" : "-", 370 sc->sc_rx_flags); 371 } 372 #endif 373 374 #if 0 375 int 376 plcomprobe1(bus_space_tag_t iot, bus_space_handle_t ioh) 377 { 378 int data; 379 380 /* Disable the UART. */ 381 bus_space_write_1(iot, ioh, plcom_cr, 0); 382 /* Make sure the FIFO is off. */ 383 bus_space_write_1(iot, ioh, plcom_lcr, PL01X_LCR_8BITS); 384 /* Disable interrupts. */ 385 bus_space_write_1(iot, ioh, plcom_iir, 0); 386 387 /* Make sure we swallow anything in the receiving register. */ 388 data = bus_space_read_1(iot, ioh, plcom_dr); 389 390 if (bus_space_read_1(iot, ioh, plcom_lcr) != PL01X_LCR_8BITS) 391 return 0; 392 393 data = bus_space_read_1(iot, ioh, plcom_fr) & (PL01X_FR_RXFF | PL01X_FR_RXFE); 394 395 if (data != PL01X_FR_RXFE) 396 return 0; 397 398 return 1; 399 } 400 #endif 401 402 /* 403 * No locking in this routine; it is only called during attach, 404 * or with the port already locked. 405 */ 406 static void 407 plcom_enable_debugport(struct plcom_softc *sc) 408 { 409 struct plcom_instance *pi = &sc->sc_pi; 410 411 sc->sc_cr = PL01X_CR_UARTEN; 412 SET(sc->sc_mcr, PL01X_MCR_DTR | PL01X_MCR_RTS); 413 414 /* Turn on line break interrupt, set carrier. */ 415 switch (pi->pi_type) { 416 case PLCOM_TYPE_PL010: 417 SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE); 418 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 419 if (sc->sc_set_mcr) { 420 /* XXX device_unit() abuse */ 421 sc->sc_set_mcr(sc->sc_set_mcr_arg, 422 device_unit(sc->sc_dev), sc->sc_mcr); 423 } 424 break; 425 case PLCOM_TYPE_PL011: 426 sc->sc_imsc = PL011_INT_RX | PL011_INT_RT; 427 SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE); 428 SET(sc->sc_cr, PL011_MCR(sc->sc_mcr)); 429 PWRITE4(pi, PL011COM_CR, sc->sc_cr); 430 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 431 break; 432 } 433 434 } 435 436 void 437 plcom_attach_subr(struct plcom_softc *sc) 438 { 439 struct plcom_instance *pi = &sc->sc_pi; 440 struct tty *tp; 441 442 callout_init(&sc->sc_diag_callout, 0); 443 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH); 444 445 switch (pi->pi_type) { 446 case PLCOM_TYPE_PL010: 447 case PLCOM_TYPE_PL011: 448 break; 449 default: 450 aprint_error_dev(sc->sc_dev, 451 "Unknown plcom type: %d\n", pi->pi_type); 452 return; 453 } 454 455 /* Disable interrupts before configuring the device. */ 456 sc->sc_cr = 0; 457 sc->sc_imsc = 0; 458 459 if (bus_space_is_equal(pi->pi_iot, plcomcons_info.pi_iot) && 460 pi->pi_iobase == plcomcons_info.pi_iobase) { 461 plcomconsattached = 1; 462 463 /* Make sure the console is always "hardwired". */ 464 delay(1000); /* wait for output to finish */ 465 SET(sc->sc_hwflags, PLCOM_HW_CONSOLE); 466 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); 467 /* 468 * Must re-enable the console immediately, or we will 469 * hang when trying to print. 470 */ 471 sc->sc_cr = PL01X_CR_UARTEN; 472 if (pi->pi_type == PLCOM_TYPE_PL011) 473 SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE); 474 } 475 476 switch (pi->pi_type) { 477 case PLCOM_TYPE_PL010: 478 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 479 break; 480 481 case PLCOM_TYPE_PL011: 482 PWRITE4(pi, PL011COM_CR, sc->sc_cr); 483 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 484 break; 485 } 486 487 if (sc->sc_fifolen == 0) { 488 switch (pi->pi_type) { 489 case PLCOM_TYPE_PL010: 490 /* 491 * The PL010 has a 16-byte fifo, but the tx interrupt 492 * triggers when there is space for 8 more bytes. 493 */ 494 sc->sc_fifolen = 8; 495 break; 496 case PLCOM_TYPE_PL011: 497 /* Some revisions have a 32 byte TX FIFO */ 498 sc->sc_fifolen = 16; 499 break; 500 } 501 } 502 503 if (ISSET(sc->sc_hwflags, PLCOM_HW_TXFIFO_DISABLE)) { 504 sc->sc_fifolen = 1; 505 aprint_normal_dev(sc->sc_dev, "txfifo disabled\n"); 506 } 507 508 if (sc->sc_fifolen > 1) 509 SET(sc->sc_hwflags, PLCOM_HW_FIFO); 510 511 tp = tty_alloc(); 512 tp->t_oproc = plcomstart; 513 tp->t_param = plcomparam; 514 tp->t_hwiflow = plcomhwiflow; 515 516 sc->sc_tty = tp; 517 sc->sc_rbuf = malloc(plcom_rbuf_size << 1, M_DEVBUF, M_WAITOK); 518 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 519 sc->sc_rbavail = plcom_rbuf_size; 520 sc->sc_ebuf = sc->sc_rbuf + (plcom_rbuf_size << 1); 521 522 tty_attach(tp); 523 524 if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 525 int maj; 526 527 /* locate the major number */ 528 maj = cdevsw_lookup_major(&plcom_cdevsw); 529 530 tp->t_dev = cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); 531 532 aprint_normal_dev(sc->sc_dev, "console\n"); 533 } 534 535 #ifdef KGDB 536 /* 537 * Allow kgdb to "take over" this port. If this is 538 * the kgdb device, it has exclusive use. 539 */ 540 if (bus_space_is_equal(pi->pi_iot, plcomkgdb_info.pi_iot) && 541 pi->pi_iobase == plcomkgdb_info.pi_iobase) { 542 if (!ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 543 plcom_kgdb_attached = 1; 544 545 SET(sc->sc_hwflags, PLCOM_HW_KGDB); 546 } 547 aprint_normal_dev(sc->sc_dev, "kgdb\n"); 548 } 549 #endif 550 551 sc->sc_si = softint_establish(SOFTINT_SERIAL, plcomsoft, sc); 552 553 #ifdef RND_COM 554 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 555 RND_TYPE_TTY, RND_FLAG_DEFAULT); 556 #endif 557 558 /* 559 * if there are no enable/disable functions, assume the device 560 * is always enabled 561 */ 562 if (!sc->enable) 563 sc->enabled = 1; 564 565 plcom_config(sc); 566 567 SET(sc->sc_hwflags, PLCOM_HW_DEV_OK); 568 } 569 570 void 571 plcom_config(struct plcom_softc *sc) 572 { 573 struct plcom_instance *pi = &sc->sc_pi; 574 575 /* Disable interrupts before configuring the device. */ 576 sc->sc_cr = 0; 577 sc->sc_imsc = 0; 578 switch (pi->pi_type) { 579 case PLCOM_TYPE_PL010: 580 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 581 break; 582 583 case PLCOM_TYPE_PL011: 584 PWRITE4(pi, PL011COM_CR, sc->sc_cr); 585 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 586 break; 587 } 588 589 if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE|PLCOM_HW_KGDB)) 590 plcom_enable_debugport(sc); 591 } 592 593 int 594 plcom_detach(device_t self, int flags) 595 { 596 struct plcom_softc *sc = device_private(self); 597 int maj, mn; 598 599 if (sc->sc_hwflags & (PLCOM_HW_CONSOLE|PLCOM_HW_KGDB)) 600 return EBUSY; 601 602 if (sc->disable != NULL && sc->enabled != 0) { 603 (*sc->disable)(sc); 604 sc->enabled = 0; 605 } 606 607 /* locate the major number */ 608 maj = cdevsw_lookup_major(&plcom_cdevsw); 609 610 /* Nuke the vnodes for any open instances. */ 611 mn = device_unit(self); 612 vdevgone(maj, mn, mn, VCHR); 613 614 mn |= PLCOMDIALOUT_MASK; 615 vdevgone(maj, mn, mn, VCHR); 616 617 if (sc->sc_rbuf == NULL) { 618 /* 619 * Ring buffer allocation failed in the plcom_attach_subr, 620 * only the tty is allocated, and nothing else. 621 */ 622 tty_free(sc->sc_tty); 623 return 0; 624 } 625 626 /* Free the receive buffer. */ 627 free(sc->sc_rbuf, M_DEVBUF); 628 629 /* Detach and free the tty. */ 630 tty_detach(sc->sc_tty); 631 tty_free(sc->sc_tty); 632 633 /* Unhook the soft interrupt handler. */ 634 softint_disestablish(sc->sc_si); 635 636 #ifdef RND_COM 637 /* Unhook the entropy source. */ 638 rnd_detach_source(&sc->rnd_source); 639 #endif 640 callout_destroy(&sc->sc_diag_callout); 641 642 /* Destroy the lock. */ 643 mutex_destroy(&sc->sc_lock); 644 645 return 0; 646 } 647 648 int 649 plcom_activate(device_t self, enum devact act) 650 { 651 struct plcom_softc *sc = device_private(self); 652 653 switch (act) { 654 case DVACT_DEACTIVATE: 655 sc->enabled = 0; 656 return 0; 657 default: 658 return EOPNOTSUPP; 659 } 660 } 661 662 void 663 plcom_shutdown(struct plcom_softc *sc) 664 { 665 struct plcom_instance *pi = &sc->sc_pi; 666 struct tty *tp = sc->sc_tty; 667 mutex_spin_enter(&sc->sc_lock); 668 669 /* If we were asserting flow control, then deassert it. */ 670 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); 671 plcom_hwiflow(sc); 672 673 /* Clear any break condition set with TIOCSBRK. */ 674 plcom_break(sc, 0); 675 676 /* Turn off PPS capture on last close. */ 677 mutex_spin_enter(&timecounter_lock); 678 sc->sc_ppsmask = 0; 679 sc->ppsparam.mode = 0; 680 mutex_spin_exit(&timecounter_lock); 681 682 /* 683 * Hang up if necessary. Wait a bit, so the other side has time to 684 * notice even if we immediately open the port again. 685 * Avoid tsleeping above splhigh(). 686 */ 687 if (ISSET(tp->t_cflag, HUPCL)) { 688 plcom_modem(sc, 0); 689 microuptime(&sc->sc_hup_pending); 690 sc->sc_hup_pending.tv_sec++; 691 } 692 693 sc->sc_cr = 0; 694 sc->sc_imsc = 0; 695 /* Turn off interrupts. */ 696 if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 697 /* interrupt on break */ 698 699 sc->sc_cr = PL01X_CR_UARTEN; 700 sc->sc_imsc = 0; 701 switch (pi->pi_type) { 702 case PLCOM_TYPE_PL010: 703 SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE); 704 break; 705 case PLCOM_TYPE_PL011: 706 SET(sc->sc_cr, PL011_CR_RXE); 707 SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX); 708 break; 709 } 710 } 711 switch (pi->pi_type) { 712 case PLCOM_TYPE_PL010: 713 SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE); 714 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 715 break; 716 case PLCOM_TYPE_PL011: 717 SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE); 718 SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX); 719 PWRITE4(pi, PL011COM_CR, sc->sc_cr); 720 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 721 break; 722 } 723 724 mutex_spin_exit(&sc->sc_lock); 725 if (sc->disable) { 726 #ifdef DIAGNOSTIC 727 if (!sc->enabled) 728 panic("plcom_shutdown: not enabled?"); 729 #endif 730 (*sc->disable)(sc); 731 sc->enabled = 0; 732 } 733 } 734 735 int 736 plcomopen(dev_t dev, int flag, int mode, struct lwp *l) 737 { 738 struct plcom_softc *sc; 739 struct plcom_instance *pi; 740 struct tty *tp; 741 int s; 742 int error; 743 744 sc = device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 745 if (sc == NULL || !ISSET(sc->sc_hwflags, PLCOM_HW_DEV_OK) || 746 sc->sc_rbuf == NULL) 747 return ENXIO; 748 749 if (!device_is_active(sc->sc_dev)) 750 return ENXIO; 751 752 pi = &sc->sc_pi; 753 754 #ifdef KGDB 755 /* 756 * If this is the kgdb port, no other use is permitted. 757 */ 758 if (ISSET(sc->sc_hwflags, PLCOM_HW_KGDB)) 759 return EBUSY; 760 #endif 761 762 tp = sc->sc_tty; 763 764 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 765 return (EBUSY); 766 767 s = spltty(); 768 769 /* 770 * Do the following iff this is a first open. 771 */ 772 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 773 struct termios t; 774 struct timeval now, diff; 775 776 tp->t_dev = dev; 777 778 if (sc->enable) { 779 if ((*sc->enable)(sc)) { 780 splx(s); 781 aprint_error_dev(sc->sc_dev, 782 "device enable failed\n"); 783 return EIO; 784 } 785 mutex_spin_enter(&sc->sc_lock); 786 sc->enabled = 1; 787 plcom_config(sc); 788 } else { 789 mutex_spin_enter(&sc->sc_lock); 790 } 791 792 if (timerisset(&sc->sc_hup_pending)) { 793 microuptime(&now); 794 while (timercmp(&now, &sc->sc_hup_pending, <)) { 795 timersub(&sc->sc_hup_pending, &now, &diff); 796 const int ms = diff.tv_sec * 100 + 797 diff.tv_usec / 1000; 798 kpause(ttclos, false, uimax(mstohz(ms), 1), 799 &sc->sc_lock); 800 microuptime(&now); 801 } 802 timerclear(&sc->sc_hup_pending); 803 } 804 805 /* Turn on interrupts. */ 806 /* IER_ERXRDY | IER_ERLS | IER_EMSC; */ 807 /* Fetch the current modem control status, needed later. */ 808 sc->sc_cr = PL01X_CR_UARTEN; 809 switch (pi->pi_type) { 810 case PLCOM_TYPE_PL010: 811 SET(sc->sc_cr, 812 PL010_CR_RIE | PL010_CR_RTIE | PL010_CR_MSIE); 813 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 814 sc->sc_msr = PREAD1(pi, PL01XCOM_FR); 815 break; 816 case PLCOM_TYPE_PL011: 817 SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE); 818 SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX | 819 PL011_INT_MSMASK); 820 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 821 sc->sc_msr = PREAD4(pi, PL01XCOM_FR); 822 break; 823 } 824 825 /* Clear PPS capture state on first open. */ 826 827 mutex_spin_enter(&timecounter_lock); 828 sc->sc_ppsmask = 0; 829 sc->ppsparam.mode = 0; 830 mutex_spin_exit(&timecounter_lock); 831 832 mutex_spin_exit(&sc->sc_lock); 833 834 /* 835 * Initialize the termios status to the defaults. Add in the 836 * sticky bits from TIOCSFLAGS. 837 */ 838 if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 839 t.c_ospeed = plcomconsrate; 840 t.c_cflag = plcomconscflag; 841 } else { 842 t.c_ospeed = TTYDEF_SPEED; 843 t.c_cflag = TTYDEF_CFLAG; 844 } 845 t.c_ispeed = t.c_ospeed; 846 847 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) 848 SET(t.c_cflag, CLOCAL); 849 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) 850 SET(t.c_cflag, CRTSCTS); 851 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) 852 SET(t.c_cflag, MDMBUF); 853 /* Make sure plcomparam() will do something. */ 854 tp->t_ospeed = 0; 855 (void) plcomparam(tp, &t); 856 tp->t_iflag = TTYDEF_IFLAG; 857 tp->t_oflag = TTYDEF_OFLAG; 858 tp->t_lflag = TTYDEF_LFLAG; 859 ttychars(tp); 860 ttsetwater(tp); 861 862 mutex_spin_enter(&sc->sc_lock); 863 864 /* 865 * Turn on DTR. We must always do this, even if carrier is not 866 * present, because otherwise we'd have to use TIOCSDTR 867 * immediately after setting CLOCAL, which applications do not 868 * expect. We always assert DTR while the device is open 869 * unless explicitly requested to deassert it. 870 */ 871 plcom_modem(sc, 1); 872 873 /* Clear the input ring, and unblock. */ 874 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; 875 sc->sc_rbavail = plcom_rbuf_size; 876 plcom_iflush(sc); 877 CLR(sc->sc_rx_flags, RX_ANY_BLOCK); 878 plcom_hwiflow(sc); 879 880 #ifdef PLCOM_DEBUG 881 if (plcom_debug) 882 plcomstatus(sc, "plcomopen "); 883 #endif 884 885 mutex_spin_exit(&sc->sc_lock); 886 } 887 888 splx(s); 889 890 error = ttyopen(tp, PLCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); 891 if (error) 892 goto bad; 893 894 error = (*tp->t_linesw->l_open)(dev, tp); 895 if (error) 896 goto bad; 897 898 return 0; 899 900 bad: 901 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 902 /* 903 * We failed to open the device, and nobody else had it opened. 904 * Clean up the state as appropriate. 905 */ 906 plcom_shutdown(sc); 907 } 908 909 return error; 910 } 911 912 int 913 plcomclose(dev_t dev, int flag, int mode, struct lwp *l) 914 { 915 struct plcom_softc *sc = 916 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 917 struct tty *tp = sc->sc_tty; 918 919 /* XXX This is for cons.c. */ 920 if (!ISSET(tp->t_state, TS_ISOPEN)) 921 return 0; 922 923 (*tp->t_linesw->l_close)(tp, flag); 924 ttyclose(tp); 925 926 if (PLCOM_ISALIVE(sc) == 0) 927 return 0; 928 929 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 930 /* 931 * Although we got a last close, the device may still be in 932 * use; e.g. if this was the dialout node, and there are still 933 * processes waiting for carrier on the non-dialout node. 934 */ 935 plcom_shutdown(sc); 936 } 937 938 return 0; 939 } 940 941 int 942 plcomread(dev_t dev, struct uio *uio, int flag) 943 { 944 struct plcom_softc *sc = 945 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 946 struct tty *tp = sc->sc_tty; 947 948 if (PLCOM_ISALIVE(sc) == 0) 949 return EIO; 950 951 return (*tp->t_linesw->l_read)(tp, uio, flag); 952 } 953 954 int 955 plcomwrite(dev_t dev, struct uio *uio, int flag) 956 { 957 struct plcom_softc *sc = 958 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 959 struct tty *tp = sc->sc_tty; 960 961 if (PLCOM_ISALIVE(sc) == 0) 962 return EIO; 963 964 return (*tp->t_linesw->l_write)(tp, uio, flag); 965 } 966 967 int 968 plcompoll(dev_t dev, int events, struct lwp *l) 969 { 970 struct plcom_softc *sc = 971 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 972 struct tty *tp = sc->sc_tty; 973 974 if (PLCOM_ISALIVE(sc) == 0) 975 return EIO; 976 977 return (*tp->t_linesw->l_poll)(tp, events, l); 978 } 979 980 struct tty * 981 plcomtty(dev_t dev) 982 { 983 struct plcom_softc *sc = 984 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 985 struct tty *tp = sc->sc_tty; 986 987 return tp; 988 } 989 990 int 991 plcomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 992 { 993 struct plcom_softc *sc = 994 device_lookup_private(&plcom_cd, PLCOMUNIT(dev)); 995 struct tty *tp; 996 int error; 997 998 if (sc == NULL) 999 return ENXIO; 1000 if (PLCOM_ISALIVE(sc) == 0) 1001 return EIO; 1002 1003 tp = sc->sc_tty; 1004 1005 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 1006 if (error != EPASSTHROUGH) 1007 return error; 1008 1009 error = ttioctl(tp, cmd, data, flag, l); 1010 if (error != EPASSTHROUGH) 1011 return error; 1012 1013 error = 0; 1014 switch (cmd) { 1015 case TIOCSFLAGS: 1016 error = kauth_authorize_device_tty(l->l_cred, 1017 KAUTH_DEVICE_TTY_PRIVSET, tp); 1018 break; 1019 default: 1020 /* nothing */ 1021 break; 1022 } 1023 if (error) { 1024 return error; 1025 } 1026 1027 mutex_spin_enter(&sc->sc_lock); 1028 switch (cmd) { 1029 case TIOCSBRK: 1030 plcom_break(sc, 1); 1031 break; 1032 1033 case TIOCCBRK: 1034 plcom_break(sc, 0); 1035 break; 1036 1037 case TIOCSDTR: 1038 plcom_modem(sc, 1); 1039 break; 1040 1041 case TIOCCDTR: 1042 plcom_modem(sc, 0); 1043 break; 1044 1045 case TIOCGFLAGS: 1046 *(int *)data = sc->sc_swflags; 1047 break; 1048 1049 case TIOCSFLAGS: 1050 sc->sc_swflags = *(int *)data; 1051 break; 1052 1053 case TIOCMSET: 1054 case TIOCMBIS: 1055 case TIOCMBIC: 1056 tiocm_to_plcom(sc, cmd, *(int *)data); 1057 break; 1058 1059 case TIOCMGET: 1060 *(int *)data = plcom_to_tiocm(sc); 1061 break; 1062 1063 case PPS_IOC_CREATE: 1064 break; 1065 1066 case PPS_IOC_DESTROY: 1067 break; 1068 1069 case PPS_IOC_GETPARAMS: { 1070 pps_params_t *pp; 1071 pp = (pps_params_t *)data; 1072 mutex_spin_enter(&timecounter_lock); 1073 *pp = sc->ppsparam; 1074 mutex_spin_exit(&timecounter_lock); 1075 break; 1076 } 1077 1078 case PPS_IOC_SETPARAMS: { 1079 pps_params_t *pp; 1080 int mode; 1081 pp = (pps_params_t *)data; 1082 mutex_spin_enter(&timecounter_lock); 1083 if (pp->mode & ~ppscap) { 1084 error = EINVAL; 1085 mutex_spin_exit(&timecounter_lock); 1086 break; 1087 } 1088 sc->ppsparam = *pp; 1089 /* 1090 * Compute msr masks from user-specified timestamp state. 1091 */ 1092 mode = sc->ppsparam.mode; 1093 #ifdef PPS_SYNC 1094 if (mode & PPS_HARDPPSONASSERT) { 1095 mode |= PPS_CAPTUREASSERT; 1096 /* XXX revoke any previous HARDPPS source */ 1097 } 1098 if (mode & PPS_HARDPPSONCLEAR) { 1099 mode |= PPS_CAPTURECLEAR; 1100 /* XXX revoke any previous HARDPPS source */ 1101 } 1102 #endif /* PPS_SYNC */ 1103 switch (mode & PPS_CAPTUREBOTH) { 1104 case 0: 1105 sc->sc_ppsmask = 0; 1106 break; 1107 1108 case PPS_CAPTUREASSERT: 1109 sc->sc_ppsmask = PL01X_MSR_DCD; 1110 sc->sc_ppsassert = PL01X_MSR_DCD; 1111 sc->sc_ppsclear = -1; 1112 break; 1113 1114 case PPS_CAPTURECLEAR: 1115 sc->sc_ppsmask = PL01X_MSR_DCD; 1116 sc->sc_ppsassert = -1; 1117 sc->sc_ppsclear = 0; 1118 break; 1119 1120 case PPS_CAPTUREBOTH: 1121 sc->sc_ppsmask = PL01X_MSR_DCD; 1122 sc->sc_ppsassert = PL01X_MSR_DCD; 1123 sc->sc_ppsclear = 0; 1124 break; 1125 1126 default: 1127 error = EINVAL; 1128 break; 1129 } 1130 mutex_spin_exit(&timecounter_lock); 1131 break; 1132 } 1133 1134 case PPS_IOC_GETCAP: 1135 *(int*)data = ppscap; 1136 break; 1137 1138 case PPS_IOC_FETCH: { 1139 pps_info_t *pi; 1140 pi = (pps_info_t *)data; 1141 mutex_spin_enter(&timecounter_lock); 1142 *pi = sc->ppsinfo; 1143 mutex_spin_exit(&timecounter_lock); 1144 break; 1145 } 1146 1147 case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */ 1148 /* 1149 * Some GPS clocks models use the falling rather than 1150 * rising edge as the on-the-second signal. 1151 * The old API has no way to specify PPS polarity. 1152 */ 1153 mutex_spin_enter(&timecounter_lock); 1154 sc->sc_ppsmask = PL01X_MSR_DCD; 1155 #ifndef PPS_TRAILING_EDGE 1156 sc->sc_ppsassert = PL01X_MSR_DCD; 1157 sc->sc_ppsclear = -1; 1158 TIMESPEC_TO_TIMEVAL((struct timeval *)data, 1159 &sc->ppsinfo.assert_timestamp); 1160 #else 1161 sc->sc_ppsassert = -1 1162 sc->sc_ppsclear = 0; 1163 TIMESPEC_TO_TIMEVAL((struct timeval *)data, 1164 &sc->ppsinfo.clear_timestamp); 1165 #endif 1166 mutex_spin_exit(&timecounter_lock); 1167 break; 1168 1169 default: 1170 error = EPASSTHROUGH; 1171 break; 1172 } 1173 1174 mutex_spin_exit(&sc->sc_lock); 1175 1176 #ifdef PLCOM_DEBUG 1177 if (plcom_debug) 1178 plcomstatus(sc, "plcomioctl "); 1179 #endif 1180 1181 return error; 1182 } 1183 1184 integrate void 1185 plcom_schedrx(struct plcom_softc *sc) 1186 { 1187 1188 sc->sc_rx_ready = 1; 1189 1190 /* Wake up the poller. */ 1191 softint_schedule(sc->sc_si); 1192 } 1193 1194 void 1195 plcom_break(struct plcom_softc *sc, int onoff) 1196 { 1197 1198 if (onoff) 1199 SET(sc->sc_lcr, PL01X_LCR_BRK); 1200 else 1201 CLR(sc->sc_lcr, PL01X_LCR_BRK); 1202 1203 if (!sc->sc_heldchange) { 1204 if (sc->sc_tx_busy) { 1205 sc->sc_heldtbc = sc->sc_tbc; 1206 sc->sc_tbc = 0; 1207 sc->sc_heldchange = 1; 1208 } else 1209 plcom_loadchannelregs(sc); 1210 } 1211 } 1212 1213 void 1214 plcom_modem(struct plcom_softc *sc, int onoff) 1215 { 1216 1217 if (sc->sc_mcr_dtr == 0) 1218 return; 1219 1220 if (onoff) 1221 SET(sc->sc_mcr, sc->sc_mcr_dtr); 1222 else 1223 CLR(sc->sc_mcr, sc->sc_mcr_dtr); 1224 1225 if (!sc->sc_heldchange) { 1226 if (sc->sc_tx_busy) { 1227 sc->sc_heldtbc = sc->sc_tbc; 1228 sc->sc_tbc = 0; 1229 sc->sc_heldchange = 1; 1230 } else 1231 plcom_loadchannelregs(sc); 1232 } 1233 } 1234 1235 void 1236 tiocm_to_plcom(struct plcom_softc *sc, u_long how, int ttybits) 1237 { 1238 u_char plcombits; 1239 1240 plcombits = 0; 1241 if (ISSET(ttybits, TIOCM_DTR)) 1242 SET(plcombits, PL01X_MCR_DTR); 1243 if (ISSET(ttybits, TIOCM_RTS)) 1244 SET(plcombits, PL01X_MCR_RTS); 1245 1246 switch (how) { 1247 case TIOCMBIC: 1248 CLR(sc->sc_mcr, plcombits); 1249 break; 1250 1251 case TIOCMBIS: 1252 SET(sc->sc_mcr, plcombits); 1253 break; 1254 1255 case TIOCMSET: 1256 CLR(sc->sc_mcr, PL01X_MCR_DTR | PL01X_MCR_RTS); 1257 SET(sc->sc_mcr, plcombits); 1258 break; 1259 } 1260 1261 if (!sc->sc_heldchange) { 1262 if (sc->sc_tx_busy) { 1263 sc->sc_heldtbc = sc->sc_tbc; 1264 sc->sc_tbc = 0; 1265 sc->sc_heldchange = 1; 1266 } else 1267 plcom_loadchannelregs(sc); 1268 } 1269 } 1270 1271 int 1272 plcom_to_tiocm(struct plcom_softc *sc) 1273 { 1274 u_char plcombits; 1275 int ttybits = 0; 1276 1277 plcombits = sc->sc_mcr; 1278 if (ISSET(plcombits, PL01X_MCR_DTR)) 1279 SET(ttybits, TIOCM_DTR); 1280 if (ISSET(plcombits, PL01X_MCR_RTS)) 1281 SET(ttybits, TIOCM_RTS); 1282 1283 plcombits = sc->sc_msr; 1284 if (ISSET(plcombits, PL01X_MSR_DCD)) 1285 SET(ttybits, TIOCM_CD); 1286 if (ISSET(plcombits, PL01X_MSR_CTS)) 1287 SET(ttybits, TIOCM_CTS); 1288 if (ISSET(plcombits, PL01X_MSR_DSR)) 1289 SET(ttybits, TIOCM_DSR); 1290 if (ISSET(plcombits, PL011_MSR_RI)) 1291 SET(ttybits, TIOCM_RI); 1292 1293 if (sc->sc_cr != 0) 1294 SET(ttybits, TIOCM_LE); 1295 1296 return ttybits; 1297 } 1298 1299 static u_char 1300 cflag2lcr(tcflag_t cflag) 1301 { 1302 u_char lcr = 0; 1303 1304 switch (ISSET(cflag, CSIZE)) { 1305 case CS5: 1306 SET(lcr, PL01X_LCR_5BITS); 1307 break; 1308 case CS6: 1309 SET(lcr, PL01X_LCR_6BITS); 1310 break; 1311 case CS7: 1312 SET(lcr, PL01X_LCR_7BITS); 1313 break; 1314 case CS8: 1315 SET(lcr, PL01X_LCR_8BITS); 1316 break; 1317 } 1318 if (ISSET(cflag, PARENB)) { 1319 SET(lcr, PL01X_LCR_PEN); 1320 if (!ISSET(cflag, PARODD)) 1321 SET(lcr, PL01X_LCR_EPS); 1322 } 1323 if (ISSET(cflag, CSTOPB)) 1324 SET(lcr, PL01X_LCR_STP2); 1325 1326 return lcr; 1327 } 1328 1329 int 1330 plcomparam(struct tty *tp, struct termios *t) 1331 { 1332 struct plcom_softc *sc = 1333 device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev)); 1334 struct plcom_instance *pi = &sc->sc_pi; 1335 int ospeed = -1; 1336 u_char lcr; 1337 1338 if (PLCOM_ISALIVE(sc) == 0) 1339 return EIO; 1340 1341 switch (pi->pi_type) { 1342 case PLCOM_TYPE_PL010: 1343 ospeed = pl010comspeed(t->c_ospeed, sc->sc_frequency); 1344 break; 1345 case PLCOM_TYPE_PL011: 1346 ospeed = pl011comspeed(t->c_ospeed, sc->sc_frequency); 1347 break; 1348 } 1349 1350 /* Check requested parameters. */ 1351 if (ospeed < 0) 1352 return EINVAL; 1353 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) 1354 return EINVAL; 1355 1356 /* 1357 * For the console, always force CLOCAL and !HUPCL, so that the port 1358 * is always active. 1359 */ 1360 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || 1361 ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) { 1362 SET(t->c_cflag, CLOCAL); 1363 CLR(t->c_cflag, HUPCL); 1364 } 1365 1366 /* 1367 * If there were no changes, don't do anything. This avoids dropping 1368 * input and improves performance when all we did was frob things like 1369 * VMIN and VTIME. 1370 */ 1371 if (tp->t_ospeed == t->c_ospeed && 1372 tp->t_cflag == t->c_cflag) 1373 return 0; 1374 1375 lcr = ISSET(sc->sc_lcr, PL01X_LCR_BRK) | cflag2lcr(t->c_cflag); 1376 1377 mutex_spin_enter(&sc->sc_lock); 1378 1379 sc->sc_lcr = lcr; 1380 1381 /* 1382 * PL010 has a fixed-length FIFO trigger point. 1383 */ 1384 if (ISSET(sc->sc_hwflags, PLCOM_HW_FIFO)) 1385 sc->sc_fifo = 1; 1386 else 1387 sc->sc_fifo = 0; 1388 1389 if (sc->sc_fifo) 1390 SET(sc->sc_lcr, PL01X_LCR_FEN); 1391 1392 /* 1393 * If we're not in a mode that assumes a connection is present, then 1394 * ignore carrier changes. 1395 */ 1396 if (ISSET(t->c_cflag, CLOCAL | MDMBUF)) 1397 sc->sc_msr_dcd = 0; 1398 else 1399 sc->sc_msr_dcd = PL01X_MSR_DCD; 1400 /* 1401 * Set the flow control pins depending on the current flow control 1402 * mode. 1403 */ 1404 if (ISSET(t->c_cflag, CRTSCTS)) { 1405 sc->sc_mcr_dtr = PL01X_MCR_DTR; 1406 sc->sc_mcr_rts = PL01X_MCR_RTS; 1407 sc->sc_msr_cts = PL01X_MSR_CTS; 1408 } else if (ISSET(t->c_cflag, MDMBUF)) { 1409 /* 1410 * For DTR/DCD flow control, make sure we don't toggle DTR for 1411 * carrier detection. 1412 */ 1413 sc->sc_mcr_dtr = 0; 1414 sc->sc_mcr_rts = PL01X_MCR_DTR; 1415 sc->sc_msr_cts = PL01X_MSR_DCD; 1416 } else { 1417 /* 1418 * If no flow control, then always set RTS. This will make 1419 * the other side happy if it mistakenly thinks we're doing 1420 * RTS/CTS flow control. 1421 */ 1422 sc->sc_mcr_dtr = PL01X_MCR_DTR | PL01X_MCR_RTS; 1423 sc->sc_mcr_rts = 0; 1424 sc->sc_msr_cts = 0; 1425 if (ISSET(sc->sc_mcr, PL01X_MCR_DTR)) 1426 SET(sc->sc_mcr, PL01X_MCR_RTS); 1427 else 1428 CLR(sc->sc_mcr, PL01X_MCR_RTS); 1429 } 1430 sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd; 1431 1432 #if 0 1433 if (ospeed == 0) 1434 CLR(sc->sc_mcr, sc->sc_mcr_dtr); 1435 else 1436 SET(sc->sc_mcr, sc->sc_mcr_dtr); 1437 #endif 1438 1439 switch (pi->pi_type) { 1440 case PLCOM_TYPE_PL010: 1441 sc->sc_ratel = ospeed & 0xff; 1442 sc->sc_rateh = (ospeed >> 8) & 0xff; 1443 break; 1444 case PLCOM_TYPE_PL011: 1445 sc->sc_ratel = ospeed & ((1 << 6) - 1); 1446 sc->sc_rateh = ospeed >> 6; 1447 break; 1448 } 1449 1450 /* And copy to tty. */ 1451 tp->t_ispeed = t->c_ospeed; 1452 tp->t_ospeed = t->c_ospeed; 1453 tp->t_cflag = t->c_cflag; 1454 1455 if (!sc->sc_heldchange) { 1456 if (sc->sc_tx_busy) { 1457 sc->sc_heldtbc = sc->sc_tbc; 1458 sc->sc_tbc = 0; 1459 sc->sc_heldchange = 1; 1460 } else 1461 plcom_loadchannelregs(sc); 1462 } 1463 1464 if (!ISSET(t->c_cflag, CHWFLOW)) { 1465 /* Disable the high water mark. */ 1466 sc->sc_r_hiwat = 0; 1467 sc->sc_r_lowat = 0; 1468 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { 1469 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1470 plcom_schedrx(sc); 1471 } 1472 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) { 1473 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED); 1474 plcom_hwiflow(sc); 1475 } 1476 } else { 1477 sc->sc_r_hiwat = plcom_rbuf_hiwat; 1478 sc->sc_r_lowat = plcom_rbuf_lowat; 1479 } 1480 1481 mutex_spin_exit(&sc->sc_lock); 1482 1483 /* 1484 * Update the tty layer's idea of the carrier bit, in case we changed 1485 * CLOCAL or MDMBUF. We don't hang up here; we only do that by 1486 * explicit request. 1487 */ 1488 (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, PL01X_MSR_DCD)); 1489 1490 #ifdef PLCOM_DEBUG 1491 if (plcom_debug) 1492 plcomstatus(sc, "plcomparam "); 1493 #endif 1494 1495 if (!ISSET(t->c_cflag, CHWFLOW)) { 1496 if (sc->sc_tx_stopped) { 1497 sc->sc_tx_stopped = 0; 1498 plcomstart(tp); 1499 } 1500 } 1501 1502 return 0; 1503 } 1504 1505 void 1506 plcom_iflush(struct plcom_softc *sc) 1507 { 1508 struct plcom_instance *pi = &sc->sc_pi; 1509 #ifdef DIAGNOSTIC 1510 int reg; 1511 #endif 1512 int timo; 1513 1514 #ifdef DIAGNOSTIC 1515 reg = 0xffff; 1516 #endif 1517 timo = 50000; 1518 /* flush any pending I/O */ 1519 while (! ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE) 1520 && --timo) 1521 #ifdef DIAGNOSTIC 1522 reg = 1523 #else 1524 (void) 1525 #endif 1526 PREAD1(pi, PL01XCOM_DR); 1527 #ifdef DIAGNOSTIC 1528 if (!timo) 1529 aprint_error_dev(sc->sc_dev, ": %s timeout %02x\n", __func__, 1530 reg); 1531 #endif 1532 } 1533 1534 void 1535 plcom_loadchannelregs(struct plcom_softc *sc) 1536 { 1537 struct plcom_instance *pi = &sc->sc_pi; 1538 1539 /* XXXXX necessary? */ 1540 plcom_iflush(sc); 1541 1542 switch (pi->pi_type) { 1543 case PLCOM_TYPE_PL010: 1544 PWRITE1(pi, PL010COM_CR, 0); 1545 if (sc->sc_frequency != 0) { 1546 PWRITE1(pi, PL010COM_DLBL, sc->sc_ratel); 1547 PWRITE1(pi, PL010COM_DLBH, sc->sc_rateh); 1548 } 1549 PWRITE1(pi, PL010COM_LCR, sc->sc_lcr); 1550 1551 /* XXX device_unit() abuse */ 1552 if (sc->sc_set_mcr) 1553 sc->sc_set_mcr(sc->sc_set_mcr_arg, 1554 device_unit(sc->sc_dev), 1555 sc->sc_mcr_active = sc->sc_mcr); 1556 1557 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 1558 break; 1559 1560 case PLCOM_TYPE_PL011: 1561 PWRITE4(pi, PL011COM_CR, 0); 1562 if (sc->sc_frequency != 0) { 1563 PWRITE1(pi, PL011COM_FBRD, sc->sc_ratel); 1564 PWRITE4(pi, PL011COM_IBRD, sc->sc_rateh); 1565 } 1566 PWRITE1(pi, PL011COM_LCRH, sc->sc_lcr); 1567 sc->sc_mcr_active = sc->sc_mcr; 1568 CLR(sc->sc_cr, PL011_MCR(PL01X_MCR_RTS | PL01X_MCR_DTR)); 1569 SET(sc->sc_cr, PL011_MCR(sc->sc_mcr_active)); 1570 PWRITE4(pi, PL011COM_CR, sc->sc_cr); 1571 break; 1572 } 1573 } 1574 1575 int 1576 plcomhwiflow(struct tty *tp, int block) 1577 { 1578 struct plcom_softc *sc = 1579 device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev)); 1580 1581 if (PLCOM_ISALIVE(sc) == 0) 1582 return 0; 1583 1584 if (sc->sc_mcr_rts == 0) 1585 return 0; 1586 1587 mutex_spin_enter(&sc->sc_lock); 1588 1589 if (block) { 1590 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1591 SET(sc->sc_rx_flags, RX_TTY_BLOCKED); 1592 plcom_hwiflow(sc); 1593 } 1594 } else { 1595 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { 1596 CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1597 plcom_schedrx(sc); 1598 } 1599 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1600 CLR(sc->sc_rx_flags, RX_TTY_BLOCKED); 1601 plcom_hwiflow(sc); 1602 } 1603 } 1604 1605 mutex_spin_exit(&sc->sc_lock); 1606 return 1; 1607 } 1608 1609 /* 1610 * (un)block input via hw flowcontrol 1611 */ 1612 void 1613 plcom_hwiflow(struct plcom_softc *sc) 1614 { 1615 struct plcom_instance *pi = &sc->sc_pi; 1616 1617 if (sc->sc_mcr_rts == 0) 1618 return; 1619 1620 if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) { 1621 CLR(sc->sc_mcr, sc->sc_mcr_rts); 1622 CLR(sc->sc_mcr_active, sc->sc_mcr_rts); 1623 } else { 1624 SET(sc->sc_mcr, sc->sc_mcr_rts); 1625 SET(sc->sc_mcr_active, sc->sc_mcr_rts); 1626 } 1627 switch (pi->pi_type) { 1628 case PLCOM_TYPE_PL010: 1629 if (sc->sc_set_mcr) 1630 /* XXX device_unit() abuse */ 1631 sc->sc_set_mcr(sc->sc_set_mcr_arg, 1632 device_unit(sc->sc_dev), sc->sc_mcr_active); 1633 break; 1634 case PLCOM_TYPE_PL011: 1635 CLR(sc->sc_cr, PL011_MCR(PL01X_MCR_RTS | PL01X_MCR_DTR)); 1636 SET(sc->sc_cr, PL011_MCR(sc->sc_mcr_active)); 1637 PWRITE4(pi, PL011COM_CR, sc->sc_cr); 1638 break; 1639 } 1640 } 1641 1642 1643 void 1644 plcomstart(struct tty *tp) 1645 { 1646 struct plcom_softc *sc = 1647 device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev)); 1648 struct plcom_instance *pi = &sc->sc_pi; 1649 int s; 1650 1651 if (PLCOM_ISALIVE(sc) == 0) 1652 return; 1653 1654 s = spltty(); 1655 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 1656 goto out; 1657 if (sc->sc_tx_stopped) 1658 goto out; 1659 1660 if (!ttypull(tp)) 1661 goto out; 1662 1663 /* Grab the first contiguous region of buffer space. */ 1664 { 1665 u_char *tba; 1666 int tbc; 1667 1668 tba = tp->t_outq.c_cf; 1669 tbc = ndqb(&tp->t_outq, 0); 1670 1671 mutex_spin_enter(&sc->sc_lock); 1672 1673 sc->sc_tba = tba; 1674 sc->sc_tbc = tbc; 1675 } 1676 1677 SET(tp->t_state, TS_BUSY); 1678 sc->sc_tx_busy = 1; 1679 1680 /* Enable transmit completion interrupts if necessary. */ 1681 switch (pi->pi_type) { 1682 case PLCOM_TYPE_PL010: 1683 if (!ISSET(sc->sc_cr, PL010_CR_TIE)) { 1684 SET(sc->sc_cr, PL010_CR_TIE); 1685 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 1686 } 1687 break; 1688 case PLCOM_TYPE_PL011: 1689 if (!ISSET(sc->sc_imsc, PL011_INT_TX)) { 1690 SET(sc->sc_imsc, PL011_INT_TX); 1691 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 1692 } 1693 break; 1694 } 1695 1696 /* Output the first chunk of the contiguous buffer. */ 1697 { 1698 int n; 1699 1700 n = sc->sc_tbc; 1701 if (n > sc->sc_fifolen) 1702 n = sc->sc_fifolen; 1703 PWRITEM1(pi, PL01XCOM_DR, sc->sc_tba, n); 1704 sc->sc_tbc -= n; 1705 sc->sc_tba += n; 1706 } 1707 mutex_spin_exit(&sc->sc_lock); 1708 out: 1709 splx(s); 1710 return; 1711 } 1712 1713 /* 1714 * Stop output on a line. 1715 */ 1716 void 1717 plcomstop(struct tty *tp, int flag) 1718 { 1719 struct plcom_softc *sc = 1720 device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev)); 1721 1722 mutex_spin_enter(&sc->sc_lock); 1723 if (ISSET(tp->t_state, TS_BUSY)) { 1724 /* Stop transmitting at the next chunk. */ 1725 sc->sc_tbc = 0; 1726 sc->sc_heldtbc = 0; 1727 if (!ISSET(tp->t_state, TS_TTSTOP)) 1728 SET(tp->t_state, TS_FLUSH); 1729 } 1730 mutex_spin_exit(&sc->sc_lock); 1731 } 1732 1733 void 1734 plcomdiag(void *arg) 1735 { 1736 struct plcom_softc *sc = arg; 1737 int overflows, floods; 1738 1739 mutex_spin_enter(&sc->sc_lock); 1740 overflows = sc->sc_overflows; 1741 sc->sc_overflows = 0; 1742 floods = sc->sc_floods; 1743 sc->sc_floods = 0; 1744 sc->sc_errors = 0; 1745 mutex_spin_exit(&sc->sc_lock); 1746 1747 log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", 1748 device_xname(sc->sc_dev), 1749 overflows, overflows == 1 ? "" : "s", 1750 floods, floods == 1 ? "" : "s"); 1751 } 1752 1753 integrate void 1754 plcom_rxsoft(struct plcom_softc *sc, struct tty *tp) 1755 { 1756 int (*rint) (int, struct tty *) = tp->t_linesw->l_rint; 1757 struct plcom_instance *pi = &sc->sc_pi; 1758 u_char *get, *end; 1759 u_int cc, scc; 1760 u_char rsr; 1761 int code; 1762 1763 end = sc->sc_ebuf; 1764 get = sc->sc_rbget; 1765 scc = cc = plcom_rbuf_size - sc->sc_rbavail; 1766 1767 if (cc == plcom_rbuf_size) { 1768 sc->sc_floods++; 1769 if (sc->sc_errors++ == 0) 1770 callout_reset(&sc->sc_diag_callout, 60 * hz, 1771 plcomdiag, sc); 1772 } 1773 1774 while (cc) { 1775 code = get[0]; 1776 rsr = get[1]; 1777 if (ISSET(rsr, PL01X_RSR_ERROR)) { 1778 if (ISSET(rsr, PL01X_RSR_OE)) { 1779 sc->sc_overflows++; 1780 if (sc->sc_errors++ == 0) 1781 callout_reset(&sc->sc_diag_callout, 1782 60 * hz, plcomdiag, sc); 1783 } 1784 if (ISSET(rsr, PL01X_RSR_BE | PL01X_RSR_FE)) 1785 SET(code, TTY_FE); 1786 if (ISSET(rsr, PL01X_RSR_PE)) 1787 SET(code, TTY_PE); 1788 } 1789 if ((*rint)(code, tp) == -1) { 1790 /* 1791 * The line discipline's buffer is out of space. 1792 */ 1793 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { 1794 /* 1795 * We're either not using flow control, or the 1796 * line discipline didn't tell us to block for 1797 * some reason. Either way, we have no way to 1798 * know when there's more space available, so 1799 * just drop the rest of the data. 1800 */ 1801 get += cc << 1; 1802 if (get >= end) 1803 get -= plcom_rbuf_size << 1; 1804 cc = 0; 1805 } else { 1806 /* 1807 * Don't schedule any more receive processing 1808 * until the line discipline tells us there's 1809 * space available (through plcomhwiflow()). 1810 * Leave the rest of the data in the input 1811 * buffer. 1812 */ 1813 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED); 1814 } 1815 break; 1816 } 1817 get += 2; 1818 if (get >= end) 1819 get = sc->sc_rbuf; 1820 cc--; 1821 } 1822 1823 if (cc != scc) { 1824 sc->sc_rbget = get; 1825 mutex_spin_enter(&sc->sc_lock); 1826 1827 cc = sc->sc_rbavail += scc - cc; 1828 /* Buffers should be ok again, release possible block. */ 1829 if (cc >= sc->sc_r_lowat) { 1830 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1831 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1832 switch (pi->pi_type) { 1833 case PLCOM_TYPE_PL010: 1834 SET(sc->sc_cr, 1835 PL010_CR_RIE | PL010_CR_RTIE); 1836 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 1837 break; 1838 case PLCOM_TYPE_PL011: 1839 SET(sc->sc_imsc, 1840 PL011_INT_RX | PL011_INT_RT); 1841 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 1842 break; 1843 } 1844 } 1845 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { 1846 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1847 plcom_hwiflow(sc); 1848 } 1849 } 1850 mutex_spin_exit(&sc->sc_lock); 1851 } 1852 } 1853 1854 integrate void 1855 plcom_txsoft(struct plcom_softc *sc, struct tty *tp) 1856 { 1857 1858 CLR(tp->t_state, TS_BUSY); 1859 if (ISSET(tp->t_state, TS_FLUSH)) 1860 CLR(tp->t_state, TS_FLUSH); 1861 else 1862 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf)); 1863 (*tp->t_linesw->l_start)(tp); 1864 } 1865 1866 integrate void 1867 plcom_stsoft(struct plcom_softc *sc, struct tty *tp) 1868 { 1869 u_char msr, delta; 1870 1871 mutex_spin_enter(&sc->sc_lock); 1872 msr = sc->sc_msr; 1873 delta = sc->sc_msr_delta; 1874 sc->sc_msr_delta = 0; 1875 mutex_spin_exit(&sc->sc_lock); 1876 1877 if (ISSET(delta, sc->sc_msr_dcd)) { 1878 /* 1879 * Inform the tty layer that carrier detect changed. 1880 */ 1881 (void) (*tp->t_linesw->l_modem)(tp, ISSET(msr, PL01X_MSR_DCD)); 1882 } 1883 1884 if (ISSET(delta, sc->sc_msr_cts)) { 1885 /* Block or unblock output according to flow control. */ 1886 if (ISSET(msr, sc->sc_msr_cts)) { 1887 sc->sc_tx_stopped = 0; 1888 (*tp->t_linesw->l_start)(tp); 1889 } else { 1890 sc->sc_tx_stopped = 1; 1891 } 1892 } 1893 1894 #ifdef PLCOM_DEBUG 1895 if (plcom_debug) 1896 plcomstatus(sc, "plcom_stsoft"); 1897 #endif 1898 } 1899 1900 void 1901 plcomsoft(void *arg) 1902 { 1903 struct plcom_softc *sc = arg; 1904 struct tty *tp; 1905 1906 if (PLCOM_ISALIVE(sc) == 0) 1907 return; 1908 1909 tp = sc->sc_tty; 1910 1911 if (sc->sc_rx_ready) { 1912 sc->sc_rx_ready = 0; 1913 plcom_rxsoft(sc, tp); 1914 } 1915 1916 if (sc->sc_st_check) { 1917 sc->sc_st_check = 0; 1918 plcom_stsoft(sc, tp); 1919 } 1920 1921 if (sc->sc_tx_done) { 1922 sc->sc_tx_done = 0; 1923 plcom_txsoft(sc, tp); 1924 } 1925 } 1926 1927 bool 1928 plcom_intstatus(struct plcom_instance *pi, u_int *istatus) 1929 { 1930 bool ret = false; 1931 u_int stat = 0; 1932 1933 switch (pi->pi_type) { 1934 case PLCOM_TYPE_PL010: 1935 stat = PREAD1(pi, PL010COM_IIR); 1936 ret = ISSET(stat, PL010_IIR_IMASK); 1937 break; 1938 case PLCOM_TYPE_PL011: 1939 stat = PREAD4(pi, PL011COM_MIS); 1940 ret = ISSET(stat, PL011_INT_ALLMASK); 1941 break; 1942 } 1943 *istatus = stat; 1944 1945 return ret; 1946 } 1947 1948 int 1949 plcomintr(void *arg) 1950 { 1951 struct plcom_softc *sc = arg; 1952 struct plcom_instance *pi = &sc->sc_pi; 1953 u_char *put, *end; 1954 u_int cc; 1955 u_int istatus = 0; 1956 u_char rsr; 1957 bool intr = false; 1958 1959 PLCOM_BARRIER(pi, BR | BW); 1960 1961 if (PLCOM_ISALIVE(sc) == 0) 1962 return 0; 1963 1964 mutex_spin_enter(&sc->sc_lock); 1965 intr = plcom_intstatus(pi, &istatus); 1966 if (!intr) { 1967 mutex_spin_exit(&sc->sc_lock); 1968 return 0; 1969 } 1970 1971 end = sc->sc_ebuf; 1972 put = sc->sc_rbput; 1973 cc = sc->sc_rbavail; 1974 1975 do { 1976 u_int msr = 0, delta, fr; 1977 bool rxintr = false, txintr = false, msintr; 1978 1979 /* don't need RI here*/ 1980 fr = PREAD1(pi, PL01XCOM_FR); 1981 1982 if (!ISSET(fr, PL01X_FR_RXFE) && 1983 !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1984 while (cc > 0) { 1985 int cn_trapped = 0; 1986 put[0] = PREAD1(pi, PL01XCOM_DR); 1987 rsr = PREAD1(pi, PL01XCOM_RSR); 1988 /* Clear any error status. */ 1989 if (ISSET(rsr, PL01X_RSR_ERROR)) 1990 PWRITE1(pi, PL01XCOM_ECR, 0); 1991 if (ISSET(rsr, PL01X_RSR_BE)) { 1992 cn_trapped = 0; 1993 cn_check_magic(sc->sc_tty->t_dev, 1994 CNC_BREAK, plcom_cnm_state); 1995 if (cn_trapped) 1996 continue; 1997 #if defined(KGDB) 1998 if (ISSET(sc->sc_hwflags, 1999 PLCOM_HW_KGDB)) { 2000 kgdb_connect(1); 2001 continue; 2002 } 2003 #endif 2004 } 2005 2006 put[1] = rsr; 2007 cn_trapped = 0; 2008 cn_check_magic(sc->sc_tty->t_dev, put[0], 2009 plcom_cnm_state); 2010 if (cn_trapped) { 2011 fr = PREAD1(pi, PL01XCOM_FR); 2012 if (ISSET(fr, PL01X_FR_RXFE)) 2013 break; 2014 2015 continue; 2016 } 2017 put += 2; 2018 if (put >= end) 2019 put = sc->sc_rbuf; 2020 cc--; 2021 2022 /* don't need RI here*/ 2023 fr = PREAD1(pi, PL01XCOM_FR); 2024 if (ISSET(fr, PL01X_FR_RXFE)) 2025 break; 2026 } 2027 2028 /* 2029 * Current string of incoming characters ended because 2030 * no more data was available or we ran out of space. 2031 * Schedule a receive event if any data was received. 2032 * If we're out of space, turn off receive interrupts. 2033 */ 2034 sc->sc_rbput = put; 2035 sc->sc_rbavail = cc; 2036 if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) 2037 sc->sc_rx_ready = 1; 2038 2039 /* 2040 * See if we are in danger of overflowing a buffer. If 2041 * so, use hardware flow control to ease the pressure. 2042 */ 2043 if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) && 2044 cc < sc->sc_r_hiwat) { 2045 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); 2046 plcom_hwiflow(sc); 2047 } 2048 2049 /* 2050 * If we're out of space, disable receive interrupts 2051 * until the queue has drained a bit. 2052 */ 2053 if (!cc) { 2054 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 2055 switch (pi->pi_type) { 2056 case PLCOM_TYPE_PL010: 2057 CLR(sc->sc_cr, 2058 PL010_CR_RIE | PL010_CR_RTIE); 2059 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 2060 break; 2061 case PLCOM_TYPE_PL011: 2062 CLR(sc->sc_imsc, 2063 PL011_INT_RT | PL011_INT_RX); 2064 PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc); 2065 break; 2066 } 2067 } 2068 } else { 2069 switch (pi->pi_type) { 2070 case PLCOM_TYPE_PL010: 2071 rxintr = ISSET(istatus, PL010_IIR_RIS); 2072 if (rxintr) { 2073 PWRITE1(pi, PL010COM_CR, 0); 2074 delay(10); 2075 PWRITE1(pi, PL010COM_CR, sc->sc_cr); 2076 continue; 2077 } 2078 break; 2079 case PLCOM_TYPE_PL011: 2080 rxintr = ISSET(istatus, PL011_INT_RX); 2081 if (rxintr) { 2082 PWRITE4(pi, PL011COM_CR, 0); 2083 delay(10); 2084 PWRITE4(pi, PL011COM_CR, sc->sc_cr); 2085 continue; 2086 } 2087 break; 2088 } 2089 } 2090 2091 switch (pi->pi_type) { 2092 case PLCOM_TYPE_PL010: 2093 msr = PREAD1(pi, PL01XCOM_FR); 2094 break; 2095 case PLCOM_TYPE_PL011: 2096 msr = PREAD4(pi, PL01XCOM_FR); 2097 break; 2098 } 2099 delta = msr ^ sc->sc_msr; 2100 sc->sc_msr = msr; 2101 2102 /* Clear any pending modem status interrupt. */ 2103 switch (pi->pi_type) { 2104 case PLCOM_TYPE_PL010: 2105 msintr = ISSET(istatus, PL010_IIR_MIS); 2106 if (msintr) { 2107 PWRITE1(pi, PL010COM_ICR, 0); 2108 } 2109 break; 2110 case PLCOM_TYPE_PL011: 2111 msintr = ISSET(istatus, PL011_INT_MSMASK); 2112 if (msintr) { 2113 PWRITE4(pi, PL011COM_ICR, PL011_INT_MSMASK); 2114 } 2115 break; 2116 } 2117 /* 2118 * Pulse-per-second (PSS) signals on edge of DCD? 2119 * Process these even if line discipline is ignoring DCD. 2120 */ 2121 if (delta & sc->sc_ppsmask) { 2122 struct timeval tv; 2123 mutex_spin_enter(&timecounter_lock); 2124 if ((msr & sc->sc_ppsmask) == sc->sc_ppsassert) { 2125 /* XXX nanotime() */ 2126 microtime(&tv); 2127 TIMEVAL_TO_TIMESPEC(&tv, 2128 &sc->ppsinfo.assert_timestamp); 2129 if (sc->ppsparam.mode & PPS_OFFSETASSERT) { 2130 timespecadd(&sc->ppsinfo.assert_timestamp, 2131 &sc->ppsparam.assert_offset, 2132 &sc->ppsinfo.assert_timestamp); 2133 } 2134 2135 #ifdef PPS_SYNC 2136 if (sc->ppsparam.mode & PPS_HARDPPSONASSERT) 2137 hardpps(&tv, tv.tv_usec); 2138 #endif 2139 sc->ppsinfo.assert_sequence++; 2140 sc->ppsinfo.current_mode = sc->ppsparam.mode; 2141 2142 } else if ((msr & sc->sc_ppsmask) == sc->sc_ppsclear) { 2143 /* XXX nanotime() */ 2144 microtime(&tv); 2145 TIMEVAL_TO_TIMESPEC(&tv, 2146 &sc->ppsinfo.clear_timestamp); 2147 if (sc->ppsparam.mode & PPS_OFFSETCLEAR) { 2148 timespecadd(&sc->ppsinfo.clear_timestamp, 2149 &sc->ppsparam.clear_offset, 2150 &sc->ppsinfo.clear_timestamp); 2151 } 2152 2153 #ifdef PPS_SYNC 2154 if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR) 2155 hardpps(&tv, tv.tv_usec); 2156 #endif 2157 sc->ppsinfo.clear_sequence++; 2158 sc->ppsinfo.current_mode = sc->ppsparam.mode; 2159 } 2160 mutex_spin_exit(&timecounter_lock); 2161 } 2162 2163 /* 2164 * Process normal status changes 2165 */ 2166 if (ISSET(delta, sc->sc_msr_mask)) { 2167 SET(sc->sc_msr_delta, delta); 2168 2169 /* 2170 * Stop output immediately if we lose the output 2171 * flow control signal or carrier detect. 2172 */ 2173 if (ISSET(~msr, sc->sc_msr_mask)) { 2174 sc->sc_tbc = 0; 2175 sc->sc_heldtbc = 0; 2176 #ifdef PLCOM_DEBUG 2177 if (plcom_debug) 2178 plcomstatus(sc, "plcomintr "); 2179 #endif 2180 } 2181 2182 sc->sc_st_check = 1; 2183 } 2184 2185 /* 2186 * Done handling any receive interrupts. See if data 2187 * can be transmitted as well. Schedule tx done 2188 * event if no data left and tty was marked busy. 2189 */ 2190 2191 switch (pi->pi_type) { 2192 case PLCOM_TYPE_PL010: 2193 txintr = ISSET(istatus, PL010_IIR_TIS); 2194 break; 2195 case PLCOM_TYPE_PL011: 2196 txintr = ISSET(istatus, PL011_INT_TX); 2197 break; 2198 } 2199 if (txintr) { 2200 /* 2201 * If we've delayed a parameter change, do it 2202 * now, and restart * output. 2203 */ 2204 // PWRITE4(pi, PL011COM_ICR, PL011_INT_TX); 2205 if (sc->sc_heldchange) { 2206 plcom_loadchannelregs(sc); 2207 sc->sc_heldchange = 0; 2208 sc->sc_tbc = sc->sc_heldtbc; 2209 sc->sc_heldtbc = 0; 2210 } 2211 2212 /* 2213 * Output the next chunk of the contiguous 2214 * buffer, if any. 2215 */ 2216 if (sc->sc_tbc > 0) { 2217 int n; 2218 2219 n = sc->sc_tbc; 2220 if (n > sc->sc_fifolen) 2221 n = sc->sc_fifolen; 2222 PWRITEM1(pi, PL01XCOM_DR, sc->sc_tba, n); 2223 sc->sc_tbc -= n; 2224 sc->sc_tba += n; 2225 } else { 2226 /* 2227 * Disable transmit completion 2228 * interrupts if necessary. 2229 */ 2230 switch (pi->pi_type) { 2231 case PLCOM_TYPE_PL010: 2232 if (ISSET(sc->sc_cr, PL010_CR_TIE)) { 2233 CLR(sc->sc_cr, PL010_CR_TIE); 2234 PWRITE1(pi, PL010COM_CR, 2235 sc->sc_cr); 2236 } 2237 break; 2238 case PLCOM_TYPE_PL011: 2239 if (ISSET(sc->sc_imsc, PL011_INT_TX)) { 2240 CLR(sc->sc_imsc, PL011_INT_TX); 2241 PWRITE4(pi, PL011COM_IMSC, 2242 sc->sc_imsc); 2243 } 2244 break; 2245 } 2246 if (sc->sc_tx_busy) { 2247 sc->sc_tx_busy = 0; 2248 sc->sc_tx_done = 1; 2249 } 2250 } 2251 } 2252 2253 } while (plcom_intstatus(pi, &istatus)); 2254 2255 mutex_spin_exit(&sc->sc_lock); 2256 2257 /* Wake up the poller. */ 2258 softint_schedule(sc->sc_si); 2259 2260 #ifdef RND_COM 2261 rnd_add_uint32(&sc->rnd_source, istatus | rsr); 2262 #endif 2263 2264 PLCOM_BARRIER(pi, BR | BW); 2265 2266 return 1; 2267 } 2268 2269 /* 2270 * The following functions are polled getc and putc routines, shared 2271 * by the console and kgdb glue. 2272 * 2273 * The read-ahead code is so that you can detect pending in-band 2274 * cn_magic in polled mode while doing output rather than having to 2275 * wait until the kernel decides it needs input. 2276 */ 2277 2278 #define MAX_READAHEAD 20 2279 static int plcom_readahead[MAX_READAHEAD]; 2280 static int plcom_readaheadcount = 0; 2281 2282 int 2283 plcom_common_getc(dev_t dev, struct plcom_instance *pi) 2284 { 2285 int s = splserial(); 2286 u_char c; 2287 2288 /* got a character from reading things earlier */ 2289 if (plcom_readaheadcount > 0) { 2290 int i; 2291 2292 c = plcom_readahead[0]; 2293 for (i = 1; i < plcom_readaheadcount; i++) { 2294 plcom_readahead[i-1] = plcom_readahead[i]; 2295 } 2296 plcom_readaheadcount--; 2297 splx(s); 2298 return c; 2299 } 2300 2301 if (ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE)) { 2302 splx(s); 2303 return -1; 2304 } 2305 2306 c = PREAD1(pi, PL01XCOM_DR); 2307 { 2308 int cn_trapped __unused = 0; 2309 #ifdef DDB 2310 extern int db_active; 2311 if (!db_active) 2312 #endif 2313 cn_check_magic(dev, c, plcom_cnm_state); 2314 } 2315 splx(s); 2316 return c; 2317 } 2318 2319 void 2320 plcom_common_putc(dev_t dev, struct plcom_instance *pi, int c) 2321 { 2322 int s = splserial(); 2323 int timo; 2324 2325 int cin, stat; 2326 if (plcom_readaheadcount < MAX_READAHEAD 2327 && !ISSET(stat = PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE)) { 2328 int cn_trapped __unused = 0; 2329 cin = PREAD1(pi, PL01XCOM_DR); 2330 cn_check_magic(dev, cin, plcom_cnm_state); 2331 plcom_readahead[plcom_readaheadcount++] = cin; 2332 } 2333 2334 /* wait for any pending transmission to finish */ 2335 timo = 150000; 2336 while (ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_TXFF) && --timo) 2337 continue; 2338 2339 PWRITE1(pi, PL01XCOM_DR, c); 2340 PLCOM_BARRIER(pi, BR | BW); 2341 2342 splx(s); 2343 } 2344 2345 /* 2346 * Initialize UART for use as console or KGDB line. 2347 */ 2348 int 2349 plcominit(struct plcom_instance *pi, int rate, int frequency, tcflag_t cflag) 2350 { 2351 u_char lcr; 2352 2353 switch (pi->pi_type) { 2354 case PLCOM_TYPE_PL010: 2355 if (pi->pi_size == 0) 2356 pi->pi_size = PL010COM_UART_SIZE; 2357 break; 2358 case PLCOM_TYPE_PL011: 2359 if (pi->pi_size == 0) 2360 pi->pi_size = PL011COM_UART_SIZE; 2361 break; 2362 default: 2363 panic("Unknown plcom type"); 2364 } 2365 2366 if (bus_space_map(pi->pi_iot, pi->pi_iobase, pi->pi_size, 0, 2367 &pi->pi_ioh)) 2368 return ENOMEM; /* ??? */ 2369 2370 lcr = cflag2lcr(cflag) | PL01X_LCR_FEN; 2371 switch (pi->pi_type) { 2372 case PLCOM_TYPE_PL010: 2373 PWRITE1(pi, PL010COM_CR, 0); 2374 2375 if (rate && frequency) { 2376 rate = pl010comspeed(rate, frequency); 2377 PWRITE1(pi, PL010COM_DLBL, (rate & 0xff)); 2378 PWRITE1(pi, PL010COM_DLBH, ((rate >> 8) & 0xff)); 2379 } 2380 PWRITE1(pi, PL010COM_LCR, lcr); 2381 PWRITE1(pi, PL010COM_CR, PL01X_CR_UARTEN); 2382 break; 2383 case PLCOM_TYPE_PL011: 2384 PWRITE4(pi, PL011COM_CR, 0); 2385 2386 if (rate && frequency) { 2387 rate = pl011comspeed(rate, frequency); 2388 PWRITE1(pi, PL011COM_FBRD, rate & ((1 << 6) - 1)); 2389 PWRITE4(pi, PL011COM_IBRD, rate >> 6); 2390 } 2391 PWRITE1(pi, PL011COM_LCRH, lcr); 2392 PWRITE4(pi, PL011COM_CR, 2393 PL01X_CR_UARTEN | PL011_CR_RXE | PL011_CR_TXE); 2394 break; 2395 } 2396 2397 #if 0 2398 /* Ought to do something like this, but we have no sc to 2399 dereference. */ 2400 /* XXX device_unit() abuse */ 2401 sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(sc->sc_dev), 2402 PL01X_MCR_DTR | PL01X_MCR_RTS); 2403 #endif 2404 2405 return 0; 2406 } 2407 2408 /* 2409 * Following are all routines needed for PLCOM to act as console 2410 */ 2411 struct consdev plcomcons = { 2412 NULL, NULL, plcomcngetc, plcomcnputc, plcomcnpollc, NULL, 2413 plcomcnhalt, NULL, NODEV, CN_NORMAL 2414 }; 2415 2416 int 2417 plcomcnattach(struct plcom_instance *pi, int rate, int frequency, 2418 tcflag_t cflag, int unit) 2419 { 2420 int res; 2421 2422 plcomcons_info = *pi; 2423 2424 res = plcominit(&plcomcons_info, rate, frequency, cflag); 2425 if (res) 2426 return res; 2427 2428 cn_tab = &plcomcons; 2429 cn_init_magic(&plcom_cnm_state); 2430 cn_set_magic("\047\001"); /* default magic is BREAK */ 2431 2432 plcomconsunit = unit; 2433 plcomconsrate = rate; 2434 plcomconscflag = cflag; 2435 2436 return 0; 2437 } 2438 2439 void 2440 plcomcndetach(void) 2441 { 2442 2443 bus_space_unmap(plcomcons_info.pi_iot, plcomcons_info.pi_ioh, 2444 plcomcons_info.pi_size); 2445 plcomcons_info.pi_iot = NULL; 2446 2447 cn_tab = NULL; 2448 } 2449 2450 int 2451 plcomcngetc(dev_t dev) 2452 { 2453 return plcom_common_getc(dev, &plcomcons_info); 2454 } 2455 2456 /* 2457 * Console kernel output character routine. 2458 */ 2459 void 2460 plcomcnputc(dev_t dev, int c) 2461 { 2462 plcom_common_putc(dev, &plcomcons_info, c); 2463 } 2464 2465 void 2466 plcomcnpollc(dev_t dev, int on) 2467 { 2468 2469 plcom_readaheadcount = 0; 2470 } 2471 2472 void 2473 plcomcnhalt(dev_t dev) 2474 { 2475 struct plcom_instance *pi = &plcomcons_info; 2476 2477 switch (pi->pi_type) { 2478 case PLCOM_TYPE_PL010: 2479 PWRITE1(pi, PL010COM_CR, PL01X_CR_UARTEN); 2480 break; 2481 case PLCOM_TYPE_PL011: 2482 PWRITE4(pi, PL011COM_CR, 2483 PL01X_CR_UARTEN | PL011_CR_RXE | PL011_CR_TXE); 2484 PWRITE4(pi, PL011COM_IMSC, 0); 2485 break; 2486 } 2487 } 2488 2489 #ifdef KGDB 2490 int 2491 plcom_kgdb_attach(struct plcom_instance *pi, int rate, int frequency, 2492 tcflag_t cflag, int unit) 2493 { 2494 int res; 2495 2496 if (pi->pi_iot == plcomcons_info.pi_iot && 2497 pi->pi_iobase == plcomcons_info.pi_iobase) 2498 return EBUSY; /* cannot share with console */ 2499 2500 res = plcominit(pi, rate, frequency, cflag); 2501 if (res) 2502 return res; 2503 2504 kgdb_attach(plcom_kgdb_getc, plcom_kgdb_putc, NULL); 2505 kgdb_dev = 123; /* unneeded, only to satisfy some tests */ 2506 2507 plcomkgdb_info.pi_iot = pi->pi_iot; 2508 plcomkgdb_info.pi_ioh = pi->pi_ioh; 2509 plcomkgdb_info.pi_iobase = pi->pi_iobase; 2510 2511 return 0; 2512 } 2513 2514 /* ARGSUSED */ 2515 int 2516 plcom_kgdb_getc(void *arg) 2517 { 2518 return plcom_common_getc(NODEV, &plcomkgdb_info); 2519 } 2520 2521 /* ARGSUSED */ 2522 void 2523 plcom_kgdb_putc(void *arg, int c) 2524 { 2525 plcom_common_putc(NODEV, &plcomkgdb_info, c); 2526 } 2527 #endif /* KGDB */ 2528 2529 /* helper function to identify the plcom ports used by 2530 console or KGDB (and not yet autoconf attached) */ 2531 int 2532 plcom_is_console(bus_space_tag_t iot, bus_addr_t iobase, 2533 bus_space_handle_t *ioh) 2534 { 2535 bus_space_handle_t help; 2536 2537 if (!plcomconsattached && 2538 bus_space_is_equal(iot, plcomcons_info.pi_iot) && 2539 iobase == plcomcons_info.pi_iobase) 2540 help = plcomcons_info.pi_ioh; 2541 #ifdef KGDB 2542 else if (!plcom_kgdb_attached && 2543 bus_space_is_equal(iot, plcomkgdb_info.pi_iot) && 2544 iobase == plcomkgdb_info.pi_iobase) 2545 help = plcomkgdb_info.pi_ioh; 2546 #endif 2547 else 2548 return 0; 2549 2550 if (ioh) 2551 *ioh = help; 2552 return 1; 2553 } 2554