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