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