Update for the new z8530 driver
This commit is contained in:
parent
a650625b1a
commit
f261ae08c7
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.sun3,v 1.16 1996/01/01 22:48:55 thorpej Exp $
|
||||
# $NetBSD: files.sun3,v 1.17 1996/01/24 22:39:48 gwr Exp $
|
||||
|
||||
#
|
||||
# sun3-specific configuration info
|
||||
|
@ -32,7 +32,6 @@ file arch/sun3/sun3/vm_machdep.c
|
|||
file arch/m68k/fpe/fpu_emulate.c fpu_emulate
|
||||
file arch/m68k/m68k/copy.s
|
||||
file dev/cons.c
|
||||
file dev/cninit.c
|
||||
|
||||
# Declare our "catch-all" root node.
|
||||
device mainbus at root {}
|
||||
|
@ -62,11 +61,6 @@ file arch/sun3/dev/obio.c obio
|
|||
file arch/sun3/dev/obmem.c obmem
|
||||
file arch/sun3/dev/vme.c vmes vmel
|
||||
|
||||
#
|
||||
# Sun-compatible Frame Buffers (?)
|
||||
#
|
||||
define sunfb {}
|
||||
|
||||
#
|
||||
# Machine-independent SCSI drivers
|
||||
#
|
||||
|
@ -75,8 +69,6 @@ include "../../../scsi/files.scsi"
|
|||
#
|
||||
# On-Board I/O (OBIO)
|
||||
#
|
||||
device zs at obio: tty
|
||||
file arch/sun3/dev/zs.c zs needs-count
|
||||
|
||||
device eeprom at obio
|
||||
file arch/sun3/dev/eeprom.c eeprom
|
||||
|
@ -98,6 +90,12 @@ file arch/sun3/dev/si.c si
|
|||
device ncr_si at obio, vmes: scsi, ncr5380sbc
|
||||
file arch/sun3/dev/ncr_si.c ncr_si
|
||||
|
||||
#
|
||||
# Sun-compatible Frame Buffers (?)
|
||||
#
|
||||
define sunfb
|
||||
file arch/sun3/dev/fb.c sunfb
|
||||
|
||||
#
|
||||
# On-Board MEMory (OBMEM)
|
||||
#
|
||||
|
@ -133,11 +131,24 @@ file arch/sun3/dev/idprom.c idprom needs-count
|
|||
#
|
||||
# Console (zs) related stuff
|
||||
#
|
||||
file arch/sun3/dev/kbd.c zs
|
||||
file arch/sun3/dev/event.c zs
|
||||
file arch/sun3/dev/kd.c zs
|
||||
file arch/sun3/dev/ms.c zs
|
||||
file arch/sun3/dev/fb.c
|
||||
device zsc at obio {channel = -1}
|
||||
file arch/sun3/dev/zs.c zsc needs-flag
|
||||
file dev/ic/z8530sc.c zsc
|
||||
|
||||
device zstty at zsc: tty
|
||||
file dev/ic/z8530tty.c zstty needs-flag
|
||||
|
||||
define zsevent
|
||||
file dev/sun/event.c zsevent
|
||||
|
||||
device kbd at zsc: zsevent
|
||||
file dev/sun/kbd.c kbd needs-flag
|
||||
file dev/sun/kbd_tables.c kbd
|
||||
file arch/sun3/dev/kd.c kbd
|
||||
|
||||
device ms at zsc: zsevent
|
||||
file dev/sun/ms.c ms needs-flag
|
||||
|
||||
|
||||
# RAM Disk for boot tape
|
||||
device rd at mainbus
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: std.sun3,v 1.13 1995/10/08 23:38:46 gwr Exp $
|
||||
# $NetBSD: std.sun3,v 1.14 1996/01/24 22:39:56 gwr Exp $
|
||||
|
||||
# Standard information for sun3's.
|
||||
machine sun3 m68k
|
||||
|
@ -25,11 +25,16 @@ vmel0 at mainbus?
|
|||
idprom0 at obctl? addr ?
|
||||
|
||||
# OBIO
|
||||
zs0 at obio? addr ?
|
||||
zs1 at obio? addr ?
|
||||
eeprom0 at obio? addr ?
|
||||
clock0 at obio? addr ?
|
||||
|
||||
# Console (zs) stuff
|
||||
zsc0 at obio? addr ?
|
||||
zsc1 at obio? addr ?
|
||||
kbd0 at zsc0 channel 0
|
||||
ms0 at zsc0 channel 1
|
||||
zstty* at zsc? channel ?
|
||||
|
||||
# Standard defines
|
||||
|
||||
# XXX - Still needed?
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
/* $NetBSD: event.c,v 1.4 1994/12/01 22:46:23 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)event.c 8.1 (Berkeley) 6/11/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internal `Firm_event' interface for the keyboard and mouse drivers.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <machine/vuid_event.h>
|
||||
#include "event_var.h"
|
||||
|
||||
/*
|
||||
* Initialize a firm_event queue.
|
||||
*/
|
||||
void
|
||||
ev_init(ev)
|
||||
register struct evvar *ev;
|
||||
{
|
||||
|
||||
ev->ev_get = ev->ev_put = 0;
|
||||
ev->ev_q = malloc((u_long)EV_QSIZE * sizeof(struct firm_event),
|
||||
M_DEVBUF, M_WAITOK);
|
||||
bzero((caddr_t)ev->ev_q, EV_QSIZE * sizeof(struct firm_event));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tear down a firm_event queue.
|
||||
*/
|
||||
void
|
||||
ev_fini(ev)
|
||||
register struct evvar *ev;
|
||||
{
|
||||
|
||||
free(ev->ev_q, M_DEVBUF);
|
||||
}
|
||||
|
||||
/*
|
||||
* User-level interface: read, select.
|
||||
* (User cannot write an event queue.)
|
||||
*/
|
||||
int
|
||||
ev_read(ev, uio, flags)
|
||||
register struct evvar *ev;
|
||||
struct uio *uio;
|
||||
int flags;
|
||||
{
|
||||
int s, n, cnt, error;
|
||||
|
||||
/*
|
||||
* Make sure we can return at least 1.
|
||||
*/
|
||||
if (uio->uio_resid < sizeof(struct firm_event))
|
||||
return (EMSGSIZE); /* ??? */
|
||||
s = splev();
|
||||
while (ev->ev_get == ev->ev_put) {
|
||||
if (flags & IO_NDELAY) {
|
||||
splx(s);
|
||||
return (EWOULDBLOCK);
|
||||
}
|
||||
ev->ev_wanted = 1;
|
||||
error = tsleep((caddr_t)ev, PEVENT | PCATCH, "firm_event", 0);
|
||||
if (error) {
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Move firm_events from tail end of queue (there is at least one
|
||||
* there).
|
||||
*/
|
||||
if (ev->ev_put < ev->ev_get)
|
||||
cnt = EV_QSIZE - ev->ev_get; /* events in [get..QSIZE) */
|
||||
else
|
||||
cnt = ev->ev_put - ev->ev_get; /* events in [get..put) */
|
||||
splx(s);
|
||||
n = howmany(uio->uio_resid, sizeof(struct firm_event));
|
||||
if (cnt > n)
|
||||
cnt = n;
|
||||
error = uiomove((caddr_t)&ev->ev_q[ev->ev_get],
|
||||
cnt * sizeof(struct firm_event), uio);
|
||||
n -= cnt;
|
||||
/*
|
||||
* If we do not wrap to 0, used up all our space, or had an error,
|
||||
* stop. Otherwise move from front of queue to put index, if there
|
||||
* is anything there to move.
|
||||
*/
|
||||
if ((ev->ev_get = (ev->ev_get + cnt) % EV_QSIZE) != 0 ||
|
||||
n == 0 || error || (cnt = ev->ev_put) == 0)
|
||||
return (error);
|
||||
if (cnt > n)
|
||||
cnt = n;
|
||||
error = uiomove((caddr_t)&ev->ev_q[0],
|
||||
cnt * sizeof(struct firm_event), uio);
|
||||
ev->ev_get = cnt;
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ev_select(ev, rw, p)
|
||||
register struct evvar *ev;
|
||||
int rw;
|
||||
struct proc *p;
|
||||
{
|
||||
int s = splev();
|
||||
|
||||
switch (rw) {
|
||||
|
||||
case FREAD:
|
||||
/* succeed if there is something to read */
|
||||
if (ev->ev_get != ev->ev_put) {
|
||||
splx(s);
|
||||
return (1);
|
||||
}
|
||||
selrecord(p, &ev->ev_sel);
|
||||
break;
|
||||
|
||||
case FWRITE:
|
||||
return (1); /* always fails => never blocks */
|
||||
}
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/* $NetBSD: event_var.h,v 1.3 1994/11/21 21:30:47 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* from: @(#)event_var.h 8.1 (Berkeley) 6/11/93
|
||||
* from: Hdr: event_var.h,v 1.5 92/11/26 01:11:51 torek Exp (LBL)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internal `Firm_event' interface for the keyboard and mouse drivers.
|
||||
* The drivers are expected not to place events in the queue above spltty(),
|
||||
* i.e., are expected to run off serial ports.
|
||||
*/
|
||||
|
||||
/* EV_QSIZE should be a power of two so that `%' is fast */
|
||||
#define EV_QSIZE 256 /* may need tuning; this uses 2k */
|
||||
|
||||
struct evvar {
|
||||
u_int ev_get; /* get (read) index (modified synchronously) */
|
||||
volatile u_int ev_put; /* put (write) index (modified by interrupt) */
|
||||
struct selinfo ev_sel; /* process selecting */
|
||||
struct proc *ev_io; /* process that opened queue (can get SIGIO) */
|
||||
char ev_wanted; /* wake up on input ready */
|
||||
char ev_async; /* send SIGIO on input ready */
|
||||
struct firm_event *ev_q;/* circular buffer (queue) of events */
|
||||
};
|
||||
|
||||
#define splev() spltty()
|
||||
|
||||
#define EV_WAKEUP(ev) { \
|
||||
selwakeup(&(ev)->ev_sel); \
|
||||
if ((ev)->ev_wanted) { \
|
||||
(ev)->ev_wanted = 0; \
|
||||
wakeup((caddr_t)(ev)); \
|
||||
} \
|
||||
if ((ev)->ev_async) \
|
||||
psignal((ev)->ev_io, SIGIO); \
|
||||
}
|
||||
|
||||
void ev_init __P((struct evvar *));
|
||||
void ev_fini __P((struct evvar *));
|
||||
int ev_read __P((struct evvar *, struct uio *, int));
|
||||
int ev_select __P((struct evvar *, int, struct proc *));
|
||||
|
||||
/*
|
||||
* PEVENT is set just above PSOCK, which is just above TTIPRI, on the
|
||||
* theory that mouse and keyboard `user' input should be quick.
|
||||
*/
|
||||
#define PEVENT 23
|
|
@ -1,808 +0,0 @@
|
|||
/* $NetBSD: kbd.c,v 1.11 1995/10/08 23:40:42 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)kbd.c 8.2 (Berkeley) 10/30/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Keyboard driver (/dev/kbd -- note that we do not have minor numbers
|
||||
* [yet?]). Translates incoming bytes to ASCII or to `firm_events' and
|
||||
* passes them up to the appropriate reader.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/tty.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/kbd.h>
|
||||
#include <machine/kbio.h>
|
||||
#include <machine/vuid_event.h>
|
||||
|
||||
#include "event_var.h"
|
||||
|
||||
/*
|
||||
* Sun keyboard definitions (from Sprite).
|
||||
* These apply to type 2, 3 and 4 keyboards.
|
||||
*/
|
||||
#define KEY_CODE(c) ((c) & KBD_KEYMASK) /* keyboard code index */
|
||||
#define KEY_UP(c) ((c) & KBD_UP) /* true => key went up */
|
||||
|
||||
/*
|
||||
* Each KEY_CODE(x) can be translated via the tables below.
|
||||
* The result is either a valid ASCII value in [0..0x7f] or is one
|
||||
* of the following `magic' values saying something interesting
|
||||
* happened. If LSHIFT or RSHIFT has changed state the next
|
||||
* lookup should come from the appropriate table; if ALLUP is
|
||||
* sent all keys (including both shifts and the control key) are
|
||||
* now up, and the next byte is the keyboard ID code.
|
||||
*
|
||||
* These tables ignore all function keys (on the theory that if you
|
||||
* want these keys, you should use a window system). Note that
|
||||
* `caps lock' is just mapped as `ignore' (so there!). (Only the
|
||||
* type 3 and 4 keyboards have a caps lock key anyway.)
|
||||
*/
|
||||
#define KEY_MAGIC 0x80 /* flag => magic value */
|
||||
#define KEY_IGNORE 0x80
|
||||
#define KEY_L1 KEY_IGNORE
|
||||
#define KEY_CAPSLOCK KEY_IGNORE
|
||||
#define KEY_LSHIFT 0x81
|
||||
#define KEY_RSHIFT 0x82
|
||||
#define KEY_CONTROL 0x83
|
||||
#define KEY_ALLUP 0x84 /* all keys are now up; also reset */
|
||||
|
||||
/*
|
||||
* Decode tables for type 2, 3, and 4 keyboards
|
||||
* (stolen from Sprite; see also kbd.h).
|
||||
*/
|
||||
static u_char kbd_unshifted[] = {
|
||||
/* 0 */ KEY_IGNORE, KEY_L1, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 4 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 8 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 12 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 16 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 20 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 24 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 28 */ KEY_IGNORE, '\033', '1', '2',
|
||||
/* 32 */ '3', '4', '5', '6',
|
||||
/* 36 */ '7', '8', '9', '0',
|
||||
/* 40 */ '-', '=', '`', '\b',
|
||||
/* 44 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 48 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 52 */ KEY_IGNORE, '\t', 'q', 'w',
|
||||
/* 56 */ 'e', 'r', 't', 'y',
|
||||
/* 60 */ 'u', 'i', 'o', 'p',
|
||||
/* 64 */ '[', ']', '\177', KEY_IGNORE,
|
||||
/* 68 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 72 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 76 */ KEY_CONTROL, 'a', 's', 'd',
|
||||
/* 80 */ 'f', 'g', 'h', 'j',
|
||||
/* 84 */ 'k', 'l', ';', '\'',
|
||||
/* 88 */ '\\', '\r', KEY_IGNORE, KEY_IGNORE,
|
||||
/* 92 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 96 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_LSHIFT,
|
||||
/* 100 */ 'z', 'x', 'c', 'v',
|
||||
/* 104 */ 'b', 'n', 'm', ',',
|
||||
/* 108 */ '.', '/', KEY_RSHIFT, '\n',
|
||||
/* 112 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 116 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_CAPSLOCK,
|
||||
/* 120 */ KEY_IGNORE, ' ', KEY_IGNORE, KEY_IGNORE,
|
||||
/* 124 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_ALLUP,
|
||||
};
|
||||
|
||||
static u_char kbd_shifted[] = {
|
||||
/* 0 */ KEY_IGNORE, KEY_L1, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 4 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 8 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 12 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 16 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 20 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 24 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 28 */ KEY_IGNORE, '\033', '!', '@',
|
||||
/* 32 */ '#', '$', '%', '^',
|
||||
/* 36 */ '&', '*', '(', ')',
|
||||
/* 40 */ '_', '+', '~', '\b',
|
||||
/* 44 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 48 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 52 */ KEY_IGNORE, '\t', 'Q', 'W',
|
||||
/* 56 */ 'E', 'R', 'T', 'Y',
|
||||
/* 60 */ 'U', 'I', 'O', 'P',
|
||||
/* 64 */ '{', '}', '\177', KEY_IGNORE,
|
||||
/* 68 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 72 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 76 */ KEY_CONTROL, 'A', 'S', 'D',
|
||||
/* 80 */ 'F', 'G', 'H', 'J',
|
||||
/* 84 */ 'K', 'L', ':', '"',
|
||||
/* 88 */ '|', '\r', KEY_IGNORE, KEY_IGNORE,
|
||||
/* 92 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 96 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_LSHIFT,
|
||||
/* 100 */ 'Z', 'X', 'C', 'V',
|
||||
/* 104 */ 'B', 'N', 'M', '<',
|
||||
/* 108 */ '>', '?', KEY_RSHIFT, '\n',
|
||||
/* 112 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 116 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_CAPSLOCK,
|
||||
/* 120 */ KEY_IGNORE, ' ', KEY_IGNORE, KEY_IGNORE,
|
||||
/* 124 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_ALLUP,
|
||||
};
|
||||
|
||||
/*
|
||||
* We need to remember the state of the keyboard's shift and control
|
||||
* keys, and we need a per-type translation table.
|
||||
*/
|
||||
struct kbd_state {
|
||||
const u_char *kbd_unshifted; /* unshifted keys */
|
||||
const u_char *kbd_shifted; /* shifted keys */
|
||||
const u_char *kbd_cur; /* current keys (either of the preceding) */
|
||||
union {
|
||||
char c[2]; /* left and right shift keys */
|
||||
short s; /* true => either shift key */
|
||||
} kbd_shift;
|
||||
#define kbd_lshift kbd_shift.c[0]
|
||||
#define kbd_rshift kbd_shift.c[1]
|
||||
#define kbd_anyshift kbd_shift.s
|
||||
char kbd_control; /* true => ctrl down */
|
||||
char kbd_click; /* true => keyclick enabled */
|
||||
char kbd_takeid; /* take next byte as ID */
|
||||
u_char kbd_id; /* a place to store the ID */
|
||||
char kbd_leds; /* LED state */
|
||||
char _pad;
|
||||
};
|
||||
|
||||
/*
|
||||
* Keyboard driver state. The ascii and kbd links go up and down and
|
||||
* we just sit in the middle doing translation. Note that it is possible
|
||||
* to get just one of the two links, in which case /dev/kbd is unavailable.
|
||||
* The downlink supplies us with `internal' open and close routines which
|
||||
* will enable dataflow across the downlink. We promise to call open when
|
||||
* we are willing to take keystrokes, and to call close when we are not.
|
||||
* If /dev/kbd is not the console tty input source, we do this whenever
|
||||
* /dev/kbd is in use; otherwise we just leave it open forever.
|
||||
*/
|
||||
struct kbd_softc {
|
||||
struct tty *k_cons; /* uplink for ASCII data to console */
|
||||
struct tty *k_kbd; /* downlink for output to keyboard */
|
||||
void (*k_open) __P((struct tty *)); /* enable dataflow */
|
||||
void (*k_close) __P((struct tty *)); /* disable dataflow */
|
||||
int k_evmode; /* set if we should produce events */
|
||||
int k_isopen; /* set if open has been done */
|
||||
struct kbd_state k_state; /* ASCII decode state */
|
||||
struct evvar k_events; /* event queue state */
|
||||
int k_repeatc; /* repeated character */
|
||||
int k_repeating; /* we've called timeout() */
|
||||
} kbd_softc;
|
||||
|
||||
/* Prototypes */
|
||||
void kbd_ascii(struct tty *);
|
||||
void kbd_serial(struct tty *, void (*)(), void (*)());
|
||||
int kbd_iopen(void);
|
||||
void kbd_reset(struct kbd_softc *);
|
||||
int kbd_translate(int);
|
||||
void kbd_rint(int);
|
||||
int kbdopen(dev_t, int, int, struct proc *);
|
||||
int kbdclose(dev_t, int, int, struct proc *);
|
||||
int kbdread(dev_t, struct uio *, int);
|
||||
int kbdwrite(dev_t, struct uio *, int);
|
||||
int kbdioctl(dev_t, u_long, caddr_t, int, struct proc *);
|
||||
int kbdselect(dev_t, int, struct proc *);
|
||||
int kbd_docmd(int, int);
|
||||
|
||||
/* set in kbdattach() */
|
||||
int kbd_repeat_start;
|
||||
int kbd_repeat_step;
|
||||
|
||||
/*
|
||||
* Initialization done by either kdcninit or kbd_iopen
|
||||
*/
|
||||
void
|
||||
kbd_init_tables()
|
||||
{
|
||||
struct kbd_state *ks;
|
||||
|
||||
ks = &kbd_softc.k_state;
|
||||
if (ks->kbd_cur == NULL) {
|
||||
ks->kbd_cur = kbd_unshifted;
|
||||
ks->kbd_unshifted = kbd_unshifted;
|
||||
ks->kbd_shifted = kbd_shifted;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach the console keyboard ASCII (up-link) interface.
|
||||
* This is called by the "kd" (keyboard/display) driver to
|
||||
* tell this module where to send read-side data.
|
||||
*/
|
||||
void
|
||||
kbd_ascii(struct tty *tp)
|
||||
{
|
||||
kbd_softc.k_cons = tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach the console keyboard serial (down-link) interface.
|
||||
* This is called by the "zs" driver for the keyboard port
|
||||
* to tell this module how to talk to the keyboard.
|
||||
*/
|
||||
void
|
||||
kbd_serial(struct tty *tp, void (*iopen)(), void (*iclose)())
|
||||
{
|
||||
register struct kbd_softc *k;
|
||||
|
||||
k = &kbd_softc;
|
||||
k->k_kbd = tp;
|
||||
k->k_open = iopen;
|
||||
k->k_close = iclose;
|
||||
|
||||
/* Do this before any calls to kbd_rint(). */
|
||||
kbd_init_tables();
|
||||
|
||||
/* Now attach the (kd) pseudo-driver. */
|
||||
kd_attach(1); /* This calls kbd_ascii() */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization to be done at first open.
|
||||
* This is called from kbdopen or kdopen (in kd.c)
|
||||
*/
|
||||
int
|
||||
kbd_iopen()
|
||||
{
|
||||
struct kbd_softc *k;
|
||||
struct tty *tp;
|
||||
int error, s;
|
||||
|
||||
k = &kbd_softc;
|
||||
|
||||
/* Tolerate extra calls. */
|
||||
if (k->k_isopen)
|
||||
return (0);
|
||||
|
||||
/* Make sure "down" link (to zs1a) is established. */
|
||||
tp = k->k_kbd;
|
||||
if (tp == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
kbd_repeat_start = hz/2;
|
||||
kbd_repeat_step = hz/20;
|
||||
|
||||
/* Open the "down" link (never to be closed). */
|
||||
tp->t_ispeed = tp->t_ospeed = 1200;
|
||||
(*k->k_open)(tp);
|
||||
|
||||
/* Reset the keyboard and find out its type. */
|
||||
s = spltty();
|
||||
(void) ttyoutput(KBD_CMD_RESET, tp);
|
||||
(*tp->t_oproc)(tp);
|
||||
/* The wakeup for this sleep is in kbd_reset(). */
|
||||
error = tsleep((caddr_t)k, PZERO | PCATCH,
|
||||
devopn, hz);
|
||||
if (error == EWOULDBLOCK) { /* no response */
|
||||
log(LOG_ERR, "keyboard reset failed\n");
|
||||
/*
|
||||
* Allow the open anyway (to keep getty happy)
|
||||
* but assume the "least common denominator".
|
||||
*/
|
||||
k->k_state.kbd_id = KB_SUN2;
|
||||
error = 0;
|
||||
}
|
||||
|
||||
if (error == 0)
|
||||
k->k_isopen = 1;
|
||||
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
kbd_reset(k)
|
||||
struct kbd_softc *k;
|
||||
{
|
||||
struct kbd_state *ks;
|
||||
|
||||
ks = &k->k_state;
|
||||
|
||||
/*
|
||||
* On first identification, wake up anyone waiting for type
|
||||
* and set up the table pointers.
|
||||
*/
|
||||
if (k->k_isopen == 0)
|
||||
wakeup((caddr_t)k);
|
||||
|
||||
/* Restore keyclick, if necessary */
|
||||
switch (ks->kbd_id) {
|
||||
|
||||
case KB_SUN2:
|
||||
/* Type 2 keyboards don't support keyclick */
|
||||
break;
|
||||
|
||||
case KB_SUN3:
|
||||
/* Type 3 keyboards come up with keyclick on */
|
||||
if (!ks->kbd_click)
|
||||
(void) kbd_docmd(KBD_CMD_NOCLICK, 0);
|
||||
break;
|
||||
|
||||
case KB_SUN4:
|
||||
/* Type 4 keyboards come up with keyclick off */
|
||||
if (ks->kbd_click)
|
||||
(void) kbd_docmd(KBD_CMD_CLICK, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* LEDs are off after reset. */
|
||||
ks->kbd_leds = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn keyboard up/down codes into ASCII.
|
||||
*/
|
||||
int
|
||||
kbd_translate(register int c)
|
||||
{
|
||||
register struct kbd_state *ks;
|
||||
register int down;
|
||||
|
||||
ks = &kbd_softc.k_state;
|
||||
if (ks->kbd_cur == NULL) {
|
||||
/*
|
||||
* Do not know how to translate yet.
|
||||
* We will find out when a RESET comes along.
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
down = !KEY_UP(c);
|
||||
c = ks->kbd_cur[KEY_CODE(c)];
|
||||
if (c & KEY_MAGIC) {
|
||||
switch (c) {
|
||||
|
||||
case KEY_LSHIFT:
|
||||
ks->kbd_lshift = down;
|
||||
break;
|
||||
|
||||
case KEY_RSHIFT:
|
||||
ks->kbd_rshift = down;
|
||||
break;
|
||||
|
||||
case KEY_ALLUP:
|
||||
ks->kbd_anyshift = 0;
|
||||
ks->kbd_control = 0;
|
||||
break;
|
||||
|
||||
case KEY_CONTROL:
|
||||
ks->kbd_control = down;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case KEY_IGNORE:
|
||||
return (-1);
|
||||
|
||||
default:
|
||||
panic("kbd_translate");
|
||||
}
|
||||
if (ks->kbd_anyshift)
|
||||
ks->kbd_cur = ks->kbd_shifted;
|
||||
else
|
||||
ks->kbd_cur = ks->kbd_unshifted;
|
||||
return (-1);
|
||||
}
|
||||
if (!down)
|
||||
return (-1);
|
||||
if (ks->kbd_control) {
|
||||
/* control space and unshifted control atsign return null */
|
||||
if (c == ' ' || c == '2')
|
||||
return (0);
|
||||
/* unshifted control hat */
|
||||
if (c == '6')
|
||||
return ('^' & 0x1f);
|
||||
/* standard controls */
|
||||
if (c >= '@' && c < 0x7f)
|
||||
return (c & 0x1f);
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
|
||||
void
|
||||
kbd_repeat(void *arg)
|
||||
{
|
||||
struct kbd_softc *k = (struct kbd_softc *)arg;
|
||||
int s = spltty();
|
||||
|
||||
if (k->k_repeating && k->k_repeatc >= 0 && k->k_cons != NULL) {
|
||||
ttyinput(k->k_repeatc, k->k_cons);
|
||||
timeout(kbd_repeat, k, kbd_repeat_step);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
kbd_rint(register int c)
|
||||
{
|
||||
register struct kbd_softc *k = &kbd_softc;
|
||||
register struct firm_event *fe;
|
||||
register int put;
|
||||
|
||||
if (k->k_repeating) {
|
||||
k->k_repeating = 0;
|
||||
untimeout(kbd_repeat, k);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset keyboard after serial port overrun, so we can resynch.
|
||||
*/
|
||||
if (c & (TTY_FE|TTY_PE)) {
|
||||
log(LOG_ERR, "keyboard input error (0x%x)\n", c);
|
||||
(void) ttyoutput(KBD_CMD_RESET, k->k_kbd);
|
||||
(*k->k_kbd->t_oproc)(k->k_kbd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read the keyboard id if we read a KBD_RESET last time */
|
||||
if (k->k_state.kbd_takeid) {
|
||||
k->k_state.kbd_takeid = 0;
|
||||
k->k_state.kbd_id = c;
|
||||
kbd_reset(k);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we have been reset, setup to grab the keyboard id next time */
|
||||
if (c == KBD_RESET) {
|
||||
k->k_state.kbd_takeid = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If /dev/kbd is not connected in event mode, but we are sending
|
||||
* data to /dev/console, translate and send upstream. Note that
|
||||
* we will get this while opening /dev/kbd if it is not already
|
||||
* open and we do not know its type.
|
||||
*/
|
||||
if (!k->k_evmode) {
|
||||
c = kbd_translate(c);
|
||||
if (c >= 0 && k->k_cons != NULL) {
|
||||
ttyinput(c, k->k_cons);
|
||||
k->k_repeating = 1;
|
||||
k->k_repeatc = c;
|
||||
timeout(kbd_repeat, k, kbd_repeat_start);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* IDLEs confuse the MIT X11R4 server badly, so we must drop them.
|
||||
* This is bad as it means the server will not automatically resync
|
||||
* on all-up IDLEs, but I did not drop them before, and the server
|
||||
* goes crazy when it comes time to blank the screen....
|
||||
*/
|
||||
if (c == KBD_IDLE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Keyboard is generating events. Turn this keystroke into an
|
||||
* event and put it in the queue. If the queue is full, the
|
||||
* keystroke is lost (sorry!).
|
||||
*/
|
||||
put = k->k_events.ev_put;
|
||||
fe = &k->k_events.ev_q[put];
|
||||
put = (put + 1) % EV_QSIZE;
|
||||
if (put == k->k_events.ev_get) {
|
||||
log(LOG_WARNING, "keyboard event queue overflow\n"); /* ??? */
|
||||
return;
|
||||
}
|
||||
fe->id = KEY_CODE(c);
|
||||
fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN;
|
||||
fe->time = time;
|
||||
k->k_events.ev_put = put;
|
||||
EV_WAKEUP(&k->k_events);
|
||||
}
|
||||
|
||||
int
|
||||
kbdopen(dev_t dev, int flags, int mode, struct proc *p)
|
||||
{
|
||||
int error;
|
||||
|
||||
#if 1 /* XXX - temporary hack */
|
||||
/* XXX - Should make login chown devices in /etc/fbtab */
|
||||
/* Require root or same UID as the kd session leader. */
|
||||
if (p->p_ucred->cr_uid) {
|
||||
struct tty *kd_tp;
|
||||
struct proc *kd_p;
|
||||
extern struct tty *kdtty();
|
||||
|
||||
/* Make sure kd is attached and open. */
|
||||
kd_tp = kdtty(0);
|
||||
if ((kd_tp == NULL) || (kd_tp->t_session == NULL))
|
||||
return (EPERM);
|
||||
kd_p = kd_tp->t_session->s_leader;
|
||||
if (p->p_ucred->cr_uid != kd_p->p_ucred->cr_uid)
|
||||
return (EACCES);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Exclusive open required for /dev/kbd */
|
||||
if (kbd_softc.k_events.ev_io)
|
||||
return (EBUSY);
|
||||
kbd_softc.k_events.ev_io = p;
|
||||
|
||||
if ((error = kbd_iopen()) != 0) {
|
||||
kbd_softc.k_events.ev_io = NULL;
|
||||
return (error);
|
||||
}
|
||||
ev_init(&kbd_softc.k_events);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
kbdclose(dev_t dev, int flags, int mode, struct proc *p)
|
||||
{
|
||||
|
||||
/*
|
||||
* Turn off event mode, dump the queue, and close the keyboard
|
||||
* unless it is supplying console input.
|
||||
*/
|
||||
kbd_softc.k_evmode = 0;
|
||||
ev_fini(&kbd_softc.k_events);
|
||||
kbd_softc.k_events.ev_io = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
kbdread(dev_t dev, struct uio *uio, int flags)
|
||||
{
|
||||
|
||||
return (ev_read(&kbd_softc.k_events, uio, flags));
|
||||
}
|
||||
|
||||
/* this routine should not exist, but is convenient to write here for now */
|
||||
int
|
||||
kbdwrite(dev_t dev, struct uio *uio, int flags)
|
||||
{
|
||||
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int
|
||||
kbdioctl(dev_t dev, u_long cmd, register caddr_t data,
|
||||
int flag, struct proc *p)
|
||||
{
|
||||
register struct kbd_softc *k = &kbd_softc;
|
||||
register struct kiockey *kmp;
|
||||
register u_char *tp;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case KIOCTRANS:
|
||||
if (*(int *)data == TR_UNTRANS_EVENT)
|
||||
return (0);
|
||||
break;
|
||||
|
||||
case KIOCGTRANS:
|
||||
/*
|
||||
* Get translation mode
|
||||
*/
|
||||
*(int *)data = TR_UNTRANS_EVENT;
|
||||
return (0);
|
||||
|
||||
case KIOCGETKEY:
|
||||
if (((struct okiockey *)data)->kio_station == 118) {
|
||||
/*
|
||||
* This is X11 asking if a type 3 keyboard is
|
||||
* really a type 3 keyboard. Say yes.
|
||||
*/
|
||||
((struct okiockey *)data)->kio_entry = HOLE;
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
|
||||
case KIOCSKEY:
|
||||
kmp = (struct kiockey *)data;
|
||||
|
||||
switch (kmp->kio_tablemask) {
|
||||
case KIOC_NOMASK:
|
||||
tp = kbd_unshifted;
|
||||
break;
|
||||
case KIOC_SHIFTMASK:
|
||||
tp = kbd_shifted;
|
||||
break;
|
||||
default:
|
||||
/* Silently ignore unsupported masks */
|
||||
return (0);
|
||||
}
|
||||
if (kmp->kio_entry & 0xff80)
|
||||
/* Silently ignore funny entries */
|
||||
return (0);
|
||||
|
||||
tp[kmp->kio_station] = kmp->kio_entry;
|
||||
return (0);
|
||||
|
||||
case KIOCGKEY:
|
||||
kmp = (struct kiockey *)data;
|
||||
|
||||
switch (kmp->kio_tablemask) {
|
||||
case KIOC_NOMASK:
|
||||
tp = kbd_unshifted;
|
||||
break;
|
||||
case KIOC_SHIFTMASK:
|
||||
tp = kbd_shifted;
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
kmp->kio_entry = tp[kmp->kio_station] & ~KEY_MAGIC;
|
||||
return (0);
|
||||
|
||||
case KIOCCMD:
|
||||
/*
|
||||
* ``unimplemented commands are ignored'' (blech)
|
||||
* so cannot check return value from kbd_docmd
|
||||
*/
|
||||
#ifdef notyet
|
||||
while (kbd_docmd(*(int *)data, 1) == ENOSPC) /*ERESTART?*/
|
||||
(void) sleep((caddr_t)&lbolt, TTOPRI);
|
||||
#else
|
||||
(void) kbd_docmd(*(int *)data, 1);
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
case KIOCTYPE:
|
||||
*(int *)data = k->k_state.kbd_id;
|
||||
return (0);
|
||||
|
||||
case KIOCSDIRECT:
|
||||
k->k_evmode = *(int *)data;
|
||||
return (0);
|
||||
|
||||
case KIOCLAYOUT:
|
||||
*data = 0;
|
||||
return (0);
|
||||
|
||||
case KIOCSLED:
|
||||
if (k->k_state.kbd_id != KB_SUN4) {
|
||||
/* xxx NYI */
|
||||
k->k_state.kbd_leds = *(char*)data;
|
||||
} else {
|
||||
int s;
|
||||
char leds = *(char *)data;
|
||||
struct tty *tp = kbd_softc.k_kbd;
|
||||
s = spltty();
|
||||
if (tp->t_outq.c_cc > 120)
|
||||
(void) tsleep((caddr_t)&lbolt, TTIPRI,
|
||||
ttyout, 0);
|
||||
splx(s);
|
||||
if (ttyoutput(KBD_CMD_SETLED, tp) >= 0)
|
||||
return (ENOSPC); /* ERESTART? */
|
||||
k->k_state.kbd_leds = leds;
|
||||
if (ttyoutput(leds, tp) >= 0)
|
||||
return (ENOSPC); /* ERESTART? */
|
||||
(*tp->t_oproc)(tp);
|
||||
}
|
||||
return (0);
|
||||
|
||||
case KIOCGLED:
|
||||
*(char *)data = k->k_state.kbd_leds;
|
||||
return (0);
|
||||
|
||||
case FIONBIO: /* we will remove this someday (soon???) */
|
||||
return (0);
|
||||
|
||||
case FIOASYNC:
|
||||
k->k_events.ev_async = *(int *)data != 0;
|
||||
return (0);
|
||||
|
||||
case TIOCSPGRP:
|
||||
if (*(int *)data != k->k_events.ev_io->p_pgid)
|
||||
return (EPERM);
|
||||
return (0);
|
||||
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
|
||||
/*
|
||||
* We identified the ioctl, but we do not handle it.
|
||||
*/
|
||||
return (EOPNOTSUPP); /* misuse, but what the heck */
|
||||
}
|
||||
|
||||
int
|
||||
kbdselect(dev_t dev, int rw, struct proc *p)
|
||||
{
|
||||
|
||||
return (ev_select(&kbd_softc.k_events, rw, p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a keyboard command; return 0 on success.
|
||||
* If `isuser', force a small delay before output if output queue
|
||||
* is flooding. (The keyboard runs at 1200 baud, or 120 cps.)
|
||||
*/
|
||||
int
|
||||
kbd_docmd(int cmd, int isuser)
|
||||
{
|
||||
register struct tty *tp = kbd_softc.k_kbd;
|
||||
register struct kbd_softc *k = &kbd_softc;
|
||||
int s;
|
||||
|
||||
if (tp == NULL)
|
||||
return (ENXIO); /* ??? */
|
||||
switch (cmd) {
|
||||
|
||||
case KBD_CMD_BELL:
|
||||
case KBD_CMD_NOBELL:
|
||||
/* Supported by type 2, 3, and 4 keyboards */
|
||||
break;
|
||||
|
||||
case KBD_CMD_CLICK:
|
||||
/* Unsupported by type 2 keyboards */
|
||||
if (k->k_state.kbd_id != KB_SUN2) {
|
||||
k->k_state.kbd_click = 1;
|
||||
break;
|
||||
}
|
||||
return (EINVAL);
|
||||
|
||||
case KBD_CMD_NOCLICK:
|
||||
/* Unsupported by type 2 keyboards */
|
||||
if (k->k_state.kbd_id != KB_SUN2) {
|
||||
k->k_state.kbd_click = 0;
|
||||
break;
|
||||
}
|
||||
return (EINVAL);
|
||||
|
||||
default:
|
||||
return (EINVAL); /* ENOTTY? EOPNOTSUPP? */
|
||||
}
|
||||
|
||||
if (isuser) {
|
||||
s = spltty();
|
||||
if (tp->t_outq.c_cc > 120)
|
||||
(void) tsleep((caddr_t)&lbolt, TTIPRI,
|
||||
ttyout, 0);
|
||||
splx(s);
|
||||
}
|
||||
if (ttyoutput(cmd, tp) >= 0)
|
||||
return (ENOSPC); /* ERESTART? */
|
||||
(*tp->t_oproc)(tp);
|
||||
return (0);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kd.c,v 1.13 1995/04/26 23:20:15 gwr Exp $ */
|
||||
/* $NetBSD: kd.c,v 1.14 1996/01/24 22:40:20 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995 Gordon W. Ross
|
||||
|
@ -53,42 +53,61 @@
|
|||
#include <machine/psl.h>
|
||||
|
||||
#include <dev/cons.h>
|
||||
#include <dev/sun/kbd_xlate.h>
|
||||
|
||||
#define BURST 64
|
||||
#define KDMAJOR 1
|
||||
#define PUT_WSIZE 64
|
||||
|
||||
cdev_decl(kd); /* open, close, read, write, ioctl, stop, ... */
|
||||
|
||||
struct kd_softc {
|
||||
struct device kd_dev; /* required first: base device */
|
||||
struct tty *kd_tty;
|
||||
};
|
||||
|
||||
/*
|
||||
* There is no point in pretending there might be
|
||||
* more than one keyboard/display device.
|
||||
*/
|
||||
struct tty *kd_tty[1];
|
||||
|
||||
int kdopen(dev_t, int, int, struct proc *);
|
||||
int kdclose(dev_t, int, int, struct proc *);
|
||||
int kdread(dev_t, struct uio *, int);
|
||||
int kdwrite(dev_t, struct uio *, int);
|
||||
int kdioctl(dev_t, int, caddr_t, int, struct proc *);
|
||||
struct kd_softc kd_softc;
|
||||
|
||||
static int kdparam(struct tty *, struct termios *);
|
||||
static void kdstart(struct tty *);
|
||||
|
||||
int kd_is_console;
|
||||
|
||||
/* This is called by kbd_serial() like a pseudo-device. */
|
||||
/*
|
||||
* This is called by kbd_attach()
|
||||
* XXX - Make this a proper child of kbd?
|
||||
*/
|
||||
void
|
||||
kd_attach(n)
|
||||
int n;
|
||||
kd_init(unit)
|
||||
int unit;
|
||||
{
|
||||
kd_tty[0] = ttymalloc();
|
||||
struct kd_softc *kd;
|
||||
struct tty *tp;
|
||||
|
||||
/* Tell keyboard module where to send read data. */
|
||||
kbd_ascii(kd_tty[0]);
|
||||
if (unit != 0)
|
||||
return;
|
||||
kd = &kd_softc; /* XXX */
|
||||
tp = ttymalloc();
|
||||
|
||||
kd->kd_tty = tp;
|
||||
tp->t_oproc = kdstart;
|
||||
tp->t_param = kdparam;
|
||||
tp->t_dev = makedev(KDMAJOR, unit);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct tty *
|
||||
kdtty(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
return kd_tty[0];
|
||||
struct kd_softc *kd;
|
||||
|
||||
kd = &kd_softc; /* XXX */
|
||||
return (kd->kd_tty);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -97,39 +116,49 @@ kdopen(dev, flag, mode, p)
|
|||
int flag, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
int error, unit;
|
||||
struct kd_softc *kd;
|
||||
int error, s, unit;
|
||||
struct tty *tp;
|
||||
|
||||
unit = minor(dev);
|
||||
if (unit) return ENXIO;
|
||||
|
||||
tp = kd_tty[unit];
|
||||
if (tp == NULL)
|
||||
if (unit != 0)
|
||||
return ENXIO;
|
||||
kd = &kd_softc; /* XXX */
|
||||
tp = kd->kd_tty;
|
||||
|
||||
if ((error = kbd_iopen()) != 0) {
|
||||
if ((error = kbd_iopen(unit)) != 0) {
|
||||
#ifdef DIAGNOSTIC
|
||||
printf("kd: kbd_iopen, error=%d\n", error);
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
|
||||
tp->t_oproc = kdstart;
|
||||
tp->t_param = kdparam;
|
||||
tp->t_dev = dev;
|
||||
/* It's simpler to do this up here. */
|
||||
if (((tp->t_state & (TS_ISOPEN | TS_XCLUDE))
|
||||
== (TS_ISOPEN | TS_XCLUDE))
|
||||
&& (p->p_ucred->cr_uid != 0) )
|
||||
{
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
s = spltty();
|
||||
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
tp->t_state |= TS_WOPEN;
|
||||
/* First open. */
|
||||
ttychars(tp);
|
||||
tp->t_iflag = TTYDEF_IFLAG;
|
||||
tp->t_oflag = TTYDEF_OFLAG;
|
||||
tp->t_cflag = TTYDEF_CFLAG;
|
||||
tp->t_lflag = TTYDEF_LFLAG;
|
||||
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
|
||||
kdparam(tp, &tp->t_termios);
|
||||
(void) kdparam(tp, &tp->t_termios);
|
||||
ttsetwater(tp);
|
||||
} else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
|
||||
return EBUSY;
|
||||
/* Flush pending input? Clear translator? */
|
||||
/* This (pseudo)device always has SOFTCAR */
|
||||
tp->t_state |= TS_CARR_ON;
|
||||
}
|
||||
|
||||
splx(s);
|
||||
|
||||
return ((*linesw[tp->t_line].l_open)(dev, tp));
|
||||
}
|
||||
|
@ -140,8 +169,15 @@ kdclose(dev, flag, mode, p)
|
|||
int flag, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
int unit = minor(dev);
|
||||
struct tty *tp = kd_tty[unit];
|
||||
struct kd_softc *kd;
|
||||
struct tty *tp;
|
||||
|
||||
kd = &kd_softc; /* XXX */
|
||||
tp = kd->kd_tty;
|
||||
|
||||
/* XXX This is for cons.c. */
|
||||
if ((tp->t_state & TS_ISOPEN) == 0)
|
||||
return 0;
|
||||
|
||||
(*linesw[tp->t_line].l_close)(tp, flag);
|
||||
ttyclose(tp);
|
||||
|
@ -154,8 +190,11 @@ kdread(dev, uio, flag)
|
|||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
int unit = minor(dev);
|
||||
struct tty *tp = kd_tty[unit];
|
||||
struct kd_softc *kd;
|
||||
struct tty *tp;
|
||||
|
||||
kd = &kd_softc; /* XXX */
|
||||
tp = kd->kd_tty;
|
||||
|
||||
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
|
||||
}
|
||||
|
@ -166,31 +205,29 @@ kdwrite(dev, uio, flag)
|
|||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
int unit = minor(dev);
|
||||
struct tty *tp = kd_tty[unit];
|
||||
struct kd_softc *kd;
|
||||
struct tty *tp;
|
||||
|
||||
kd = &kd_softc; /* XXX */
|
||||
tp = kd->kd_tty;
|
||||
|
||||
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
|
||||
}
|
||||
|
||||
int
|
||||
kdstop(tp, flag)
|
||||
struct tty *tp;
|
||||
int flag;
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
kdioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
int cmd;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct kd_softc *kd;
|
||||
struct tty *tp;
|
||||
int error;
|
||||
int unit = minor(dev);
|
||||
struct tty *tp = kd_tty[unit];
|
||||
|
||||
kd = &kd_softc; /* XXX */
|
||||
tp = kd->kd_tty;
|
||||
|
||||
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
|
@ -206,6 +243,28 @@ kdioctl(dev, cmd, data, flag, p)
|
|||
return ENOTTY;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
kdparam(tp, t)
|
||||
struct tty *tp;
|
||||
struct termios *t;
|
||||
{
|
||||
/* XXX - These are ignored... */
|
||||
tp->t_ispeed = t->c_ispeed;
|
||||
tp->t_ospeed = t->c_ospeed;
|
||||
tp->t_cflag = t->c_cflag;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
kdstop(tp, flag)
|
||||
struct tty *tp;
|
||||
int flag;
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void kd_later(void*);
|
||||
static void kd_putfb(struct tty *);
|
||||
|
||||
|
@ -285,12 +344,12 @@ kd_later(tpaddr)
|
|||
static void kd_putfb(tp)
|
||||
struct tty *tp;
|
||||
{
|
||||
char buf[BURST];
|
||||
char buf[PUT_WSIZE];
|
||||
struct clist *cl = &tp->t_outq;
|
||||
char *p, *end;
|
||||
int len;
|
||||
|
||||
while ((len = q_to_b(cl, buf, BURST-1)) > 0) {
|
||||
while ((len = q_to_b(cl, buf, PUT_WSIZE-1)) > 0) {
|
||||
/* PROM will barf if high bits are set. */
|
||||
p = buf;
|
||||
end = buf + len;
|
||||
|
@ -300,70 +359,98 @@ static void kd_putfb(tp)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
kdparam(tp, t)
|
||||
struct tty *tp;
|
||||
struct termios *t;
|
||||
{
|
||||
/* XXX - These are ignored... */
|
||||
tp->t_ispeed = t->c_ispeed;
|
||||
tp->t_ospeed = t->c_ospeed;
|
||||
tp->t_cflag = t->c_cflag;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* kd console support
|
||||
* Our "interrupt" routine for input.
|
||||
*/
|
||||
|
||||
extern int zscnprobe_kbd(), zscngetc(), kbd_translate();
|
||||
|
||||
kdcnprobe(cp)
|
||||
struct consdev *cp;
|
||||
void
|
||||
kd_input(c)
|
||||
int c;
|
||||
{
|
||||
int maj;
|
||||
struct kd_softc *kd = &kd_softc;
|
||||
struct tty *tp;
|
||||
|
||||
/* locate the major number */
|
||||
for (maj = 0; maj < nchrdev; maj++)
|
||||
if (cdevsw[maj].d_open == (void*)kdopen)
|
||||
break;
|
||||
/* XXX: Make sure the device is open. */
|
||||
tp = kd->kd_tty;
|
||||
if (tp == NULL)
|
||||
return;
|
||||
if ((tp->t_state & TS_ISOPEN) == 0)
|
||||
return;
|
||||
|
||||
/* initialize required fields */
|
||||
cp->cn_dev = makedev(maj, 0);
|
||||
cp->cn_pri = zscnprobe_kbd();
|
||||
ttyinput(c, kd->kd_tty);
|
||||
}
|
||||
|
||||
kdcninit(cp)
|
||||
struct consdev *cp;
|
||||
{
|
||||
|
||||
/* This prepares zscngetc() */
|
||||
zs_set_conschan(1, 0);
|
||||
/****************************************************************
|
||||
* kd console support
|
||||
****************************************************************/
|
||||
|
||||
extern void *zs_conschan;
|
||||
extern int zs_getc();
|
||||
extern void nullcnprobe();
|
||||
cons_decl(kd);
|
||||
|
||||
/* The debugger gets its own key translation state. */
|
||||
static struct kbd_state kdcn_state;
|
||||
|
||||
void
|
||||
kdcninit(cn)
|
||||
struct consdev *cn;
|
||||
{
|
||||
struct kbd_state *ks = &kdcn_state;
|
||||
|
||||
mon_printf("console on kd0 (keyboard/display)\n");
|
||||
|
||||
/* This prepares kbd_translate() */
|
||||
kbd_init_tables();
|
||||
ks->kbd_id = KBD_MIN_TYPE;
|
||||
kbd_xlate_init(ks);
|
||||
|
||||
/* Indicate that it is OK to use the PROM fbwrite */
|
||||
kd_is_console = 1;
|
||||
|
||||
mon_printf("console on kd0 (keyboard/display)\n");
|
||||
}
|
||||
|
||||
int
|
||||
kdcngetc(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
int c;
|
||||
struct kbd_state *ks = &kdcn_state;
|
||||
int code, class, data, keysym;
|
||||
|
||||
do {
|
||||
c = zscngetc(0);
|
||||
c = kbd_translate(c);
|
||||
} while (c == -1);
|
||||
for (;;) {
|
||||
code = zs_getc(zs_conschan);
|
||||
keysym = kbd_code_to_keysym(ks, code);
|
||||
class = KEYSYM_CLASS(keysym);
|
||||
|
||||
return (c);
|
||||
switch (class) {
|
||||
case KEYSYM_ASCII:
|
||||
goto out;
|
||||
|
||||
case KEYSYM_CLRMOD:
|
||||
case KEYSYM_SETMOD:
|
||||
data = (keysym & 0x1F);
|
||||
/* Only allow ctrl or shift. */
|
||||
if (data > KBMOD_SHIFT_R)
|
||||
break;
|
||||
data = 1 << data;
|
||||
if (class == KEYSYM_SETMOD)
|
||||
ks->kbd_modbits |= data;
|
||||
else
|
||||
ks->kbd_modbits &= ~data;
|
||||
break;
|
||||
|
||||
case KEYSYM_ALL_UP:
|
||||
/* No toggle keys here. */
|
||||
ks->kbd_modbits = 0;
|
||||
break;
|
||||
|
||||
default: /* ignore all other keysyms */
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return (keysym);
|
||||
}
|
||||
|
||||
void
|
||||
kdcnputc(dev, c)
|
||||
dev_t dev;
|
||||
int c;
|
||||
|
@ -376,6 +463,25 @@ void kdcnpollc(dev, on)
|
|||
dev_t dev;
|
||||
int on;
|
||||
{
|
||||
if (on)
|
||||
struct kbd_state *ks = &kdcn_state;
|
||||
|
||||
if (on) {
|
||||
/* Entering debugger. */
|
||||
fb_unblank();
|
||||
/* Clear shift keys too. */
|
||||
ks->kbd_modbits = 0;
|
||||
} else {
|
||||
/* Resuming kernel. */
|
||||
}
|
||||
}
|
||||
|
||||
struct consdev consdev_kd = {
|
||||
nullcnprobe,
|
||||
kdcninit,
|
||||
kdcngetc,
|
||||
kdcnputc,
|
||||
kdcnpollc,
|
||||
makedev(KDMAJOR, 0),
|
||||
CN_INTERNAL
|
||||
};
|
||||
|
||||
|
|
|
@ -1,358 +0,0 @@
|
|||
/* $NetBSD: ms.c,v 1.6 1995/10/08 23:40:44 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)ms.c 8.1 (Berkeley) 6/11/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mouse driver.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/tty.h>
|
||||
|
||||
#include <machine/vuid_event.h>
|
||||
#include "event_var.h"
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
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 */
|
||||
struct tty *ms_mouse; /* downlink for output to mouse */
|
||||
void (*ms_open) __P((struct tty *)); /* enable dataflow */
|
||||
void (*ms_close) __P((struct tty *));/* disable dataflow */
|
||||
volatile int ms_ready; /* event queue is ready */
|
||||
struct evvar ms_events; /* event queue state */
|
||||
} ms_softc;
|
||||
|
||||
/*
|
||||
* Attach the mouse serial (down-link) interface.
|
||||
*/
|
||||
void
|
||||
ms_serial(tp, iopen, iclose)
|
||||
struct tty *tp;
|
||||
void (*iopen)(), (*iclose)();
|
||||
{
|
||||
|
||||
ms_softc.ms_mouse = tp;
|
||||
ms_softc.ms_open = iopen;
|
||||
ms_softc.ms_close = iclose;
|
||||
}
|
||||
|
||||
void
|
||||
ms_rint(c)
|
||||
register int c;
|
||||
{
|
||||
register struct firm_event *fe;
|
||||
register struct ms_softc *ms = &ms_softc;
|
||||
register int mb, ub, d, get, put, any;
|
||||
static const char to_one[] = { 1, 2, 2, 4, 4, 4, 4 };
|
||||
static const int to_id[] = { MS_RIGHT, MS_MIDDLE, 0, MS_LEFT };
|
||||
|
||||
/*
|
||||
* Discard input if not ready. Drop sync on parity or framing
|
||||
* error; gain sync on button byte.
|
||||
*/
|
||||
if (ms->ms_ready == 0)
|
||||
return;
|
||||
if (c & (TTY_FE|TTY_PE)) {
|
||||
log(LOG_WARNING,
|
||||
"mouse input parity or framing error (0x%x)\n", c);
|
||||
ms->ms_byteno = -1;
|
||||
return;
|
||||
}
|
||||
if ((unsigned)(c - 0x80) < 8) /* if in 0x80..0x87 */
|
||||
ms->ms_byteno = 0;
|
||||
|
||||
/*
|
||||
* Run the decode loop, adding to the current information.
|
||||
* We add, rather than replace, deltas, so that if the event queue
|
||||
* fills, we accumulate data for when it opens up again.
|
||||
*/
|
||||
switch (ms->ms_byteno) {
|
||||
|
||||
case -1:
|
||||
return;
|
||||
|
||||
case 0:
|
||||
/* buttons */
|
||||
ms->ms_byteno = 1;
|
||||
ms->ms_mb = (~c) & 0x7;
|
||||
return;
|
||||
|
||||
case 1:
|
||||
/* first delta-x */
|
||||
ms->ms_byteno = 2;
|
||||
ms->ms_dx += (char)c;
|
||||
return;
|
||||
|
||||
case 2:
|
||||
/* first delta-y */
|
||||
ms->ms_byteno = 3;
|
||||
ms->ms_dy += (char)c;
|
||||
return;
|
||||
|
||||
case 3:
|
||||
/* second delta-x */
|
||||
ms->ms_byteno = 4;
|
||||
ms->ms_dx += (char)c;
|
||||
return;
|
||||
|
||||
case 4:
|
||||
/* second delta-x */
|
||||
ms->ms_byteno = -1; /* wait for button-byte again */
|
||||
ms->ms_dy += (char)c;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("ms_rint");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* We have at least one event (mouse button, delta-X, or
|
||||
* delta-Y; possibly all three, and possibly three separate
|
||||
* button events). Deliver these events until we are out
|
||||
* of changes or out of room. As events get delivered,
|
||||
* mark them `unchanged'.
|
||||
*/
|
||||
any = 0;
|
||||
get = ms->ms_events.ev_get;
|
||||
put = ms->ms_events.ev_put;
|
||||
fe = &ms->ms_events.ev_q[put];
|
||||
|
||||
/* NEXT prepares to put the next event, backing off if necessary */
|
||||
#define NEXT \
|
||||
if ((++put) % EV_QSIZE == get) { \
|
||||
put--; \
|
||||
goto out; \
|
||||
}
|
||||
/* ADVANCE completes the `put' of the event */
|
||||
#define ADVANCE \
|
||||
fe++; \
|
||||
if (put >= EV_QSIZE) { \
|
||||
put = 0; \
|
||||
fe = &ms->ms_events.ev_q[0]; \
|
||||
} \
|
||||
any = 1
|
||||
|
||||
mb = ms->ms_mb;
|
||||
ub = ms->ms_ub;
|
||||
while ((d = mb ^ ub) != 0) {
|
||||
/*
|
||||
* Mouse button change. Convert up to three changes
|
||||
* to the `first' change, and drop it into the event queue.
|
||||
*/
|
||||
NEXT;
|
||||
d = to_one[d - 1]; /* from 1..7 to {1,2,4} */
|
||||
fe->id = to_id[d - 1]; /* from {1,2,4} to ID */
|
||||
fe->value = mb & d ? VKEY_DOWN : VKEY_UP;
|
||||
fe->time = time;
|
||||
ADVANCE;
|
||||
ub ^= d;
|
||||
}
|
||||
if (ms->ms_dx) {
|
||||
NEXT;
|
||||
fe->id = LOC_X_DELTA;
|
||||
fe->value = ms->ms_dx;
|
||||
fe->time = time;
|
||||
ADVANCE;
|
||||
ms->ms_dx = 0;
|
||||
}
|
||||
if (ms->ms_dy) {
|
||||
NEXT;
|
||||
fe->id = LOC_Y_DELTA;
|
||||
fe->value = ms->ms_dy;
|
||||
fe->time = time;
|
||||
ADVANCE;
|
||||
ms->ms_dy = 0;
|
||||
}
|
||||
out:
|
||||
if (any) {
|
||||
ms->ms_ub = ub;
|
||||
ms->ms_events.ev_put = put;
|
||||
EV_WAKEUP(&ms->ms_events);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
msopen(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
int s, error;
|
||||
struct tty *tp;
|
||||
|
||||
#if 1 /* XXX - temporary hack */
|
||||
/* XXX - Should make login chown devices in /etc/fbtab */
|
||||
/* Require root or same UID as the kd session leader. */
|
||||
if (p->p_ucred->cr_uid) {
|
||||
struct tty *kd_tp;
|
||||
struct proc *kd_p;
|
||||
extern struct tty *kdtty();
|
||||
|
||||
/* Make sure kd is attached and open. */
|
||||
kd_tp = kdtty(0);
|
||||
if ((kd_tp == NULL) || (kd_tp->t_session == NULL))
|
||||
return (EPERM);
|
||||
kd_p = kd_tp->t_session->s_leader;
|
||||
if (p->p_ucred->cr_uid != kd_p->p_ucred->cr_uid)
|
||||
return (EACCES);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is an exclusive open device. */
|
||||
if (ms_softc.ms_events.ev_io)
|
||||
return (EBUSY);
|
||||
ms_softc.ms_events.ev_io = p;
|
||||
ev_init(&ms_softc.ms_events); /* may cause sleep */
|
||||
|
||||
tp = ms_softc.ms_mouse;
|
||||
tp->t_ispeed = tp->t_ospeed = 1200;
|
||||
(*ms_softc.ms_open)(tp);
|
||||
|
||||
ms_softc.ms_ready = 1; /* start accepting events */
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
msclose(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
ms_softc.ms_ready = 0; /* stop accepting events */
|
||||
ev_fini(&ms_softc.ms_events);
|
||||
(*ms_softc.ms_close)(ms_softc.ms_mouse);
|
||||
ms_softc.ms_events.ev_io = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
msread(dev, uio, flags)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flags;
|
||||
{
|
||||
|
||||
return (ev_read(&ms_softc.ms_events, uio, flags));
|
||||
}
|
||||
|
||||
/* this routine should not exist, but is convenient to write here for now */
|
||||
int
|
||||
mswrite(dev, uio, flags)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flags;
|
||||
{
|
||||
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int
|
||||
msioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
register caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
int s;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case FIONBIO: /* we will remove this someday (soon???) */
|
||||
return (0);
|
||||
|
||||
case FIOASYNC:
|
||||
ms_softc.ms_events.ev_async = *(int *)data != 0;
|
||||
return (0);
|
||||
|
||||
case TIOCSPGRP:
|
||||
if (*(int *)data != ms_softc.ms_events.ev_io->p_pgid)
|
||||
return (EPERM);
|
||||
return (0);
|
||||
|
||||
case VUIDGFORMAT:
|
||||
/* we only do firm_events */
|
||||
*(int *)data = VUID_FIRM_EVENT;
|
||||
return (0);
|
||||
|
||||
case VUIDSFORMAT:
|
||||
if (*(int *)data != VUID_FIRM_EVENT)
|
||||
return (EINVAL);
|
||||
return (0);
|
||||
}
|
||||
return (ENOTTY);
|
||||
}
|
||||
|
||||
int
|
||||
msselect(dev, rw, p)
|
||||
dev_t dev;
|
||||
int rw;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (ev_select(&ms_softc.ms_events, rw, p));
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,277 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 1994 Gordon W. Ross
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)zs.c 8.1 (Berkeley) 7/19/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hooks for kgdb when attached vi the z8530 driver
|
||||
* XXX - not tested yet...
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <dev/ic/z8530reg.h>
|
||||
#include <machine/z8530var.h>
|
||||
|
||||
#include <machine/remote-sl.h>
|
||||
|
||||
/* The Sun3 provides a 4.9152 MHz clock to the ZS chips. */
|
||||
#define PCLK (9600 * 512) /* PCLK pin input clock rate */
|
||||
|
||||
extern int kgdb_dev;
|
||||
extern int kgdb_rate;
|
||||
|
||||
struct zschan * zs_get_chan_addr __P((int zsc_unit, int channel));
|
||||
|
||||
extern int zs_getc __P((void *arg));
|
||||
extern void zs_putc __P((void *arg, int c));
|
||||
|
||||
struct zsops zsops_kgdb;
|
||||
|
||||
static u_char zs_kgdb_regs[16] = {
|
||||
0, /* 0: CMD (reset, etc.) */
|
||||
ZSWR1_RIE, /* NOT: (ZSWR1_TIE | ZSWR1_SIE) */
|
||||
0x18 + ZSHARD_PRI, /* IVECT */
|
||||
ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
|
||||
ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
|
||||
ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
|
||||
0, /* 6: TXSYNC/SYNCLO */
|
||||
0, /* 7: RXSYNC/SYNCHI */
|
||||
0, /* 8: alias for data port */
|
||||
ZSWR9_MASTER_IE,
|
||||
0, /*10: Misc. TX/RX control bits */
|
||||
ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
|
||||
14, /*12: BAUDLO (default=9600) */
|
||||
0, /*13: BAUDHI (default=9600) */
|
||||
ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA,
|
||||
ZSWR15_BREAK_IE | ZSWR15_DCD_IE,
|
||||
};
|
||||
|
||||
static void
|
||||
zs_setparam(cs, iena, rate)
|
||||
struct zs_chanstate *cs;
|
||||
int iena;
|
||||
int rate;
|
||||
{
|
||||
int s, tconst;
|
||||
|
||||
bcopy(zs_kgdb_regs, cs->cs_preg, 16);
|
||||
|
||||
if (iena == 0) {
|
||||
cs->cs_preg[1] = 0;
|
||||
}
|
||||
|
||||
/* Initialize the speed, etc. */
|
||||
tconst = BPS_TO_TCONST(cs->cs_pclk_div16, rate);
|
||||
cs->cs_preg[5] |= ZSWR5_DTR | ZSWR5_RTS;
|
||||
cs->cs_preg[12] = tconst;
|
||||
cs->cs_preg[13] = tconst >> 8;
|
||||
|
||||
s = splhigh();
|
||||
zs_loadchannelregs(cs);
|
||||
splx(s);
|
||||
|
||||
|
||||
/*
|
||||
* Set up for kgdb; called at boot time before configuration.
|
||||
* KGDB interrupts will be enabled later when zs0 is configured.
|
||||
*/
|
||||
void
|
||||
zs_kgdb_init()
|
||||
{
|
||||
struct zs_chanstate cs;
|
||||
volatile struct zschan *zc;
|
||||
int channel, zsc_unit;
|
||||
|
||||
if (major(kgdb_dev) != ZSMAJOR)
|
||||
return;
|
||||
|
||||
zsc_unit = 1; /* XXX */
|
||||
channel = minor(kgdb_dev) & 1;
|
||||
printf("zs_kgdb_init: attaching zstty%d at %d baud\n",
|
||||
channel, kgdb_rate);
|
||||
|
||||
/* Setup temporary chanstate. */
|
||||
bzero((caddr_t)&cs, sizeof(cs));
|
||||
zc = zs_get_chan_addr(zsc_unit, channel);
|
||||
cs.cs_reg_csr = &zc->zc_csr;
|
||||
cs.cs_reg_data = &zc->zc_data;
|
||||
cs.cs_channel = channel;
|
||||
cs.cs_pclk_div16 = PCLK / 16;
|
||||
|
||||
/* Now set parameters. (interrupts disabled) */
|
||||
zs_setparam(&cs, 0, kgdb_rate);
|
||||
|
||||
/* Store the getc/putc functions and arg. */
|
||||
kgdb_attach(zs_getc, zs_putc, (void *)zc);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a "hook" called by zstty_attach to allow the tty
|
||||
* to be "taken over" for exclusive use by kgdb.
|
||||
* Return non-zero if this is the kgdb port.
|
||||
*
|
||||
* Set the speed to kgdb_rate, CS8, etc.
|
||||
*/
|
||||
int
|
||||
zs_check_kgdb(cs, dev)
|
||||
struct zs_chanstate *cs;
|
||||
int dev;
|
||||
{
|
||||
int tconst;
|
||||
|
||||
if (dev != kgdb_dev)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Yes, this is the kgdb port. Finish the autoconfig
|
||||
* message and set up the port for our exclusive use.
|
||||
*/
|
||||
printf(" (kgdb,%d)\n", kgdb_rate);
|
||||
|
||||
cs->cs_private = NULL;
|
||||
cs->cs_ops = &zsops_kgdb;
|
||||
|
||||
/* Now set parameters. (interrupts enabled) */
|
||||
zs_setparam(&cs, 1, kgdb_rate);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* KGDB framing character received: enter kernel debugger. This probably
|
||||
* should time out after a few seconds to avoid hanging on spurious input.
|
||||
*/
|
||||
zskgdb()
|
||||
{
|
||||
unit = minor(kgdb_dev);
|
||||
|
||||
printf("zstty%d: kgdb interrupt\n", unit);
|
||||
/* This will trap into the debugger. */
|
||||
kgdb_connect(1);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Interface to the lower layer (zscc)
|
||||
****************************************************************/
|
||||
|
||||
int kgdb_input_lost;
|
||||
|
||||
static int
|
||||
zs_kgdb_rxint(cs)
|
||||
register struct zs_chanstate *cs;
|
||||
{
|
||||
register u_char c, rr1;
|
||||
|
||||
/* Read the input data ASAP. */
|
||||
c = *(cs->cs_reg_data);
|
||||
ZS_DELAY();
|
||||
|
||||
/* Save the status register too. */
|
||||
rr1 = ZS_READ(cs, 1);
|
||||
|
||||
if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
|
||||
/* Clear the receive error. */
|
||||
*(cs->cs_reg_csr) = ZSWR0_RESET_ERRORS;
|
||||
ZS_DELAY();
|
||||
}
|
||||
|
||||
if (c == FRAME_START) {
|
||||
zskgdb();
|
||||
} else {
|
||||
kgdb_input_lost++;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
zs_kgdb_txint(cs)
|
||||
register struct zs_chanstate *cs;
|
||||
{
|
||||
register int count, rval;
|
||||
|
||||
*(cs->cs_reg_csr) = ZSWR0_RESET_TXINT;
|
||||
ZS_DELAY();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zs_kgdb_stint(cs)
|
||||
register struct zs_chanstate *cs;
|
||||
{
|
||||
register int rr0;
|
||||
|
||||
rr0 = *(cs->cs_reg_csr);
|
||||
ZS_DELAY();
|
||||
|
||||
*(cs->cs_reg_csr) = ZSWR0_RESET_STATUS;
|
||||
ZS_DELAY();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zs_kgdb_softint(cs)
|
||||
struct zs_chanstate *cs;
|
||||
{
|
||||
printf("zs_kgdb_softint?\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct zsops zsops_kgdb = {
|
||||
zs_kgdb_rxint, /* receive char available */
|
||||
zs_kgdb_stint, /* external/status */
|
||||
zs_kgdb_txint, /* xmit buffer empty */
|
||||
zs_kgdb_softint, /* process software interrupt */
|
||||
};
|
|
@ -1,152 +0,0 @@
|
|||
/* $NetBSD: zsvar.h,v 1.7 1995/04/11 02:41:49 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Gordon W. Ross
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)zsvar.h 8.1 (Berkeley) 6/11/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Software state, per zs channel.
|
||||
*
|
||||
* The zs chip has insufficient buffering, so we provide a software
|
||||
* buffer using a two-level interrupt scheme. The hardware (high priority)
|
||||
* interrupt simply grabs the `cause' of the interrupt and stuffs it into
|
||||
* a ring buffer. It then schedules a software interrupt; the latter
|
||||
* empties the ring as fast as it can, hoping to avoid overflow.
|
||||
*
|
||||
* Interrupts can happen because of:
|
||||
* - received data;
|
||||
* - transmit pseudo-DMA done; and
|
||||
* - status change.
|
||||
* These are all stored together in the (single) ring. The size of the
|
||||
* ring is a power of two, to make % operations fast. Since we need two
|
||||
* bits to distinguish the interrupt type, and up to 16 for the received
|
||||
* data plus RR1 status, we use 32 bits per ring entry.
|
||||
*
|
||||
* When the value is a character + RR1 status, the character is in the
|
||||
* upper 8 bits of the RR1 status.
|
||||
*/
|
||||
#define ZLRB_RING_SIZE 256 /* ZS line ring buffer size */
|
||||
#define ZLRB_RING_MASK 255 /* mask for same */
|
||||
|
||||
/* 0 is reserved (means "no interrupt") */
|
||||
#define ZRING_RINT 1 /* receive data interrupt */
|
||||
#define ZRING_XINT 2 /* transmit done interrupt */
|
||||
#define ZRING_SINT 3 /* status change interrupt */
|
||||
|
||||
#define ZRING_TYPE(x) ((x) & 3)
|
||||
#define ZRING_VALUE(x) ((x) >> 8)
|
||||
#define ZRING_MAKE(t, v) ((t) | (v) << 8)
|
||||
|
||||
struct zs_chanstate {
|
||||
struct zs_chanstate *cs_next; /* linked list for zshard() */
|
||||
volatile struct zschan *cs_zc; /* points to hardware regs */
|
||||
int cs_unit; /* unit number */
|
||||
struct tty *cs_ttyp; /* ### */
|
||||
|
||||
/*
|
||||
* We must keep a copy of the write registers as they are
|
||||
* mostly write-only and we sometimes need to set and clear
|
||||
* individual bits (e.g., in WR3). Not all of these are
|
||||
* needed but 16 bytes is cheap and this makes the addressing
|
||||
* simpler. Unfortunately, we can only write to some registers
|
||||
* when the chip is not actually transmitting, so whenever
|
||||
* we are expecting a `transmit done' interrupt the preg array
|
||||
* is allowed to `get ahead' of the current values. In a
|
||||
* few places we must change the current value of a register,
|
||||
* rather than (or in addition to) the pending value; for these
|
||||
* cs_creg[] contains the current value.
|
||||
*/
|
||||
u_char cs_creg[16]; /* current values */
|
||||
u_char cs_preg[16]; /* pending values */
|
||||
u_char cs_heldchange; /* change pending (creg != preg) */
|
||||
u_char cs_rr0; /* last rr0 processed */
|
||||
|
||||
/* pure software data, per channel */
|
||||
char cs_softcar; /* software carrier */
|
||||
char cs_conk; /* is console keyboard, decode L1-A */
|
||||
char cs_brkabort; /* abort (as if via L1-A) on BREAK */
|
||||
char cs_kgdb; /* enter debugger on frame char */
|
||||
char cs_consio; /* port does /dev/console I/O */
|
||||
char cs_xxx; /* (spare) */
|
||||
int cs_speed; /* default baud rate (from ROM) */
|
||||
|
||||
/*
|
||||
* The transmit byte count and address are used for pseudo-DMA
|
||||
* output in the hardware interrupt code. PDMA can be suspended
|
||||
* to get pending changes done; heldtbc is used for this. It can
|
||||
* also be stopped for ^S; this sets TS_TTSTOP in tp->t_state.
|
||||
*/
|
||||
int cs_tbc; /* transmit byte count */
|
||||
caddr_t cs_tba; /* transmit buffer address */
|
||||
int cs_heldtbc; /* held tbc while xmission stopped */
|
||||
|
||||
/*
|
||||
* Printing an overrun error message often takes long enough to
|
||||
* cause another overrun, so we only print one per second.
|
||||
*/
|
||||
long cs_rotime; /* time of last ring overrun */
|
||||
long cs_fotime; /* time of last fifo overrun */
|
||||
|
||||
/*
|
||||
* The ring buffer.
|
||||
*/
|
||||
u_int cs_rbget; /* ring buffer `get' index */
|
||||
volatile u_int cs_rbput; /* ring buffer `put' index */
|
||||
int cs_rbuf[ZLRB_RING_SIZE];/* type, value pairs */
|
||||
};
|
||||
|
||||
/*
|
||||
* N.B.: the keyboard is channel 1, the mouse channel 0; ttyb is 1, ttya
|
||||
* is 0. In other words, the things are BACKWARDS.
|
||||
*/
|
||||
#define ZS_CHAN_A 1
|
||||
#define ZS_CHAN_B 0
|
||||
|
||||
/*
|
||||
* Macros to read and write individual registers (except 0) in a channel.
|
||||
* The ZS chip requires a 1.6 uSec. recovery time between accesses.
|
||||
*/
|
||||
#define ZS_READ(c, r) zs_read(c, r)
|
||||
#define ZS_WRITE(c, r, v) zs_write(c, r, v)
|
||||
#define ZS_DELAY() delay2us()
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kbd.h,v 1.2 1995/05/24 20:57:00 gwr Exp $ */
|
||||
/* $NetBSD: kbd.h,v 1.3 1996/01/24 22:40:40 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -56,8 +56,11 @@
|
|||
* KBD_IDLE does not take the place of any `up' transitions (it merely occurs
|
||||
* after them).
|
||||
*/
|
||||
#define KBD_RESET 0xff /* keyboard `reset' response */
|
||||
#define KBD_RESET 0xff /* `reset' response (ID follows) */
|
||||
#define KBD_LAYOUT 0xfe /* Indicates that `layout' follows */
|
||||
#define KBD_IDLE 0x7f /* keyboard `all keys are up' code */
|
||||
#define KBD_ERROR 0x7e /* keyboard detected an error */
|
||||
#define KBD_SPECIAL(c) (((c) & 0x7e) == 0x7e)
|
||||
|
||||
/* Keyboard IDs */
|
||||
#define KB_SUN2 2 /* type 2 keyboard */
|
||||
|
@ -79,6 +82,7 @@
|
|||
#define KBD_CMD_CLICK 10 /* turn keyclick on */
|
||||
#define KBD_CMD_NOCLICK 11 /* turn keyclick off */
|
||||
#define KBD_CMD_SETLED 14 /* set LED state (type 4 kbd) */
|
||||
#define KBD_CMD_GETLAYOUT 15 /* ask for layout (type 4 kbd) */
|
||||
|
||||
#define LED_NUM_LOCK 0x1
|
||||
#define LED_COMPOSE 0x2
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kbio.h,v 1.3 1995/08/08 20:57:51 gwr Exp $ */
|
||||
/* $NetBSD: kbio.h,v 1.4 1996/01/24 22:40:43 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -70,40 +70,42 @@
|
|||
struct okiockey { /* Out-dated key translation structure */
|
||||
int kio_tablemask; /* whatever */
|
||||
u_char kio_station; /* key number */
|
||||
u_char kio_entry; /* HOLE if not present */
|
||||
u_char kio_entry; /* 0xA2 (HOLE) if not present */
|
||||
char kio_text[10]; /* the silly escape sequences (unsupported) */
|
||||
};
|
||||
|
||||
struct kiockey {
|
||||
struct kiockeymap {
|
||||
int kio_tablemask; /* whatever */
|
||||
u_char kio_station; /* key number */
|
||||
u_short kio_entry; /* HOLE if not present */
|
||||
u_short kio_entry; /* keymap entry - see kbd_map.h */
|
||||
char kio_text[10]; /* the silly escape sequences (unsupported) */
|
||||
};
|
||||
|
||||
/*
|
||||
* Values for kio_tablemask. These determine which table to read/modify
|
||||
* in KIOC[SG]KEY ioctls. Currently, we only have "non-shift" and "shift"
|
||||
* tables.
|
||||
* in KIOC[SG]KEY ioctls. Currently handle: {NO,SHIFT,CTRL,UP}MASK
|
||||
* Note: these are SunOS-4.1 compatible values
|
||||
*/
|
||||
#define KIOC_NOMASK 0x0
|
||||
#define KIOC_CAPSMASK 0x1
|
||||
#define KIOC_SHIFTMASK 0xe
|
||||
#define KIOC_NOMASK 0x00
|
||||
#define KIOC_CAPSMASK 0x01
|
||||
#define KIOC_SHIFTMASK 0x0E
|
||||
#define KIOC_CTRLMASK 0x30
|
||||
#define KIOC_UPMASK 0x80
|
||||
#define KIOC_ALTGMASK 0x200
|
||||
#define KIOC_ALTMASK 0x400
|
||||
#define KIOC_NUMLMASK 0x800
|
||||
|
||||
#define HOLE 0x302 /* value for kio_entry to say `really type 3' */
|
||||
|
||||
#define KIOCTRANS _IOW('k', 0, int) /* set translation mode */
|
||||
/* (we only accept TR_UNTRANS_EVENT) */
|
||||
|
||||
#define KIOCSETKEY _IOWR('k', 1, struct okiockey) /* fill in kio_entry */
|
||||
#define KIOCGETKEY _IOWR('k', 2, struct okiockey) /* fill in kio_entry */
|
||||
|
||||
#define KIOCGTRANS _IOR('k', 5, int) /* get translation mode */
|
||||
#define KIOCCMD _IOW('k', 8, int) /* X uses this to ring bell */
|
||||
#define KIOCTYPE _IOR('k', 9, int) /* get keyboard type */
|
||||
#define KIOCSDIRECT _IOW('k', 10, int) /* keys to console? */
|
||||
#define KIOCSKEY _IOW('k', 12, struct kiockey) /* set xlat mode */
|
||||
#define KIOCGKEY _IOWR('k', 13, struct kiockey) /* get xlat mode */
|
||||
#define KIOCSKEY _IOW('k', 12, struct kiockeymap) /* set xlat mode */
|
||||
#define KIOCGKEY _IOWR('k', 13, struct kiockeymap) /* get xlat mode */
|
||||
#define KIOCSLED _IOW('k', 14, char) /* set LED state */
|
||||
#define KIOCGLED _IOR('k', 15, char) /* get LED state */
|
||||
#define KIOCLAYOUT _IOR('k', 20, int) /* get keyboard layout */
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* $NetBSD: z8530var.h,v 1.2 1996/01/24 22:40:48 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Gordon W. Ross
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)zsvar.h 8.1 (Berkeley) 6/11/93
|
||||
*/
|
||||
|
||||
#include <dev/ic/z8530sc.h>
|
||||
|
||||
/*
|
||||
* Macros to read and write individual registers (except 0) in a channel.
|
||||
* The ZS chip requires a 1.6 uSec. recovery time between accesses, and
|
||||
* the Sun3 hardware does NOT take care of this for you.
|
||||
*/
|
||||
#define ZS_READ(c, r) zs_read_reg(c, r)
|
||||
#define ZS_WRITE(c, r, v) zs_write_reg(c, r, v)
|
||||
#define ZS_DELAY() delay2us()
|
||||
|
||||
u_char zs_read_reg __P((struct zs_chanstate *zc, u_char reg));
|
||||
void zs_write_reg __P((struct zs_chanstate *zc, u_char reg, u_char val));
|
||||
|
||||
/*
|
||||
* How to request a "soft" interrupt.
|
||||
* This could be a macro if you like.
|
||||
*/
|
||||
void zsc_req_softint __P((struct zsc_softc *zsc));
|
||||
|
||||
/* Handle user request to enter kernel debugger. */
|
||||
void zs_abort();
|
||||
|
||||
/*
|
||||
* Some warts needed by z8530tty.c -
|
||||
* The default parity REALLY needs to be the same as the PROM uses,
|
||||
* or you can not see messages done with printf during boot-up...
|
||||
*/
|
||||
#define ZSTTY_MAJOR 12 /* XXX */
|
||||
#define ZSTTY_DEF_CFLAG (CREAD | CS8 | HUPCL)
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: conf.c,v 1.45 1995/10/29 04:15:59 gwr Exp $ */
|
||||
/* $NetBSD: conf.c,v 1.46 1996/01/24 22:40:58 gwr Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994 Adam Glass, Gordon W. Ross
|
||||
|
@ -368,28 +368,3 @@ chrtoblk(dev)
|
|||
return (makedev(blkmaj, minor(dev)));
|
||||
}
|
||||
|
||||
/*
|
||||
* This entire table could be autoconfig()ed but that would mean that
|
||||
* the kernel's idea of the console could be out of sync with that of
|
||||
* the standalone boot. I think it best that they both use the same
|
||||
* known algorithm unless we see a pressing need otherwise.
|
||||
*/
|
||||
#include <dev/cons.h>
|
||||
|
||||
cons_decl(kd);
|
||||
#define zscnpollc nullcnpollc
|
||||
|
||||
cons_decl(zs);
|
||||
dev_type_cnprobe(zscnprobe_a);
|
||||
dev_type_cnprobe(zscnprobe_b);
|
||||
|
||||
struct consdev constab[] = {
|
||||
#if NZS > 0
|
||||
{ zscnprobe_a, zscninit, zscngetc, zscnputc, zscnpollc },
|
||||
{ zscnprobe_b, zscninit, zscngetc, zscnputc, zscnpollc },
|
||||
#endif
|
||||
#if NKD > 0
|
||||
cons_init(kd),
|
||||
#endif
|
||||
{ 0 }, /* REQIURED! */
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue