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