summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sgi/conf/GENERIC-IP2220
-rw-r--r--sys/arch/sgi/conf/RAMDISK-IP2214
-rw-r--r--sys/arch/sgi/hpc/files.hpc8
-rw-r--r--sys/arch/sgi/hpc/wskbdmap_sgi.c147
-rw-r--r--sys/arch/sgi/hpc/z8530kbd.c593
-rw-r--r--sys/arch/sgi/hpc/z8530ms.c337
6 files changed, 1096 insertions, 23 deletions
diff --git a/sys/arch/sgi/conf/GENERIC-IP22 b/sys/arch/sgi/conf/GENERIC-IP22
index ac9503fc7fb..e277f1cf84b 100644
--- a/sys/arch/sgi/conf/GENERIC-IP22
+++ b/sys/arch/sgi/conf/GENERIC-IP22
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC-IP22,v 1.8 2012/04/17 15:36:52 miod Exp $
+# $OpenBSD: GENERIC-IP22,v 1.9 2012/04/17 22:06:33 miod Exp $
#
# THIS KERNEL IS FOR INDIGO (IP20), INDY (IP22) AND INDIGO2 (IP24) SYSTEMS ONLY.
#
@@ -62,26 +62,24 @@ panel* at hpc? # Indy front panel buttons
pckbc* at hpc? # Indy/Indigo2 keyboard and mouse
zs0 at hpc0
-#zs1 at hpc0
+zs1 at hpc0
zstty* at zs0 # Serial ports
-#zskbd* at zs1 channel 0
-#wskbd* at zskbd? mux 1
-#zsms* at zs1 channel 1
-#wsmouse* at zsms? mux 0
+zskbd* at zs1 channel 0
+wskbd* at zskbd? mux 1
+zsms* at zs1 channel 1
+wsmouse* at zsms? mux 0
pckbd* at pckbc?
wskbd* at pckbd? mux 1
pms* at pckbc?
wsmouse* at pms? mux 0
-newport* at gio? # Indy Newport and Indigo2 XL graphics
-wsdisplay* at newport?
-
-#grtwo* at gio? disable # Express (GR2) graphics
+#grtwo* at gio? # Express (GR2) graphics
#wsdisplay* at grtwo?
-
light* at gio? # Light/Starter/Entry (LG1/LG2) graphics
wsdisplay* at light?
+newport* at gio? # Indy Newport and Indigo2 XL graphics
+wsdisplay* at newport?
#audio* at haltwo?
diff --git a/sys/arch/sgi/conf/RAMDISK-IP22 b/sys/arch/sgi/conf/RAMDISK-IP22
index 6db3c73b0b5..99b29b2d2c4 100644
--- a/sys/arch/sgi/conf/RAMDISK-IP22
+++ b/sys/arch/sgi/conf/RAMDISK-IP22
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK-IP22,v 1.5 2012/04/17 15:36:52 miod Exp $
+# $OpenBSD: RAMDISK-IP22,v 1.6 2012/04/17 22:06:33 miod Exp $
#
# THIS KERNEL IS FOR INDIGO (IP20), INDY (IP22) AND INDIGO2 (IP24) SYSTEMS ONLY.
@@ -69,10 +69,10 @@ wdsc* at hpc? # On-board SCSI or GIO32 SCSI adapter
pckbc* at hpc? # Indy/Indigo2 keyboard and mouse
zs0 at hpc0
-#zs1 at hpc0
+zs1 at hpc0
zstty* at zs0 # Serial ports
-#zskbd* at zs1 channel 0
-#wskbd* at zskbd? mux 1
+zskbd* at zs1 channel 0
+wskbd* at zskbd? mux 1
#zsms* at zs1 channel 1
#wsmouse* at zsms? mux 0
@@ -81,14 +81,12 @@ wskbd* at pckbd? mux 1
#pms* at pckbc?
#wsmouse* at pms? mux 0
-newport* at gio? # Indy Newport graphics
-wsdisplay* at newport?
-
#grtwo* at gio? # Express (GR2) graphics
#wsdisplay* at grtwo?
-
light* at gio? # Light/Starter/Entry (LG1/LG2) graphics
wsdisplay* at light?
+newport* at gio? # Indy Newport and Indigo2 XL graphics
+wsdisplay* at newport?
scsibus* at scsi?
sd* at scsibus?
diff --git a/sys/arch/sgi/hpc/files.hpc b/sys/arch/sgi/hpc/files.hpc
index 4463f066a45..1fed4498bf1 100644
--- a/sys/arch/sgi/hpc/files.hpc
+++ b/sys/arch/sgi/hpc/files.hpc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.hpc,v 1.1 2012/03/28 20:44:23 miod Exp $
+# $OpenBSD: files.hpc,v 1.2 2012/04/17 22:06:33 miod Exp $
# $NetBSD: files.hpc,v 1.14 2009/05/14 01:10:19 macallan Exp $
# IP20 RTC
@@ -37,12 +37,12 @@ file arch/sgi/hpc/z8530tty.c zstty needs-flag
device zskbd: wskbddev
attach zskbd at zs
-file arch/sgi/hpc/zs_kbd.c zskbd needs-flag
-file arch/sgi/dev/wskbdmap_sgi.c zskbd
+file arch/sgi/hpc/z8530kbd.c zskbd needs-flag
+file arch/sgi/hpc/wskbdmap_sgi.c zskbd
device zsms: wsmousedev
attach zsms at zs
-file arch/sgi/hpc/zs_ms.c zsms
+file arch/sgi/hpc/z8530ms.c zsms
attach pckbc at hpc with pckbc_hpc
file arch/sgi/hpc/pckbc_hpc.c pckbc_hpc
diff --git a/sys/arch/sgi/hpc/wskbdmap_sgi.c b/sys/arch/sgi/hpc/wskbdmap_sgi.c
new file mode 100644
index 00000000000..0a8d43391c4
--- /dev/null
+++ b/sys/arch/sgi/hpc/wskbdmap_sgi.c
@@ -0,0 +1,147 @@
+/* $OpenBSD: wskbdmap_sgi.c,v 1.1 2012/04/17 22:06:33 miod Exp $ */
+/* $NetBSD: wskbdmap_sgi.c,v 1.5 2006/12/26 17:37:22 rumble Exp $ */
+
+/*
+ * Copyright (c) 2004 Steve Rumble
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
+
+#define KC(n) KS_KEYCODE(n)
+
+static const keysym_t wssgi_keydesctab_us[] = {
+/* pos command normal shifted */
+ KC(0x02), KS_Cmd1, KS_Control_L,
+ KC(0x03), KS_Caps_Lock,
+ KC(0x04), KS_Shift_R,
+ KC(0x05), KS_Shift_L,
+ KC(0x06), KS_Cmd_Debugger, KS_Escape,
+ KC(0x07), KS_1, KS_exclam,
+ KC(0x08), KS_Tab,
+ KC(0x09), KS_q,
+ KC(0x0A), KS_a,
+ KC(0x0B), KS_s,
+ KC(0x0D), KS_2, KS_at,
+ KC(0x0E), KS_3, KS_numbersign,
+ KC(0x0F), KS_w,
+ KC(0x10), KS_e,
+ KC(0x11), KS_d,
+ KC(0x12), KS_f,
+ KC(0x13), KS_z,
+ KC(0x14), KS_x,
+ KC(0x15), KS_4, KS_dollar,
+ KC(0x16), KS_5, KS_percent,
+ KC(0x17), KS_r,
+ KC(0x18), KS_t,
+ KC(0x19), KS_g,
+ KC(0x1A), KS_h,
+ KC(0x1B), KS_c,
+ KC(0x1C), KS_v,
+ KC(0x1D), KS_6, KS_asciicircum,
+ KC(0x1E), KS_7, KS_ampersand,
+ KC(0x1F), KS_y,
+ KC(0x20), KS_u,
+ KC(0x21), KS_j,
+ KC(0x22), KS_k,
+ KC(0x23), KS_b,
+ KC(0x24), KS_n,
+ KC(0x25), KS_8, KS_asterisk,
+ KC(0x26), KS_9, KS_parenleft,
+ KC(0x27), KS_i,
+ KC(0x28), KS_o,
+ KC(0x29), KS_l,
+ KC(0x2A), KS_semicolon, KS_colon,
+ KC(0x2B), KS_m,
+ KC(0x2C), KS_comma, KS_less,
+ KC(0x2D), KS_0, KS_parenright,
+ KC(0x2E), KS_minus, KS_underscore,
+ KC(0x2F), KS_p,
+ KC(0x30), KS_bracketleft, KS_braceleft,
+ KC(0x31), KS_apostrophe, KS_quotedbl,
+ KC(0x32), KS_Return,
+ KC(0x33), KS_period, KS_greater,
+ KC(0x34), KS_slash, KS_question,
+ KC(0x35), KS_equal, KS_plus,
+ KC(0x36), KS_grave, KS_asciitilde,
+ KC(0x37), KS_bracketright,KS_braceright,
+ KC(0x38), KS_backslash, KS_bar,
+ KC(0x39), KS_KP_End, KS_KP_1,
+ KC(0x3A), KS_KP_Insert, KS_KP_0,
+ KC(0x3C), KS_Delete,
+ KC(0x3D), KS_Delete,
+ KC(0x3E), KS_KP_Left, KS_KP_4,
+ KC(0x3F), KS_KP_Down, KS_KP_2,
+ KC(0x40), KS_KP_Next, KS_KP_3,
+ KC(0x41), KS_KP_Delete, KS_KP_Decimal,
+ KC(0x42), KS_KP_Home, KS_KP_7,
+ KC(0x43), KS_KP_Up, KS_KP_8,
+ KC(0x44), KS_KP_Begin, KS_KP_5,
+ KC(0x45), KS_KP_Right, KS_KP_6,
+ KC(0x48), KS_Left,
+ KC(0x49), KS_Down,
+ KC(0x4A), KS_KP_Prior, KS_KP_9,
+ KC(0x4B), KS_KP_Subtract,
+ KC(0x4F), KS_Right,
+ KC(0x50), KS_Up,
+ KC(0x51), KS_KP_Enter,
+ KC(0x52), KS_space,
+ KC(0x53), KS_Cmd2, KS_Alt_L,
+ KC(0x54), KS_Cmd2, KS_Alt_R, KS_Multi_key,
+ KC(0x55), KS_Cmd1, KS_Control_R,
+ KC(0x56), KS_f1,
+ KC(0x57), KS_f2,
+ KC(0x58), KS_f3,
+ KC(0x59), KS_f4,
+ KC(0x5A), KS_f5,
+ KC(0x5B), KS_f6,
+ KC(0x5C), KS_f7,
+ KC(0x5D), KS_f8,
+ KC(0x5E), KS_f9,
+ KC(0x5F), KS_f10,
+ KC(0x60), KS_f11,
+ KC(0x61), KS_f12,
+ KC(0x62), KS_Print_Screen,
+ KC(0x63), KS_Hold_Screen,
+ KC(0x64), KS_Pause,
+ KC(0x65), KS_Insert,
+ KC(0x66), KS_Home,
+ KC(0x67), KS_Prior,
+ KC(0x68), KS_End,
+ KC(0x69), KS_Next,
+ KC(0x6A), KS_Num_Lock,
+ KC(0x6B), KS_KP_Divide,
+ KC(0x6C), KS_KP_Multiply,
+ KC(0x6D), KS_KP_Add,
+};
+
+#define KBD_MAP(name, base, map) \
+ { name, base, sizeof(map)/sizeof(keysym_t), map }
+
+const struct wscons_keydesc wssgi_keydesctab[] = {
+ KBD_MAP(KB_US, 0, wssgi_keydesctab_us)
+};
diff --git a/sys/arch/sgi/hpc/z8530kbd.c b/sys/arch/sgi/hpc/z8530kbd.c
new file mode 100644
index 00000000000..282e6fd575b
--- /dev/null
+++ b/sys/arch/sgi/hpc/z8530kbd.c
@@ -0,0 +1,593 @@
+/* $OpenBSD: z8530kbd.c,v 1.1 2012/04/17 22:06:33 miod Exp $ */
+/* $NetBSD: zs_kbd.c,v 1.8 2008/03/29 19:15:35 tsutsui Exp $ */
+
+/*
+ * Copyright (c) 2004 Steve Rumble
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * IP20 serial keyboard driver attached to zs channel 0 at 600bps.
+ * This layer is the parent of wskbd.
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wskbdvar.h>
+#include <dev/wscons/wsksymdef.h>
+#include <dev/wscons/wsksymvar.h>
+
+#include <machine/autoconf.h>
+#include <mips64/archtype.h>
+
+#include <dev/ic/z8530reg.h>
+#include <machine/z8530var.h>
+
+#define ZSKBD_BAUD 600
+#define ZSKBD_TXQ_LEN 16 /* power of 2 */
+#define ZSKBD_RXQ_LEN 64 /* power of 2 */
+
+#define ZSKBD_DIP_SYNC 0x6e
+#define ZSKBD_KEY_UP 0x80
+#define ZSKBD_KEY_ALL_UP 0xf0
+
+#ifdef ZSKBD_DEBUG
+int zskbd_debug = 0;
+
+#define DPRINTF(_x) if (zskbd_debug) printf _x
+#else
+#define DPRINTF(_x)
+#endif
+
+struct zskbd_softc {
+ struct device sc_dev;
+
+ struct zskbd_devconfig *sc_dc;
+
+#ifdef WSDISPLAY_COMPAT_RAWKBD
+ int sc_rawkbd;
+#endif
+};
+
+struct zskbd_devconfig {
+ /* transmit tail-chasing fifo */
+ uint8_t txq[ZSKBD_TXQ_LEN];
+ u_int txq_head;
+ u_int txq_tail;
+
+ /* receive tail-chasing fifo */
+ uint8_t rxq[ZSKBD_RXQ_LEN];
+ u_int rxq_head;
+ u_int rxq_tail;
+
+ /* state */
+#define TX_READY 0x1
+#define RX_DIP 0x2
+ u_int state;
+
+ /* keyboard configuration */
+#define ZSKBD_CTRL_A 0x0
+#define ZSKBD_CTRL_A_SBEEP 0x2 /* 200 ms */
+#define ZSKBD_CTRL_A_LBEEP 0x4 /* 1000 ms */
+#define ZSKBD_CTRL_A_NOCLICK 0x8 /* turn off keyboard click */
+#define ZSKBD_CTRL_A_RCB 0x10 /* request config byte */
+#define ZSKBD_CTRL_A_NUMLK 0x20 /* num lock led */
+#define ZSKBD_CTRL_A_CAPSLK 0x40 /* caps lock led */
+#define ZSKBD_CTRL_A_AUTOREP 0x80 /* auto-repeat after 650 ms, 28x/sec */
+
+#define ZSKBD_CTRL_B 0x1
+#define ZSKBD_CTRL_B_CMPL_DS1_2 0x2 /* complement of ds1+ds2 (num+capslk) */
+#define ZSKBD_CTRL_B_SCRLK 0x4 /* scroll lock light */
+#define ZSKBD_CTRL_B_L1 0x8 /* user-configurable lights */
+#define ZSKBD_CTRL_B_L2 0x10
+#define ZSKBD_CTRL_B_L3 0x20
+#define ZSKBD_CTRL_B_L4 0x40
+ uint8_t kbd_conf[2];
+
+ /* dip switch settings */
+ uint8_t dip;
+
+ /* wscons glue */
+ struct device *wskbddev;
+ int enabled;
+};
+
+int zskbd_match(struct device *, void *, void *);
+void zskbd_attach(struct device *, struct device *, void *);
+
+struct cfdriver zskbd_cd = {
+ NULL, "zskbd", DV_DULL
+};
+
+const struct cfattach zskbd_ca = {
+ sizeof(struct zskbd_softc), zskbd_match, zskbd_attach
+};
+
+void zskbd_rxint(struct zs_chanstate *);
+void zskbd_stint(struct zs_chanstate *, int);
+void zskbd_txint(struct zs_chanstate *);
+void zskbd_softint(struct zs_chanstate *);
+void zskbd_send(struct zs_chanstate *, uint8_t *, u_int);
+void zskbd_ctrl(struct zs_chanstate *, uint8_t, uint8_t, uint8_t, uint8_t);
+
+void zskbd_wskbd_input(struct zs_chanstate *, uint8_t);
+int zskbd_wskbd_enable(void *, int);
+void zskbd_wskbd_set_leds(void *, int);
+int zskbd_wskbd_get_leds(void *);
+void zskbd_wskbd_set_keyclick(void *, int);
+int zskbd_wskbd_get_keyclick(void *);
+int zskbd_wskbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
+
+void zskbd_cnattach(int, int);
+void zskbd_wskbd_getc(void *, u_int *, int *);
+void zskbd_wskbd_pollc(void *, int);
+void zskbd_wskbd_bell(void *, u_int, u_int, u_int);
+
+extern struct zschan *zs_get_chan_addr(int, int);
+extern int zs_getc(void *);
+extern void zs_putc(void *, int);
+
+static struct zsops zskbd_zsops = {
+ zskbd_rxint,
+ zskbd_stint,
+ zskbd_txint,
+ zskbd_softint
+};
+
+extern const struct wscons_keydesc wssgi_keydesctab[];
+const struct wskbd_mapdata sgikbd_wskbd_keymapdata = {
+ wssgi_keydesctab,
+ KB_US
+};
+
+const struct wskbd_accessops zskbd_wskbd_accessops = {
+ zskbd_wskbd_enable,
+ zskbd_wskbd_set_leds,
+ zskbd_wskbd_ioctl
+};
+
+const struct wskbd_consops zskbd_wskbd_consops = {
+ zskbd_wskbd_getc,
+ zskbd_wskbd_pollc,
+ zskbd_wskbd_bell
+};
+
+struct zskbd_devconfig zskbd_console_dc;
+int zskbd_is_console = 0;
+
+int
+zskbd_match(struct device *parent, void *vcf, void *aux)
+{
+ if (sys_config.system_type == SGI_IP20) {
+ struct zsc_attach_args *args = aux;
+
+ if (args->channel == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+zskbd_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct zskbd_softc *sc = (struct zskbd_softc *)self;
+ struct zsc_softc *zsc = (struct zsc_softc *)parent;
+ struct zsc_attach_args *args = aux;
+ struct zs_chanstate *cs;
+ struct wskbddev_attach_args wskaa;
+ int s, channel;
+
+ /* Establish ourself with the MD z8530 driver */
+ channel = args->channel;
+ cs = zsc->zsc_cs[channel];
+ cs->cs_ops = &zskbd_zsops;
+ cs->cs_private = sc;
+
+ if (zskbd_is_console) {
+ sc->sc_dc = &zskbd_console_dc;
+ sc->sc_dc->enabled = 1;
+ } else {
+ sc->sc_dc = malloc(sizeof(struct zskbd_devconfig), M_DEVBUF,
+ M_WAITOK | M_ZERO);
+ sc->sc_dc->state = TX_READY;
+ }
+
+ printf("\n");
+
+ s = splzs();
+ zs_write_reg(cs, 9, (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET);
+ cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_TIE;
+ cs->cs_preg[4] = (cs->cs_preg[4] & ZSWR4_CLK_MASK) |
+ (ZSWR4_ONESB | ZSWR4_PARENB); /* 1 stop, odd parity */
+ zs_set_speed(cs, ZSKBD_BAUD);
+ zs_loadchannelregs(cs);
+
+ /* request DIP switch settings just in case */
+ zskbd_ctrl(cs, ZSKBD_CTRL_A_RCB, 0, 0, 0);
+
+ /* disable key click by default */
+ zskbd_ctrl(cs, ZSKBD_CTRL_A_NOCLICK, 0, 0, 0);
+
+ splx(s);
+
+ /* attach wskbd */
+ wskaa.console = zskbd_is_console;
+ wskaa.keymap = &sgikbd_wskbd_keymapdata;
+ wskaa.accessops = &zskbd_wskbd_accessops;
+ wskaa.accesscookie = cs;
+ sc->sc_dc->wskbddev = config_found(self, &wskaa, wskbddevprint);
+}
+
+void
+zskbd_rxint(struct zs_chanstate *cs)
+{
+ struct zskbd_softc *sc = cs->cs_private;
+ struct zskbd_devconfig *dc = sc->sc_dc;
+ uint8_t c, r;
+
+ /* clear errors */
+ r = zs_read_reg(cs, 1);
+ if (r & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE))
+ zs_write_csr(cs, ZSWR0_RESET_ERRORS);
+
+ /* read byte and append to our queue */
+ c = zs_read_data(cs);
+
+ dc->rxq[dc->rxq_tail] = c;
+ dc->rxq_tail = (dc->rxq_tail + 1) & ~ZSKBD_RXQ_LEN;
+
+ cs->cs_softreq = 1;
+}
+
+void
+zskbd_stint(struct zs_chanstate *cs, int force)
+{
+ zs_write_csr(cs, ZSWR0_RESET_STATUS);
+ cs->cs_softreq = 1;
+}
+
+void
+zskbd_txint(struct zs_chanstate *cs)
+{
+ struct zskbd_softc *sc = cs->cs_private;
+
+ zs_write_reg(cs, 0, ZSWR0_RESET_TXINT);
+ sc->sc_dc->state |= TX_READY;
+ cs->cs_softreq = 1;
+}
+
+void
+zskbd_softint(struct zs_chanstate *cs)
+{
+ struct zskbd_softc *sc = cs->cs_private;
+ struct zskbd_devconfig *dc = sc->sc_dc;
+
+ /* handle pending transmissions */
+ if (dc->txq_head != dc->txq_tail && (dc->state & TX_READY)) {
+ int s;
+
+ dc->state &= ~TX_READY;
+
+ s = splzs();
+ zs_write_data(cs, dc->txq[dc->txq_head]);
+ splx(s);
+
+ dc->txq_head = (dc->txq_head + 1) & ~ZSKBD_TXQ_LEN;
+ }
+
+ /* don't bother if nobody is listening */
+ if (!dc->enabled) {
+ dc->rxq_head = dc->rxq_tail;
+ return;
+ }
+
+ /* handle incoming keystrokes/config */
+ while (dc->rxq_head != dc->rxq_tail) {
+ uint8_t key = dc->rxq[dc->rxq_head];
+
+ if (dc->state & RX_DIP) {
+ dc->dip = key;
+ dc->state &= ~RX_DIP;
+ } else if (key == ZSKBD_DIP_SYNC) {
+ dc->state |= RX_DIP;
+ } else {
+ /* toss wskbd a bone */
+ zskbd_wskbd_input(cs, key);
+ }
+
+ dc->rxq_head = (dc->rxq_head + 1) & ~ZSKBD_RXQ_LEN;
+ }
+}
+
+/* expects to be in splzs() */
+void
+zskbd_send(struct zs_chanstate *cs, uint8_t *c, u_int len)
+{
+ struct zskbd_softc *sc = cs->cs_private;
+ struct zskbd_devconfig *dc = sc->sc_dc;
+ u_int i;
+
+ for (i = 0; i < len; i++) {
+ if (dc->state & TX_READY) {
+ zs_write_data(cs, c[i]);
+ dc->state &= ~TX_READY;
+ } else {
+ dc->txq[dc->txq_tail] = c[i];
+ dc->txq_tail = (dc->txq_tail + 1) & ~ZSKBD_TXQ_LEN;
+ cs->cs_softreq = 1;
+ }
+ }
+}
+
+/* expects to be in splzs() */
+void
+zskbd_ctrl(struct zs_chanstate *cs, uint8_t a_on, uint8_t a_off, uint8_t b_on,
+ uint8_t b_off)
+{
+ struct zskbd_softc *sc = cs->cs_private;
+ struct zskbd_devconfig *dc = sc->sc_dc;
+
+ dc->kbd_conf[ZSKBD_CTRL_A] |= a_on;
+ dc->kbd_conf[ZSKBD_CTRL_A] &= ~(a_off | ZSKBD_CTRL_B);
+ dc->kbd_conf[ZSKBD_CTRL_B] &= ~b_off;
+ dc->kbd_conf[ZSKBD_CTRL_B] |= (b_on | ZSKBD_CTRL_B);
+
+ zskbd_send(cs, dc->kbd_conf, 2);
+
+ /* make sure we don't resend these each time */
+ dc->kbd_conf[ZSKBD_CTRL_A] &= ~(ZSKBD_CTRL_A_RCB | ZSKBD_CTRL_A_SBEEP |
+ ZSKBD_CTRL_A_LBEEP);
+}
+
+/******************************************************************************
+ * wskbd glue
+ ******************************************************************************/
+
+void
+zskbd_wskbd_input(struct zs_chanstate *cs, uint8_t key)
+{
+ struct zskbd_softc *sc = cs->cs_private;
+ u_int type;
+#ifdef WSDISPLAY_COMPAT_RAWKBD
+ int s;
+#endif
+
+ if (sc->sc_dc->wskbddev == NULL)
+ return; /* why bother */
+
+ if (key & ZSKBD_KEY_UP) {
+ if (key & ZSKBD_KEY_ALL_UP)
+ type = WSCONS_EVENT_ALL_KEYS_UP;
+ else
+ type = WSCONS_EVENT_KEY_UP;
+ } else
+ type = WSCONS_EVENT_KEY_DOWN;
+
+ wskbd_input(sc->sc_dc->wskbddev, type, (key & ~ZSKBD_KEY_UP));
+
+ DPRINTF(("zskbd_wskbd_input: inputted key 0x%x\n", key));
+
+#ifdef WSDISPLAY_COMPAT_RAWKBD
+ if (sc->sc_rawkbd &&
+ type != WSCONS_EVENT_ALL_KEYS_UP) {
+ s = spltty();
+ wskbd_rawinput(sc->sc_dc->wskbddev, &key, 1);
+ splx(s);
+ }
+#endif
+}
+
+int
+zskbd_wskbd_enable(void *cookie, int on)
+{
+ struct zs_chanstate *cs = cookie;
+ struct zskbd_softc *sc = cs->cs_private;
+
+ if (on) {
+ if (sc->sc_dc->enabled)
+ return (EBUSY);
+ else
+ sc->sc_dc->enabled = 1;
+ } else
+ sc->sc_dc->enabled = 0;
+
+ DPRINTF(("zskbd_wskbd_enable: %s\n", on ? "enabled" : "disabled"));
+
+ return (0);
+}
+
+void
+zskbd_wskbd_set_leds(void *cookie, int leds)
+{
+ struct zs_chanstate *cs = cookie;
+ int s;
+ uint8_t a_on, a_off, b_on, b_off;
+
+ a_on = a_off = b_on = b_off = 0;
+
+ if (leds & WSKBD_LED_CAPS)
+ a_on |= ZSKBD_CTRL_A_CAPSLK;
+ else
+ a_off |= ZSKBD_CTRL_A_CAPSLK;
+
+ if (leds & WSKBD_LED_NUM)
+ a_on |= ZSKBD_CTRL_A_NUMLK;
+ else
+ a_off |= ZSKBD_CTRL_A_NUMLK;
+
+ if (leds & WSKBD_LED_SCROLL)
+ b_on |= ZSKBD_CTRL_B_SCRLK;
+ else
+ b_off |= ZSKBD_CTRL_B_SCRLK;
+
+ s = splzs();
+ zskbd_ctrl(cs, a_on, a_off, b_on, b_off);
+ splx(s);
+}
+
+int
+zskbd_wskbd_get_leds(void *cookie)
+{
+ struct zs_chanstate *cs = cookie;
+ struct zskbd_softc *sc = cs->cs_private;
+ int leds;
+
+ leds = 0;
+
+ if (sc->sc_dc->kbd_conf[ZSKBD_CTRL_A] & ZSKBD_CTRL_A_NUMLK)
+ leds |= WSKBD_LED_NUM;
+
+ if (sc->sc_dc->kbd_conf[ZSKBD_CTRL_A] & ZSKBD_CTRL_A_CAPSLK)
+ leds |= WSKBD_LED_CAPS;
+
+ if (sc->sc_dc->kbd_conf[ZSKBD_CTRL_B] & ZSKBD_CTRL_B_SCRLK)
+ leds |= WSKBD_LED_SCROLL;
+
+ return (leds);
+}
+
+#if 0
+void
+zskbd_wskbd_set_keyclick(void *cookie, int on)
+{
+ struct zs_chanstate *cs = cookie;
+ int s;
+
+ if (on) {
+ if (!zskbd_wskbd_get_keyclick(cookie)) {
+ s = splzs();
+ zskbd_ctrl(cs, 0, ZSKBD_CTRL_A_NOCLICK, 0, 0);
+ splx(s);
+ }
+ } else {
+ if (zskbd_wskbd_get_keyclick(cookie)) {
+ s = splzs();
+ zskbd_ctrl(cs, ZSKBD_CTRL_A_NOCLICK, 0, 0, 0);
+ splx(s);
+ }
+ }
+}
+
+int
+zskbd_wskbd_get_keyclick(void *cookie)
+{
+ struct zs_chanstate *cs = cookie;
+ struct zskbd_softc *sc = cs->cs_private;
+
+ if (sc->sc_dc->kbd_conf[ZSKBD_CTRL_A] & ZSKBD_CTRL_A_NOCLICK)
+ return (0);
+ else
+ return (1);
+}
+#endif
+
+int
+zskbd_wskbd_ioctl(void *cookie, u_long cmd, caddr_t data, int flag,
+ struct proc *p)
+{
+ struct zs_chanstate *cs = cookie;
+#ifdef WSDISPLAY_COMPAT_RAWKBD
+ struct zskbd_softc *sc = cs->cs_private;
+#endif
+
+ switch (cmd) {
+ case WSKBDIO_GTYPE:
+ *(int *)data = WSKBD_TYPE_SGI;
+ break;
+ case WSKBDIO_SETLEDS:
+ zskbd_wskbd_set_leds(cs, *(int *)data);
+ break;
+ case WSKBDIO_GETLEDS:
+ *(int *)data = zskbd_wskbd_get_leds(cs);
+ break;
+#if 0
+ case WSKBDIO_SETKEYCLICK:
+ zskbd_wskbd_set_keyclick(cs, *(int *)data);
+ break;
+ case WSKBDIO_GETKEYCLICK:
+ *(int *)data = zskbd_wskbd_get_keyclick(cs);
+ break;
+#endif
+#ifdef WSDISPLAY_COMPAT_RAWKBD
+ case WSKBDIO_SETMODE:
+ sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
+ break;
+#endif
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * console routines
+ */
+void
+zskbd_cnattach(int zsunit, int zschan)
+{
+ wskbd_cnattach(&zskbd_wskbd_consops, zs_get_chan_addr(zsunit, zschan),
+ &sgikbd_wskbd_keymapdata);
+ zskbd_is_console = 1;
+}
+
+void
+zskbd_wskbd_getc(void *cookie, u_int *type, int *data)
+{
+ int key;
+
+ key = zs_getc(cookie);
+
+ if (key & ZSKBD_KEY_UP)
+ *type = WSCONS_EVENT_KEY_UP;
+ else
+ *type = WSCONS_EVENT_KEY_DOWN;
+
+ *data = key & ~ZSKBD_KEY_UP;
+}
+
+void
+zskbd_wskbd_pollc(void *cookie, int on)
+{
+}
+
+void
+zskbd_wskbd_bell(void *cookie, u_int pitch, u_int period, u_int volume)
+{
+ /*
+ * Since we don't have any state, this'll nuke our lights,
+ * key click, and other bits in ZSKBD_CTRL_A.
+ */
+ if (period >= 1000)
+ zs_putc(cookie, ZSKBD_CTRL_A_LBEEP);
+ else
+ zs_putc(cookie, ZSKBD_CTRL_A_SBEEP);
+}
diff --git a/sys/arch/sgi/hpc/z8530ms.c b/sys/arch/sgi/hpc/z8530ms.c
new file mode 100644
index 00000000000..4c6bdb43217
--- /dev/null
+++ b/sys/arch/sgi/hpc/z8530ms.c
@@ -0,0 +1,337 @@
+/* $OpenBSD: z8530ms.c,v 1.1 2012/04/17 22:06:33 miod Exp $ */
+/* $NetBSD: zs_ms.c,v 1.7 2008/03/29 19:15:35 tsutsui Exp $ */
+
+/*
+ * Copyright (c) 2004 Steve Rumble
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * IP20 serial mouse driver attached to zs channel 1 at 4800bps.
+ * This layer feeds wsmouse.
+ *
+ * 5 byte packets: sync, x1, y1, x2, y2
+ * sync format: binary 10000LMR (left, middle, right) 0 is down
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#include <machine/autoconf.h>
+#include <mips64/archtype.h>
+
+#include <dev/ic/z8530reg.h>
+#include <machine/z8530var.h>
+
+#define ZSMS_BAUD 4800
+#define ZSMS_RXQ_LEN 64 /* power of 2 */
+
+/* protocol */
+#define ZSMS_SYNC 0x80
+#define ZSMS_SYNC_MASK 0xf8
+#define ZSMS_SYNC_BTN_R 0x01
+#define ZSMS_SYNC_BTN_M 0x02
+#define ZSMS_SYNC_BTN_L 0x04
+#define ZSMS_SYNC_BTN_MASK 0x07
+
+struct zsms_softc {
+ struct device sc_dev;
+
+ /* tail-chasing fifo */
+ uint8_t rxq[ZSMS_RXQ_LEN];
+ uint8_t rxq_head;
+ uint8_t rxq_tail;
+
+ /* 5-byte packet as described above */
+#define ZSMS_PACKET_SYNC 0
+#define ZSMS_PACKET_X1 1
+#define ZSMS_PACKET_Y1 2
+#define ZSMS_PACKET_X2 3
+#define ZSMS_PACKET_Y2 4
+ int8_t packet[5];
+
+#define ZSMS_STATE_SYNC 0x01
+#define ZSMS_STATE_X1 0x02
+#define ZSMS_STATE_Y1 0x04
+#define ZSMS_STATE_X2 0x08
+#define ZSMS_STATE_Y2 0x10
+ uint8_t state;
+
+ /* wsmouse bits */
+ int enabled;
+ struct device *wsmousedev;
+};
+
+int zsms_match(struct device *, void *, void *);
+void zsms_attach(struct device *, struct device *, void *);
+
+struct cfdriver zsms_cd = {
+ NULL, "zsms", DV_DULL
+};
+
+const struct cfattach zsms_ca = {
+ sizeof(struct zsms_softc), zsms_match, zsms_attach
+};
+
+void zsms_rxint(struct zs_chanstate *);
+void zsms_txint(struct zs_chanstate *);
+void zsms_stint(struct zs_chanstate *, int);
+void zsms_softint(struct zs_chanstate *);
+
+void zsms_wsmouse_input(struct zsms_softc *);
+int zsms_wsmouse_enable(void *);
+void zsms_wsmouse_disable(void *);
+int zsms_wsmouse_ioctl(void *, u_long, caddr_t, int, struct proc *);
+
+static struct zsops zsms_zsops = {
+ zsms_rxint,
+ zsms_stint,
+ zsms_txint,
+ zsms_softint
+};
+
+static const struct wsmouse_accessops zsms_wsmouse_accessops = {
+ zsms_wsmouse_enable,
+ zsms_wsmouse_ioctl,
+ zsms_wsmouse_disable
+};
+
+int
+zsms_match(struct device *parent, void *vcf, void *aux)
+{
+ if (sys_config.system_type == SGI_IP20) {
+ struct zsc_attach_args *args = aux;
+
+ if (args->channel == 1)
+ return (1);
+ }
+
+ return (0);
+}
+
+void
+zsms_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct zsc_softc *zsc = (struct zsc_softc *)parent;
+ struct zsms_softc *sc = (struct zsms_softc *)self;
+ struct zsc_attach_args *args = aux;
+ struct zs_chanstate *cs;
+ int s, channel;
+ struct wsmousedev_attach_args wsmaa;
+
+ /* Establish ourself with the MD z8530 driver */
+ channel = args->channel;
+ cs = zsc->zsc_cs[channel];
+ cs->cs_ops = &zsms_zsops;
+ cs->cs_private = sc;
+
+ sc->enabled = 0;
+ sc->rxq_head = 0;
+ sc->rxq_tail = 0;
+ sc->state = ZSMS_STATE_SYNC;
+
+ printf("\n");
+
+ s = splzs();
+ zs_write_reg(cs, 9, (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET);
+ cs->cs_preg[1] = ZSWR1_RIE;
+ zs_set_speed(cs, ZSMS_BAUD);
+ zs_loadchannelregs(cs);
+ splx(s);
+
+ /* attach wsmouse */
+ wsmaa.accessops = &zsms_wsmouse_accessops;
+ wsmaa.accesscookie = sc;
+ sc->wsmousedev = config_found(self, &wsmaa, wsmousedevprint);
+}
+
+void
+zsms_rxint(struct zs_chanstate *cs)
+{
+ struct zsms_softc *sc = cs->cs_private;
+ uint8_t c, r;
+
+ /* clear errors */
+ r = zs_read_reg(cs, 1);
+ if (r & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE))
+ zs_write_csr(cs, ZSWR0_RESET_ERRORS);
+
+ /* read byte and append to our queue */
+ c = zs_read_data(cs);
+
+ sc->rxq[sc->rxq_tail] = c;
+ sc->rxq_tail = (sc->rxq_tail + 1) & ~ZSMS_RXQ_LEN;
+
+ cs->cs_softreq = 1;
+}
+
+/* We should never get here. */
+void
+zsms_txint(struct zs_chanstate *cs)
+{
+ zs_write_reg(cs, 0, ZSWR0_RESET_TXINT);
+
+ /* disable tx interrupts */
+ CLR(cs->cs_preg[1], ZSWR1_TIE);
+ zs_loadchannelregs(cs);
+}
+
+void
+zsms_stint(struct zs_chanstate *cs, int force)
+{
+ zs_write_csr(cs, ZSWR0_RESET_STATUS);
+ cs->cs_softreq = 1;
+}
+
+void
+zsms_softint(struct zs_chanstate *cs)
+{
+ struct zsms_softc *sc = cs->cs_private;
+
+ /* No need to keep score if nobody is listening */
+ if (!sc->enabled) {
+ sc->rxq_head = sc->rxq_tail;
+ return;
+ }
+
+ /*
+ * Here's the real action. Read a full packet and
+ * then let wsmouse know what has happened.
+ */
+ while (sc->rxq_head != sc->rxq_tail) {
+ int8_t c = sc->rxq[sc->rxq_head];
+
+ switch (sc->state) {
+ case ZSMS_STATE_SYNC:
+ if ((c & ZSMS_SYNC_MASK) == ZSMS_SYNC) {
+ sc->packet[ZSMS_PACKET_SYNC] = c;
+ sc->state = ZSMS_STATE_X1;
+ }
+ break;
+
+ case ZSMS_STATE_X1:
+ sc->packet[ZSMS_PACKET_X1] = c;
+ sc->state = ZSMS_STATE_Y1;
+ break;
+
+ case ZSMS_STATE_Y1:
+ sc->packet[ZSMS_PACKET_Y1] = c;
+ sc->state = ZSMS_STATE_X2;
+ break;
+
+ case ZSMS_STATE_X2:
+ sc->packet[ZSMS_PACKET_X2] = c;
+ sc->state = ZSMS_STATE_Y2;
+ break;
+
+ case ZSMS_STATE_Y2:
+ sc->packet[ZSMS_PACKET_Y2] = c;
+
+ /* tweak wsmouse */
+ zsms_wsmouse_input(sc);
+
+ sc->state = ZSMS_STATE_SYNC;
+ }
+
+ sc->rxq_head = (sc->rxq_head + 1) & ~ZSMS_RXQ_LEN;
+ }
+}
+
+/******************************************************************************
+ * wsmouse glue
+ ******************************************************************************/
+
+void
+zsms_wsmouse_input(struct zsms_softc *sc)
+{
+ u_int btns;
+ int bl, bm, br;
+ int x, y;
+
+ if (sc->wsmousedev == NULL)
+ return;
+
+ btns = (uint8_t)sc->packet[ZSMS_PACKET_SYNC] & ZSMS_SYNC_BTN_MASK;
+
+ bl = (btns & ZSMS_SYNC_BTN_L) == 0;
+ bm = (btns & ZSMS_SYNC_BTN_M) == 0;
+ br = (btns & ZSMS_SYNC_BTN_R) == 0;
+
+ /* for wsmouse(4), 1 is down, 0 is up, the most left button is LSB */
+ btns = 0;
+ if (bl)
+ btns |= 1 << 0;
+ if (bm)
+ btns |= 1 << 1;
+ if (br)
+ btns |= 1 << 2;
+
+ x = (int)sc->packet[ZSMS_PACKET_X1] + (int)sc->packet[ZSMS_PACKET_X2];
+ y = (int)sc->packet[ZSMS_PACKET_Y1] + (int)sc->packet[ZSMS_PACKET_Y2];
+
+ wsmouse_input(sc->wsmousedev, btns, x, y, 0, 0, WSMOUSE_INPUT_DELTA);
+}
+
+int
+zsms_wsmouse_enable(void *cookie)
+{
+ struct zsms_softc *sc = cookie;
+
+ if (sc->enabled)
+ return (EBUSY);
+
+ sc->state = ZSMS_STATE_SYNC;
+ sc->enabled = 1;
+
+ return (0);
+}
+
+void
+zsms_wsmouse_disable(void *cookie)
+{
+ struct zsms_softc *sc = cookie;
+
+ sc->enabled = 0;
+}
+
+int
+zsms_wsmouse_ioctl(void *cookie, u_long cmd, caddr_t data, int flag,
+ struct proc *p)
+{
+ switch (cmd) {
+ case WSMOUSEIO_GTYPE:
+ *(u_int *)data = WSMOUSE_TYPE_SGI;
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}