1 1.44 tsutsui /* $NetBSD: dz.c,v 1.44 2024/02/02 15:44:43 tsutsui Exp $ */ 2 1.1 ad /* 3 1.1 ad * Copyright (c) 1992, 1993 4 1.1 ad * The Regents of the University of California. All rights reserved. 5 1.1 ad * 6 1.1 ad * This code is derived from software contributed to Berkeley by 7 1.1 ad * Ralph Campbell and Rick Macklem. 8 1.1 ad * 9 1.1 ad * Redistribution and use in source and binary forms, with or without 10 1.1 ad * modification, are permitted provided that the following conditions 11 1.1 ad * are met: 12 1.1 ad * 1. Redistributions of source code must retain the above copyright 13 1.1 ad * notice, this list of conditions and the following disclaimer. 14 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 ad * notice, this list of conditions and the following disclaimer in the 16 1.1 ad * documentation and/or other materials provided with the distribution. 17 1.10 agc * 3. Neither the name of the University nor the names of its contributors 18 1.10 agc * may be used to endorse or promote products derived from this software 19 1.10 agc * without specific prior written permission. 20 1.10 agc * 21 1.10 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 1.10 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 1.10 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 1.10 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 1.10 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 1.10 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 1.10 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 1.10 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 1.10 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 1.10 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 1.10 agc * SUCH DAMAGE. 32 1.10 agc */ 33 1.10 agc 34 1.10 agc /* 35 1.10 agc * Copyright (c) 1996 Ken C. Wellsch. All rights reserved. 36 1.10 agc * 37 1.10 agc * This code is derived from software contributed to Berkeley by 38 1.10 agc * Ralph Campbell and Rick Macklem. 39 1.10 agc * 40 1.10 agc * Redistribution and use in source and binary forms, with or without 41 1.10 agc * modification, are permitted provided that the following conditions 42 1.10 agc * are met: 43 1.10 agc * 1. Redistributions of source code must retain the above copyright 44 1.10 agc * notice, this list of conditions and the following disclaimer. 45 1.10 agc * 2. Redistributions in binary form must reproduce the above copyright 46 1.10 agc * notice, this list of conditions and the following disclaimer in the 47 1.10 agc * documentation and/or other materials provided with the distribution. 48 1.1 ad * 3. All advertising materials mentioning features or use of this software 49 1.1 ad * must display the following acknowledgement: 50 1.1 ad * This product includes software developed by the University of 51 1.1 ad * California, Berkeley and its contributors. 52 1.1 ad * 4. Neither the name of the University nor the names of its contributors 53 1.1 ad * may be used to endorse or promote products derived from this software 54 1.1 ad * without specific prior written permission. 55 1.1 ad * 56 1.1 ad * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 57 1.1 ad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 1.1 ad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 1.1 ad * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 60 1.1 ad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 1.1 ad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 1.1 ad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 1.1 ad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 1.1 ad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 1.1 ad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 1.1 ad * SUCH DAMAGE. 67 1.1 ad */ 68 1.1 ad 69 1.1 ad #include <sys/cdefs.h> 70 1.44 tsutsui __KERNEL_RCSID(0, "$NetBSD: dz.c,v 1.44 2024/02/02 15:44:43 tsutsui Exp $"); 71 1.1 ad 72 1.1 ad #include <sys/param.h> 73 1.1 ad #include <sys/systm.h> 74 1.1 ad #include <sys/callout.h> 75 1.1 ad #include <sys/ioctl.h> 76 1.1 ad #include <sys/tty.h> 77 1.1 ad #include <sys/proc.h> 78 1.1 ad #include <sys/buf.h> 79 1.1 ad #include <sys/conf.h> 80 1.1 ad #include <sys/file.h> 81 1.1 ad #include <sys/uio.h> 82 1.1 ad #include <sys/kernel.h> 83 1.1 ad #include <sys/syslog.h> 84 1.1 ad #include <sys/device.h> 85 1.20 yamt #include <sys/kauth.h> 86 1.1 ad 87 1.30 ad #include <sys/bus.h> 88 1.1 ad 89 1.1 ad #include <dev/dec/dzreg.h> 90 1.1 ad #include <dev/dec/dzvar.h> 91 1.1 ad 92 1.11 ragge #include <dev/cons.h> 93 1.11 ragge 94 1.29 ad #ifdef __mips__ 95 1.29 ad #define DZ_DELAY(x) DELAY(x) 96 1.38 gmcgarry #define control __noinline 97 1.29 ad #else /* presumably vax */ 98 1.29 ad #define DZ_DELAY(x) /* nothing */ 99 1.29 ad #define control inline 100 1.29 ad #endif 101 1.29 ad 102 1.29 ad static control uint 103 1.29 ad dz_read1(struct dz_softc *sc, u_int off) 104 1.29 ad { 105 1.29 ad u_int rv; 106 1.29 ad 107 1.29 ad rv = bus_space_read_1(sc->sc_iot, sc->sc_ioh, off); 108 1.29 ad DZ_DELAY(1); 109 1.29 ad return rv; 110 1.29 ad } 111 1.29 ad 112 1.29 ad static control u_int 113 1.29 ad dz_read2(struct dz_softc *sc, u_int off) 114 1.29 ad { 115 1.29 ad u_int rv; 116 1.29 ad 117 1.29 ad rv = bus_space_read_2(sc->sc_iot, sc->sc_ioh, off); 118 1.29 ad DZ_DELAY(1); 119 1.29 ad return rv; 120 1.29 ad } 121 1.29 ad 122 1.29 ad static control void 123 1.29 ad dz_write1(struct dz_softc *sc, u_int off, u_int val) 124 1.29 ad { 125 1.29 ad 126 1.29 ad bus_space_write_1(sc->sc_iot, sc->sc_ioh, off, val); 127 1.29 ad bus_space_barrier(sc->sc_iot, sc->sc_ioh, sc->sc_dr.dr_firstreg, 128 1.29 ad sc->sc_dr.dr_winsize, BUS_SPACE_BARRIER_WRITE | 129 1.29 ad BUS_SPACE_BARRIER_READ); 130 1.29 ad DZ_DELAY(10); 131 1.29 ad } 132 1.29 ad 133 1.29 ad static control void 134 1.29 ad dz_write2(struct dz_softc *sc, u_int off, u_int val) 135 1.29 ad { 136 1.29 ad 137 1.29 ad bus_space_write_2(sc->sc_iot, sc->sc_ioh, off, val); 138 1.29 ad bus_space_barrier(sc->sc_iot, sc->sc_ioh, sc->sc_dr.dr_firstreg, 139 1.29 ad sc->sc_dr.dr_winsize, BUS_SPACE_BARRIER_WRITE | 140 1.29 ad BUS_SPACE_BARRIER_READ); 141 1.29 ad DZ_DELAY(10); 142 1.29 ad } 143 1.1 ad 144 1.1 ad #include "ioconf.h" 145 1.1 ad 146 1.1 ad /* Flags used to monitor modem bits, make them understood outside driver */ 147 1.1 ad 148 1.1 ad #define DML_DTR TIOCM_DTR 149 1.1 ad #define DML_DCD TIOCM_CD 150 1.1 ad #define DML_RI TIOCM_RI 151 1.1 ad #define DML_BRK 0100000 /* no equivalent, we will mask */ 152 1.1 ad 153 1.15 matt static const struct speedtab dzspeedtab[] = 154 1.1 ad { 155 1.1 ad { 0, 0 }, 156 1.1 ad { 50, DZ_LPR_B50 }, 157 1.1 ad { 75, DZ_LPR_B75 }, 158 1.1 ad { 110, DZ_LPR_B110 }, 159 1.1 ad { 134, DZ_LPR_B134 }, 160 1.1 ad { 150, DZ_LPR_B150 }, 161 1.1 ad { 300, DZ_LPR_B300 }, 162 1.1 ad { 600, DZ_LPR_B600 }, 163 1.1 ad { 1200, DZ_LPR_B1200 }, 164 1.1 ad { 1800, DZ_LPR_B1800 }, 165 1.1 ad { 2000, DZ_LPR_B2000 }, 166 1.1 ad { 2400, DZ_LPR_B2400 }, 167 1.1 ad { 3600, DZ_LPR_B3600 }, 168 1.1 ad { 4800, DZ_LPR_B4800 }, 169 1.1 ad { 7200, DZ_LPR_B7200 }, 170 1.1 ad { 9600, DZ_LPR_B9600 }, 171 1.1 ad { 19200, DZ_LPR_B19200 }, 172 1.1 ad { -1, -1 } 173 1.1 ad }; 174 1.1 ad 175 1.1 ad static void dzstart(struct tty *); 176 1.1 ad static int dzparam(struct tty *, struct termios *); 177 1.1 ad static unsigned dzmctl(struct dz_softc *, int, int, int); 178 1.1 ad static void dzscan(void *); 179 1.3 gehenna 180 1.34 matt static dev_type_open(dzopen); 181 1.34 matt static dev_type_close(dzclose); 182 1.34 matt static dev_type_read(dzread); 183 1.34 matt static dev_type_write(dzwrite); 184 1.34 matt static dev_type_ioctl(dzioctl); 185 1.34 matt static dev_type_stop(dzstop); 186 1.34 matt static dev_type_tty(dztty); 187 1.34 matt static dev_type_poll(dzpoll); 188 1.3 gehenna 189 1.3 gehenna const struct cdevsw dz_cdevsw = { 190 1.41 dholland .d_open = dzopen, 191 1.41 dholland .d_close = dzclose, 192 1.41 dholland .d_read = dzread, 193 1.41 dholland .d_write = dzwrite, 194 1.41 dholland .d_ioctl = dzioctl, 195 1.41 dholland .d_stop = dzstop, 196 1.41 dholland .d_tty = dztty, 197 1.41 dholland .d_poll = dzpoll, 198 1.41 dholland .d_mmap = nommap, 199 1.41 dholland .d_kqfilter = ttykqfilter, 200 1.42 dholland .d_discard = nodiscard, 201 1.41 dholland .d_flag = D_TTY 202 1.3 gehenna }; 203 1.1 ad 204 1.1 ad /* 205 1.1 ad * The DZ series doesn't interrupt on carrier transitions, 206 1.1 ad * so we have to use a timer to watch it. 207 1.1 ad */ 208 1.1 ad int dz_timer; /* true if timer started */ 209 1.1 ad struct callout dzscan_ch; 210 1.11 ragge static struct cnm_state dz_cnm_state; 211 1.1 ad 212 1.1 ad void 213 1.7 ad dzattach(struct dz_softc *sc, struct evcnt *parent_evcnt, int consline) 214 1.1 ad { 215 1.1 ad int n; 216 1.1 ad 217 1.39 hans /* Initialize our softc structure. */ 218 1.1 ad 219 1.4 ad for (n = 0; n < sc->sc_type; n++) { 220 1.6 ad sc->sc_dz[n].dz_sc = sc; 221 1.4 ad sc->sc_dz[n].dz_line = n; 222 1.40 rmind sc->sc_dz[n].dz_tty = tty_alloc(); 223 1.4 ad } 224 1.1 ad 225 1.1 ad evcnt_attach_dynamic(&sc->sc_rintrcnt, EVCNT_TYPE_INTR, parent_evcnt, 226 1.35 matt device_xname(sc->sc_dev), "rintr"); 227 1.1 ad evcnt_attach_dynamic(&sc->sc_tintrcnt, EVCNT_TYPE_INTR, parent_evcnt, 228 1.35 matt device_xname(sc->sc_dev), "tintr"); 229 1.1 ad 230 1.11 ragge /* Console magic keys */ 231 1.11 ragge cn_init_magic(&dz_cnm_state); 232 1.11 ragge cn_set_magic("\047\001"); /* default magic is BREAK */ 233 1.11 ragge /* VAX will change it in MD code */ 234 1.11 ragge 235 1.39 hans sc->sc_rxint = sc->sc_brk = 0; 236 1.39 hans sc->sc_consline = consline; 237 1.39 hans 238 1.39 hans sc->sc_dr.dr_tcrw = sc->sc_dr.dr_tcr; 239 1.39 hans dz_write2(sc, sc->sc_dr.dr_csr, DZ_CSR_MSE | DZ_CSR_RXIE | DZ_CSR_TXIE); 240 1.39 hans dz_write1(sc, sc->sc_dr.dr_dtr, 0); 241 1.39 hans dz_write1(sc, sc->sc_dr.dr_break, 0); 242 1.39 hans DELAY(10000); 243 1.39 hans 244 1.1 ad /* Alas no interrupt on modem bit changes, so we manually scan */ 245 1.1 ad if (dz_timer == 0) { 246 1.1 ad dz_timer = 1; 247 1.26 ad callout_init(&dzscan_ch, 0); 248 1.1 ad callout_reset(&dzscan_ch, hz, dzscan, NULL); 249 1.1 ad } 250 1.44 tsutsui aprint_normal("\n"); 251 1.1 ad } 252 1.1 ad 253 1.1 ad /* Receiver Interrupt */ 254 1.1 ad 255 1.1 ad void 256 1.1 ad dzrint(void *arg) 257 1.1 ad { 258 1.1 ad struct dz_softc *sc = arg; 259 1.1 ad struct tty *tp; 260 1.12 ad int cc, mcc, line; 261 1.1 ad unsigned c; 262 1.1 ad int overrun = 0; 263 1.1 ad 264 1.1 ad sc->sc_rxint++; 265 1.1 ad 266 1.29 ad while ((c = dz_read2(sc, sc->sc_dr.dr_rbuf)) & DZ_RBUF_DATA_VALID) { 267 1.1 ad cc = c & 0xFF; 268 1.1 ad line = DZ_PORT(c>>8); 269 1.1 ad tp = sc->sc_dz[line].dz_tty; 270 1.1 ad 271 1.1 ad /* Must be caught early */ 272 1.1 ad if (sc->sc_dz[line].dz_catch && 273 1.1 ad (*sc->sc_dz[line].dz_catch)(sc->sc_dz[line].dz_private, cc)) 274 1.1 ad continue; 275 1.11 ragge 276 1.12 ad if ((c & (DZ_RBUF_FRAMING_ERR | 0xff)) == DZ_RBUF_FRAMING_ERR) 277 1.12 ad mcc = CNC_BREAK; 278 1.12 ad else 279 1.12 ad mcc = cc; 280 1.12 ad 281 1.12 ad cn_check_magic(tp->t_dev, mcc, dz_cnm_state); 282 1.1 ad 283 1.1 ad if (!(tp->t_state & TS_ISOPEN)) { 284 1.37 ad cv_broadcast(&tp->t_rawcv); 285 1.1 ad continue; 286 1.1 ad } 287 1.1 ad 288 1.1 ad if ((c & DZ_RBUF_OVERRUN_ERR) && overrun == 0) { 289 1.1 ad log(LOG_WARNING, "%s: silo overflow, line %d\n", 290 1.35 matt device_xname(sc->sc_dev), line); 291 1.1 ad overrun = 1; 292 1.1 ad } 293 1.12 ad 294 1.1 ad if (c & DZ_RBUF_FRAMING_ERR) 295 1.1 ad cc |= TTY_FE; 296 1.1 ad if (c & DZ_RBUF_PARITY_ERR) 297 1.1 ad cc |= TTY_PE; 298 1.1 ad 299 1.1 ad (*tp->t_linesw->l_rint)(cc, tp); 300 1.1 ad } 301 1.1 ad } 302 1.1 ad 303 1.1 ad /* Transmitter Interrupt */ 304 1.1 ad 305 1.1 ad void 306 1.1 ad dzxint(void *arg) 307 1.1 ad { 308 1.1 ad struct dz_softc *sc = arg; 309 1.1 ad struct tty *tp; 310 1.1 ad struct clist *cl; 311 1.1 ad int line, ch, csr; 312 1.1 ad u_char tcr; 313 1.1 ad 314 1.1 ad /* 315 1.1 ad * Switch to POLLED mode. 316 1.1 ad * Some simple measurements indicated that even on 317 1.1 ad * one port, by freeing the scanner in the controller 318 1.1 ad * by either providing a character or turning off 319 1.1 ad * the port when output is complete, the transmitter 320 1.1 ad * was ready to accept more output when polled again. 321 1.1 ad * With just two ports running the game "worms," 322 1.1 ad * almost every interrupt serviced both transmitters! 323 1.1 ad * Each UART is double buffered, so if the scanner 324 1.1 ad * is quick enough and timing works out, we can even 325 1.1 ad * feed the same port twice. 326 1.1 ad * 327 1.1 ad * Ragge 980517: 328 1.1 ad * Do not need to turn off interrupts, already at interrupt level. 329 1.1 ad * Remove the pdma stuff; no great need of it right now. 330 1.1 ad */ 331 1.1 ad 332 1.29 ad for (;;) { 333 1.29 ad csr = dz_read2(sc, sc->sc_dr.dr_csr); 334 1.29 ad if ((csr & DZ_CSR_TX_READY) == 0) 335 1.29 ad break; 336 1.1 ad 337 1.29 ad line = DZ_PORT(csr >> 8); 338 1.1 ad tp = sc->sc_dz[line].dz_tty; 339 1.1 ad cl = &tp->t_outq; 340 1.1 ad tp->t_state &= ~TS_BUSY; 341 1.1 ad 342 1.1 ad /* Just send out a char if we have one */ 343 1.1 ad /* As long as we can fill the chip buffer, we just loop here */ 344 1.1 ad if (cl->c_cc) { 345 1.1 ad tp->t_state |= TS_BUSY; 346 1.1 ad ch = getc(cl); 347 1.29 ad dz_write1(sc, sc->sc_dr.dr_tbuf, ch); 348 1.1 ad continue; 349 1.16 perry } 350 1.29 ad 351 1.1 ad /* Nothing to send; clear the scan bit */ 352 1.1 ad /* Clear xmit scanner bit; dzstart may set it again */ 353 1.29 ad tcr = dz_read2(sc, sc->sc_dr.dr_tcrw); 354 1.1 ad tcr &= 255; 355 1.1 ad tcr &= ~(1 << line); 356 1.29 ad dz_write1(sc, sc->sc_dr.dr_tcr, tcr); 357 1.1 ad if (sc->sc_dz[line].dz_catch) 358 1.1 ad continue; 359 1.1 ad 360 1.1 ad if (tp->t_state & TS_FLUSH) 361 1.1 ad tp->t_state &= ~TS_FLUSH; 362 1.1 ad else 363 1.1 ad ndflush (&tp->t_outq, cl->c_cc); 364 1.1 ad 365 1.1 ad (*tp->t_linesw->l_start)(tp); 366 1.1 ad } 367 1.1 ad } 368 1.1 ad 369 1.1 ad int 370 1.18 christos dzopen(dev_t dev, int flag, int mode, struct lwp *l) 371 1.1 ad { 372 1.34 matt const int line = DZ_PORT(minor(dev)); 373 1.35 matt struct dz_softc *sc = device_lookup_private(&dz_cd, DZ_I2C(minor(dev))); 374 1.1 ad struct tty *tp; 375 1.29 ad int error = 0; 376 1.1 ad 377 1.34 matt if (sc == NULL || line >= sc->sc_type) 378 1.1 ad return ENXIO; 379 1.1 ad 380 1.1 ad /* if some other device is using the line, it's busy */ 381 1.1 ad if (sc->sc_dz[line].dz_catch) 382 1.1 ad return EBUSY; 383 1.1 ad 384 1.1 ad tp = sc->sc_dz[line].dz_tty; 385 1.1 ad if (tp == NULL) 386 1.1 ad return (ENODEV); 387 1.34 matt tp->t_oproc = dzstart; 388 1.34 matt tp->t_param = dzparam; 389 1.1 ad tp->t_dev = dev; 390 1.23 elad 391 1.23 elad if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 392 1.23 elad return (EBUSY); 393 1.23 elad 394 1.1 ad if ((tp->t_state & TS_ISOPEN) == 0) { 395 1.1 ad ttychars(tp); 396 1.1 ad if (tp->t_ispeed == 0) { 397 1.1 ad tp->t_iflag = TTYDEF_IFLAG; 398 1.1 ad tp->t_oflag = TTYDEF_OFLAG; 399 1.1 ad tp->t_cflag = TTYDEF_CFLAG; 400 1.1 ad tp->t_lflag = TTYDEF_LFLAG; 401 1.1 ad tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 402 1.1 ad } 403 1.1 ad (void) dzparam(tp, &tp->t_termios); 404 1.1 ad ttsetwater(tp); 405 1.24 he } 406 1.29 ad 407 1.1 ad /* Use DMBIS and *not* DMSET or else we clobber incoming bits */ 408 1.1 ad if (dzmctl(sc, line, DML_DTR, DMBIS) & DML_DCD) 409 1.1 ad tp->t_state |= TS_CARR_ON; 410 1.43 riastrad ttylock(tp); 411 1.1 ad while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) && 412 1.1 ad !(tp->t_state & TS_CARR_ON)) { 413 1.1 ad tp->t_wopen++; 414 1.36 ad error = ttysleep(tp, &tp->t_rawcv, true, 0); 415 1.1 ad tp->t_wopen--; 416 1.1 ad if (error) 417 1.1 ad break; 418 1.1 ad } 419 1.43 riastrad ttyunlock(tp); 420 1.1 ad if (error) 421 1.1 ad return (error); 422 1.1 ad return ((*tp->t_linesw->l_open)(dev, tp)); 423 1.1 ad } 424 1.1 ad 425 1.1 ad /*ARGSUSED*/ 426 1.1 ad int 427 1.18 christos dzclose(dev_t dev, int flag, int mode, struct lwp *l) 428 1.1 ad { 429 1.34 matt const int line = DZ_PORT(minor(dev)); 430 1.35 matt struct dz_softc *sc = device_lookup_private(&dz_cd, DZ_I2C(minor(dev))); 431 1.34 matt struct tty *tp = sc->sc_dz[line].dz_tty; 432 1.1 ad 433 1.1 ad (*tp->t_linesw->l_close)(tp, flag); 434 1.1 ad 435 1.1 ad /* Make sure a BREAK state is not left enabled. */ 436 1.1 ad (void) dzmctl(sc, line, DML_BRK, DMBIC); 437 1.1 ad 438 1.1 ad /* Do a hangup if so required. */ 439 1.1 ad if ((tp->t_cflag & HUPCL) || tp->t_wopen || !(tp->t_state & TS_ISOPEN)) 440 1.1 ad (void) dzmctl(sc, line, 0, DMSET); 441 1.1 ad 442 1.34 matt return ttyclose(tp); 443 1.1 ad } 444 1.1 ad 445 1.1 ad int 446 1.1 ad dzread(dev_t dev, struct uio *uio, int flag) 447 1.1 ad { 448 1.35 matt struct dz_softc *sc = device_lookup_private(&dz_cd, DZ_I2C(minor(dev))); 449 1.34 matt struct tty *tp = sc->sc_dz[DZ_PORT(minor(dev))].dz_tty; 450 1.1 ad 451 1.1 ad return ((*tp->t_linesw->l_read)(tp, uio, flag)); 452 1.1 ad } 453 1.1 ad 454 1.1 ad int 455 1.1 ad dzwrite(dev_t dev, struct uio *uio, int flag) 456 1.1 ad { 457 1.35 matt struct dz_softc *sc = device_lookup_private(&dz_cd, DZ_I2C(minor(dev))); 458 1.34 matt struct tty *tp = sc->sc_dz[DZ_PORT(minor(dev))].dz_tty; 459 1.1 ad 460 1.1 ad return ((*tp->t_linesw->l_write)(tp, uio, flag)); 461 1.1 ad } 462 1.1 ad 463 1.1 ad int 464 1.34 matt dzpoll(dev_t dev, int events, struct lwp *l) 465 1.1 ad { 466 1.35 matt struct dz_softc *sc = device_lookup_private(&dz_cd, DZ_I2C(minor(dev))); 467 1.34 matt struct tty *tp = sc->sc_dz[DZ_PORT(minor(dev))].dz_tty; 468 1.1 ad 469 1.18 christos return ((*tp->t_linesw->l_poll)(tp, events, l)); 470 1.1 ad } 471 1.1 ad 472 1.1 ad /*ARGSUSED*/ 473 1.1 ad int 474 1.25 christos dzioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 475 1.1 ad { 476 1.35 matt struct dz_softc *sc = device_lookup_private(&dz_cd, DZ_I2C(minor(dev))); 477 1.34 matt const int line = DZ_PORT(minor(dev)); 478 1.34 matt struct tty *tp = sc->sc_dz[line].dz_tty; 479 1.1 ad int error; 480 1.1 ad 481 1.18 christos error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 482 1.1 ad if (error >= 0) 483 1.1 ad return (error); 484 1.2 atatat 485 1.18 christos error = ttioctl(tp, cmd, data, flag, l); 486 1.1 ad if (error >= 0) 487 1.1 ad return (error); 488 1.1 ad 489 1.1 ad switch (cmd) { 490 1.1 ad case TIOCSBRK: 491 1.1 ad (void) dzmctl(sc, line, DML_BRK, DMBIS); 492 1.1 ad break; 493 1.1 ad 494 1.1 ad case TIOCCBRK: 495 1.1 ad (void) dzmctl(sc, line, DML_BRK, DMBIC); 496 1.1 ad break; 497 1.1 ad 498 1.1 ad case TIOCSDTR: 499 1.1 ad (void) dzmctl(sc, line, DML_DTR, DMBIS); 500 1.1 ad break; 501 1.1 ad 502 1.1 ad case TIOCCDTR: 503 1.1 ad (void) dzmctl(sc, line, DML_DTR, DMBIC); 504 1.1 ad break; 505 1.1 ad 506 1.1 ad case TIOCMSET: 507 1.1 ad (void) dzmctl(sc, line, *(int *)data, DMSET); 508 1.1 ad break; 509 1.1 ad 510 1.1 ad case TIOCMBIS: 511 1.1 ad (void) dzmctl(sc, line, *(int *)data, DMBIS); 512 1.1 ad break; 513 1.1 ad 514 1.1 ad case TIOCMBIC: 515 1.1 ad (void) dzmctl(sc, line, *(int *)data, DMBIC); 516 1.1 ad break; 517 1.1 ad 518 1.1 ad case TIOCMGET: 519 1.1 ad *(int *)data = (dzmctl(sc, line, 0, DMGET) & ~DML_BRK); 520 1.1 ad break; 521 1.1 ad 522 1.1 ad default: 523 1.2 atatat return (EPASSTHROUGH); 524 1.1 ad } 525 1.1 ad return (0); 526 1.1 ad } 527 1.1 ad 528 1.1 ad struct tty * 529 1.1 ad dztty(dev_t dev) 530 1.1 ad { 531 1.35 matt struct dz_softc *sc = device_lookup_private(&dz_cd, DZ_I2C(minor(dev))); 532 1.29 ad 533 1.34 matt return sc->sc_dz[DZ_PORT(minor(dev))].dz_tty; 534 1.1 ad } 535 1.1 ad 536 1.1 ad /*ARGSUSED*/ 537 1.1 ad void 538 1.1 ad dzstop(struct tty *tp, int flag) 539 1.1 ad { 540 1.29 ad if ((tp->t_state & (TS_BUSY | TS_TTSTOP)) == TS_BUSY) 541 1.29 ad tp->t_state |= TS_FLUSH; 542 1.1 ad } 543 1.1 ad 544 1.1 ad void 545 1.1 ad dzstart(struct tty *tp) 546 1.1 ad { 547 1.1 ad struct dz_softc *sc; 548 1.34 matt int line; 549 1.34 matt int s; 550 1.1 ad char state; 551 1.1 ad 552 1.1 ad s = spltty(); 553 1.14 ad if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { 554 1.14 ad splx(s); 555 1.1 ad return; 556 1.14 ad } 557 1.34 matt if (!ttypull(tp)) { 558 1.34 matt splx(s); 559 1.1 ad return; 560 1.34 matt } 561 1.34 matt 562 1.34 matt line = DZ_PORT(minor(tp->t_dev)); 563 1.35 matt sc = device_lookup_private(&dz_cd, DZ_I2C(minor(tp->t_dev))); 564 1.34 matt 565 1.1 ad tp->t_state |= TS_BUSY; 566 1.29 ad state = dz_read2(sc, sc->sc_dr.dr_tcrw) & 255; 567 1.29 ad if ((state & (1 << line)) == 0) 568 1.29 ad dz_write1(sc, sc->sc_dr.dr_tcr, state | (1 << line)); 569 1.1 ad dzxint(sc); 570 1.1 ad splx(s); 571 1.1 ad } 572 1.1 ad 573 1.1 ad static int 574 1.1 ad dzparam(struct tty *tp, struct termios *t) 575 1.1 ad { 576 1.35 matt struct dz_softc *sc = device_lookup_private(&dz_cd, DZ_I2C(minor(tp->t_dev))); 577 1.34 matt const int line = DZ_PORT(minor(tp->t_dev)); 578 1.1 ad int cflag = t->c_cflag; 579 1.1 ad int ispeed = ttspeedtab(t->c_ispeed, dzspeedtab); 580 1.1 ad int ospeed = ttspeedtab(t->c_ospeed, dzspeedtab); 581 1.1 ad unsigned lpr; 582 1.1 ad int s; 583 1.1 ad 584 1.1 ad /* check requested parameters */ 585 1.1 ad if (ospeed < 0 || ispeed < 0 || ispeed != ospeed) 586 1.1 ad return (EINVAL); 587 1.1 ad 588 1.1 ad tp->t_ispeed = t->c_ispeed; 589 1.1 ad tp->t_ospeed = t->c_ospeed; 590 1.1 ad tp->t_cflag = cflag; 591 1.1 ad 592 1.1 ad if (ospeed == 0) { 593 1.1 ad (void) dzmctl(sc, line, 0, DMSET); /* hang up line */ 594 1.1 ad return (0); 595 1.1 ad } 596 1.1 ad 597 1.1 ad s = spltty(); 598 1.1 ad 599 1.28 ad /* XXX This is wrong. Flush output or the chip gets very confused. */ 600 1.28 ad ttywait(tp); 601 1.28 ad 602 1.1 ad lpr = DZ_LPR_RX_ENABLE | ((ispeed&0xF)<<8) | line; 603 1.1 ad 604 1.1 ad switch (cflag & CSIZE) 605 1.1 ad { 606 1.1 ad case CS5: 607 1.1 ad lpr |= DZ_LPR_5_BIT_CHAR; 608 1.1 ad break; 609 1.1 ad case CS6: 610 1.1 ad lpr |= DZ_LPR_6_BIT_CHAR; 611 1.1 ad break; 612 1.1 ad case CS7: 613 1.1 ad lpr |= DZ_LPR_7_BIT_CHAR; 614 1.1 ad break; 615 1.1 ad default: 616 1.1 ad lpr |= DZ_LPR_8_BIT_CHAR; 617 1.1 ad break; 618 1.1 ad } 619 1.1 ad if (cflag & PARENB) 620 1.1 ad lpr |= DZ_LPR_PARENB; 621 1.1 ad if (cflag & PARODD) 622 1.1 ad lpr |= DZ_LPR_OPAR; 623 1.1 ad if (cflag & CSTOPB) 624 1.1 ad lpr |= DZ_LPR_2_STOP; 625 1.1 ad 626 1.29 ad dz_write2(sc, sc->sc_dr.dr_lpr, lpr); 627 1.28 ad (void) splx(s); 628 1.28 ad DELAY(10000); 629 1.1 ad 630 1.1 ad return (0); 631 1.1 ad } 632 1.1 ad 633 1.1 ad static unsigned 634 1.1 ad dzmctl(struct dz_softc *sc, int line, int bits, int how) 635 1.1 ad { 636 1.1 ad unsigned status; 637 1.1 ad unsigned mbits; 638 1.1 ad unsigned bit; 639 1.1 ad int s; 640 1.1 ad 641 1.1 ad s = spltty(); 642 1.1 ad mbits = 0; 643 1.1 ad bit = (1 << line); 644 1.1 ad 645 1.1 ad /* external signals as seen from the port */ 646 1.29 ad status = dz_read1(sc, sc->sc_dr.dr_dcd) | sc->sc_dsr; 647 1.1 ad if (status & bit) 648 1.1 ad mbits |= DML_DCD; 649 1.29 ad status = dz_read1(sc, sc->sc_dr.dr_ring); 650 1.1 ad if (status & bit) 651 1.1 ad mbits |= DML_RI; 652 1.1 ad 653 1.1 ad /* internal signals/state delivered to port */ 654 1.29 ad status = dz_read1(sc, sc->sc_dr.dr_dtr); 655 1.1 ad if (status & bit) 656 1.1 ad mbits |= DML_DTR; 657 1.1 ad if (sc->sc_brk & bit) 658 1.1 ad mbits |= DML_BRK; 659 1.1 ad 660 1.1 ad switch (how) 661 1.1 ad { 662 1.1 ad case DMSET: 663 1.1 ad mbits = bits; 664 1.1 ad break; 665 1.1 ad 666 1.1 ad case DMBIS: 667 1.1 ad mbits |= bits; 668 1.1 ad break; 669 1.1 ad 670 1.1 ad case DMBIC: 671 1.1 ad mbits &= ~bits; 672 1.1 ad break; 673 1.1 ad 674 1.1 ad case DMGET: 675 1.1 ad (void) splx(s); 676 1.1 ad return (mbits); 677 1.1 ad } 678 1.1 ad 679 1.1 ad if (mbits & DML_DTR) { 680 1.29 ad dz_write1(sc, sc->sc_dr.dr_dtr, dz_read1(sc, sc->sc_dr.dr_dtr) | bit); 681 1.1 ad } else { 682 1.29 ad dz_write1(sc, sc->sc_dr.dr_dtr, dz_read1(sc, sc->sc_dr.dr_dtr) & ~bit); 683 1.1 ad } 684 1.1 ad 685 1.1 ad if (mbits & DML_BRK) { 686 1.1 ad sc->sc_brk |= bit; 687 1.29 ad dz_write1(sc, sc->sc_dr.dr_break, sc->sc_brk); 688 1.1 ad } else { 689 1.1 ad sc->sc_brk &= ~bit; 690 1.29 ad dz_write1(sc, sc->sc_dr.dr_break, sc->sc_brk); 691 1.1 ad } 692 1.1 ad 693 1.1 ad (void) splx(s); 694 1.28 ad 695 1.1 ad return (mbits); 696 1.1 ad } 697 1.1 ad 698 1.1 ad /* 699 1.1 ad * This is called by timeout() periodically. 700 1.1 ad * Check to see if modem status bits have changed. 701 1.1 ad */ 702 1.1 ad static void 703 1.1 ad dzscan(void *arg) 704 1.1 ad { 705 1.1 ad struct dz_softc *sc; 706 1.1 ad struct tty *tp; 707 1.1 ad int n, bit, port; 708 1.34 matt unsigned int csr; 709 1.34 matt unsigned int tmp; 710 1.1 ad int s; 711 1.1 ad 712 1.1 ad s = spltty(); 713 1.1 ad for (n = 0; n < dz_cd.cd_ndevs; n++) { 714 1.35 matt if ((sc = device_lookup_private(&dz_cd, n)) == NULL) 715 1.1 ad continue; 716 1.1 ad 717 1.1 ad for (port = 0; port < sc->sc_type; port++) { 718 1.1 ad tp = sc->sc_dz[port].dz_tty; 719 1.1 ad bit = (1 << port); 720 1.16 perry 721 1.29 ad if ((dz_read1(sc, sc->sc_dr.dr_dcd) | sc->sc_dsr) & bit) { 722 1.1 ad if (!(tp->t_state & TS_CARR_ON)) 723 1.1 ad (*tp->t_linesw->l_modem) (tp, 1); 724 1.1 ad } else if ((tp->t_state & TS_CARR_ON) && 725 1.1 ad (*tp->t_linesw->l_modem)(tp, 0) == 0) { 726 1.29 ad tmp = dz_read2(sc, sc->sc_dr.dr_tcrw) & 255; 727 1.29 ad dz_write1(sc, sc->sc_dr.dr_tcr, tmp & ~bit); 728 1.1 ad } 729 1.1 ad } 730 1.1 ad 731 1.1 ad /* 732 1.1 ad * If the RX interrupt rate is this high, switch 733 1.1 ad * the controller to Silo Alarm - which means don't 734 1.1 ad * interrupt until the RX silo has 16 characters in 735 1.1 ad * it (the silo is 64 characters in all). 736 1.1 ad * Avoid oscillating SA on and off by not turning 737 1.1 ad * if off unless the rate is appropriately low. 738 1.1 ad */ 739 1.29 ad csr = dz_read2(sc, sc->sc_dr.dr_csr); 740 1.29 ad tmp = csr; 741 1.29 ad if (sc->sc_rxint > 16*10) 742 1.29 ad csr |= DZ_CSR_SAE; 743 1.29 ad else if (sc->sc_rxint < 10) 744 1.29 ad csr &= ~DZ_CSR_SAE; 745 1.29 ad if (csr != tmp) 746 1.29 ad dz_write2(sc, sc->sc_dr.dr_csr, csr); 747 1.29 ad sc->sc_rxint = 0; 748 1.1 ad 749 1.29 ad dzxint(sc); 750 1.29 ad dzrint(sc); 751 1.1 ad } 752 1.1 ad (void) splx(s); 753 1.1 ad callout_reset(&dzscan_ch, hz, dzscan, NULL); 754 1.1 ad } 755 1.1 ad 756 1.1 ad /* 757 1.1 ad * Called after an ubareset. The DZ card is reset, but the only thing 758 1.1 ad * that must be done is to start the receiver and transmitter again. 759 1.1 ad * No DMA setup to care about. 760 1.1 ad */ 761 1.1 ad void 762 1.34 matt dzreset(device_t dev) 763 1.1 ad { 764 1.35 matt struct dz_softc *sc = device_private(dev); 765 1.1 ad struct tty *tp; 766 1.1 ad int i; 767 1.1 ad 768 1.1 ad for (i = 0; i < sc->sc_type; i++) { 769 1.1 ad tp = sc->sc_dz[i].dz_tty; 770 1.1 ad 771 1.1 ad if (((tp->t_state & TS_ISOPEN) == 0) || (tp->t_wopen == 0)) 772 1.1 ad continue; 773 1.1 ad 774 1.1 ad dzparam(tp, &tp->t_termios); 775 1.1 ad dzmctl(sc, i, DML_DTR, DMSET); 776 1.1 ad tp->t_state &= ~TS_BUSY; 777 1.1 ad dzstart(tp); /* Kick off transmitter again */ 778 1.1 ad } 779 1.1 ad } 780