1 1.135 riastrad /* $NetBSD: z8530tty.c,v 1.135 2022/10/26 23:45:25 riastradh Exp $ */ 2 1.21 mycroft 3 1.21 mycroft /*- 4 1.57 mycroft * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999 5 1.21 mycroft * Charles M. Hannum. All rights reserved. 6 1.21 mycroft * 7 1.21 mycroft * Redistribution and use in source and binary forms, with or without 8 1.21 mycroft * modification, are permitted provided that the following conditions 9 1.21 mycroft * are met: 10 1.21 mycroft * 1. Redistributions of source code must retain the above copyright 11 1.21 mycroft * notice, this list of conditions and the following disclaimer. 12 1.21 mycroft * 2. Redistributions in binary form must reproduce the above copyright 13 1.21 mycroft * notice, this list of conditions and the following disclaimer in the 14 1.21 mycroft * documentation and/or other materials provided with the distribution. 15 1.21 mycroft * 3. All advertising materials mentioning features or use of this software 16 1.21 mycroft * must display the following acknowledgement: 17 1.21 mycroft * This product includes software developed by Charles M. Hannum. 18 1.21 mycroft * 4. The name of the author may not be used to endorse or promote products 19 1.21 mycroft * derived from this software without specific prior written permission. 20 1.21 mycroft * 21 1.21 mycroft * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 1.21 mycroft * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 1.21 mycroft * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 1.21 mycroft * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 1.21 mycroft * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 1.21 mycroft * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 1.21 mycroft * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.21 mycroft * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 1.21 mycroft * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 1.21 mycroft * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 1.21 mycroft */ 32 1.1 gwr 33 1.1 gwr /* 34 1.1 gwr * Copyright (c) 1992, 1993 35 1.1 gwr * The Regents of the University of California. All rights reserved. 36 1.1 gwr * 37 1.1 gwr * This software was developed by the Computer Systems Engineering group 38 1.1 gwr * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 39 1.1 gwr * contributed to Berkeley. 40 1.1 gwr * 41 1.1 gwr * All advertising materials mentioning features or use of this software 42 1.1 gwr * must display the following acknowledgement: 43 1.1 gwr * This product includes software developed by the University of 44 1.1 gwr * California, Lawrence Berkeley Laboratory. 45 1.1 gwr * 46 1.1 gwr * Redistribution and use in source and binary forms, with or without 47 1.1 gwr * modification, are permitted provided that the following conditions 48 1.1 gwr * are met: 49 1.1 gwr * 1. Redistributions of source code must retain the above copyright 50 1.1 gwr * notice, this list of conditions and the following disclaimer. 51 1.1 gwr * 2. Redistributions in binary form must reproduce the above copyright 52 1.1 gwr * notice, this list of conditions and the following disclaimer in the 53 1.1 gwr * documentation and/or other materials provided with the distribution. 54 1.92 agc * 3. Neither the name of the University nor the names of its contributors 55 1.92 agc * may be used to endorse or promote products derived from this software 56 1.92 agc * without specific prior written permission. 57 1.92 agc * 58 1.92 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 1.92 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 1.92 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 1.92 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 1.92 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 1.92 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 1.92 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 1.92 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 1.92 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 1.92 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 1.92 agc * SUCH DAMAGE. 69 1.92 agc * 70 1.92 agc * @(#)zs.c 8.1 (Berkeley) 7/19/93 71 1.92 agc */ 72 1.92 agc 73 1.92 agc /* 74 1.92 agc * Copyright (c) 1994 Gordon W. Ross 75 1.92 agc * 76 1.92 agc * This software was developed by the Computer Systems Engineering group 77 1.92 agc * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 78 1.92 agc * contributed to Berkeley. 79 1.92 agc * 80 1.92 agc * All advertising materials mentioning features or use of this software 81 1.92 agc * must display the following acknowledgement: 82 1.92 agc * This product includes software developed by the University of 83 1.92 agc * California, Lawrence Berkeley Laboratory. 84 1.92 agc * 85 1.92 agc * Redistribution and use in source and binary forms, with or without 86 1.92 agc * modification, are permitted provided that the following conditions 87 1.92 agc * are met: 88 1.92 agc * 1. Redistributions of source code must retain the above copyright 89 1.92 agc * notice, this list of conditions and the following disclaimer. 90 1.92 agc * 2. Redistributions in binary form must reproduce the above copyright 91 1.92 agc * notice, this list of conditions and the following disclaimer in the 92 1.92 agc * documentation and/or other materials provided with the distribution. 93 1.1 gwr * 3. All advertising materials mentioning features or use of this software 94 1.1 gwr * must display the following acknowledgement: 95 1.1 gwr * This product includes software developed by the University of 96 1.1 gwr * California, Berkeley and its contributors. 97 1.1 gwr * 4. Neither the name of the University nor the names of its contributors 98 1.1 gwr * may be used to endorse or promote products derived from this software 99 1.1 gwr * without specific prior written permission. 100 1.1 gwr * 101 1.1 gwr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 102 1.1 gwr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 103 1.1 gwr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 104 1.1 gwr * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 105 1.1 gwr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 106 1.1 gwr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 107 1.1 gwr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 108 1.1 gwr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 109 1.1 gwr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 110 1.1 gwr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 111 1.1 gwr * SUCH DAMAGE. 112 1.1 gwr * 113 1.1 gwr * @(#)zs.c 8.1 (Berkeley) 7/19/93 114 1.1 gwr */ 115 1.1 gwr 116 1.1 gwr /* 117 1.1 gwr * Zilog Z8530 Dual UART driver (tty interface) 118 1.1 gwr * 119 1.1 gwr * This is the "slave" driver that will be attached to 120 1.1 gwr * the "zsc" driver for plain "tty" async. serial lines. 121 1.8 gwr * 122 1.8 gwr * Credits, history: 123 1.8 gwr * 124 1.8 gwr * The original version of this code was the sparc/dev/zs.c driver 125 1.8 gwr * as distributed with the Berkeley 4.4 Lite release. Since then, 126 1.8 gwr * Gordon Ross reorganized the code into the current parent/child 127 1.8 gwr * driver scheme, separating the Sun keyboard and mouse support 128 1.8 gwr * into independent child drivers. 129 1.8 gwr * 130 1.8 gwr * RTS/CTS flow-control support was a collaboration of: 131 1.93 keihan * Gordon Ross <gwr (at) NetBSD.org>, 132 1.8 gwr * Bill Studenmund <wrstuden (at) loki.stanford.edu> 133 1.8 gwr * Ian Dall <Ian.Dall (at) dsto.defence.gov.au> 134 1.57 mycroft * 135 1.57 mycroft * The driver was massively overhauled in November 1997 by Charles Hannum, 136 1.57 mycroft * fixing *many* bugs, and substantially improving performance. 137 1.1 gwr */ 138 1.78 lukem 139 1.78 lukem #include <sys/cdefs.h> 140 1.135 riastrad __KERNEL_RCSID(0, "$NetBSD: z8530tty.c,v 1.135 2022/10/26 23:45:25 riastradh Exp $"); 141 1.77 lukem 142 1.77 lukem #include "opt_kgdb.h" 143 1.94 simonb #include "opt_ntp.h" 144 1.1 gwr 145 1.1 gwr #include <sys/param.h> 146 1.1 gwr #include <sys/systm.h> 147 1.1 gwr #include <sys/proc.h> 148 1.1 gwr #include <sys/device.h> 149 1.1 gwr #include <sys/conf.h> 150 1.1 gwr #include <sys/file.h> 151 1.1 gwr #include <sys/ioctl.h> 152 1.6 gwr #include <sys/malloc.h> 153 1.59 wrstuden #include <sys/timepps.h> 154 1.1 gwr #include <sys/tty.h> 155 1.1 gwr #include <sys/time.h> 156 1.1 gwr #include <sys/kernel.h> 157 1.1 gwr #include <sys/syslog.h> 158 1.107 elad #include <sys/kauth.h> 159 1.1 gwr 160 1.1 gwr #include <dev/ic/z8530reg.h> 161 1.1 gwr #include <machine/z8530var.h> 162 1.1 gwr 163 1.52 drochner #include <dev/cons.h> 164 1.52 drochner 165 1.122 tsutsui #include "ioconf.h" 166 1.17 jtk #include "locators.h" 167 1.17 jtk 168 1.1 gwr /* 169 1.1 gwr * How many input characters we can buffer. 170 1.1 gwr * The port-specific var.h may override this. 171 1.1 gwr * Note: must be a power of two! 172 1.1 gwr */ 173 1.1 gwr #ifndef ZSTTY_RING_SIZE 174 1.36 mycroft #define ZSTTY_RING_SIZE 2048 175 1.1 gwr #endif 176 1.6 gwr 177 1.72 eeh static struct cnm_state zstty_cnm_state; 178 1.6 gwr /* 179 1.6 gwr * Make this an option variable one can patch. 180 1.6 gwr * But be warned: this must be a power of 2! 181 1.6 gwr */ 182 1.35 mycroft u_int zstty_rbuf_size = ZSTTY_RING_SIZE; 183 1.1 gwr 184 1.35 mycroft /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ 185 1.35 mycroft u_int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE * 1) / 4; 186 1.35 mycroft u_int zstty_rbuf_lowat = (ZSTTY_RING_SIZE * 3) / 4; 187 1.8 gwr 188 1.1 gwr struct zstty_softc { 189 1.122 tsutsui device_t zst_dev; /* required first: base device */ 190 1.1 gwr struct tty *zst_tty; 191 1.1 gwr struct zs_chanstate *zst_cs; 192 1.1 gwr 193 1.65 thorpej struct callout zst_diag_ch; 194 1.65 thorpej 195 1.35 mycroft u_int zst_overflows, 196 1.35 mycroft zst_floods, 197 1.35 mycroft zst_errors; 198 1.35 mycroft 199 1.35 mycroft int zst_hwflags, /* see z8530var.h */ 200 1.35 mycroft zst_swflags; /* TIOCFLAG_SOFTCAR, ... <ttycom.h> */ 201 1.35 mycroft 202 1.35 mycroft u_int zst_r_hiwat, 203 1.35 mycroft zst_r_lowat; 204 1.122 tsutsui uint8_t *volatile zst_rbget, 205 1.122 tsutsui *volatile zst_rbput; 206 1.35 mycroft volatile u_int zst_rbavail; 207 1.122 tsutsui uint8_t *zst_rbuf, 208 1.122 tsutsui *zst_ebuf; 209 1.1 gwr 210 1.1 gwr /* 211 1.1 gwr * The transmit byte count and address are used for pseudo-DMA 212 1.1 gwr * output in the hardware interrupt code. PDMA can be suspended 213 1.1 gwr * to get pending changes done; heldtbc is used for this. It can 214 1.1 gwr * also be stopped for ^S; this sets TS_TTSTOP in tp->t_state. 215 1.1 gwr */ 216 1.122 tsutsui uint8_t *zst_tba; /* transmit buffer address */ 217 1.35 mycroft u_int zst_tbc, /* transmit byte count */ 218 1.35 mycroft zst_heldtbc; /* held tbc while xmission stopped */ 219 1.1 gwr 220 1.8 gwr /* Flags to communicate with zstty_softint() */ 221 1.122 tsutsui volatile uint8_t zst_rx_flags, /* receiver blocked */ 222 1.35 mycroft #define RX_TTY_BLOCKED 0x01 223 1.35 mycroft #define RX_TTY_OVERFLOWED 0x02 224 1.35 mycroft #define RX_IBUF_BLOCKED 0x04 225 1.35 mycroft #define RX_IBUF_OVERFLOWED 0x08 226 1.35 mycroft #define RX_ANY_BLOCK 0x0f 227 1.35 mycroft zst_tx_busy, /* working on an output chunk */ 228 1.35 mycroft zst_tx_done, /* done with one output chunk */ 229 1.35 mycroft zst_tx_stopped, /* H/W level stop (lost CTS) */ 230 1.35 mycroft zst_st_check, /* got a status interrupt */ 231 1.35 mycroft zst_rx_ready; 232 1.59 wrstuden 233 1.59 wrstuden /* PPS signal on DCD, with or without inkernel clock disciplining */ 234 1.122 tsutsui uint8_t zst_ppsmask; /* pps signal mask */ 235 1.108 kardel struct pps_state zst_pps_state; 236 1.1 gwr }; 237 1.1 gwr 238 1.1 gwr /* Definition of the driver for autoconfig. */ 239 1.122 tsutsui static int zstty_match(device_t, cfdata_t, void *); 240 1.122 tsutsui static void zstty_attach(device_t, device_t, void *); 241 1.1 gwr 242 1.122 tsutsui CFATTACH_DECL_NEW(zstty, sizeof(struct zstty_softc), 243 1.84 thorpej zstty_match, zstty_attach, NULL, NULL); 244 1.4 thorpej 245 1.80 gehenna dev_type_open(zsopen); 246 1.80 gehenna dev_type_close(zsclose); 247 1.80 gehenna dev_type_read(zsread); 248 1.80 gehenna dev_type_write(zswrite); 249 1.80 gehenna dev_type_ioctl(zsioctl); 250 1.80 gehenna dev_type_stop(zsstop); 251 1.80 gehenna dev_type_tty(zstty); 252 1.80 gehenna dev_type_poll(zspoll); 253 1.80 gehenna 254 1.80 gehenna const struct cdevsw zstty_cdevsw = { 255 1.129 dholland .d_open = zsopen, 256 1.129 dholland .d_close = zsclose, 257 1.129 dholland .d_read = zsread, 258 1.129 dholland .d_write = zswrite, 259 1.129 dholland .d_ioctl = zsioctl, 260 1.129 dholland .d_stop = zsstop, 261 1.129 dholland .d_tty = zstty, 262 1.129 dholland .d_poll = zspoll, 263 1.129 dholland .d_mmap = nommap, 264 1.129 dholland .d_kqfilter = ttykqfilter, 265 1.130 dholland .d_discard = nodiscard, 266 1.129 dholland .d_flag = D_TTY 267 1.80 gehenna }; 268 1.80 gehenna 269 1.1 gwr struct zsops zsops_tty; 270 1.1 gwr 271 1.96 perry static void zs_shutdown(struct zstty_softc *); 272 1.96 perry static void zsstart(struct tty *); 273 1.96 perry static int zsparam(struct tty *, struct termios *); 274 1.96 perry static void zs_modem(struct zstty_softc *, int); 275 1.96 perry static void tiocm_to_zs(struct zstty_softc *, u_long, int); 276 1.96 perry static int zs_to_tiocm(struct zstty_softc *); 277 1.96 perry static int zshwiflow(struct tty *, int); 278 1.96 perry static void zs_hwiflow(struct zstty_softc *); 279 1.96 perry static void zs_maskintr(struct zstty_softc *); 280 1.1 gwr 281 1.57 mycroft /* Low-level routines. */ 282 1.96 perry static void zstty_rxint (struct zs_chanstate *); 283 1.96 perry static void zstty_stint (struct zs_chanstate *, int); 284 1.96 perry static void zstty_txint (struct zs_chanstate *); 285 1.96 perry static void zstty_softint(struct zs_chanstate *); 286 1.118 ad static void zstty_softint1(struct zs_chanstate *); 287 1.57 mycroft 288 1.131 christos #define ZSUNIT(x) TTUNIT(x) 289 1.131 christos #define ZSDIALOUT(x) TTDIALOUT(x) 290 1.47 mycroft 291 1.126 cegger struct tty *zstty_get_tty_from_dev(device_t); 292 1.99 macallan 293 1.99 macallan /* 294 1.126 cegger * XXX get the (struct tty *) out of a (device_t) we trust to be a 295 1.99 macallan * (struct zstty_softc *) - needed by sparc/dev/zs.c, sparc64/dev/zs.c, 296 1.99 macallan * sun3/dev/zs.c and sun2/dev/zs.c will probably need it at some point 297 1.99 macallan */ 298 1.99 macallan 299 1.99 macallan struct tty * 300 1.126 cegger zstty_get_tty_from_dev(device_t dev) 301 1.99 macallan { 302 1.122 tsutsui struct zstty_softc *sc = device_private(dev); 303 1.99 macallan 304 1.99 macallan return sc->zst_tty; 305 1.99 macallan } 306 1.99 macallan 307 1.1 gwr /* 308 1.1 gwr * zstty_match: how is this zs channel configured? 309 1.1 gwr */ 310 1.97 perry int 311 1.122 tsutsui zstty_match(device_t parent, cfdata_t cf, void *aux) 312 1.1 gwr { 313 1.1 gwr struct zsc_attach_args *args = aux; 314 1.1 gwr 315 1.1 gwr /* Exact match is better than wildcard. */ 316 1.95 thorpej if (cf->zsccf_channel == args->channel) 317 1.1 gwr return 2; 318 1.1 gwr 319 1.1 gwr /* This driver accepts wildcard. */ 320 1.95 thorpej if (cf->zsccf_channel == ZSCCF_CHANNEL_DEFAULT) 321 1.1 gwr return 1; 322 1.1 gwr 323 1.1 gwr return 0; 324 1.1 gwr } 325 1.1 gwr 326 1.97 perry void 327 1.122 tsutsui zstty_attach(device_t parent, device_t self, void *aux) 328 1.1 gwr { 329 1.122 tsutsui struct zstty_softc *zst = device_private(self); 330 1.122 tsutsui struct zsc_softc *zsc = device_private(parent); 331 1.125 cegger cfdata_t cf = device_cfdata(self); 332 1.1 gwr struct zsc_attach_args *args = aux; 333 1.1 gwr struct zs_chanstate *cs; 334 1.1 gwr struct tty *tp; 335 1.122 tsutsui int channel, tty_unit; 336 1.1 gwr dev_t dev; 337 1.98 christos const char *i, *o; 338 1.89 pk int dtr_on; 339 1.89 pk int resetbit; 340 1.1 gwr 341 1.122 tsutsui zst->zst_dev = self; 342 1.122 tsutsui 343 1.114 ad callout_init(&zst->zst_diag_ch, 0); 344 1.72 eeh cn_init_magic(&zstty_cnm_state); 345 1.65 thorpej 346 1.122 tsutsui tty_unit = device_unit(self); 347 1.1 gwr channel = args->channel; 348 1.14 gwr cs = zsc->zsc_cs[channel]; 349 1.1 gwr cs->cs_private = zst; 350 1.1 gwr cs->cs_ops = &zsops_tty; 351 1.1 gwr 352 1.1 gwr zst->zst_cs = cs; 353 1.1 gwr zst->zst_swflags = cf->cf_flags; /* softcar, etc. */ 354 1.1 gwr zst->zst_hwflags = args->hwflags; 355 1.80 gehenna dev = makedev(cdevsw_lookup_major(&zstty_cdevsw), tty_unit); 356 1.1 gwr 357 1.1 gwr if (zst->zst_swflags) 358 1.122 tsutsui aprint_normal(" flags 0x%x", zst->zst_swflags); 359 1.1 gwr 360 1.64 pk /* 361 1.64 pk * Check whether we serve as a console device. 362 1.64 pk * XXX - split console input/output channels aren't 363 1.64 pk * supported yet on /dev/console 364 1.64 pk */ 365 1.64 pk i = o = NULL; 366 1.64 pk if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) { 367 1.64 pk i = "input"; 368 1.64 pk if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) { 369 1.72 eeh args->consdev->cn_dev = dev; 370 1.64 pk cn_tab->cn_pollc = args->consdev->cn_pollc; 371 1.64 pk cn_tab->cn_getc = args->consdev->cn_getc; 372 1.64 pk } 373 1.64 pk cn_tab->cn_dev = dev; 374 1.72 eeh /* Set console magic to BREAK */ 375 1.72 eeh cn_set_magic("\047\001"); 376 1.64 pk } 377 1.64 pk if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) { 378 1.64 pk o = "output"; 379 1.64 pk if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) { 380 1.64 pk cn_tab->cn_putc = args->consdev->cn_putc; 381 1.64 pk } 382 1.52 drochner cn_tab->cn_dev = dev; 383 1.64 pk } 384 1.64 pk if (i != NULL || o != NULL) 385 1.122 tsutsui aprint_normal(" (console %s)", i ? (o ? "i/o" : i) : o); 386 1.64 pk 387 1.1 gwr #ifdef KGDB 388 1.57 mycroft if (zs_check_kgdb(cs, dev)) { 389 1.1 gwr /* 390 1.15 gwr * Allow kgdb to "take over" this port. Returns true 391 1.15 gwr * if this serial port is in-use by kgdb. 392 1.1 gwr */ 393 1.122 tsutsui aprint_normal(" (kgdb)\n"); 394 1.57 mycroft /* 395 1.57 mycroft * This is the kgdb port (exclusive use) 396 1.57 mycroft * so skip the normal attach code. 397 1.57 mycroft */ 398 1.57 mycroft return; 399 1.64 pk } 400 1.1 gwr #endif 401 1.122 tsutsui aprint_normal("\n"); 402 1.1 gwr 403 1.128 rmind tp = tty_alloc(); 404 1.49 wrstuden tp->t_dev = dev; 405 1.1 gwr tp->t_oproc = zsstart; 406 1.1 gwr tp->t_param = zsparam; 407 1.8 gwr tp->t_hwiflow = zshwiflow; 408 1.9 gwr tty_attach(tp); 409 1.1 gwr 410 1.6 gwr zst->zst_tty = tp; 411 1.134 chs zst->zst_rbuf = malloc(zstty_rbuf_size << 1, M_DEVBUF, M_WAITOK); 412 1.35 mycroft zst->zst_ebuf = zst->zst_rbuf + (zstty_rbuf_size << 1); 413 1.35 mycroft /* Disable the high water mark. */ 414 1.35 mycroft zst->zst_r_hiwat = 0; 415 1.35 mycroft zst->zst_r_lowat = 0; 416 1.35 mycroft zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf; 417 1.35 mycroft zst->zst_rbavail = zstty_rbuf_size; 418 1.6 gwr 419 1.63 jdc /* if there are no enable/disable functions, assume the device 420 1.63 jdc is always enabled */ 421 1.63 jdc if (!cs->enable) 422 1.63 jdc cs->enabled = 1; 423 1.14 gwr 424 1.1 gwr /* 425 1.1 gwr * Hardware init 426 1.1 gwr */ 427 1.89 pk dtr_on = 0; 428 1.89 pk resetbit = 0; 429 1.35 mycroft if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) { 430 1.14 gwr /* Call zsparam similar to open. */ 431 1.14 gwr struct termios t; 432 1.74 tsutsui 433 1.74 tsutsui /* Wait a while for previous console output to complete */ 434 1.74 tsutsui DELAY(10000); 435 1.52 drochner 436 1.57 mycroft /* Setup the "new" parameters in t. */ 437 1.57 mycroft t.c_ispeed = 0; 438 1.57 mycroft t.c_ospeed = cs->cs_defspeed; 439 1.57 mycroft t.c_cflag = cs->cs_defcflag; 440 1.14 gwr 441 1.57 mycroft /* 442 1.57 mycroft * Turn on receiver and status interrupts. 443 1.57 mycroft * We defer the actual write of the register to zsparam(), 444 1.57 mycroft * but we must make sure status interrupts are turned on by 445 1.57 mycroft * the time zsparam() reads the initial rr0 state. 446 1.57 mycroft */ 447 1.124 tsutsui SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE); 448 1.34 gwr 449 1.14 gwr /* Make sure zsparam will see changes. */ 450 1.14 gwr tp->t_ospeed = 0; 451 1.34 gwr (void) zsparam(tp, &t); 452 1.35 mycroft 453 1.34 gwr /* Make sure DTR is on now. */ 454 1.89 pk dtr_on = 1; 455 1.43 mycroft 456 1.76 thorpej } else if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_NORESET)) { 457 1.1 gwr /* Not the console; may need reset. */ 458 1.89 pk resetbit = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; 459 1.89 pk } 460 1.43 mycroft 461 1.115 ad mutex_spin_enter(&cs->cs_lock); 462 1.89 pk if (resetbit) 463 1.89 pk zs_write_reg(cs, 9, resetbit); 464 1.89 pk zs_modem(zst, dtr_on); 465 1.115 ad mutex_spin_exit(&cs->cs_lock); 466 1.1 gwr } 467 1.1 gwr 468 1.1 gwr 469 1.1 gwr /* 470 1.1 gwr * Return pointer to our tty. 471 1.1 gwr */ 472 1.1 gwr struct tty * 473 1.122 tsutsui zstty(dev_t dev) 474 1.1 gwr { 475 1.122 tsutsui struct zstty_softc *zst; 476 1.122 tsutsui 477 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(dev)); 478 1.1 gwr 479 1.1 gwr return (zst->zst_tty); 480 1.1 gwr } 481 1.1 gwr 482 1.1 gwr 483 1.45 mycroft void 484 1.122 tsutsui zs_shutdown(struct zstty_softc *zst) 485 1.45 mycroft { 486 1.46 mycroft struct zs_chanstate *cs = zst->zst_cs; 487 1.45 mycroft struct tty *tp = zst->zst_tty; 488 1.45 mycroft 489 1.115 ad mutex_spin_enter(&cs->cs_lock); 490 1.45 mycroft 491 1.45 mycroft /* If we were asserting flow control, then deassert it. */ 492 1.45 mycroft SET(zst->zst_rx_flags, RX_IBUF_BLOCKED); 493 1.45 mycroft zs_hwiflow(zst); 494 1.45 mycroft 495 1.45 mycroft /* Clear any break condition set with TIOCSBRK. */ 496 1.45 mycroft zs_break(cs, 0); 497 1.45 mycroft 498 1.45 mycroft /* 499 1.45 mycroft * Hang up if necessary. Wait a bit, so the other side has time to 500 1.45 mycroft * notice even if we immediately open the port again. 501 1.45 mycroft */ 502 1.45 mycroft if (ISSET(tp->t_cflag, HUPCL)) { 503 1.45 mycroft zs_modem(zst, 0); 504 1.115 ad mutex_spin_exit(&cs->cs_lock); 505 1.88 pk /* 506 1.88 pk * XXX - another process is not prevented from opening 507 1.88 pk * the device during our sleep. 508 1.88 pk */ 509 1.45 mycroft (void) tsleep(cs, TTIPRI, ttclos, hz); 510 1.89 pk /* Re-check state in case we were opened during our sleep */ 511 1.89 pk if (ISSET(tp->t_state, TS_ISOPEN) || tp->t_wopen != 0) 512 1.89 pk return; 513 1.89 pk 514 1.115 ad mutex_spin_enter(&cs->cs_lock); 515 1.45 mycroft } 516 1.45 mycroft 517 1.45 mycroft /* Turn off interrupts if not the console. */ 518 1.57 mycroft if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) { 519 1.124 tsutsui CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE); 520 1.57 mycroft cs->cs_creg[1] = cs->cs_preg[1]; 521 1.57 mycroft zs_write_reg(cs, 1, cs->cs_creg[1]); 522 1.57 mycroft } 523 1.45 mycroft 524 1.63 jdc /* Call the power management hook. */ 525 1.63 jdc if (cs->disable) { 526 1.63 jdc #ifdef DIAGNOSTIC 527 1.63 jdc if (!cs->enabled) 528 1.122 tsutsui panic("%s: not enabled?", __func__); 529 1.63 jdc #endif 530 1.63 jdc (*cs->disable)(zst->zst_cs); 531 1.63 jdc } 532 1.63 jdc 533 1.115 ad mutex_spin_exit(&cs->cs_lock); 534 1.45 mycroft } 535 1.45 mycroft 536 1.1 gwr /* 537 1.1 gwr * Open a zs serial (tty) port. 538 1.1 gwr */ 539 1.1 gwr int 540 1.122 tsutsui zsopen(dev_t dev, int flags, int mode, struct lwp *l) 541 1.1 gwr { 542 1.45 mycroft struct zstty_softc *zst; 543 1.45 mycroft struct zs_chanstate *cs; 544 1.35 mycroft struct tty *tp; 545 1.45 mycroft int error; 546 1.1 gwr 547 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(dev)); 548 1.68 thorpej if (zst == NULL) 549 1.1 gwr return (ENXIO); 550 1.68 thorpej 551 1.1 gwr tp = zst->zst_tty; 552 1.1 gwr cs = zst->zst_cs; 553 1.1 gwr 554 1.1 gwr /* If KGDB took the line, then tp==NULL */ 555 1.1 gwr if (tp == NULL) 556 1.1 gwr return (EBUSY); 557 1.1 gwr 558 1.132 martin /* 559 1.132 martin * If the device is exclusively for kernel use, deny userland 560 1.132 martin * open. 561 1.132 martin */ 562 1.132 martin if (ISSET(tp->t_state, TS_KERN_ONLY)) 563 1.132 martin return (EBUSY); 564 1.132 martin 565 1.111 elad if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 566 1.1 gwr return (EBUSY); 567 1.1 gwr 568 1.135 riastrad ttylock(tp); 569 1.1 gwr 570 1.35 mycroft /* 571 1.35 mycroft * Do the following iff this is a first open. 572 1.35 mycroft */ 573 1.45 mycroft if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 574 1.14 gwr struct termios t; 575 1.50 wrstuden 576 1.50 wrstuden tp->t_dev = dev; 577 1.63 jdc 578 1.63 jdc /* Call the power management hook. */ 579 1.63 jdc if (cs->enable) { 580 1.63 jdc if ((*cs->enable)(cs)) { 581 1.135 riastrad ttyunlock(tp); 582 1.63 jdc printf("%s: device enable failed\n", 583 1.122 tsutsui device_xname(zst->zst_dev)); 584 1.63 jdc return (EIO); 585 1.63 jdc } 586 1.63 jdc } 587 1.35 mycroft 588 1.14 gwr /* 589 1.35 mycroft * Initialize the termios status to the defaults. Add in the 590 1.35 mycroft * sticky bits from TIOCSFLAGS. 591 1.14 gwr */ 592 1.20 mycroft t.c_ispeed = 0; 593 1.20 mycroft t.c_ospeed = cs->cs_defspeed; 594 1.20 mycroft t.c_cflag = cs->cs_defcflag; 595 1.35 mycroft if (ISSET(zst->zst_swflags, TIOCFLAG_CLOCAL)) 596 1.35 mycroft SET(t.c_cflag, CLOCAL); 597 1.35 mycroft if (ISSET(zst->zst_swflags, TIOCFLAG_CRTSCTS)) 598 1.35 mycroft SET(t.c_cflag, CRTSCTS); 599 1.40 mycroft if (ISSET(zst->zst_swflags, TIOCFLAG_CDTRCTS)) 600 1.40 mycroft SET(t.c_cflag, CDTRCTS); 601 1.35 mycroft if (ISSET(zst->zst_swflags, TIOCFLAG_MDMBUF)) 602 1.35 mycroft SET(t.c_cflag, MDMBUF); 603 1.57 mycroft 604 1.115 ad mutex_spin_enter(&cs->cs_lock); 605 1.57 mycroft 606 1.57 mycroft /* 607 1.57 mycroft * Turn on receiver and status interrupts. 608 1.57 mycroft * We defer the actual write of the register to zsparam(), 609 1.57 mycroft * but we must make sure status interrupts are turned on by 610 1.57 mycroft * the time zsparam() reads the initial rr0 state. 611 1.57 mycroft */ 612 1.124 tsutsui SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE); 613 1.57 mycroft 614 1.59 wrstuden /* Clear PPS capture state on first open. */ 615 1.123 ad mutex_spin_enter(&timecounter_lock); 616 1.59 wrstuden zst->zst_ppsmask = 0; 617 1.108 kardel memset(&zst->zst_pps_state, 0, sizeof(zst->zst_pps_state)); 618 1.122 tsutsui zst->zst_pps_state.ppscap = 619 1.122 tsutsui PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; 620 1.108 kardel pps_init(&zst->zst_pps_state); 621 1.123 ad mutex_spin_exit(&timecounter_lock); 622 1.59 wrstuden 623 1.115 ad mutex_spin_exit(&cs->cs_lock); 624 1.57 mycroft 625 1.14 gwr /* Make sure zsparam will see changes. */ 626 1.14 gwr tp->t_ospeed = 0; 627 1.135 riastrad ttyunlock(tp); 628 1.14 gwr (void) zsparam(tp, &t); 629 1.135 riastrad ttylock(tp); 630 1.57 mycroft 631 1.14 gwr /* 632 1.14 gwr * Note: zsparam has done: cflag, ispeed, ospeed 633 1.14 gwr * so we just need to do: iflag, oflag, lflag, cc 634 1.14 gwr * For "raw" mode, just leave all zeros. 635 1.14 gwr */ 636 1.35 mycroft if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_RAW)) { 637 1.14 gwr tp->t_iflag = TTYDEF_IFLAG; 638 1.14 gwr tp->t_oflag = TTYDEF_OFLAG; 639 1.14 gwr tp->t_lflag = TTYDEF_LFLAG; 640 1.35 mycroft } else { 641 1.35 mycroft tp->t_iflag = 0; 642 1.35 mycroft tp->t_oflag = 0; 643 1.35 mycroft tp->t_lflag = 0; 644 1.14 gwr } 645 1.19 gwr ttychars(tp); 646 1.1 gwr ttsetwater(tp); 647 1.20 mycroft 648 1.115 ad mutex_spin_enter(&cs->cs_lock); 649 1.43 mycroft 650 1.20 mycroft /* 651 1.20 mycroft * Turn on DTR. We must always do this, even if carrier is not 652 1.20 mycroft * present, because otherwise we'd have to use TIOCSDTR 653 1.28 mycroft * immediately after setting CLOCAL, which applications do not 654 1.28 mycroft * expect. We always assert DTR while the device is open 655 1.28 mycroft * unless explicitly requested to deassert it. 656 1.20 mycroft */ 657 1.20 mycroft zs_modem(zst, 1); 658 1.20 mycroft 659 1.20 mycroft /* Clear the input ring, and unblock. */ 660 1.35 mycroft zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf; 661 1.35 mycroft zst->zst_rbavail = zstty_rbuf_size; 662 1.20 mycroft zs_iflush(cs); 663 1.35 mycroft CLR(zst->zst_rx_flags, RX_ANY_BLOCK); 664 1.24 mycroft zs_hwiflow(zst); 665 1.26 mycroft 666 1.115 ad mutex_spin_exit(&cs->cs_lock); 667 1.1 gwr } 668 1.14 gwr 669 1.135 riastrad ttyunlock(tp); 670 1.1 gwr 671 1.47 mycroft error = ttyopen(tp, ZSDIALOUT(dev), ISSET(flags, O_NONBLOCK)); 672 1.47 mycroft if (error) 673 1.47 mycroft goto bad; 674 1.45 mycroft 675 1.70 eeh error = (*tp->t_linesw->l_open)(dev, tp); 676 1.45 mycroft if (error) 677 1.45 mycroft goto bad; 678 1.45 mycroft 679 1.45 mycroft return (0); 680 1.45 mycroft 681 1.45 mycroft bad: 682 1.45 mycroft if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 683 1.45 mycroft /* 684 1.45 mycroft * We failed to open the device, and nobody else had it opened. 685 1.45 mycroft * Clean up the state as appropriate. 686 1.45 mycroft */ 687 1.45 mycroft zs_shutdown(zst); 688 1.45 mycroft } 689 1.45 mycroft 690 1.1 gwr return (error); 691 1.1 gwr } 692 1.1 gwr 693 1.1 gwr /* 694 1.1 gwr * Close a zs serial port. 695 1.1 gwr */ 696 1.1 gwr int 697 1.122 tsutsui zsclose(dev_t dev, int flags, int mode, struct lwp *l) 698 1.1 gwr { 699 1.122 tsutsui struct zstty_softc *zst; 700 1.122 tsutsui struct tty *tp; 701 1.122 tsutsui 702 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(dev)); 703 1.122 tsutsui tp = zst->zst_tty; 704 1.1 gwr 705 1.1 gwr /* XXX This is for cons.c. */ 706 1.35 mycroft if (!ISSET(tp->t_state, TS_ISOPEN)) 707 1.1 gwr return 0; 708 1.1 gwr 709 1.70 eeh (*tp->t_linesw->l_close)(tp, flags); 710 1.20 mycroft ttyclose(tp); 711 1.20 mycroft 712 1.47 mycroft if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 713 1.47 mycroft /* 714 1.47 mycroft * Although we got a last close, the device may still be in 715 1.47 mycroft * use; e.g. if this was the dialout node, and there are still 716 1.47 mycroft * processes waiting for carrier on the non-dialout node. 717 1.47 mycroft */ 718 1.47 mycroft zs_shutdown(zst); 719 1.47 mycroft } 720 1.14 gwr 721 1.1 gwr return (0); 722 1.1 gwr } 723 1.1 gwr 724 1.1 gwr /* 725 1.1 gwr * Read/write zs serial port. 726 1.1 gwr */ 727 1.1 gwr int 728 1.122 tsutsui zsread(dev_t dev, struct uio *uio, int flags) 729 1.1 gwr { 730 1.122 tsutsui struct zstty_softc *zst; 731 1.122 tsutsui struct tty *tp; 732 1.122 tsutsui 733 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(dev)); 734 1.122 tsutsui tp = zst->zst_tty; 735 1.1 gwr 736 1.70 eeh return ((*tp->t_linesw->l_read)(tp, uio, flags)); 737 1.1 gwr } 738 1.1 gwr 739 1.1 gwr int 740 1.122 tsutsui zswrite(dev_t dev, struct uio *uio, int flags) 741 1.1 gwr { 742 1.122 tsutsui struct zstty_softc *zst; 743 1.122 tsutsui struct tty *tp; 744 1.122 tsutsui 745 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(dev)); 746 1.122 tsutsui tp = zst->zst_tty; 747 1.1 gwr 748 1.70 eeh return ((*tp->t_linesw->l_write)(tp, uio, flags)); 749 1.75 scw } 750 1.75 scw 751 1.75 scw int 752 1.122 tsutsui zspoll(dev_t dev, int events, struct lwp *l) 753 1.75 scw { 754 1.122 tsutsui struct zstty_softc *zst; 755 1.122 tsutsui struct tty *tp; 756 1.122 tsutsui 757 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(dev)); 758 1.122 tsutsui tp = zst->zst_tty; 759 1.75 scw 760 1.101 christos return ((*tp->t_linesw->l_poll)(tp, events, l)); 761 1.1 gwr } 762 1.1 gwr 763 1.1 gwr int 764 1.122 tsutsui zsioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 765 1.1 gwr { 766 1.122 tsutsui struct zstty_softc *zst; 767 1.122 tsutsui struct zs_chanstate *cs; 768 1.122 tsutsui struct tty *tp; 769 1.35 mycroft int error; 770 1.1 gwr 771 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(dev)); 772 1.122 tsutsui cs = zst->zst_cs; 773 1.122 tsutsui tp = zst->zst_tty; 774 1.101 christos error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 775 1.79 atatat if (error != EPASSTHROUGH) 776 1.1 gwr return (error); 777 1.14 gwr 778 1.101 christos error = ttioctl(tp, cmd, data, flag, l); 779 1.79 atatat if (error != EPASSTHROUGH) 780 1.1 gwr return (error); 781 1.1 gwr 782 1.14 gwr #ifdef ZS_MD_IOCTL 783 1.79 atatat error = ZS_MD_IOCTL(cs, cmd, data); 784 1.79 atatat if (error != EPASSTHROUGH) 785 1.14 gwr return (error); 786 1.14 gwr #endif /* ZS_MD_IOCTL */ 787 1.44 mycroft 788 1.44 mycroft error = 0; 789 1.14 gwr 790 1.115 ad mutex_spin_enter(&cs->cs_lock); 791 1.43 mycroft 792 1.1 gwr switch (cmd) { 793 1.1 gwr case TIOCSBRK: 794 1.1 gwr zs_break(cs, 1); 795 1.1 gwr break; 796 1.1 gwr 797 1.1 gwr case TIOCCBRK: 798 1.1 gwr zs_break(cs, 0); 799 1.1 gwr break; 800 1.1 gwr 801 1.1 gwr case TIOCGFLAGS: 802 1.1 gwr *(int *)data = zst->zst_swflags; 803 1.1 gwr break; 804 1.1 gwr 805 1.1 gwr case TIOCSFLAGS: 806 1.112 elad error = kauth_authorize_device_tty(l->l_cred, 807 1.112 elad KAUTH_DEVICE_TTY_PRIVSET, tp); 808 1.20 mycroft if (error) 809 1.43 mycroft break; 810 1.20 mycroft zst->zst_swflags = *(int *)data; 811 1.1 gwr break; 812 1.1 gwr 813 1.1 gwr case TIOCSDTR: 814 1.1 gwr zs_modem(zst, 1); 815 1.1 gwr break; 816 1.1 gwr 817 1.1 gwr case TIOCCDTR: 818 1.1 gwr zs_modem(zst, 0); 819 1.1 gwr break; 820 1.1 gwr 821 1.1 gwr case TIOCMSET: 822 1.1 gwr case TIOCMBIS: 823 1.1 gwr case TIOCMBIC: 824 1.58 mycroft tiocm_to_zs(zst, cmd, *(int *)data); 825 1.54 christos break; 826 1.54 christos 827 1.1 gwr case TIOCMGET: 828 1.58 mycroft *(int *)data = zs_to_tiocm(zst); 829 1.54 christos break; 830 1.54 christos 831 1.108 kardel case PPS_IOC_CREATE: 832 1.108 kardel case PPS_IOC_DESTROY: 833 1.108 kardel case PPS_IOC_GETPARAMS: 834 1.108 kardel case PPS_IOC_SETPARAMS: 835 1.108 kardel case PPS_IOC_GETCAP: 836 1.108 kardel case PPS_IOC_FETCH: 837 1.108 kardel #ifdef PPS_SYNC 838 1.108 kardel case PPS_IOC_KCBIND: 839 1.108 kardel #endif 840 1.123 ad mutex_spin_enter(&timecounter_lock); 841 1.108 kardel error = pps_ioctl(cmd, data, &zst->zst_pps_state); 842 1.108 kardel if (zst->zst_pps_state.ppsparam.mode & PPS_CAPTUREBOTH) 843 1.108 kardel zst->zst_ppsmask = ZSRR0_DCD; 844 1.108 kardel else 845 1.108 kardel zst->zst_ppsmask = 0; 846 1.123 ad mutex_spin_exit(&timecounter_lock); 847 1.108 kardel break; 848 1.94 simonb 849 1.59 wrstuden case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */ 850 1.59 wrstuden if (cs->cs_rr0_pps == 0) { 851 1.59 wrstuden error = EINVAL; 852 1.59 wrstuden break; 853 1.59 wrstuden } 854 1.123 ad mutex_spin_enter(&timecounter_lock); 855 1.108 kardel #ifndef PPS_TRAILING_EDGE 856 1.108 kardel TIMESPEC_TO_TIMEVAL((struct timeval *)data, 857 1.108 kardel &zst->zst_pps_state.ppsinfo.assert_timestamp); 858 1.108 kardel #else 859 1.108 kardel TIMESPEC_TO_TIMEVAL((struct timeval *)data, 860 1.108 kardel &zst->zst_pps_state.ppsinfo.clear_timestamp); 861 1.108 kardel #endif 862 1.123 ad mutex_spin_exit(&timecounter_lock); 863 1.59 wrstuden /* 864 1.59 wrstuden * Now update interrupts. 865 1.59 wrstuden */ 866 1.59 wrstuden zs_maskintr(zst); 867 1.59 wrstuden /* 868 1.59 wrstuden * If nothing is being transmitted, set up new current values, 869 1.59 wrstuden * else mark them as pending. 870 1.59 wrstuden */ 871 1.59 wrstuden if (!cs->cs_heldchange) { 872 1.59 wrstuden if (zst->zst_tx_busy) { 873 1.59 wrstuden zst->zst_heldtbc = zst->zst_tbc; 874 1.59 wrstuden zst->zst_tbc = 0; 875 1.59 wrstuden cs->cs_heldchange = 1; 876 1.59 wrstuden } else 877 1.59 wrstuden zs_loadchannelregs(cs); 878 1.59 wrstuden } 879 1.59 wrstuden 880 1.59 wrstuden break; 881 1.59 wrstuden 882 1.1 gwr default: 883 1.79 atatat error = EPASSTHROUGH; 884 1.43 mycroft break; 885 1.1 gwr } 886 1.43 mycroft 887 1.115 ad mutex_spin_exit(&cs->cs_lock); 888 1.43 mycroft 889 1.43 mycroft return (error); 890 1.1 gwr } 891 1.1 gwr 892 1.1 gwr /* 893 1.1 gwr * Start or restart transmission. 894 1.1 gwr */ 895 1.1 gwr static void 896 1.122 tsutsui zsstart(struct tty *tp) 897 1.1 gwr { 898 1.122 tsutsui struct zstty_softc *zst; 899 1.122 tsutsui struct zs_chanstate *cs; 900 1.102 chs u_char *tba; 901 1.115 ad int tbc; 902 1.1 gwr 903 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(tp->t_dev)); 904 1.122 tsutsui cs = zst->zst_cs; 905 1.122 tsutsui 906 1.35 mycroft if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 907 1.116 ad return; 908 1.14 gwr if (zst->zst_tx_stopped) 909 1.116 ad return; 910 1.117 ad if (!ttypull(tp)) 911 1.117 ad return; 912 1.1 gwr 913 1.20 mycroft /* Grab the first contiguous region of buffer space. */ 914 1.102 chs tba = tp->t_outq.c_cf; 915 1.102 chs tbc = ndqb(&tp->t_outq, 0); 916 1.20 mycroft 917 1.115 ad mutex_spin_enter(&cs->cs_lock); 918 1.97 perry 919 1.102 chs zst->zst_tba = tba; 920 1.102 chs zst->zst_tbc = tbc; 921 1.102 chs SET(tp->t_state, TS_BUSY); 922 1.102 chs zst->zst_tx_busy = 1; 923 1.20 mycroft 924 1.102 chs #ifdef ZS_TXDMA 925 1.102 chs if (zst->zst_tbc > 1) { 926 1.102 chs zs_dma_setup(cs, zst->zst_tba, zst->zst_tbc); 927 1.115 ad mutex_spin_exit(&cs->cs_lock); 928 1.116 ad return; 929 1.20 mycroft } 930 1.102 chs #endif 931 1.1 gwr 932 1.20 mycroft /* Output the first character of the contiguous buffer. */ 933 1.102 chs zs_write_data(cs, *zst->zst_tba); 934 1.102 chs zst->zst_tbc--; 935 1.102 chs zst->zst_tba++; 936 1.102 chs 937 1.115 ad mutex_spin_exit(&cs->cs_lock); 938 1.1 gwr } 939 1.1 gwr 940 1.1 gwr /* 941 1.1 gwr * Stop output, e.g., for ^S or output flush. 942 1.1 gwr */ 943 1.10 mycroft void 944 1.122 tsutsui zsstop(struct tty *tp, int flag) 945 1.1 gwr { 946 1.122 tsutsui struct zstty_softc *zst; 947 1.1 gwr 948 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(tp->t_dev)); 949 1.122 tsutsui 950 1.127 mrg mutex_spin_enter(&zst->zst_cs->cs_lock); 951 1.35 mycroft if (ISSET(tp->t_state, TS_BUSY)) { 952 1.35 mycroft /* Stop transmitting at the next chunk. */ 953 1.1 gwr zst->zst_tbc = 0; 954 1.8 gwr zst->zst_heldtbc = 0; 955 1.35 mycroft if (!ISSET(tp->t_state, TS_TTSTOP)) 956 1.35 mycroft SET(tp->t_state, TS_FLUSH); 957 1.1 gwr } 958 1.127 mrg mutex_spin_exit(&zst->zst_cs->cs_lock); 959 1.1 gwr } 960 1.1 gwr 961 1.1 gwr /* 962 1.1 gwr * Set ZS tty parameters from termios. 963 1.1 gwr * XXX - Should just copy the whole termios after 964 1.1 gwr * making sure all the changes could be done. 965 1.1 gwr */ 966 1.1 gwr static int 967 1.122 tsutsui zsparam(struct tty *tp, struct termios *t) 968 1.1 gwr { 969 1.122 tsutsui struct zstty_softc *zst; 970 1.122 tsutsui struct zs_chanstate *cs; 971 1.86 thorpej int ospeed; 972 1.86 thorpej tcflag_t cflag; 973 1.122 tsutsui uint8_t tmp3, tmp4, tmp5; 974 1.115 ad int error; 975 1.1 gwr 976 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(tp->t_dev)); 977 1.122 tsutsui cs = zst->zst_cs; 978 1.35 mycroft ospeed = t->c_ospeed; 979 1.14 gwr cflag = t->c_cflag; 980 1.1 gwr 981 1.35 mycroft /* Check requested parameters. */ 982 1.35 mycroft if (ospeed < 0) 983 1.35 mycroft return (EINVAL); 984 1.35 mycroft if (t->c_ispeed && t->c_ispeed != ospeed) 985 1.1 gwr return (EINVAL); 986 1.14 gwr 987 1.14 gwr /* 988 1.20 mycroft * For the console, always force CLOCAL and !HUPCL, so that the port 989 1.20 mycroft * is always active. 990 1.20 mycroft */ 991 1.35 mycroft if (ISSET(zst->zst_swflags, TIOCFLAG_SOFTCAR) || 992 1.35 mycroft ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) { 993 1.35 mycroft SET(cflag, CLOCAL); 994 1.35 mycroft CLR(cflag, HUPCL); 995 1.20 mycroft } 996 1.20 mycroft 997 1.20 mycroft /* 998 1.14 gwr * Only whack the UART when params change. 999 1.14 gwr * Some callers need to clear tp->t_ospeed 1000 1.14 gwr * to make sure initialization gets done. 1001 1.14 gwr */ 1002 1.35 mycroft if (tp->t_ospeed == ospeed && 1003 1.20 mycroft tp->t_cflag == cflag) 1004 1.1 gwr return (0); 1005 1.1 gwr 1006 1.14 gwr /* 1007 1.14 gwr * Call MD functions to deal with changed 1008 1.14 gwr * clock modes or H/W flow control modes. 1009 1.14 gwr * The BRG divisor is set now. (reg 12,13) 1010 1.14 gwr */ 1011 1.35 mycroft error = zs_set_speed(cs, ospeed); 1012 1.14 gwr if (error) 1013 1.14 gwr return (error); 1014 1.14 gwr error = zs_set_modes(cs, cflag); 1015 1.14 gwr if (error) 1016 1.14 gwr return (error); 1017 1.1 gwr 1018 1.1 gwr /* 1019 1.1 gwr * Block interrupts so that state will not 1020 1.1 gwr * be altered until we are done setting it up. 1021 1.14 gwr * 1022 1.1 gwr * Initial values in cs_preg are set before 1023 1.1 gwr * our attach routine is called. The master 1024 1.1 gwr * interrupt enable is handled by zsc.c 1025 1.14 gwr * 1026 1.1 gwr */ 1027 1.115 ad mutex_spin_enter(&cs->cs_lock); 1028 1.29 mycroft 1029 1.59 wrstuden /* 1030 1.59 wrstuden * Recalculate which status ints to enable. 1031 1.59 wrstuden */ 1032 1.59 wrstuden zs_maskintr(zst); 1033 1.1 gwr 1034 1.14 gwr /* Recompute character size bits. */ 1035 1.35 mycroft tmp3 = cs->cs_preg[3]; 1036 1.35 mycroft tmp5 = cs->cs_preg[5]; 1037 1.35 mycroft CLR(tmp3, ZSWR3_RXSIZE); 1038 1.35 mycroft CLR(tmp5, ZSWR5_TXSIZE); 1039 1.35 mycroft switch (ISSET(cflag, CSIZE)) { 1040 1.1 gwr case CS5: 1041 1.35 mycroft SET(tmp3, ZSWR3_RX_5); 1042 1.35 mycroft SET(tmp5, ZSWR5_TX_5); 1043 1.1 gwr break; 1044 1.1 gwr case CS6: 1045 1.35 mycroft SET(tmp3, ZSWR3_RX_6); 1046 1.35 mycroft SET(tmp5, ZSWR5_TX_6); 1047 1.1 gwr break; 1048 1.1 gwr case CS7: 1049 1.35 mycroft SET(tmp3, ZSWR3_RX_7); 1050 1.35 mycroft SET(tmp5, ZSWR5_TX_7); 1051 1.1 gwr break; 1052 1.1 gwr case CS8: 1053 1.35 mycroft SET(tmp3, ZSWR3_RX_8); 1054 1.35 mycroft SET(tmp5, ZSWR5_TX_8); 1055 1.1 gwr break; 1056 1.1 gwr } 1057 1.14 gwr cs->cs_preg[3] = tmp3; 1058 1.14 gwr cs->cs_preg[5] = tmp5; 1059 1.14 gwr 1060 1.14 gwr /* 1061 1.14 gwr * Recompute the stop bits and parity bits. Note that 1062 1.14 gwr * zs_set_speed() may have set clock selection bits etc. 1063 1.14 gwr * in wr4, so those must preserved. 1064 1.14 gwr */ 1065 1.14 gwr tmp4 = cs->cs_preg[4]; 1066 1.35 mycroft CLR(tmp4, ZSWR4_SBMASK | ZSWR4_PARMASK); 1067 1.35 mycroft if (ISSET(cflag, CSTOPB)) 1068 1.35 mycroft SET(tmp4, ZSWR4_TWOSB); 1069 1.35 mycroft else 1070 1.35 mycroft SET(tmp4, ZSWR4_ONESB); 1071 1.35 mycroft if (!ISSET(cflag, PARODD)) 1072 1.35 mycroft SET(tmp4, ZSWR4_EVENP); 1073 1.35 mycroft if (ISSET(cflag, PARENB)) 1074 1.35 mycroft SET(tmp4, ZSWR4_PARENB); 1075 1.1 gwr cs->cs_preg[4] = tmp4; 1076 1.1 gwr 1077 1.35 mycroft /* And copy to tty. */ 1078 1.35 mycroft tp->t_ispeed = 0; 1079 1.35 mycroft tp->t_ospeed = ospeed; 1080 1.35 mycroft tp->t_cflag = cflag; 1081 1.8 gwr 1082 1.8 gwr /* 1083 1.1 gwr * If nothing is being transmitted, set up new current values, 1084 1.1 gwr * else mark them as pending. 1085 1.1 gwr */ 1086 1.25 mycroft if (!cs->cs_heldchange) { 1087 1.8 gwr if (zst->zst_tx_busy) { 1088 1.1 gwr zst->zst_heldtbc = zst->zst_tbc; 1089 1.1 gwr zst->zst_tbc = 0; 1090 1.25 mycroft cs->cs_heldchange = 1; 1091 1.25 mycroft } else 1092 1.1 gwr zs_loadchannelregs(cs); 1093 1.1 gwr } 1094 1.20 mycroft 1095 1.57 mycroft /* 1096 1.57 mycroft * If hardware flow control is disabled, turn off the buffer water 1097 1.57 mycroft * marks and unblock any soft flow control state. Otherwise, enable 1098 1.57 mycroft * the water marks. 1099 1.57 mycroft */ 1100 1.35 mycroft if (!ISSET(cflag, CHWFLOW)) { 1101 1.35 mycroft zst->zst_r_hiwat = 0; 1102 1.35 mycroft zst->zst_r_lowat = 0; 1103 1.35 mycroft if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) { 1104 1.35 mycroft CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED); 1105 1.35 mycroft zst->zst_rx_ready = 1; 1106 1.35 mycroft cs->cs_softreq = 1; 1107 1.35 mycroft } 1108 1.35 mycroft if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) { 1109 1.35 mycroft CLR(zst->zst_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED); 1110 1.33 mycroft zs_hwiflow(zst); 1111 1.33 mycroft } 1112 1.33 mycroft } else { 1113 1.35 mycroft zst->zst_r_hiwat = zstty_rbuf_hiwat; 1114 1.35 mycroft zst->zst_r_lowat = zstty_rbuf_lowat; 1115 1.33 mycroft } 1116 1.33 mycroft 1117 1.56 wrstuden /* 1118 1.57 mycroft * Force a recheck of the hardware carrier and flow control status, 1119 1.57 mycroft * since we may have changed which bits we're looking at. 1120 1.56 wrstuden */ 1121 1.57 mycroft zstty_stint(cs, 1); 1122 1.56 wrstuden 1123 1.115 ad mutex_spin_exit(&cs->cs_lock); 1124 1.15 gwr 1125 1.20 mycroft /* 1126 1.57 mycroft * If hardware flow control is disabled, unblock any hard flow control 1127 1.57 mycroft * state. 1128 1.55 wrstuden */ 1129 1.35 mycroft if (!ISSET(cflag, CHWFLOW)) { 1130 1.14 gwr if (zst->zst_tx_stopped) { 1131 1.14 gwr zst->zst_tx_stopped = 0; 1132 1.14 gwr zsstart(tp); 1133 1.14 gwr } 1134 1.14 gwr } 1135 1.14 gwr 1136 1.118 ad zstty_softint1(cs); 1137 1.57 mycroft 1138 1.1 gwr return (0); 1139 1.1 gwr } 1140 1.1 gwr 1141 1.1 gwr /* 1142 1.87 wiz * Compute interrupt enable bits and set in the pending bits. Called both 1143 1.59 wrstuden * in zsparam() and when PPS (pulse per second timing) state changes. 1144 1.59 wrstuden * Must be called at splzs(). 1145 1.59 wrstuden */ 1146 1.59 wrstuden static void 1147 1.122 tsutsui zs_maskintr(struct zstty_softc *zst) 1148 1.59 wrstuden { 1149 1.59 wrstuden struct zs_chanstate *cs = zst->zst_cs; 1150 1.122 tsutsui uint8_t tmp15; 1151 1.59 wrstuden 1152 1.59 wrstuden cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd; 1153 1.59 wrstuden if (zst->zst_ppsmask != 0) 1154 1.59 wrstuden cs->cs_rr0_mask |= cs->cs_rr0_pps; 1155 1.59 wrstuden tmp15 = cs->cs_preg[15]; 1156 1.59 wrstuden if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD)) 1157 1.59 wrstuden SET(tmp15, ZSWR15_DCD_IE); 1158 1.59 wrstuden else 1159 1.59 wrstuden CLR(tmp15, ZSWR15_DCD_IE); 1160 1.59 wrstuden if (ISSET(cs->cs_rr0_mask, ZSRR0_CTS)) 1161 1.59 wrstuden SET(tmp15, ZSWR15_CTS_IE); 1162 1.59 wrstuden else 1163 1.59 wrstuden CLR(tmp15, ZSWR15_CTS_IE); 1164 1.59 wrstuden cs->cs_preg[15] = tmp15; 1165 1.59 wrstuden } 1166 1.59 wrstuden 1167 1.59 wrstuden 1168 1.59 wrstuden /* 1169 1.1 gwr * Raise or lower modem control (DTR/RTS) signals. If a character is 1170 1.1 gwr * in transmission, the change is deferred. 1171 1.89 pk * Called at splzs() and with the channel lock held. 1172 1.1 gwr */ 1173 1.1 gwr static void 1174 1.122 tsutsui zs_modem(struct zstty_softc *zst, int onoff) 1175 1.1 gwr { 1176 1.81 ad struct zs_chanstate *cs = zst->zst_cs, *ccs; 1177 1.1 gwr 1178 1.14 gwr if (cs->cs_wr5_dtr == 0) 1179 1.14 gwr return; 1180 1.1 gwr 1181 1.81 ad ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs); 1182 1.81 ad 1183 1.24 mycroft if (onoff) 1184 1.81 ad SET(ccs->cs_preg[5], cs->cs_wr5_dtr); 1185 1.24 mycroft else 1186 1.81 ad CLR(ccs->cs_preg[5], cs->cs_wr5_dtr); 1187 1.14 gwr 1188 1.25 mycroft if (!cs->cs_heldchange) { 1189 1.8 gwr if (zst->zst_tx_busy) { 1190 1.1 gwr zst->zst_heldtbc = zst->zst_tbc; 1191 1.1 gwr zst->zst_tbc = 0; 1192 1.25 mycroft cs->cs_heldchange = 1; 1193 1.25 mycroft } else 1194 1.25 mycroft zs_loadchannelregs(cs); 1195 1.1 gwr } 1196 1.54 christos } 1197 1.54 christos 1198 1.89 pk /* 1199 1.89 pk * Set modem bits. 1200 1.89 pk * Called at splzs() and with the channel lock held. 1201 1.89 pk */ 1202 1.54 christos static void 1203 1.122 tsutsui tiocm_to_zs(struct zstty_softc *zst, u_long how, int ttybits) 1204 1.54 christos { 1205 1.81 ad struct zs_chanstate *cs = zst->zst_cs, *ccs; 1206 1.122 tsutsui uint8_t zsbits; 1207 1.54 christos 1208 1.81 ad ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs); 1209 1.81 ad 1210 1.57 mycroft zsbits = 0; 1211 1.57 mycroft if (ISSET(ttybits, TIOCM_DTR)) 1212 1.57 mycroft SET(zsbits, ZSWR5_DTR); 1213 1.57 mycroft if (ISSET(ttybits, TIOCM_RTS)) 1214 1.57 mycroft SET(zsbits, ZSWR5_RTS); 1215 1.54 christos 1216 1.54 christos switch (how) { 1217 1.54 christos case TIOCMBIC: 1218 1.81 ad CLR(ccs->cs_preg[5], zsbits); 1219 1.54 christos break; 1220 1.54 christos 1221 1.54 christos case TIOCMBIS: 1222 1.81 ad SET(ccs->cs_preg[5], zsbits); 1223 1.54 christos break; 1224 1.54 christos 1225 1.54 christos case TIOCMSET: 1226 1.81 ad CLR(ccs->cs_preg[5], ZSWR5_RTS | ZSWR5_DTR); 1227 1.81 ad SET(ccs->cs_preg[5], zsbits); 1228 1.54 christos break; 1229 1.54 christos } 1230 1.54 christos 1231 1.54 christos if (!cs->cs_heldchange) { 1232 1.54 christos if (zst->zst_tx_busy) { 1233 1.54 christos zst->zst_heldtbc = zst->zst_tbc; 1234 1.54 christos zst->zst_tbc = 0; 1235 1.54 christos cs->cs_heldchange = 1; 1236 1.57 mycroft } else 1237 1.57 mycroft zs_loadchannelregs(cs); 1238 1.54 christos } 1239 1.54 christos } 1240 1.54 christos 1241 1.89 pk /* 1242 1.89 pk * Get modem bits. 1243 1.89 pk * Called at splzs() and with the channel lock held. 1244 1.89 pk */ 1245 1.54 christos static int 1246 1.122 tsutsui zs_to_tiocm(struct zstty_softc *zst) 1247 1.54 christos { 1248 1.81 ad struct zs_chanstate *cs = zst->zst_cs, *ccs; 1249 1.122 tsutsui uint8_t zsbits; 1250 1.57 mycroft int ttybits = 0; 1251 1.54 christos 1252 1.81 ad ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs); 1253 1.81 ad 1254 1.81 ad zsbits = ccs->cs_preg[5]; 1255 1.57 mycroft if (ISSET(zsbits, ZSWR5_DTR)) 1256 1.57 mycroft SET(ttybits, TIOCM_DTR); 1257 1.57 mycroft if (ISSET(zsbits, ZSWR5_RTS)) 1258 1.57 mycroft SET(ttybits, TIOCM_RTS); 1259 1.57 mycroft 1260 1.57 mycroft zsbits = cs->cs_rr0; 1261 1.57 mycroft if (ISSET(zsbits, ZSRR0_DCD)) 1262 1.57 mycroft SET(ttybits, TIOCM_CD); 1263 1.57 mycroft if (ISSET(zsbits, ZSRR0_CTS)) 1264 1.57 mycroft SET(ttybits, TIOCM_CTS); 1265 1.54 christos 1266 1.57 mycroft return (ttybits); 1267 1.1 gwr } 1268 1.1 gwr 1269 1.8 gwr /* 1270 1.8 gwr * Try to block or unblock input using hardware flow-control. 1271 1.8 gwr * This is called by kern/tty.c if MDMBUF|CRTSCTS is set, and 1272 1.8 gwr * if this function returns non-zero, the TS_TBLOCK flag will 1273 1.24 mycroft * be set or cleared according to the "block" arg passed. 1274 1.8 gwr */ 1275 1.8 gwr int 1276 1.122 tsutsui zshwiflow(struct tty *tp, int block) 1277 1.8 gwr { 1278 1.122 tsutsui struct zstty_softc *zst; 1279 1.122 tsutsui struct zs_chanstate *cs; 1280 1.122 tsutsui 1281 1.122 tsutsui zst = device_lookup_private(&zstty_cd, ZSUNIT(tp->t_dev)); 1282 1.122 tsutsui cs = zst->zst_cs; 1283 1.8 gwr 1284 1.14 gwr if (cs->cs_wr5_rts == 0) 1285 1.14 gwr return (0); 1286 1.8 gwr 1287 1.115 ad mutex_spin_enter(&cs->cs_lock); 1288 1.24 mycroft if (block) { 1289 1.35 mycroft if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) { 1290 1.35 mycroft SET(zst->zst_rx_flags, RX_TTY_BLOCKED); 1291 1.24 mycroft zs_hwiflow(zst); 1292 1.24 mycroft } 1293 1.8 gwr } else { 1294 1.35 mycroft if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) { 1295 1.35 mycroft CLR(zst->zst_rx_flags, RX_TTY_OVERFLOWED); 1296 1.35 mycroft zst->zst_rx_ready = 1; 1297 1.35 mycroft cs->cs_softreq = 1; 1298 1.35 mycroft } 1299 1.35 mycroft if (ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) { 1300 1.35 mycroft CLR(zst->zst_rx_flags, RX_TTY_BLOCKED); 1301 1.24 mycroft zs_hwiflow(zst); 1302 1.24 mycroft } 1303 1.8 gwr } 1304 1.115 ad mutex_spin_exit(&cs->cs_lock); 1305 1.35 mycroft return (1); 1306 1.8 gwr } 1307 1.8 gwr 1308 1.8 gwr /* 1309 1.8 gwr * Internal version of zshwiflow 1310 1.89 pk * Called at splzs() and with the channel lock held. 1311 1.8 gwr */ 1312 1.8 gwr static void 1313 1.122 tsutsui zs_hwiflow(struct zstty_softc *zst) 1314 1.8 gwr { 1315 1.81 ad struct zs_chanstate *cs = zst->zst_cs, *ccs; 1316 1.8 gwr 1317 1.14 gwr if (cs->cs_wr5_rts == 0) 1318 1.14 gwr return; 1319 1.8 gwr 1320 1.81 ad ccs = (cs->cs_ctl_chan != NULL ? cs->cs_ctl_chan : cs); 1321 1.81 ad 1322 1.35 mycroft if (ISSET(zst->zst_rx_flags, RX_ANY_BLOCK)) { 1323 1.81 ad CLR(ccs->cs_preg[5], cs->cs_wr5_rts); 1324 1.81 ad CLR(ccs->cs_creg[5], cs->cs_wr5_rts); 1325 1.8 gwr } else { 1326 1.81 ad SET(ccs->cs_preg[5], cs->cs_wr5_rts); 1327 1.81 ad SET(ccs->cs_creg[5], cs->cs_wr5_rts); 1328 1.8 gwr } 1329 1.81 ad zs_write_reg(ccs, 5, ccs->cs_creg[5]); 1330 1.8 gwr } 1331 1.8 gwr 1332 1.1 gwr 1333 1.1 gwr /**************************************************************** 1334 1.1 gwr * Interface to the lower layer (zscc) 1335 1.1 gwr ****************************************************************/ 1336 1.3 gwr 1337 1.35 mycroft #define integrate static inline 1338 1.96 perry integrate void zstty_rxsoft(struct zstty_softc *, struct tty *); 1339 1.96 perry integrate void zstty_txsoft(struct zstty_softc *, struct tty *); 1340 1.96 perry integrate void zstty_stsoft(struct zstty_softc *, struct tty *); 1341 1.96 perry static void zstty_diag(void *); 1342 1.1 gwr 1343 1.6 gwr /* 1344 1.89 pk * Receiver Ready interrupt. 1345 1.89 pk * Called at splzs() and with the channel lock held. 1346 1.6 gwr */ 1347 1.6 gwr static void 1348 1.122 tsutsui zstty_rxint(struct zs_chanstate *cs) 1349 1.1 gwr { 1350 1.35 mycroft struct zstty_softc *zst = cs->cs_private; 1351 1.122 tsutsui uint8_t *put, *end; 1352 1.35 mycroft u_int cc; 1353 1.122 tsutsui uint8_t rr0, rr1, c; 1354 1.1 gwr 1355 1.35 mycroft end = zst->zst_ebuf; 1356 1.1 gwr put = zst->zst_rbput; 1357 1.35 mycroft cc = zst->zst_rbavail; 1358 1.1 gwr 1359 1.35 mycroft while (cc > 0) { 1360 1.35 mycroft /* 1361 1.35 mycroft * First read the status, because reading the received char 1362 1.35 mycroft * destroys the status of this char. 1363 1.35 mycroft */ 1364 1.35 mycroft rr1 = zs_read_reg(cs, 1); 1365 1.35 mycroft c = zs_read_data(cs); 1366 1.35 mycroft 1367 1.35 mycroft if (ISSET(rr1, ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) { 1368 1.35 mycroft /* Clear the receive error. */ 1369 1.35 mycroft zs_write_csr(cs, ZSWR0_RESET_ERRORS); 1370 1.35 mycroft } 1371 1.35 mycroft 1372 1.72 eeh cn_check_magic(zst->zst_tty->t_dev, c, zstty_cnm_state); 1373 1.35 mycroft put[0] = c; 1374 1.35 mycroft put[1] = rr1; 1375 1.35 mycroft put += 2; 1376 1.35 mycroft if (put >= end) 1377 1.35 mycroft put = zst->zst_rbuf; 1378 1.35 mycroft cc--; 1379 1.35 mycroft 1380 1.35 mycroft rr0 = zs_read_csr(cs); 1381 1.35 mycroft if (!ISSET(rr0, ZSRR0_RX_READY)) 1382 1.35 mycroft break; 1383 1.35 mycroft } 1384 1.1 gwr 1385 1.5 gwr /* 1386 1.35 mycroft * Current string of incoming characters ended because 1387 1.35 mycroft * no more data was available or we ran out of space. 1388 1.35 mycroft * Schedule a receive event if any data was received. 1389 1.35 mycroft * If we're out of space, turn off receive interrupts. 1390 1.5 gwr */ 1391 1.35 mycroft zst->zst_rbput = put; 1392 1.35 mycroft zst->zst_rbavail = cc; 1393 1.35 mycroft if (!ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) { 1394 1.35 mycroft zst->zst_rx_ready = 1; 1395 1.35 mycroft cs->cs_softreq = 1; 1396 1.1 gwr } 1397 1.1 gwr 1398 1.35 mycroft /* 1399 1.35 mycroft * See if we are in danger of overflowing a buffer. If 1400 1.35 mycroft * so, use hardware flow control to ease the pressure. 1401 1.35 mycroft */ 1402 1.35 mycroft if (!ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED) && 1403 1.35 mycroft cc < zst->zst_r_hiwat) { 1404 1.35 mycroft SET(zst->zst_rx_flags, RX_IBUF_BLOCKED); 1405 1.35 mycroft zs_hwiflow(zst); 1406 1.1 gwr } 1407 1.1 gwr 1408 1.8 gwr /* 1409 1.35 mycroft * If we're out of space, disable receive interrupts 1410 1.35 mycroft * until the queue has drained a bit. 1411 1.8 gwr */ 1412 1.35 mycroft if (!cc) { 1413 1.35 mycroft SET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED); 1414 1.35 mycroft CLR(cs->cs_preg[1], ZSWR1_RIE); 1415 1.35 mycroft cs->cs_creg[1] = cs->cs_preg[1]; 1416 1.35 mycroft zs_write_reg(cs, 1, cs->cs_creg[1]); 1417 1.8 gwr } 1418 1.8 gwr 1419 1.35 mycroft #if 0 1420 1.35 mycroft printf("%xH%04d\n", zst->zst_rx_flags, zst->zst_rbavail); 1421 1.35 mycroft #endif 1422 1.1 gwr } 1423 1.1 gwr 1424 1.6 gwr /* 1425 1.89 pk * Transmitter Ready interrupt. 1426 1.89 pk * Called at splzs() and with the channel lock held. 1427 1.6 gwr */ 1428 1.6 gwr static void 1429 1.122 tsutsui zstty_txint(struct zs_chanstate *cs) 1430 1.1 gwr { 1431 1.35 mycroft struct zstty_softc *zst = cs->cs_private; 1432 1.8 gwr 1433 1.124 tsutsui zs_write_csr(cs, ZSWR0_RESET_TXINT); 1434 1.124 tsutsui 1435 1.8 gwr /* 1436 1.35 mycroft * If we've delayed a parameter change, do it now, and restart 1437 1.35 mycroft * output. 1438 1.8 gwr */ 1439 1.8 gwr if (cs->cs_heldchange) { 1440 1.25 mycroft zs_loadchannelregs(cs); 1441 1.8 gwr cs->cs_heldchange = 0; 1442 1.35 mycroft zst->zst_tbc = zst->zst_heldtbc; 1443 1.35 mycroft zst->zst_heldtbc = 0; 1444 1.35 mycroft } 1445 1.1 gwr 1446 1.35 mycroft /* Output the next character in the buffer, if any. */ 1447 1.48 mycroft if (zst->zst_tbc > 0) { 1448 1.2 gwr zs_write_data(cs, *zst->zst_tba); 1449 1.35 mycroft zst->zst_tbc--; 1450 1.2 gwr zst->zst_tba++; 1451 1.35 mycroft } else { 1452 1.35 mycroft if (zst->zst_tx_busy) { 1453 1.35 mycroft zst->zst_tx_busy = 0; 1454 1.35 mycroft zst->zst_tx_done = 1; 1455 1.35 mycroft cs->cs_softreq = 1; 1456 1.35 mycroft } 1457 1.1 gwr } 1458 1.1 gwr } 1459 1.1 gwr 1460 1.6 gwr /* 1461 1.89 pk * Status Change interrupt. 1462 1.89 pk * Called at splzs() and with the channel lock held. 1463 1.6 gwr */ 1464 1.6 gwr static void 1465 1.122 tsutsui zstty_stint(struct zs_chanstate *cs, int force) 1466 1.1 gwr { 1467 1.35 mycroft struct zstty_softc *zst = cs->cs_private; 1468 1.122 tsutsui uint8_t rr0, delta; 1469 1.1 gwr 1470 1.2 gwr rr0 = zs_read_csr(cs); 1471 1.2 gwr zs_write_csr(cs, ZSWR0_RESET_STATUS); 1472 1.1 gwr 1473 1.6 gwr /* 1474 1.6 gwr * Check here for console break, so that we can abort 1475 1.6 gwr * even when interrupts are locking up the machine. 1476 1.6 gwr */ 1477 1.72 eeh if (ISSET(rr0, ZSRR0_BREAK)) 1478 1.72 eeh cn_check_magic(zst->zst_tty->t_dev, CNC_BREAK, zstty_cnm_state); 1479 1.1 gwr 1480 1.57 mycroft if (!force) 1481 1.57 mycroft delta = rr0 ^ cs->cs_rr0; 1482 1.57 mycroft else 1483 1.57 mycroft delta = cs->cs_rr0_mask; 1484 1.14 gwr cs->cs_rr0 = rr0; 1485 1.57 mycroft 1486 1.35 mycroft if (ISSET(delta, cs->cs_rr0_mask)) { 1487 1.35 mycroft SET(cs->cs_rr0_delta, delta); 1488 1.59 wrstuden 1489 1.59 wrstuden /* 1490 1.59 wrstuden * Pulse-per-second clock signal on edge of DCD? 1491 1.59 wrstuden */ 1492 1.59 wrstuden if (ISSET(delta, zst->zst_ppsmask)) { 1493 1.122 tsutsui if (zst->zst_pps_state.ppsparam.mode & 1494 1.122 tsutsui PPS_CAPTUREBOTH) { 1495 1.123 ad mutex_spin_enter(&timecounter_lock); 1496 1.108 kardel pps_capture(&zst->zst_pps_state); 1497 1.108 kardel pps_event(&zst->zst_pps_state, 1498 1.108 kardel (ISSET(cs->cs_rr0, zst->zst_ppsmask)) 1499 1.108 kardel ? PPS_CAPTUREASSERT 1500 1.108 kardel : PPS_CAPTURECLEAR); 1501 1.123 ad mutex_spin_exit(&timecounter_lock); 1502 1.108 kardel } 1503 1.59 wrstuden } 1504 1.14 gwr 1505 1.22 mycroft /* 1506 1.22 mycroft * Stop output immediately if we lose the output 1507 1.22 mycroft * flow control signal or carrier detect. 1508 1.22 mycroft */ 1509 1.35 mycroft if (ISSET(~rr0, cs->cs_rr0_mask)) { 1510 1.22 mycroft zst->zst_tbc = 0; 1511 1.22 mycroft zst->zst_heldtbc = 0; 1512 1.22 mycroft } 1513 1.22 mycroft 1514 1.22 mycroft zst->zst_st_check = 1; 1515 1.35 mycroft cs->cs_softreq = 1; 1516 1.35 mycroft } 1517 1.35 mycroft } 1518 1.35 mycroft 1519 1.35 mycroft void 1520 1.122 tsutsui zstty_diag(void *arg) 1521 1.35 mycroft { 1522 1.35 mycroft struct zstty_softc *zst = arg; 1523 1.35 mycroft int overflows, floods; 1524 1.35 mycroft 1525 1.127 mrg mutex_spin_enter(&zst->zst_cs->cs_lock); 1526 1.35 mycroft overflows = zst->zst_overflows; 1527 1.35 mycroft zst->zst_overflows = 0; 1528 1.35 mycroft floods = zst->zst_floods; 1529 1.35 mycroft zst->zst_floods = 0; 1530 1.35 mycroft zst->zst_errors = 0; 1531 1.127 mrg mutex_spin_exit(&zst->zst_cs->cs_lock); 1532 1.35 mycroft 1533 1.35 mycroft log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", 1534 1.122 tsutsui device_xname(zst->zst_dev), 1535 1.35 mycroft overflows, overflows == 1 ? "" : "s", 1536 1.35 mycroft floods, floods == 1 ? "" : "s"); 1537 1.35 mycroft } 1538 1.35 mycroft 1539 1.35 mycroft integrate void 1540 1.122 tsutsui zstty_rxsoft(struct zstty_softc *zst, struct tty *tp) 1541 1.35 mycroft { 1542 1.35 mycroft struct zs_chanstate *cs = zst->zst_cs; 1543 1.98 christos int (*rint)(int, struct tty *) = tp->t_linesw->l_rint; 1544 1.122 tsutsui uint8_t *get, *end; 1545 1.35 mycroft u_int cc, scc; 1546 1.122 tsutsui uint8_t rr1; 1547 1.35 mycroft int code; 1548 1.35 mycroft 1549 1.35 mycroft end = zst->zst_ebuf; 1550 1.35 mycroft get = zst->zst_rbget; 1551 1.35 mycroft scc = cc = zstty_rbuf_size - zst->zst_rbavail; 1552 1.35 mycroft 1553 1.35 mycroft if (cc == zstty_rbuf_size) { 1554 1.35 mycroft zst->zst_floods++; 1555 1.35 mycroft if (zst->zst_errors++ == 0) 1556 1.66 hannken callout_reset(&zst->zst_diag_ch, 60 * hz, 1557 1.65 thorpej zstty_diag, zst); 1558 1.35 mycroft } 1559 1.35 mycroft 1560 1.60 pk /* If not yet open, drop the entire buffer content here */ 1561 1.60 pk if (!ISSET(tp->t_state, TS_ISOPEN)) { 1562 1.60 pk get += cc << 1; 1563 1.60 pk if (get >= end) 1564 1.60 pk get -= zstty_rbuf_size << 1; 1565 1.60 pk cc = 0; 1566 1.60 pk } 1567 1.35 mycroft while (cc) { 1568 1.37 mycroft code = get[0]; 1569 1.35 mycroft rr1 = get[1]; 1570 1.37 mycroft if (ISSET(rr1, ZSRR1_DO | ZSRR1_FE | ZSRR1_PE)) { 1571 1.37 mycroft if (ISSET(rr1, ZSRR1_DO)) { 1572 1.37 mycroft zst->zst_overflows++; 1573 1.37 mycroft if (zst->zst_errors++ == 0) 1574 1.66 hannken callout_reset(&zst->zst_diag_ch, 1575 1.65 thorpej 60 * hz, zstty_diag, zst); 1576 1.37 mycroft } 1577 1.35 mycroft if (ISSET(rr1, ZSRR1_FE)) 1578 1.35 mycroft SET(code, TTY_FE); 1579 1.35 mycroft if (ISSET(rr1, ZSRR1_PE)) 1580 1.35 mycroft SET(code, TTY_PE); 1581 1.35 mycroft } 1582 1.35 mycroft if ((*rint)(code, tp) == -1) { 1583 1.35 mycroft /* 1584 1.35 mycroft * The line discipline's buffer is out of space. 1585 1.35 mycroft */ 1586 1.35 mycroft if (!ISSET(zst->zst_rx_flags, RX_TTY_BLOCKED)) { 1587 1.35 mycroft /* 1588 1.35 mycroft * We're either not using flow control, or the 1589 1.35 mycroft * line discipline didn't tell us to block for 1590 1.35 mycroft * some reason. Either way, we have no way to 1591 1.35 mycroft * know when there's more space available, so 1592 1.35 mycroft * just drop the rest of the data. 1593 1.35 mycroft */ 1594 1.35 mycroft get += cc << 1; 1595 1.35 mycroft if (get >= end) 1596 1.35 mycroft get -= zstty_rbuf_size << 1; 1597 1.35 mycroft cc = 0; 1598 1.35 mycroft } else { 1599 1.35 mycroft /* 1600 1.35 mycroft * Don't schedule any more receive processing 1601 1.35 mycroft * until the line discipline tells us there's 1602 1.35 mycroft * space available (through comhwiflow()). 1603 1.35 mycroft * Leave the rest of the data in the input 1604 1.35 mycroft * buffer. 1605 1.35 mycroft */ 1606 1.35 mycroft SET(zst->zst_rx_flags, RX_TTY_OVERFLOWED); 1607 1.35 mycroft } 1608 1.35 mycroft break; 1609 1.35 mycroft } 1610 1.35 mycroft get += 2; 1611 1.35 mycroft if (get >= end) 1612 1.35 mycroft get = zst->zst_rbuf; 1613 1.35 mycroft cc--; 1614 1.8 gwr } 1615 1.6 gwr 1616 1.35 mycroft if (cc != scc) { 1617 1.35 mycroft zst->zst_rbget = get; 1618 1.115 ad mutex_spin_enter(&cs->cs_lock); 1619 1.35 mycroft cc = zst->zst_rbavail += scc - cc; 1620 1.35 mycroft /* Buffers should be ok again, release possible block. */ 1621 1.35 mycroft if (cc >= zst->zst_r_lowat) { 1622 1.35 mycroft if (ISSET(zst->zst_rx_flags, RX_IBUF_OVERFLOWED)) { 1623 1.35 mycroft CLR(zst->zst_rx_flags, RX_IBUF_OVERFLOWED); 1624 1.35 mycroft SET(cs->cs_preg[1], ZSWR1_RIE); 1625 1.35 mycroft cs->cs_creg[1] = cs->cs_preg[1]; 1626 1.35 mycroft zs_write_reg(cs, 1, cs->cs_creg[1]); 1627 1.35 mycroft } 1628 1.35 mycroft if (ISSET(zst->zst_rx_flags, RX_IBUF_BLOCKED)) { 1629 1.35 mycroft CLR(zst->zst_rx_flags, RX_IBUF_BLOCKED); 1630 1.35 mycroft zs_hwiflow(zst); 1631 1.35 mycroft } 1632 1.35 mycroft } 1633 1.115 ad mutex_spin_exit(&cs->cs_lock); 1634 1.35 mycroft } 1635 1.35 mycroft 1636 1.35 mycroft #if 0 1637 1.35 mycroft printf("%xS%04d\n", zst->zst_rx_flags, zst->zst_rbavail); 1638 1.35 mycroft #endif 1639 1.1 gwr } 1640 1.1 gwr 1641 1.35 mycroft integrate void 1642 1.122 tsutsui zstty_txsoft(struct zstty_softc *zst, struct tty *tp) 1643 1.35 mycroft { 1644 1.89 pk struct zs_chanstate *cs = zst->zst_cs; 1645 1.35 mycroft 1646 1.115 ad mutex_spin_enter(&cs->cs_lock); 1647 1.35 mycroft CLR(tp->t_state, TS_BUSY); 1648 1.35 mycroft if (ISSET(tp->t_state, TS_FLUSH)) 1649 1.35 mycroft CLR(tp->t_state, TS_FLUSH); 1650 1.35 mycroft else 1651 1.35 mycroft ndflush(&tp->t_outq, (int)(zst->zst_tba - tp->t_outq.c_cf)); 1652 1.115 ad mutex_spin_exit(&cs->cs_lock); 1653 1.70 eeh (*tp->t_linesw->l_start)(tp); 1654 1.35 mycroft } 1655 1.35 mycroft 1656 1.35 mycroft integrate void 1657 1.122 tsutsui zstty_stsoft(struct zstty_softc *zst, struct tty *tp) 1658 1.1 gwr { 1659 1.35 mycroft struct zs_chanstate *cs = zst->zst_cs; 1660 1.122 tsutsui uint8_t rr0, delta; 1661 1.35 mycroft 1662 1.115 ad mutex_spin_enter(&cs->cs_lock); 1663 1.35 mycroft rr0 = cs->cs_rr0; 1664 1.35 mycroft delta = cs->cs_rr0_delta; 1665 1.35 mycroft cs->cs_rr0_delta = 0; 1666 1.115 ad mutex_spin_exit(&cs->cs_lock); 1667 1.35 mycroft 1668 1.35 mycroft if (ISSET(delta, cs->cs_rr0_dcd)) { 1669 1.35 mycroft /* 1670 1.35 mycroft * Inform the tty layer that carrier detect changed. 1671 1.35 mycroft */ 1672 1.70 eeh (void) (*tp->t_linesw->l_modem)(tp, ISSET(rr0, ZSRR0_DCD)); 1673 1.35 mycroft } 1674 1.1 gwr 1675 1.35 mycroft if (ISSET(delta, cs->cs_rr0_cts)) { 1676 1.35 mycroft /* Block or unblock output according to flow control. */ 1677 1.35 mycroft if (ISSET(rr0, cs->cs_rr0_cts)) { 1678 1.35 mycroft zst->zst_tx_stopped = 0; 1679 1.70 eeh (*tp->t_linesw->l_start)(tp); 1680 1.35 mycroft } else { 1681 1.35 mycroft zst->zst_tx_stopped = 1; 1682 1.35 mycroft } 1683 1.1 gwr } 1684 1.1 gwr } 1685 1.1 gwr 1686 1.6 gwr /* 1687 1.6 gwr * Software interrupt. Called at zssoft 1688 1.8 gwr * 1689 1.8 gwr * The main job to be done here is to empty the input ring 1690 1.8 gwr * by passing its contents up to the tty layer. The ring is 1691 1.8 gwr * always emptied during this operation, therefore the ring 1692 1.8 gwr * must not be larger than the space after "high water" in 1693 1.8 gwr * the tty layer, or the tty layer might drop our input. 1694 1.8 gwr * 1695 1.8 gwr * Note: an "input blockage" condition is assumed to exist if 1696 1.8 gwr * EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set. 1697 1.6 gwr */ 1698 1.6 gwr static void 1699 1.122 tsutsui zstty_softint(struct zs_chanstate *cs) 1700 1.1 gwr { 1701 1.118 ad 1702 1.118 ad zstty_softint1(cs); 1703 1.118 ad } 1704 1.118 ad 1705 1.118 ad static void 1706 1.122 tsutsui zstty_softint1(struct zs_chanstate *cs) 1707 1.118 ad { 1708 1.35 mycroft struct zstty_softc *zst = cs->cs_private; 1709 1.35 mycroft struct tty *tp = zst->zst_tty; 1710 1.1 gwr 1711 1.1 gwr 1712 1.35 mycroft if (zst->zst_rx_ready) { 1713 1.35 mycroft zst->zst_rx_ready = 0; 1714 1.35 mycroft zstty_rxsoft(zst, tp); 1715 1.1 gwr } 1716 1.1 gwr 1717 1.8 gwr if (zst->zst_st_check) { 1718 1.8 gwr zst->zst_st_check = 0; 1719 1.35 mycroft zstty_stsoft(zst, tp); 1720 1.8 gwr } 1721 1.8 gwr 1722 1.8 gwr if (zst->zst_tx_done) { 1723 1.8 gwr zst->zst_tx_done = 0; 1724 1.35 mycroft zstty_txsoft(zst, tp); 1725 1.1 gwr } 1726 1.1 gwr } 1727 1.1 gwr 1728 1.1 gwr struct zsops zsops_tty = { 1729 1.1 gwr zstty_rxint, /* receive char available */ 1730 1.1 gwr zstty_stint, /* external/status */ 1731 1.1 gwr zstty_txint, /* xmit buffer empty */ 1732 1.1 gwr zstty_softint, /* process software interrupt */ 1733 1.1 gwr }; 1734 1.102 chs 1735 1.102 chs #ifdef ZS_TXDMA 1736 1.102 chs void 1737 1.122 tsutsui zstty_txdma_int(void *arg) 1738 1.102 chs { 1739 1.102 chs struct zs_chanstate *cs = arg; 1740 1.102 chs struct zstty_softc *zst = cs->cs_private; 1741 1.102 chs 1742 1.102 chs zst->zst_tba += zst->zst_tbc; 1743 1.102 chs zst->zst_tbc = 0; 1744 1.102 chs 1745 1.102 chs if (zst->zst_tx_busy) { 1746 1.102 chs zst->zst_tx_busy = 0; 1747 1.102 chs zst->zst_tx_done = 1; 1748 1.102 chs cs->cs_softreq = 1; 1749 1.102 chs } 1750 1.102 chs } 1751 1.102 chs #endif 1752