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

Cache object: fd4516d73a2e15efe2f57468033ed5d0


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