The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/z8530tty.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: f50ae03f76c496dfe8a5ef286b999ef6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.