diff options
| author | mrg <mrg@NetBSD.org> | 1999-05-14 06:42:02 +0000 |
|---|---|---|
| committer | mrg <mrg@NetBSD.org> | 1999-05-14 06:42:02 +0000 |
| commit | 95e0190e2321f05b1bf4e4cd2a4072aaaa448e85 (patch) | |
| tree | b5e177b3269a398862d3123bd73fd9e768ada20d /sys/dev/sun/ms.c | |
| parent | 7a50b38cbd961cafba619b456ff10312fb9809f2 (diff) | |
split the sun ms/kbd drivers into frontend/backend parts at the serial
interface border, so that other serial interfaces can be attached to the
ms/kbd. zero functional changes and mostly involves moving code around
a bit. tested on the SS2.
this is necessary to attach the PCI ultrasparc keyboard/mouse drivers.
Diffstat (limited to 'sys/dev/sun/ms.c')
| -rw-r--r-- | sys/dev/sun/ms.c | 314 |
1 files changed, 3 insertions, 311 deletions
diff --git a/sys/dev/sun/ms.c b/sys/dev/sun/ms.c index 0e6dbafd1b1..8a33764e6ee 100644 --- a/sys/dev/sun/ms.c +++ b/sys/dev/sun/ms.c @@ -1,4 +1,4 @@ -/* $NetBSD: ms.c,v 1.15 1999/02/03 20:22:28 mycroft Exp $ */ +/* $NetBSD: ms.c,v 1.16 1999/05/14 06:42:02 mrg Exp $ */ /* * Copyright (c) 1992, 1993 @@ -73,152 +73,15 @@ #include <dev/ic/z8530reg.h> #include <machine/z8530var.h> +#include <dev/sun/event_var.h> +#include <dev/sun/msvar.h> -#include "event_var.h" #include "locators.h" -/* - * How many input characters we can buffer. - * The port-specific var.h may override this. - * Note: must be a power of two! - */ -#define MS_RX_RING_SIZE 256 -#define MS_RX_RING_MASK (MS_RX_RING_SIZE-1) -/* - * Output buffer. Only need a few chars. - */ -#define MS_TX_RING_SIZE 16 -#define MS_TX_RING_MASK (MS_TX_RING_SIZE-1) -/* - * Keyboard serial line speed is fixed at 1200 bps; mouse serial line - * speed defaults to 1200 bps. - */ -#ifdef SUN_MS_BPS -#define MS_BPS SUN_MS_BPS -#else -#define MS_BPS 1200 -#endif - -/* - * Mouse state. A Mouse Systems mouse is a fairly simple device, - * producing five-byte blobs of the form: - * - * b dx dy dx dy - * - * where b is the button state, encoded as 0x80|(~buttons)---there are - * three buttons (4=left, 2=middle, 1=right)---and dx,dy are X and Y - * delta values, none of which have are in [0x80..0x87]. (This lets - * us sync up with the mouse after an error.) - */ -struct ms_softc { - struct device ms_dev; /* required first: base device */ - struct zs_chanstate *ms_cs; - - /* Flags to communicate with ms_softintr() */ - volatile int ms_intr_flags; -#define INTR_RX_OVERRUN 1 -#define INTR_TX_EMPTY 2 -#define INTR_ST_CHECK 4 - - /* - * The receive ring buffer. - */ - u_int ms_rbget; /* ring buffer `get' index */ - volatile u_int ms_rbput; /* ring buffer `put' index */ - u_short ms_rbuf[MS_RX_RING_SIZE]; /* rr1, data pairs */ - - /* - * State of input translator - */ - short ms_byteno; /* input byte number, for decode */ - char ms_mb; /* mouse button state */ - char ms_ub; /* user button state */ - int ms_dx; /* delta-x */ - int ms_dy; /* delta-y */ - - /* - * State of upper interface. - */ - volatile int ms_ready; /* event queue is ready */ - struct evvar ms_events; /* event queue state */ -} ms_softc; - cdev_decl(ms); /* open, close, read, write, ioctl, stop, ... */ -struct zsops zsops_ms; - -/**************************************************************** - * Definition of the driver for autoconfig. - ****************************************************************/ - -static int ms_match(struct device *, struct cfdata *, void *); -static void ms_attach(struct device *, struct device *, void *); - -struct cfattach ms_ca = { - sizeof(struct ms_softc), ms_match, ms_attach -}; - extern struct cfdriver ms_cd; -/* - * ms_match: how is this zs channel configured? - */ -int -ms_match(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; -{ - struct zsc_attach_args *args = aux; - - /* Exact match required for keyboard. */ - if (cf->cf_loc[ZSCCF_CHANNEL] == args->channel) - return 2; - - return 0; -} - -void -ms_attach(parent, self, aux) - struct device *parent, *self; - void *aux; - -{ - struct zsc_softc *zsc = (void *) parent; - struct ms_softc *ms = (void *) self; - struct zsc_attach_args *args = aux; - struct zs_chanstate *cs; - struct cfdata *cf; - int channel, ms_unit; - int reset, s; - - cf = ms->ms_dev.dv_cfdata; - ms_unit = ms->ms_dev.dv_unit; - channel = args->channel; - cs = zsc->zsc_cs[channel]; - cs->cs_private = ms; - cs->cs_ops = &zsops_ms; - ms->ms_cs = cs; - - printf("\n"); - - /* Initialize the speed, etc. */ - s = splzs(); - /* May need reset... */ - reset = (channel == 0) ? - ZSWR9_A_RESET : ZSWR9_B_RESET; - zs_write_reg(cs, 9, reset); - /* These are OK as set by zscc: WR3, WR4, WR5 */ - /* We don't care about status or tx interrupts. */ - cs->cs_preg[1] = ZSWR1_RIE; - (void) zs_set_speed(cs, MS_BPS); - zs_loadchannelregs(cs); - splx(s); - - /* Initialize translator. */ - ms->ms_byteno = -1; -} - /**************************************************************** * Entry points for /dev/mouse * (open,close,read,write,...) @@ -345,9 +208,6 @@ mspoll(dev, events, p) * Middle layer (translator) ****************************************************************/ -static void ms_input __P((struct ms_softc *, int c)); - - /* * Called by our ms_softint() routine on input. */ @@ -484,171 +344,3 @@ out: EV_WAKEUP(&ms->ms_events); } } - -/**************************************************************** - * Interface to the lower layer (zscc) - ****************************************************************/ - -static void ms_rxint __P((struct zs_chanstate *)); -static void ms_stint __P((struct zs_chanstate *, int)); -static void ms_txint __P((struct zs_chanstate *)); -static void ms_softint __P((struct zs_chanstate *)); - -static void -ms_rxint(cs) - register struct zs_chanstate *cs; -{ - register struct ms_softc *ms; - register int put, put_next; - register u_char c, rr1; - - ms = cs->cs_private; - put = ms->ms_rbput; - - /* - * First read the status, because reading the received char - * destroys the status of this char. - */ - rr1 = zs_read_reg(cs, 1); - c = zs_read_data(cs); - - if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) { - /* Clear the receive error. */ - zs_write_csr(cs, ZSWR0_RESET_ERRORS); - } - - ms->ms_rbuf[put] = (c << 8) | rr1; - put_next = (put + 1) & MS_RX_RING_MASK; - - /* Would overrun if increment makes (put==get). */ - if (put_next == ms->ms_rbget) { - ms->ms_intr_flags |= INTR_RX_OVERRUN; - } else { - /* OK, really increment. */ - put = put_next; - } - - /* Done reading. */ - ms->ms_rbput = put; - - /* Ask for softint() call. */ - cs->cs_softreq = 1; -} - - -static void -ms_txint(cs) - register struct zs_chanstate *cs; -{ - register struct ms_softc *ms; - - ms = cs->cs_private; - zs_write_csr(cs, ZSWR0_RESET_TXINT); - ms->ms_intr_flags |= INTR_TX_EMPTY; - /* Ask for softint() call. */ - cs->cs_softreq = 1; -} - - -static void -ms_stint(cs, force) - register struct zs_chanstate *cs; - int force; -{ - register struct ms_softc *ms; - register int rr0; - - ms = cs->cs_private; - - rr0 = zs_read_csr(cs); - zs_write_csr(cs, ZSWR0_RESET_STATUS); - - /* - * We have to accumulate status line changes here. - * Otherwise, if we get multiple status interrupts - * before the softint runs, we could fail to notice - * some status line changes in the softint routine. - * Fix from Bill Studenmund, October 1996. - */ - cs->cs_rr0_delta |= (cs->cs_rr0 ^ rr0); - cs->cs_rr0 = rr0; - ms->ms_intr_flags |= INTR_ST_CHECK; - - /* Ask for softint() call. */ - cs->cs_softreq = 1; -} - - -static void -ms_softint(cs) - struct zs_chanstate *cs; -{ - register struct ms_softc *ms; - register int get, c, s; - int intr_flags; - register u_short ring_data; - - ms = cs->cs_private; - - /* Atomically get and clear flags. */ - s = splzs(); - intr_flags = ms->ms_intr_flags; - ms->ms_intr_flags = 0; - - /* Now lower to spltty for the rest. */ - (void) spltty(); - - /* - * Copy data from the receive ring to the event layer. - */ - get = ms->ms_rbget; - while (get != ms->ms_rbput) { - ring_data = ms->ms_rbuf[get]; - get = (get + 1) & MS_RX_RING_MASK; - - /* low byte of ring_data is rr1 */ - c = (ring_data >> 8) & 0xff; - - if (ring_data & ZSRR1_DO) - intr_flags |= INTR_RX_OVERRUN; - if (ring_data & (ZSRR1_FE | ZSRR1_PE)) { - log(LOG_ERR, "%s: input error (0x%x)\n", - ms->ms_dev.dv_xname, ring_data); - c = -1; /* signal input error */ - } - - /* Pass this up to the "middle" layer. */ - ms_input(ms, c); - } - if (intr_flags & INTR_RX_OVERRUN) { - log(LOG_ERR, "%s: input overrun\n", - ms->ms_dev.dv_xname); - } - ms->ms_rbget = get; - - if (intr_flags & INTR_TX_EMPTY) { - /* - * Transmit done. (Not expected.) - */ - log(LOG_ERR, "%s: transmit interrupt?\n", - ms->ms_dev.dv_xname); - } - - if (intr_flags & INTR_ST_CHECK) { - /* - * Status line change. (Not expected.) - */ - log(LOG_ERR, "%s: status interrupt?\n", - ms->ms_dev.dv_xname); - cs->cs_rr0_delta = 0; - } - - splx(s); -} - -struct zsops zsops_ms = { - ms_rxint, /* receive char available */ - ms_stint, /* external/status */ - ms_txint, /* xmit buffer empty */ - ms_softint, /* process software interrupt */ -}; |
