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/z8530sc.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: z8530sc.c,v 1.19 2003/08/07 16:31:03 agc Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1992, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * This software was developed by the Computer Systems Engineering group
    8  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
    9  * contributed to Berkeley.
   10  *
   11  * All advertising materials mentioning features or use of this software
   12  * must display the following acknowledgement:
   13  *      This product includes software developed by the University of
   14  *      California, Lawrence Berkeley Laboratory.
   15  *
   16  * Redistribution and use in source and binary forms, with or without
   17  * modification, are permitted provided that the following conditions
   18  * are met:
   19  * 1. Redistributions of source code must retain the above copyright
   20  *    notice, this list of conditions and the following disclaimer.
   21  * 2. Redistributions in binary form must reproduce the above copyright
   22  *    notice, this list of conditions and the following disclaimer in the
   23  *    documentation and/or other materials provided with the distribution.
   24  * 3. Neither the name of the University nor the names of its contributors
   25  *    may be used to endorse or promote products derived from this software
   26  *    without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   38  * SUCH DAMAGE.
   39  *
   40  *      @(#)zs.c        8.1 (Berkeley) 7/19/93
   41  */
   42 
   43 /*
   44  * Copyright (c) 1994 Gordon W. Ross
   45  *
   46  * This software was developed by the Computer Systems Engineering group
   47  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
   48  * contributed to Berkeley.
   49  *
   50  * All advertising materials mentioning features or use of this software
   51  * must display the following acknowledgement:
   52  *      This product includes software developed by the University of
   53  *      California, Lawrence Berkeley Laboratory.
   54  *
   55  * Redistribution and use in source and binary forms, with or without
   56  * modification, are permitted provided that the following conditions
   57  * are met:
   58  * 1. Redistributions of source code must retain the above copyright
   59  *    notice, this list of conditions and the following disclaimer.
   60  * 2. Redistributions in binary form must reproduce the above copyright
   61  *    notice, this list of conditions and the following disclaimer in the
   62  *    documentation and/or other materials provided with the distribution.
   63  * 3. All advertising materials mentioning features or use of this software
   64  *    must display the following acknowledgement:
   65  *      This product includes software developed by the University of
   66  *      California, Berkeley and its contributors.
   67  * 4. Neither the name of the University nor the names of its contributors
   68  *    may be used to endorse or promote products derived from this software
   69  *    without specific prior written permission.
   70  *
   71  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   72  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   73  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   74  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   75  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   76  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   77  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   78  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   79  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   80  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   81  * SUCH DAMAGE.
   82  *
   83  *      @(#)zs.c        8.1 (Berkeley) 7/19/93
   84  */
   85 
   86 /*
   87  * Zilog Z8530 Dual UART driver (common part)
   88  *
   89  * This file contains the machine-independent parts of the
   90  * driver common to tty and keyboard/mouse sub-drivers.
   91  */
   92 
   93 #include <sys/cdefs.h>
   94 __KERNEL_RCSID(0, "$NetBSD: z8530sc.c,v 1.19 2003/08/07 16:31:03 agc Exp $");
   95 
   96 #include <sys/param.h>
   97 #include <sys/systm.h>
   98 #include <sys/proc.h>
   99 #include <sys/device.h>
  100 #include <sys/conf.h>
  101 #include <sys/file.h>
  102 #include <sys/ioctl.h>
  103 #include <sys/tty.h>
  104 #include <sys/time.h>
  105 #include <sys/kernel.h>
  106 #include <sys/syslog.h>
  107 
  108 #include <dev/ic/z8530reg.h>
  109 #include <machine/z8530var.h>
  110 
  111 void
  112 zs_break(cs, set)
  113         struct zs_chanstate *cs;
  114         int set;
  115 {
  116 
  117         if (set) {
  118                 cs->cs_preg[5] |= ZSWR5_BREAK;
  119                 cs->cs_creg[5] |= ZSWR5_BREAK;
  120         } else {
  121                 cs->cs_preg[5] &= ~ZSWR5_BREAK;
  122                 cs->cs_creg[5] &= ~ZSWR5_BREAK;
  123         }
  124         zs_write_reg(cs, 5, cs->cs_creg[5]);
  125 }
  126 
  127 
  128 /*
  129  * drain on-chip fifo
  130  */
  131 void
  132 zs_iflush(cs)
  133         struct zs_chanstate *cs;
  134 {
  135         u_char c, rr0, rr1;
  136         int i;
  137 
  138         /*
  139          * Count how many times we loop. Some systems, such as some
  140          * Apple PowerBooks, claim to have SCC's which they really don't.
  141          */
  142         for (i = 0; i < 32; i++) {
  143                 /* Is there input available? */
  144                 rr0 = zs_read_csr(cs);
  145                 if ((rr0 & ZSRR0_RX_READY) == 0)
  146                         break;
  147 
  148                 /*
  149                  * First read the status, because reading the data
  150                  * destroys the status of this char.
  151                  */
  152                 rr1 = zs_read_reg(cs, 1);
  153                 c = zs_read_data(cs);
  154 
  155                 if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
  156                         /* Clear the receive error. */
  157                         zs_write_csr(cs, ZSWR0_RESET_ERRORS);
  158                 }
  159         }
  160 }
  161         
  162 
  163 /*
  164  * Write the given register set to the given zs channel in the proper order.
  165  * The channel must not be transmitting at the time.  The receiver will
  166  * be disabled for the time it takes to write all the registers.
  167  * Call this with interrupts disabled.
  168  */
  169 void
  170 zs_loadchannelregs(cs)
  171         struct zs_chanstate *cs;
  172 {
  173         u_char *reg, v;
  174 
  175         zs_write_csr(cs, ZSM_RESET_ERR); /* XXX: reset error condition */
  176 
  177 #if 1
  178         /*
  179          * XXX: Is this really a good idea?
  180          * XXX: Should go elsewhere! -gwr
  181          */
  182         zs_iflush(cs);  /* XXX */
  183 #endif
  184 
  185         if (cs->cs_ctl_chan != NULL)
  186                 v = ((cs->cs_ctl_chan->cs_creg[5] & (ZSWR5_RTS | ZSWR5_DTR)) !=
  187                     (cs->cs_ctl_chan->cs_preg[5] & (ZSWR5_RTS | ZSWR5_DTR)));
  188         else
  189                 v = 0;
  190 
  191         if (memcmp((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16) == 0 && !v)
  192                 return; /* only change if values are different */
  193 
  194         /* Copy "pending" regs to "current" */
  195         memcpy((caddr_t)cs->cs_creg, (caddr_t)cs->cs_preg, 16);
  196         reg = cs->cs_creg;      /* current regs */
  197 
  198         /* disable interrupts */
  199         zs_write_reg(cs, 1, reg[1] & ~ZSWR1_IMASK);
  200 
  201         /* baud clock divisor, stop bits, parity */
  202         zs_write_reg(cs, 4, reg[4]);
  203 
  204         /* misc. TX/RX control bits */
  205         zs_write_reg(cs, 10, reg[10]);
  206 
  207         /* char size, enable (RX/TX) */
  208         zs_write_reg(cs, 3, reg[3] & ~ZSWR3_RX_ENABLE);
  209         zs_write_reg(cs, 5, reg[5] & ~ZSWR5_TX_ENABLE);
  210 
  211         /* synchronous mode stuff */
  212         zs_write_reg(cs, 6, reg[6]);
  213         zs_write_reg(cs, 7, reg[7]);
  214 
  215 #if 0
  216         /*
  217          * Registers 2 and 9 are special because they are
  218          * actually common to both channels, but must be
  219          * programmed through channel A.  The "zsc" attach
  220          * function takes care of setting these registers
  221          * and they should not be touched thereafter.
  222          */
  223         /* interrupt vector */
  224         zs_write_reg(cs, 2, reg[2]);
  225         /* master interrupt control */
  226         zs_write_reg(cs, 9, reg[9]);
  227 #endif
  228 
  229         /* Shut down the BRG */
  230         zs_write_reg(cs, 14, reg[14] & ~ZSWR14_BAUD_ENA);
  231 
  232 #ifdef  ZS_MD_SETCLK
  233         /* Let the MD code setup any external clock. */
  234         ZS_MD_SETCLK(cs);
  235 #endif  /* ZS_MD_SETCLK */
  236 
  237         /* clock mode control */
  238         zs_write_reg(cs, 11, reg[11]);
  239 
  240         /* baud rate (lo/hi) */
  241         zs_write_reg(cs, 12, reg[12]);
  242         zs_write_reg(cs, 13, reg[13]);
  243 
  244         /* Misc. control bits */
  245         zs_write_reg(cs, 14, reg[14]);
  246 
  247         /* which lines cause status interrupts */
  248         zs_write_reg(cs, 15, reg[15]);
  249 
  250         /*
  251          * Zilog docs recommend resetting external status twice at this
  252          * point. Mainly as the status bits are latched, and the first
  253          * interrupt clear might unlatch them to new values, generating
  254          * a second interrupt request.
  255          */
  256         zs_write_csr(cs, ZSM_RESET_STINT);
  257         zs_write_csr(cs, ZSM_RESET_STINT);
  258 
  259         /* char size, enable (RX/TX)*/
  260         zs_write_reg(cs, 3, reg[3]);
  261         zs_write_reg(cs, 5, reg[5]);
  262 
  263         /* Write the status bits on the alternate channel also. */
  264         if (cs->cs_ctl_chan != NULL) {
  265                 v = cs->cs_ctl_chan->cs_preg[5];
  266                 cs->cs_ctl_chan->cs_creg[5] = v;
  267                 zs_write_reg(cs->cs_ctl_chan, 5, v);
  268         }
  269 
  270         /* interrupt enables: RX, TX, STATUS */
  271         zs_write_reg(cs, 1, reg[1]);
  272 }
  273 
  274 
  275 /*
  276  * ZS hardware interrupt.  Scan all ZS channels.  NB: we know here that
  277  * channels are kept in (A,B) pairs.
  278  *
  279  * Do just a little, then get out; set a software interrupt if more
  280  * work is needed.
  281  *
  282  * We deliberately ignore the vectoring Zilog gives us, and match up
  283  * only the number of `reset interrupt under service' operations, not
  284  * the order.
  285  */
  286 int
  287 zsc_intr_hard(arg)
  288         void *arg;
  289 {
  290         struct zsc_softc *zsc = arg;
  291         struct zs_chanstate *cs;
  292         u_char rr3;
  293 
  294         /* First look at channel A. */
  295         cs = zsc->zsc_cs[0];
  296 
  297         /* Lock both channels */
  298         simple_lock(&cs->cs_lock);
  299         simple_lock(&zsc->zsc_cs[1]->cs_lock);
  300         /* Note: only channel A has an RR3 */
  301         rr3 = zs_read_reg(cs, 3);
  302 
  303         /*
  304          * Clear interrupt first to avoid a race condition.
  305          * If a new interrupt condition happens while we are
  306          * servicing this one, we will get another interrupt
  307          * shortly.  We can NOT just sit here in a loop, or
  308          * we will cause horrible latency for other devices
  309          * on this interrupt level (i.e. sun3x floppy disk).
  310          */
  311         if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
  312                 zs_write_csr(cs, ZSWR0_CLR_INTR);
  313                 if (rr3 & ZSRR3_IP_A_RX)
  314                         (*cs->cs_ops->zsop_rxint)(cs);
  315                 if (rr3 & ZSRR3_IP_A_STAT)
  316                         (*cs->cs_ops->zsop_stint)(cs, 0);
  317                 if (rr3 & ZSRR3_IP_A_TX)
  318                         (*cs->cs_ops->zsop_txint)(cs);
  319         }
  320 
  321         /* Done with channel A */
  322         simple_unlock(&cs->cs_lock);
  323 
  324         /* Now look at channel B. */
  325         cs = zsc->zsc_cs[1];
  326         if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
  327                 zs_write_csr(cs, ZSWR0_CLR_INTR);
  328                 if (rr3 & ZSRR3_IP_B_RX)
  329                         (*cs->cs_ops->zsop_rxint)(cs);
  330                 if (rr3 & ZSRR3_IP_B_STAT)
  331                         (*cs->cs_ops->zsop_stint)(cs, 0);
  332                 if (rr3 & ZSRR3_IP_B_TX)
  333                         (*cs->cs_ops->zsop_txint)(cs);
  334         }
  335 
  336         simple_unlock(&cs->cs_lock);
  337 
  338         /* Note: caller will check cs_x->cs_softreq and DTRT. */
  339         return (rr3);
  340 }
  341 
  342 
  343 /*
  344  * ZS software interrupt.  Scan all channels for deferred interrupts.
  345  */
  346 int
  347 zsc_intr_soft(arg)
  348         void *arg;
  349 {
  350         struct zsc_softc *zsc = arg;
  351         struct zs_chanstate *cs;
  352         int rval, chan;
  353 
  354         rval = 0;
  355         for (chan = 0; chan < 2; chan++) {
  356                 cs = zsc->zsc_cs[chan];
  357 
  358                 /*
  359                  * The softint flag can be safely cleared once
  360                  * we have decided to call the softint routine.
  361                  * (No need to do splzs() first.)
  362                  */
  363                 if (cs->cs_softreq) {
  364                         cs->cs_softreq = 0;
  365                         (*cs->cs_ops->zsop_softint)(cs);
  366                         rval++;
  367                 }
  368         }
  369         return (rval);
  370 }
  371 
  372 /*
  373  * Provide a null zs "ops" vector.
  374  */
  375 
  376 static void zsnull_rxint   __P((struct zs_chanstate *));
  377 static void zsnull_stint   __P((struct zs_chanstate *, int));
  378 static void zsnull_txint   __P((struct zs_chanstate *));
  379 static void zsnull_softint __P((struct zs_chanstate *));
  380 
  381 static void
  382 zsnull_rxint(cs)
  383         struct zs_chanstate *cs;
  384 {
  385         /* Ask for softint() call. */
  386         cs->cs_softreq = 1;
  387 }
  388 
  389 static void
  390 zsnull_stint(cs, force)
  391         struct zs_chanstate *cs;
  392         int force;
  393 {
  394         /* Ask for softint() call. */
  395         cs->cs_softreq = 1;
  396 }
  397 
  398 static void
  399 zsnull_txint(cs)
  400         struct zs_chanstate *cs;
  401 {
  402         /* Ask for softint() call. */
  403         cs->cs_softreq = 1;
  404 }
  405 
  406 static void
  407 zsnull_softint(cs)
  408         struct zs_chanstate *cs;
  409 {
  410         zs_write_reg(cs,  1, 0);
  411         zs_write_reg(cs, 15, 0);
  412 }
  413 
  414 struct zsops zsops_null = {
  415         zsnull_rxint,   /* receive char available */
  416         zsnull_stint,   /* external/status */
  417         zsnull_txint,   /* xmit buffer empty */
  418         zsnull_softint, /* process software interrupt */
  419 };

Cache object: 0d434544c03fec9cf4cde683b50af635


[ 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.