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/sun/ms_zs.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: ms_zs.c,v 1.10 2003/08/07 16:31:26 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  *      @(#)ms.c        8.1 (Berkeley) 6/11/93
   41  */
   42 
   43 /*
   44  * Mouse driver (/dev/mouse)
   45  */
   46 
   47 /*
   48  * Zilog Z8530 Dual UART driver (mouse interface)
   49  *
   50  * This is the "slave" driver that will be attached to
   51  * the "zsc" driver for a Sun mouse.
   52  */
   53 
   54 #include <sys/cdefs.h>
   55 __KERNEL_RCSID(0, "$NetBSD: ms_zs.c,v 1.10 2003/08/07 16:31:26 agc Exp $");
   56 
   57 #include <sys/param.h>
   58 #include <sys/systm.h>
   59 #include <sys/conf.h>
   60 #include <sys/device.h>
   61 #include <sys/ioctl.h>
   62 #include <sys/kernel.h>
   63 #include <sys/proc.h>
   64 #include <sys/signal.h>
   65 #include <sys/signalvar.h>
   66 #include <sys/time.h>
   67 #include <sys/select.h>
   68 #include <sys/syslog.h>
   69 
   70 #include <machine/vuid_event.h>
   71 
   72 #include <dev/ic/z8530reg.h>
   73 #include <machine/z8530var.h>
   74 #include <dev/sun/event_var.h>
   75 #include <dev/sun/msvar.h>
   76 
   77 static void ms_zs_rxint __P((struct zs_chanstate *));
   78 static void ms_zs_stint __P((struct zs_chanstate *, int));
   79 static void ms_zs_txint __P((struct zs_chanstate *));
   80 static void ms_zs_softint __P((struct zs_chanstate *));
   81 
   82 struct zsops zsops_ms = {
   83         ms_zs_rxint,    /* receive char available */
   84         ms_zs_stint,    /* external/status */
   85         ms_zs_txint,    /* xmit buffer empty */
   86         ms_zs_softint,  /* process software interrupt */
   87 };
   88 
   89 /* Fall-back baud rate */
   90 #ifdef SUN_MS_BPS
   91 int     ms_zs_bps = SUN_MS_BPS;
   92 #else
   93 int     ms_zs_bps = MS_DEFAULT_BPS;
   94 #endif
   95 
   96 static int      ms_zs_match(struct device *, struct cfdata *, void *);
   97 static void     ms_zs_attach(struct device *, struct device *, void *);
   98 
   99 CFATTACH_DECL(ms_zs, sizeof(struct ms_softc),
  100     ms_zs_match, ms_zs_attach, NULL, NULL);
  101 
  102 /*
  103  * ms_match: how is this zs channel configured?
  104  */
  105 int 
  106 ms_zs_match(parent, cf, aux)
  107         struct device *parent;
  108         struct cfdata *cf;
  109         void   *aux;
  110 {
  111         struct zsc_attach_args *args = aux;
  112 
  113         if (ms_zs_bps == 0)
  114                 return 0;
  115 
  116         /* Exact match required for keyboard. */
  117         if (cf->cf_loc[ZSCCF_CHANNEL] == args->channel)
  118                 return 2;
  119 
  120         return 0;
  121 }
  122 
  123 void 
  124 ms_zs_attach(parent, self, aux)
  125         struct device *parent, *self;
  126         void   *aux;
  127 
  128 {
  129         struct zsc_softc *zsc = (void *) parent;
  130         struct ms_softc *ms = (void *) self;
  131         struct zsc_attach_args *args = aux;
  132         struct zs_chanstate *cs;
  133         struct cfdata *cf;
  134         int channel, ms_unit;
  135         int reset, s;
  136         int bps;
  137 
  138         cf = ms->ms_dev.dv_cfdata;
  139         ms_unit = ms->ms_dev.dv_unit;
  140         channel = args->channel;
  141         cs = zsc->zsc_cs[channel];
  142         cs->cs_private = ms;
  143         cs->cs_ops = &zsops_ms;
  144         ms->ms_cs = cs;
  145         /* Allow kernel option SUN_MS_BPS to hard-code baud rate */
  146 #ifndef SUN_MS_BPS
  147         if ((bps = cs->cs_defspeed) == 0)
  148 #endif
  149                 bps = ms_zs_bps;
  150 
  151         printf(": baud rate %d\n", bps);
  152 
  153         /* Initialize the speed, etc. */
  154         s = splzs();
  155         /* May need reset... */
  156         reset = (channel == 0) ?
  157                 ZSWR9_A_RESET : ZSWR9_B_RESET;
  158         zs_write_reg(cs, 9, reset);
  159         /* These are OK as set by zscc: WR3, WR4, WR5 */
  160         /* We don't care about status or tx interrupts. */
  161         cs->cs_preg[1] = ZSWR1_RIE;
  162         (void) zs_set_speed(cs, bps);
  163         zs_loadchannelregs(cs);
  164         splx(s);
  165 
  166         /* Initialize translator. */
  167         ms->ms_byteno = -1;
  168 }
  169 
  170 /****************************************************************
  171  * Interface to the lower layer (zscc)
  172  ****************************************************************/
  173 
  174 static void
  175 ms_zs_rxint(cs)
  176         struct zs_chanstate *cs;
  177 {
  178         struct ms_softc *ms;
  179         int put, put_next;
  180         u_char c, rr1;
  181 
  182         ms = cs->cs_private;
  183         put = ms->ms_rbput;
  184 
  185         /*
  186          * First read the status, because reading the received char
  187          * destroys the status of this char.
  188          */
  189         rr1 = zs_read_reg(cs, 1);
  190         c = zs_read_data(cs);
  191 
  192         if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
  193                 /* Clear the receive error. */
  194                 zs_write_csr(cs, ZSWR0_RESET_ERRORS);
  195         }
  196 
  197         ms->ms_rbuf[put] = (c << 8) | rr1;
  198         put_next = (put + 1) & MS_RX_RING_MASK;
  199 
  200         /* Would overrun if increment makes (put==get). */
  201         if (put_next == ms->ms_rbget) {
  202                 ms->ms_intr_flags |= INTR_RX_OVERRUN;
  203         } else {
  204                 /* OK, really increment. */
  205                 put = put_next;
  206         }
  207 
  208         /* Done reading. */
  209         ms->ms_rbput = put;
  210 
  211         /* Ask for softint() call. */
  212         cs->cs_softreq = 1;
  213 }
  214 
  215 static void
  216 ms_zs_txint(cs)
  217         struct zs_chanstate *cs;
  218 {
  219         struct ms_softc *ms;
  220 
  221         ms = cs->cs_private;
  222         zs_write_csr(cs, ZSWR0_RESET_TXINT);
  223         ms->ms_intr_flags |= INTR_TX_EMPTY;
  224         /* Ask for softint() call. */
  225         cs->cs_softreq = 1;
  226 }
  227 
  228 static void
  229 ms_zs_stint(cs, force)
  230         struct zs_chanstate *cs;
  231         int force;
  232 {
  233         struct ms_softc *ms;
  234         int rr0;
  235 
  236         ms = cs->cs_private;
  237 
  238         rr0 = zs_read_csr(cs);
  239         zs_write_csr(cs, ZSWR0_RESET_STATUS);
  240 
  241         /*
  242          * We have to accumulate status line changes here.
  243          * Otherwise, if we get multiple status interrupts
  244          * before the softint runs, we could fail to notice
  245          * some status line changes in the softint routine.
  246          * Fix from Bill Studenmund, October 1996.
  247          */
  248         cs->cs_rr0_delta |= (cs->cs_rr0 ^ rr0);
  249         cs->cs_rr0 = rr0;
  250         ms->ms_intr_flags |= INTR_ST_CHECK;
  251 
  252         /* Ask for softint() call. */
  253         cs->cs_softreq = 1;
  254 }
  255 
  256 static void
  257 ms_zs_softint(cs)
  258         struct zs_chanstate *cs;
  259 {
  260         struct ms_softc *ms;
  261         int get, c, s;
  262         int intr_flags;
  263         u_short ring_data;
  264 
  265         ms = cs->cs_private;
  266 
  267         /* Atomically get and clear flags. */
  268         s = splzs();
  269         intr_flags = ms->ms_intr_flags;
  270         ms->ms_intr_flags = 0;
  271 
  272         /* Now lower to spltty for the rest. */
  273         (void) spltty();
  274 
  275         /*
  276          * Copy data from the receive ring to the event layer.
  277          */
  278         get = ms->ms_rbget;
  279         while (get != ms->ms_rbput) {
  280                 ring_data = ms->ms_rbuf[get];
  281                 get = (get + 1) & MS_RX_RING_MASK;
  282 
  283                 /* low byte of ring_data is rr1 */
  284                 c = (ring_data >> 8) & 0xff;
  285 
  286                 if (ring_data & ZSRR1_DO)
  287                         intr_flags |= INTR_RX_OVERRUN;
  288                 if (ring_data & (ZSRR1_FE | ZSRR1_PE)) {
  289                         log(LOG_ERR, "%s: input error (0x%x)\n",
  290                                 ms->ms_dev.dv_xname, ring_data);
  291                         c = -1; /* signal input error */
  292                 }
  293 
  294                 /* Pass this up to the "middle" layer. */
  295                 ms_input(ms, c);
  296         }
  297         if (intr_flags & INTR_RX_OVERRUN) {
  298                 log(LOG_ERR, "%s: input overrun\n",
  299                     ms->ms_dev.dv_xname);
  300         }
  301         ms->ms_rbget = get;
  302 
  303         if (intr_flags & INTR_TX_EMPTY) {
  304                 /*
  305                  * Transmit done.  (Not expected.)
  306                  */
  307                 log(LOG_ERR, "%s: transmit interrupt?\n",
  308                     ms->ms_dev.dv_xname);
  309         }
  310 
  311         if (intr_flags & INTR_ST_CHECK) {
  312                 /*
  313                  * Status line change.  (Not expected.)
  314                  */
  315                 log(LOG_ERR, "%s: status interrupt?\n",
  316                     ms->ms_dev.dv_xname);
  317                 cs->cs_rr0_delta = 0;
  318         }
  319 
  320         splx(s);
  321 }

Cache object: 9a48e5ce60b1211dfd7a7e8517bb9103


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