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