Use common zs code.
This commit is contained in:
parent
b4e346f85d
commit
0308bf1ac6
@ -1,4 +1,4 @@
|
||||
# $NetBSD: GENERIC,v 1.49 1997/09/27 09:56:25 mrg Exp $
|
||||
# $NetBSD: GENERIC,v 1.50 1997/10/17 23:59:44 gwr Exp $
|
||||
|
||||
include "arch/sparc/conf/std.sparc"
|
||||
|
||||
@ -133,11 +133,19 @@ zs0 at mainbus0 # sun4c
|
||||
zs0 at obio0 # sun4m
|
||||
zs0 at obio0 addr 0xf1000000 level 12 flags 0x103 # sun4/200 and sun4/300
|
||||
zs0 at obio0 addr 0x01000000 level 12 flags 0x103 # sun4/100
|
||||
zstty0 at zs0 channel 0 # ttya
|
||||
zstty1 at zs0 channel 1 # ttyb
|
||||
|
||||
zs1 at mainbus0 # sun4c
|
||||
zs1 at obio0 # sun4m
|
||||
zs1 at obio0 addr 0xf0000000 level 12 flags 0x103 # sun4/200 and sun4/300
|
||||
zs1 at obio0 addr 0x00000000 level 12 flags 0x103 # sun4/100
|
||||
kbd0 at zs1 channel 0 # keyboard
|
||||
ms0 at zs1 channel 1 # mouse
|
||||
|
||||
zs2 at obio0 addr 0xe0000000 level 12 flags 0x103 # sun4/300
|
||||
zstty2 at zs2 channel 0 # ttyc
|
||||
zstty3 at zs2 channel 1 # ttyd
|
||||
|
||||
#
|
||||
# Note the flags on the esp entries below, that work around
|
||||
@ -295,7 +303,6 @@ fd* at fdc0 # the drive itself
|
||||
pseudo-device loop # loopback interface; required
|
||||
pseudo-device pty 32 # pseudo-ttys (for network, etc.)
|
||||
pseudo-device sl 2 # SLIP interfaces
|
||||
pseudo-device kbd # Sun keyboard
|
||||
pseudo-device ppp 2 # PPP interfaces
|
||||
pseudo-device tun 4 # Network "tunnel" device
|
||||
pseudo-device bpfilter 16 # Berkeley Packet Filter
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.sparc,v 1.44 1997/08/31 21:29:16 pk Exp $
|
||||
# $NetBSD: files.sparc,v 1.45 1997/10/17 23:59:57 gwr Exp $
|
||||
|
||||
# @(#)files.sparc 8.1 (Berkeley) 7/19/93
|
||||
# sparc-specific configuration info
|
||||
@ -56,9 +56,10 @@ device memreg
|
||||
attach memreg at mainbus, obio
|
||||
file arch/sparc/sparc/memreg.c
|
||||
|
||||
device zs
|
||||
device zs {channel = -1}
|
||||
attach zs at mainbus, obio
|
||||
file arch/sparc/dev/zs.c zs needs-count
|
||||
file dev/ic/z8530sc.c zs
|
||||
|
||||
device fdc {}
|
||||
attach fdc at mainbus, obio
|
||||
@ -71,6 +72,28 @@ device sbus { slot = -1, offset = -1 }
|
||||
attach sbus at mainbus, iommu
|
||||
file arch/sparc/dev/sbus.c sbus
|
||||
|
||||
#
|
||||
# Console (zs) related stuff
|
||||
#
|
||||
|
||||
device zstty: tty
|
||||
attach zstty at zs
|
||||
file dev/ic/z8530tty.c zstty needs-flag
|
||||
file arch/sparc/dev/zs_kgdb.c kgdb
|
||||
|
||||
define zsevent
|
||||
file dev/sun/event.c zsevent
|
||||
|
||||
device kbd: zsevent
|
||||
attach kbd at zs
|
||||
file dev/sun/kbd.c kbd needs-flag
|
||||
file dev/sun/kbd_tables.c kbd
|
||||
file arch/sparc/dev/kd.c kbd
|
||||
|
||||
device ms: zsevent
|
||||
attach ms at zs
|
||||
file dev/sun/ms.c ms needs-flag
|
||||
|
||||
|
||||
#
|
||||
# Machine-independent SCSI drivers
|
||||
@ -174,17 +197,12 @@ file arch/sparc/dev/if_en_sbus.c en_sbus
|
||||
attach isp at sbus with isp_sbus
|
||||
file arch/sparc/dev/isp_sbus.c isp_sbus
|
||||
|
||||
pseudo-device kbd
|
||||
|
||||
#
|
||||
# Generic Sun stuff
|
||||
#
|
||||
include "../../../dev/sun/files.sun"
|
||||
|
||||
file arch/sparc/dev/cons.c
|
||||
file dev/cons.c
|
||||
file arch/sparc/dev/fb.c
|
||||
file arch/sparc/dev/ms.c
|
||||
file arch/sparc/dev/kbd.c kbd
|
||||
|
||||
file arch/sparc/fpu/fpu.c
|
||||
file arch/sparc/fpu/fpu_add.c
|
||||
|
@ -1,701 +0,0 @@
|
||||
/* $NetBSD: cons.c,v 1.30 1997/07/07 23:30:23 pk 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.
|
||||
*
|
||||
* @(#)cons.c 8.3 (Berkeley) 12/14/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Console (indirect) driver.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <machine/bsd_openprom.h>
|
||||
#include <machine/eeprom.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/kbd.h>
|
||||
#if defined(SUN4)
|
||||
#include <machine/oldmon.h>
|
||||
#endif
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/conf.h>
|
||||
|
||||
#ifdef RASTERCONSOLE
|
||||
#include <machine/fbio.h>
|
||||
#include <machine/fbvar.h>
|
||||
#endif
|
||||
|
||||
#include "zs.h"
|
||||
|
||||
struct tty *constty = 0; /* virtual console output device */
|
||||
struct tty *fbconstty = 0; /* tty structure for frame buffer console */
|
||||
int rom_console_input; /* when set, hardclock calls cnrom() */
|
||||
|
||||
int cons_ocount; /* output byte count */
|
||||
|
||||
/*
|
||||
* The output driver may munge the minor number in cons.t_dev.
|
||||
*/
|
||||
struct tty cons; /* rom console tty device */
|
||||
static void (*fcnstop) __P((struct tty *, int));
|
||||
|
||||
static void cnstart __P((struct tty *));
|
||||
void cnstop __P((struct tty *, int));
|
||||
|
||||
static void cnfbstart __P((struct tty *));
|
||||
static void cnfbstop __P((struct tty *, int));
|
||||
static void cnfbdma __P((void *));
|
||||
static struct tty *xxcntty __P((dev_t));
|
||||
|
||||
extern char char_type[];
|
||||
|
||||
/*XXX*/
|
||||
static struct tty *
|
||||
xxcntty(dev_t dev)
|
||||
{
|
||||
return &cons;
|
||||
}
|
||||
|
||||
void
|
||||
consinit()
|
||||
{
|
||||
register struct tty *tp = &cons;
|
||||
register int in, out;
|
||||
|
||||
/*XXX*/ cdevsw[0].d_tty = xxcntty;
|
||||
tp->t_dev = makedev(0, 0); /* /dev/console */
|
||||
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
|
||||
tp->t_param = (int (*)(struct tty *, struct termios *))nullop;
|
||||
|
||||
if (promvec->pv_romvec_vers > 2) {
|
||||
/* We need to probe the PROM device tree */
|
||||
register int node,fd;
|
||||
char buffer[128];
|
||||
register struct nodeops *no;
|
||||
register struct v2devops *op;
|
||||
register char *cp;
|
||||
extern int fbnode;
|
||||
|
||||
in = out = -1;
|
||||
no = promvec->pv_nodeops;
|
||||
op = &promvec->pv_v2devops;
|
||||
|
||||
node = findroot();
|
||||
if (no->no_proplen(node, "stdin-path") >= sizeof(buffer)) {
|
||||
printf("consinit: increase buffer size and recompile\n");
|
||||
goto setup_output;
|
||||
}
|
||||
/* XXX: fix above */
|
||||
|
||||
no->no_getprop(node, "stdin-path",buffer);
|
||||
|
||||
/*
|
||||
* Open an "instance" of this device.
|
||||
* You'd think it would be appropriate to call v2_close()
|
||||
* on the handle when we're done with it. But that seems
|
||||
* to cause the device to shut down somehow; for the moment,
|
||||
* we simply leave it open...
|
||||
*/
|
||||
if ((fd = op->v2_open(buffer)) == 0 ||
|
||||
(node = op->v2_fd_phandle(fd)) == 0) {
|
||||
printf("consinit: bogus stdin path %s.\n",buffer);
|
||||
goto setup_output;
|
||||
}
|
||||
if (no->no_proplen(node,"keyboard") >= 0) {
|
||||
in = PROMDEV_KBD;
|
||||
goto setup_output;
|
||||
}
|
||||
if (strcmp(getpropstring(node,"device_type"),"serial") != 0) {
|
||||
/* not a serial, not keyboard. what is it?!? */
|
||||
in = -1;
|
||||
goto setup_output;
|
||||
}
|
||||
/*
|
||||
* At this point we assume the device path is in the form
|
||||
* ....device@x,y:a for ttya and ...device@x,y:b for ttyb.
|
||||
* If it isn't, we defer to the ROM
|
||||
*/
|
||||
cp = buffer;
|
||||
while (*cp)
|
||||
cp++;
|
||||
cp -= 2;
|
||||
#ifdef DEBUG
|
||||
if (cp < buffer)
|
||||
panic("consinit: bad stdin path %s",buffer);
|
||||
#endif
|
||||
/* XXX: only allows tty's a->z, assumes PROMDEV_TTYx contig */
|
||||
if (cp[0]==':' && cp[1] >= 'a' && cp[1] <= 'z')
|
||||
in = PROMDEV_TTYA + (cp[1] - 'a');
|
||||
/* else use rom */
|
||||
setup_output:
|
||||
node = findroot();
|
||||
if (no->no_proplen(node, "stdout-path") >= sizeof(buffer)) {
|
||||
printf("consinit: increase buffer size and recompile\n");
|
||||
goto setup_console;
|
||||
}
|
||||
/* XXX: fix above */
|
||||
|
||||
no->no_getprop(node, "stdout-path", buffer);
|
||||
|
||||
if ((fd = op->v2_open(buffer)) == 0 ||
|
||||
(node = op->v2_fd_phandle(fd)) == 0) {
|
||||
printf("consinit: bogus stdout path %s.\n",buffer);
|
||||
goto setup_output;
|
||||
}
|
||||
if (strcmp(getpropstring(node,"device_type"),"display") == 0) {
|
||||
/* frame buffer output */
|
||||
out = PROMDEV_SCREEN;
|
||||
fbnode = node;
|
||||
} else if (strcmp(getpropstring(node,"device_type"), "serial")
|
||||
!= 0) {
|
||||
/* not screen, not serial. Whatzit? */
|
||||
out = -1;
|
||||
} else { /* serial console. which? */
|
||||
/*
|
||||
* At this point we assume the device path is in the
|
||||
* form:
|
||||
* ....device@x,y:a for ttya, etc.
|
||||
* If it isn't, we defer to the ROM
|
||||
*/
|
||||
cp = buffer;
|
||||
while (*cp)
|
||||
cp++;
|
||||
cp -= 2;
|
||||
#ifdef DEBUG
|
||||
if (cp < buffer)
|
||||
panic("consinit: bad stdout path %s",buffer);
|
||||
#endif
|
||||
/* XXX: only allows tty's a->z, assumes PROMDEV_TTYx contig */
|
||||
if (cp[0]==':' && cp[1] >= 'a' && cp[1] <= 'z')
|
||||
out = PROMDEV_TTYA + (cp[1] - 'a');
|
||||
else out = -1;
|
||||
}
|
||||
} else {
|
||||
in = *promvec->pv_stdin;
|
||||
out = *promvec->pv_stdout;
|
||||
}
|
||||
setup_console:
|
||||
switch (in) {
|
||||
#if NZS > 0
|
||||
case PROMDEV_TTYA:
|
||||
zsconsole(tp, 0, 0, NULL);
|
||||
break;
|
||||
|
||||
case PROMDEV_TTYB:
|
||||
zsconsole(tp, 1, 0, NULL);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PROMDEV_KBD:
|
||||
/*
|
||||
* Tell the keyboard driver to direct ASCII input here.
|
||||
*/
|
||||
kbd_ascii(tp);
|
||||
break;
|
||||
|
||||
default:
|
||||
rom_console_input = 1;
|
||||
printf("unknown console input source %d; using rom\n", in);
|
||||
break;
|
||||
}
|
||||
switch (out) {
|
||||
|
||||
#if NZS > 0
|
||||
case PROMDEV_TTYA:
|
||||
zsconsole(tp, 0, 1, &fcnstop);
|
||||
break;
|
||||
|
||||
case PROMDEV_TTYB:
|
||||
zsconsole(tp, 1, 1, &fcnstop);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PROMDEV_SCREEN:
|
||||
fbconstty = tp;
|
||||
tp->t_oproc = cnfbstart;
|
||||
fcnstop = cnfbstop;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unknown console output sink %d; using rom\n", out);
|
||||
tp->t_oproc = cnstart;
|
||||
fcnstop = (void (*)(struct tty *, int))nullop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cnopen(dev, flag, mode, p)
|
||||
dev_t dev;
|
||||
int flag, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct tty *tp = &cons;
|
||||
static int firstopen = 1;
|
||||
static int rows = 0, cols = 0;
|
||||
|
||||
if (firstopen) {
|
||||
clalloc(&tp->t_rawq, 1024, 1);
|
||||
clalloc(&tp->t_canq, 1024, 1);
|
||||
/* output queue doesn't need quoting */
|
||||
clalloc(&tp->t_outq, 1024, 0);
|
||||
tty_attach(tp);
|
||||
|
||||
/*
|
||||
* get the console struct winsize.
|
||||
*/
|
||||
#ifdef RASTERCONSOLE
|
||||
if (fbconstty) {
|
||||
rows = fbrcons_rows();
|
||||
cols = fbrcons_cols();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CPU_ISSUN4COR4M) {
|
||||
int i;
|
||||
char *prop;
|
||||
|
||||
if (rows == 0 &&
|
||||
(prop = getpropstring(optionsnode, "screen-#rows"))) {
|
||||
i = 0;
|
||||
while (*prop != '\0')
|
||||
i = i * 10 + *prop++ - '0';
|
||||
rows = (unsigned short)i;
|
||||
}
|
||||
if (cols == 0 &&
|
||||
(prop = getpropstring(optionsnode, "screen-#columns"))) {
|
||||
i = 0;
|
||||
while (*prop != '\0')
|
||||
i = i * 10 + *prop++ - '0';
|
||||
cols = (unsigned short)i;
|
||||
}
|
||||
}
|
||||
if (CPU_ISSUN4) {
|
||||
struct eeprom *ep = (struct eeprom *)eeprom_va;
|
||||
|
||||
if (ep) {
|
||||
if (rows == 0)
|
||||
rows = (u_short)ep->eeTtyRows;
|
||||
if (cols == 0)
|
||||
cols = (u_short)ep->eeTtyCols;
|
||||
}
|
||||
}
|
||||
firstopen = 0;
|
||||
}
|
||||
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
/*
|
||||
* Leave baud rate alone!
|
||||
*/
|
||||
ttychars(tp);
|
||||
tp->t_iflag = TTYDEF_IFLAG;
|
||||
tp->t_oflag = TTYDEF_OFLAG;
|
||||
tp->t_lflag = TTYDEF_LFLAG;
|
||||
tp->t_cflag = TTYDEF_CFLAG;
|
||||
tp->t_state = TS_ISOPEN | TS_CARR_ON;
|
||||
(void)(*tp->t_param)(tp, &tp->t_termios);
|
||||
ttsetwater(tp);
|
||||
tp->t_winsize.ws_row = rows;
|
||||
tp->t_winsize.ws_col = cols;
|
||||
} else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
|
||||
return (EBUSY);
|
||||
return ((*linesw[tp->t_line].l_open)(dev, tp));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cnclose(dev, flag, mode, p)
|
||||
dev_t dev;
|
||||
int flag, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct tty *tp = &cons;
|
||||
|
||||
(*linesw[tp->t_line].l_close)(tp, flag);
|
||||
ttyclose(tp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cnread(dev, uio, flag)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
register struct tty *tp = &cons;
|
||||
|
||||
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cnwrite(dev, uio, flag)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
register struct tty *tp;
|
||||
|
||||
if ((tp = constty) == NULL ||
|
||||
(tp->t_state & (TS_CARR_ON|TS_ISOPEN)) != (TS_CARR_ON|TS_ISOPEN))
|
||||
tp = &cons;
|
||||
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
|
||||
}
|
||||
|
||||
int
|
||||
cnioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct tty *tp;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Superuser can always use this to wrest control of console
|
||||
* output from the "virtual" console.
|
||||
*/
|
||||
if (cmd == TIOCCONS && constty) {
|
||||
error = suser(p->p_ucred, (u_short *)NULL);
|
||||
if (error)
|
||||
return (error);
|
||||
constty = NULL;
|
||||
return (0);
|
||||
}
|
||||
tp = &cons;
|
||||
if ((error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p)) >= 0)
|
||||
return (error);
|
||||
if ((error = ttioctl(tp, cmd, data, flag, p)) >= 0)
|
||||
return (error);
|
||||
return (ENOTTY);
|
||||
}
|
||||
|
||||
int
|
||||
cnpoll(dev, events, p)
|
||||
dev_t dev;
|
||||
int events;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (ttpoll(makedev(major(dev), 0), events, p));
|
||||
}
|
||||
|
||||
/*
|
||||
* The rest of this code is run only when we are using the ROM vectors.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generic output. We just call putchar. (Very bad for performance.)
|
||||
*/
|
||||
static void
|
||||
cnstart(tp)
|
||||
register struct tty *tp;
|
||||
{
|
||||
register int c, s;
|
||||
register union {
|
||||
void (*v1)__P((int));
|
||||
int (*v3)__P((int, void *, int));
|
||||
} putc;
|
||||
register int fd = 0, v;
|
||||
|
||||
s = spltty();
|
||||
if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
if ((v = promvec->pv_romvec_vers) > 2) {
|
||||
putc.v3 = promvec->pv_v2devops.v2_write;
|
||||
fd = *promvec->pv_v2bootargs.v2_fd1;
|
||||
} else
|
||||
putc.v1 = promvec->pv_putchar;
|
||||
while (tp->t_outq.c_cc) {
|
||||
c = getc(&tp->t_outq);
|
||||
/*
|
||||
* *%&!*& ROM monitor console putchar is not reentrant!
|
||||
* splhigh/tty around it so as not to run so long with
|
||||
* clock interrupts blocked.
|
||||
*/
|
||||
(void) splhigh();
|
||||
if (v > 2) {
|
||||
unsigned char c0 = c & 0177;
|
||||
(*putc.v3)(fd, &c0, 1);
|
||||
} else
|
||||
(*putc.v1)(c & 0177);
|
||||
(void) spltty();
|
||||
}
|
||||
if (tp->t_state & TS_ASLEEP) { /* can't happen? */
|
||||
tp->t_state &= ~TS_ASLEEP;
|
||||
wakeup((caddr_t)&tp->t_outq);
|
||||
}
|
||||
selwakeup(&tp->t_wsel);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
cnstop(tp, flag)
|
||||
register struct tty *tp;
|
||||
int flag;
|
||||
{
|
||||
|
||||
(*fcnstop)(tp, flag);
|
||||
}
|
||||
|
||||
/*
|
||||
* Frame buffer output.
|
||||
* We use pseudo-DMA, via the ROM `write string' function, called from
|
||||
* software clock interrupts.
|
||||
*/
|
||||
static void
|
||||
cnfbstart(tp)
|
||||
register struct tty *tp;
|
||||
{
|
||||
register int s;
|
||||
|
||||
s = spltty(); /* paranoid: splsoftclock should suffice */
|
||||
if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) {
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* If there are sleepers, and output has drained below low
|
||||
* water mark, awaken.
|
||||
*/
|
||||
if (tp->t_outq.c_cc <= tp->t_lowat) {
|
||||
if (tp->t_state & TS_ASLEEP) {
|
||||
tp->t_state &= ~TS_ASLEEP;
|
||||
wakeup((caddr_t)&tp->t_outq);
|
||||
}
|
||||
selwakeup(&tp->t_wsel);
|
||||
}
|
||||
if (tp->t_outq.c_cc) {
|
||||
tp->t_state |= TS_BUSY;
|
||||
if (s == 0) {
|
||||
(void) splsoftclock();
|
||||
cnfbdma((void *)tp);
|
||||
} else
|
||||
timeout(cnfbdma, tp, 1);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop frame buffer output: just assert TS_FLUSH if necessary.
|
||||
*/
|
||||
static void
|
||||
cnfbstop(tp, flag)
|
||||
register struct tty *tp;
|
||||
int flag;
|
||||
{
|
||||
register int s = spltty(); /* paranoid */
|
||||
|
||||
if ((tp->t_state & (TS_BUSY | TS_TTSTOP)) == TS_BUSY)
|
||||
tp->t_state |= TS_FLUSH;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do pseudo-dma (called from software interrupt).
|
||||
*/
|
||||
static void
|
||||
cnfbdma(tpaddr)
|
||||
void *tpaddr;
|
||||
{
|
||||
register struct tty *tp = tpaddr;
|
||||
register unsigned char *p, *q;
|
||||
register int n, c, s;
|
||||
|
||||
s = spltty(); /* paranoid */
|
||||
if (tp->t_state & TS_FLUSH) {
|
||||
tp->t_state &= ~(TS_BUSY | TS_FLUSH);
|
||||
splx(s);
|
||||
} else {
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
splx(s);
|
||||
p = tp->t_outq.c_cf;
|
||||
n = ndqb(&tp->t_outq, 0);
|
||||
for (q = p, c = n; --c >= 0; q++)
|
||||
if (*q & 0200) /* high bits seem to be bad */
|
||||
*q &= ~0200;
|
||||
if (promvec->pv_romvec_vers > 2) {
|
||||
(*promvec->pv_v2devops.v2_write)
|
||||
(*promvec->pv_v2bootargs.v2_fd1, p, n);
|
||||
} else
|
||||
(*promvec->pv_putstr)((char *)p, n);
|
||||
ndflush(&tp->t_outq, n);
|
||||
}
|
||||
if (tp->t_line)
|
||||
(*linesw[tp->t_line].l_start)(tp);
|
||||
else
|
||||
cnfbstart(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following is for rom console input. The rom will not call
|
||||
* an `interrupt' routine on console input ready, so we must poll.
|
||||
* This is all rather sad.
|
||||
*/
|
||||
volatile int cn_rxc = -1; /* XXX receive `silo' */
|
||||
|
||||
/* called from hardclock, which is above spltty, so no tty calls! */
|
||||
int
|
||||
cnrom()
|
||||
{
|
||||
register int c;
|
||||
|
||||
if (cn_rxc >= 0)
|
||||
return (1);
|
||||
if (promvec->pv_romvec_vers > 2) {
|
||||
unsigned char c0;
|
||||
if ((*promvec->pv_v2devops.v2_read)
|
||||
(*promvec->pv_v2bootargs.v2_fd0, &c0, 1) <= 0)
|
||||
return (0);
|
||||
c = c0;
|
||||
} else if ((c = (*promvec->pv_nbgetchar)()) < 0)
|
||||
return (0);
|
||||
cn_rxc = c;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* pseudo console software interrupt scheduled when cnrom() returns 1 */
|
||||
void
|
||||
cnrint()
|
||||
{
|
||||
register struct tty *tp;
|
||||
register int c, s;
|
||||
|
||||
s = splclock();
|
||||
c = cn_rxc;
|
||||
cn_rxc = -1;
|
||||
splx(s);
|
||||
if (c < 0)
|
||||
return;
|
||||
tp = &cons;
|
||||
if ((tp->t_cflag & CSIZE) == CS7) {
|
||||
/* XXX this should be done elsewhere, if at all */
|
||||
if (tp->t_cflag & PARENB)
|
||||
if (tp->t_cflag & PARODD ?
|
||||
(char_type[c & 0177] & 0200) == (c & 0200) :
|
||||
(char_type[c & 0177] & 0200) != (c & 0200))
|
||||
c |= TTY_PE;
|
||||
c &= ~0200;
|
||||
}
|
||||
(*linesw[tp->t_line].l_rint)(c, tp);
|
||||
}
|
||||
|
||||
int
|
||||
cngetc()
|
||||
{
|
||||
register int s, c;
|
||||
|
||||
if (promvec->pv_romvec_vers > 2) {
|
||||
register int n = 0;
|
||||
unsigned char c0;
|
||||
s = splhigh();
|
||||
while (n <= 0) {
|
||||
n = (*promvec->pv_v2devops.v2_read)
|
||||
(*promvec->pv_v2bootargs.v2_fd0, &c0, 1);
|
||||
}
|
||||
splx(s);
|
||||
c = c0;
|
||||
} else {
|
||||
#if defined(SUN4)
|
||||
/* SUN4 PROM: must turn off echo to avoid double char echo */
|
||||
extern struct om_vector *oldpvec;
|
||||
int saveecho = 0;
|
||||
#endif
|
||||
|
||||
s = splhigh();
|
||||
#if defined(SUN4)
|
||||
if (CPU_ISSUN4) {
|
||||
saveecho = *(oldpvec->echo);
|
||||
*(oldpvec->echo) = 0;
|
||||
}
|
||||
#endif
|
||||
c = (*promvec->pv_getchar)();
|
||||
#if defined(SUN4)
|
||||
if (CPU_ISSUN4)
|
||||
*(oldpvec->echo) = saveecho;
|
||||
#endif
|
||||
splx(s);
|
||||
}
|
||||
if (c == '\r')
|
||||
c = '\n';
|
||||
return (c);
|
||||
}
|
||||
|
||||
void
|
||||
cnputc(c)
|
||||
register int c;
|
||||
{
|
||||
register int s;
|
||||
|
||||
if (c == '\n')
|
||||
cnputc('\r');
|
||||
s = splhigh();
|
||||
if (promvec->pv_romvec_vers > 2) {
|
||||
unsigned char c0 = c;
|
||||
(*promvec->pv_v2devops.v2_write)
|
||||
(*promvec->pv_v2bootargs.v2_fd1, &c0, 1);
|
||||
} else
|
||||
(*promvec->pv_putchar)(c);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
cnpollc(on)
|
||||
int on;
|
||||
{
|
||||
}
|
18
sys/arch/sparc/dev/cons.h
Normal file
18
sys/arch/sparc/dev/cons.h
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
struct consdev;
|
||||
struct zs_chanstate;
|
||||
|
||||
extern void *zs_conschan;
|
||||
|
||||
extern void nullcnprobe __P((struct consdev *));
|
||||
|
||||
extern int zs_getc __P((void *arg));
|
||||
extern void zs_putc __P((void *arg, int c));
|
||||
|
||||
struct zschan *
|
||||
zs_get_chan_addr __P((int zsc_unit, int channel));
|
||||
|
||||
#ifdef KGDB
|
||||
void zs_kgdb_init __P((void));
|
||||
void zskgdb __P((struct zs_chanstate *));
|
||||
#endif
|
@ -1,823 +0,0 @@
|
||||
/* $NetBSD: kbd.c,v 1.28 1997/09/13 19:12:18 pk 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/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 <sys/signalvar.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/conf.h>
|
||||
|
||||
#include <machine/vuid_event.h>
|
||||
#include <dev/sun/event_var.h>
|
||||
#include <machine/kbd.h>
|
||||
#include <machine/kbio.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 */
|
||||
u_char kbd_pending; /* Another code from the keyboard is due */
|
||||
u_char kbd_id; /* a place to store the ID */
|
||||
u_char kbd_layout; /* a place to store layout */
|
||||
char kbd_leds; /* LED state */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
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_reset __P((struct kbd_state *));
|
||||
static int kbd_translate __P((int, struct kbd_state *));
|
||||
void kbdattach __P((int));
|
||||
void kbd_repeat __P((void *arg));
|
||||
|
||||
/* set in kbdattach() */
|
||||
int kbd_repeat_start;
|
||||
int kbd_repeat_step;
|
||||
|
||||
/*
|
||||
* Attach the console keyboard ASCII (up-link) interface.
|
||||
* This happens before kbd_serial.
|
||||
*/
|
||||
void
|
||||
kbd_ascii(tp)
|
||||
struct tty *tp;
|
||||
{
|
||||
|
||||
kbd_softc.k_cons = tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach the console keyboard serial (down-link) interface.
|
||||
* We pick up the initial keyboard click state here as well.
|
||||
*/
|
||||
void
|
||||
kbd_serial(tp, iopen, iclose)
|
||||
struct tty *tp;
|
||||
void (*iopen) __P((struct tty *));
|
||||
void (*iclose) __P((struct tty *));
|
||||
{
|
||||
register struct kbd_softc *k;
|
||||
register char *cp;
|
||||
|
||||
k = &kbd_softc;
|
||||
k->k_kbd = tp;
|
||||
k->k_open = iopen;
|
||||
k->k_close = iclose;
|
||||
|
||||
if (!CPU_ISSUN4) {
|
||||
cp = getpropstring(optionsnode, "keyboard-click?");
|
||||
if (cp && strcmp(cp, "true") == 0)
|
||||
k->k_state.kbd_click = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from main() during pseudo-device setup. If this keyboard is
|
||||
* the console, this is our chance to open the underlying serial port and
|
||||
* send a RESET, so that we can find out what kind of keyboard it is.
|
||||
*/
|
||||
void
|
||||
kbdattach(kbd)
|
||||
int kbd;
|
||||
{
|
||||
register struct kbd_softc *k;
|
||||
register struct tty *tp;
|
||||
|
||||
kbd_repeat_start = hz/5;
|
||||
kbd_repeat_step = hz/20;
|
||||
|
||||
if (kbd_softc.k_cons != NULL) {
|
||||
k = &kbd_softc;
|
||||
tp = k->k_kbd;
|
||||
(*k->k_open)(tp); /* never to be closed */
|
||||
if (ttyoutput(KBD_CMD_RESET, tp) >= 0)
|
||||
panic("kbdattach");
|
||||
(*tp->t_oproc)(tp); /* get it going */
|
||||
|
||||
/*
|
||||
* Wait here for the keyboard initialization to complete
|
||||
* since subsequent kernel console access (ie. cnget())
|
||||
* may cause the PROM to interfere with the device.
|
||||
*/
|
||||
if (tsleep((caddr_t)&kbd_softc.k_state,
|
||||
PZERO | PCATCH, devopn, hz) != 0) {
|
||||
/* no response */
|
||||
printf("kbd: reset failed\n");
|
||||
kbd_reset(&kbd_softc.k_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kbd_reset(ks)
|
||||
register struct kbd_state *ks;
|
||||
{
|
||||
/*
|
||||
* On first identification, set up the table pointers.
|
||||
*/
|
||||
if (ks->kbd_unshifted == NULL) {
|
||||
ks->kbd_unshifted = kbd_unshifted;
|
||||
ks->kbd_shifted = kbd_shifted;
|
||||
ks->kbd_cur = ks->kbd_unshifted;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
default:
|
||||
printf("Unknown keyboard type %d\n", ks->kbd_id);
|
||||
}
|
||||
|
||||
ks->kbd_leds = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn keyboard up/down codes into ASCII.
|
||||
*/
|
||||
static int
|
||||
kbd_translate(c, ks)
|
||||
register int c;
|
||||
register struct kbd_state *ks;
|
||||
{
|
||||
register int down;
|
||||
|
||||
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(arg)
|
||||
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(c)
|
||||
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.
|
||||
* The printf below should be shortened and/or replaced with a
|
||||
* call to log() after this is tested (and how will we test it?!).
|
||||
*/
|
||||
if (c & (TTY_FE|TTY_PE)) {
|
||||
printf("keyboard input parity or framing 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_pending == KBD_RESET) {
|
||||
k->k_state.kbd_pending = 0;
|
||||
k->k_state.kbd_id = c;
|
||||
kbd_reset(&k->k_state);
|
||||
if (c == KB_SUN4) {
|
||||
/* Arrange to get keyboard layout as well */
|
||||
(void)ttyoutput(KBD_CMD_GLAYOUT, k->k_kbd);
|
||||
(*k->k_kbd->t_oproc)(k->k_kbd);
|
||||
} else
|
||||
wakeup((caddr_t)&k->k_state);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read the keyboard layout if we read a KBD_LAYOUT last time */
|
||||
if (k->k_state.kbd_pending == KBD_LAYOUT) {
|
||||
k->k_state.kbd_pending = 0;
|
||||
k->k_state.kbd_layout = c;
|
||||
/*
|
||||
* Wake up anyone waiting for type.
|
||||
*/
|
||||
wakeup((caddr_t)&k->k_state);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If reset or layout in progress, setup to grab the accompanying
|
||||
* keyboard response next time (id on reset, dip switch on layout).
|
||||
*/
|
||||
if (c == KBD_RESET || c == KBD_LAYOUT) {
|
||||
k->k_state.kbd_pending = c;
|
||||
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, &k->k_state);
|
||||
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, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags;
|
||||
int mode;
|
||||
struct proc *p;
|
||||
{
|
||||
int s, error;
|
||||
struct tty *tp;
|
||||
|
||||
if (kbd_softc.k_events.ev_io)
|
||||
return (EBUSY);
|
||||
kbd_softc.k_events.ev_io = p;
|
||||
/*
|
||||
* If no console keyboard, tell the device to open up, maybe for
|
||||
* the first time. Then make sure we know what kind of keyboard
|
||||
* it is.
|
||||
*/
|
||||
tp = kbd_softc.k_kbd;
|
||||
if (kbd_softc.k_cons == NULL)
|
||||
(*kbd_softc.k_open)(tp);
|
||||
error = 0;
|
||||
s = spltty();
|
||||
if (kbd_softc.k_state.kbd_cur == NULL) {
|
||||
(void) ttyoutput(KBD_CMD_RESET, tp);
|
||||
(*tp->t_oproc)(tp);
|
||||
error = tsleep((caddr_t)&kbd_softc.k_state, PZERO | PCATCH,
|
||||
devopn, hz);
|
||||
if (error == EWOULDBLOCK) /* no response */
|
||||
error = ENXIO;
|
||||
}
|
||||
splx(s);
|
||||
if (error) {
|
||||
kbd_softc.k_events.ev_io = NULL;
|
||||
return (error);
|
||||
}
|
||||
ev_init(&kbd_softc.k_events);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
kbdclose(dev, flags, mode, p)
|
||||
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);
|
||||
if (kbd_softc.k_cons == NULL)
|
||||
(*kbd_softc.k_close)(kbd_softc.k_kbd);
|
||||
kbd_softc.k_events.ev_io = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
kbdread(dev, uio, flags)
|
||||
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, uio, flags)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flags;
|
||||
{
|
||||
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int
|
||||
kbdioctl(dev, cmd, data, flag, p)
|
||||
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 (in an inappropriate fashion)
|
||||
* if a type 3 keyboard is really a type 3 keyboard.
|
||||
* Say yes (inappropriately).
|
||||
*/
|
||||
((struct okiockey *)data)->kio_entry = (u_char)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:
|
||||
*(unsigned int *)data = k->k_state.kbd_layout;
|
||||
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
|
||||
kbdpoll(dev, events, p)
|
||||
dev_t dev;
|
||||
int events;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (ev_poll(&kbd_softc.k_events, events, 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(cmd, isuser)
|
||||
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);
|
||||
}
|
591
sys/arch/sparc/dev/kd.c
Normal file
591
sys/arch/sparc/dev/kd.c
Normal file
@ -0,0 +1,591 @@
|
||||
/* $NetBSD: kd.c,v 1.1 1997/10/18 00:00:30 gwr Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Gordon W. Ross.
|
||||
*
|
||||
* 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 NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Keyboard/Display device.
|
||||
*
|
||||
* This driver exists simply to provide a tty device that
|
||||
* the indirect console driver can point to.
|
||||
* The kbd driver sends its input here.
|
||||
* Output goes to the screen via PROM printf.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/bsd_openprom.h>
|
||||
#include <machine/eeprom.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/kbd.h>
|
||||
#if defined(SUN4)
|
||||
#include <machine/oldmon.h>
|
||||
#endif
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/conf.h>
|
||||
|
||||
#ifdef RASTERCONSOLE
|
||||
#include <machine/fbio.h>
|
||||
#include <machine/fbvar.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <dev/cons.h>
|
||||
#include <dev/sun/kbd_xlate.h>
|
||||
#include <sparc/dev/cons.h>
|
||||
|
||||
extern void fb_unblank __P((void)); /* XXX */
|
||||
struct tty *fbconstty = 0; /* tty structure for frame buffer console */
|
||||
|
||||
#define KDMAJOR 1
|
||||
#define PUT_WSIZE 64
|
||||
|
||||
struct kd_softc {
|
||||
struct device kd_dev; /* required first: base device */
|
||||
struct tty *kd_tty;
|
||||
int rows, cols;
|
||||
};
|
||||
|
||||
/*
|
||||
* There is no point in pretending there might be
|
||||
* more than one keyboard/display device.
|
||||
*/
|
||||
static struct kd_softc kd_softc;
|
||||
static int kd_is_console;
|
||||
|
||||
static int kdparam(struct tty *, struct termios *);
|
||||
static void kdstart(struct tty *);
|
||||
|
||||
int rom_console_input; /* when set, hardclock calls cnrom() */
|
||||
int cons_ocount; /* output byte count */
|
||||
|
||||
/* Now talking directly to the zs, so this is not needed. */
|
||||
int
|
||||
cnrom()
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
void
|
||||
cnrint()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called by kbd_attach()
|
||||
* XXX - Make this a proper child of kbd?
|
||||
*/
|
||||
void
|
||||
kd_init(unit)
|
||||
int unit;
|
||||
{
|
||||
struct kd_softc *kd;
|
||||
struct tty *tp;
|
||||
|
||||
if (unit != 0)
|
||||
return;
|
||||
kd = &kd_softc; /* XXX */
|
||||
|
||||
tp = ttymalloc();
|
||||
tp->t_oproc = kdstart;
|
||||
tp->t_param = kdparam;
|
||||
tp->t_dev = makedev(KDMAJOR, unit);
|
||||
|
||||
#if 1 /* XXX - Why? */
|
||||
clalloc(&tp->t_rawq, 1024, 1);
|
||||
clalloc(&tp->t_canq, 1024, 1);
|
||||
/* output queue doesn't need quoting */
|
||||
clalloc(&tp->t_outq, 1024, 0);
|
||||
#endif
|
||||
|
||||
tty_attach(tp);
|
||||
kd->kd_tty = tp;
|
||||
|
||||
/*
|
||||
* get the console struct winsize.
|
||||
*/
|
||||
if (kd_is_console) {
|
||||
fbconstty = tp;
|
||||
#ifdef RASTERCONSOLE
|
||||
kd->rows = fbrcons_rows();
|
||||
kd->cols = fbrcons_cols();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (CPU_ISSUN4COR4M) {
|
||||
int i;
|
||||
char *prop;
|
||||
|
||||
if (kd->rows == 0 &&
|
||||
(prop = getpropstring(optionsnode, "screen-#rows"))) {
|
||||
i = 0;
|
||||
while (*prop != '\0')
|
||||
i = i * 10 + *prop++ - '0';
|
||||
kd->rows = (unsigned short)i;
|
||||
}
|
||||
if (kd->cols == 0 &&
|
||||
(prop = getpropstring(optionsnode, "screen-#columns"))) {
|
||||
i = 0;
|
||||
while (*prop != '\0')
|
||||
i = i * 10 + *prop++ - '0';
|
||||
kd->cols = (unsigned short)i;
|
||||
}
|
||||
}
|
||||
if (CPU_ISSUN4) {
|
||||
struct eeprom *ep = (struct eeprom *)eeprom_va;
|
||||
|
||||
if (ep) {
|
||||
if (kd->rows == 0)
|
||||
kd->rows = (u_short)ep->eeTtyRows;
|
||||
if (kd->cols == 0)
|
||||
kd->cols = (u_short)ep->eeTtyCols;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct tty *
|
||||
kdtty(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
struct kd_softc *kd;
|
||||
|
||||
kd = &kd_softc; /* XXX */
|
||||
return (kd->kd_tty);
|
||||
}
|
||||
|
||||
int
|
||||
kdopen(dev, flag, mode, p)
|
||||
dev_t dev;
|
||||
int flag, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
struct kd_softc *kd;
|
||||
int error, s, unit;
|
||||
struct tty *tp;
|
||||
|
||||
unit = minor(dev);
|
||||
if (unit != 0)
|
||||
return ENXIO;
|
||||
kd = &kd_softc; /* XXX */
|
||||
tp = kd->kd_tty;
|
||||
|
||||
if ((error = kbd_iopen(unit)) != 0) {
|
||||
#ifdef DIAGNOSTIC
|
||||
printf("kd: kbd_iopen, error=%d\n", error);
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
/* 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;
|
||||
(void) kdparam(tp, &tp->t_termios);
|
||||
ttsetwater(tp);
|
||||
tp->t_winsize.ws_row = kd->rows;
|
||||
tp->t_winsize.ws_col = kd->cols;
|
||||
/* 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));
|
||||
}
|
||||
|
||||
int
|
||||
kdclose(dev, flag, mode, p)
|
||||
dev_t dev;
|
||||
int flag, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
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);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
kdread(dev, uio, flag)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
int
|
||||
kdwrite(dev, uio, flag)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
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
|
||||
kdioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct kd_softc *kd;
|
||||
struct tty *tp;
|
||||
int error;
|
||||
|
||||
kd = &kd_softc; /* XXX */
|
||||
tp = kd->kd_tty;
|
||||
|
||||
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
return error;
|
||||
error = ttioctl(tp, cmd, data, flag, p);
|
||||
if (error >= 0)
|
||||
return error;
|
||||
|
||||
/* Handle any ioctl commands specific to kbd/display. */
|
||||
/* XXX - Send KB* ioctls to kbd module? */
|
||||
/* XXX - Send FB* ioctls to fb module? */
|
||||
|
||||
return ENOTTY;
|
||||
}
|
||||
|
||||
void
|
||||
kdstop(tp, flag)
|
||||
struct tty *tp;
|
||||
int flag;
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static void kd_later(void*);
|
||||
static void kd_putfb(struct tty *);
|
||||
|
||||
static void
|
||||
kdstart(tp)
|
||||
struct tty *tp;
|
||||
{
|
||||
struct clist *cl;
|
||||
register int s;
|
||||
|
||||
s = spltty();
|
||||
if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT))
|
||||
goto out;
|
||||
|
||||
cl = &tp->t_outq;
|
||||
if (cl->c_cc) {
|
||||
if (kd_is_console) {
|
||||
tp->t_state |= TS_BUSY;
|
||||
if ((s & PSR_PIL) == 0) {
|
||||
/* called at level zero - update screen now. */
|
||||
(void) splsoftclock();
|
||||
kd_putfb(tp);
|
||||
(void) spltty();
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
} else {
|
||||
/* called at interrupt level - do it later */
|
||||
timeout(kd_later, (void*)tp, 0);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This driver uses the PROM for writing the screen,
|
||||
* and that only works if this is the console device.
|
||||
* If this is not the console, just flush the output.
|
||||
* Sorry. (In that case, use xdm instead of getty.)
|
||||
*/
|
||||
ndflush(cl, cl->c_cc);
|
||||
}
|
||||
}
|
||||
if (cl->c_cc <= tp->t_lowat) {
|
||||
if (tp->t_state & TS_ASLEEP) {
|
||||
tp->t_state &= ~TS_ASLEEP;
|
||||
wakeup((caddr_t)cl);
|
||||
}
|
||||
selwakeup(&tp->t_wsel);
|
||||
}
|
||||
out:
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Timeout function to do delayed writes to the screen.
|
||||
* Called at splsoftclock when requested by kdstart.
|
||||
*/
|
||||
static void
|
||||
kd_later(tpaddr)
|
||||
void *tpaddr;
|
||||
{
|
||||
struct tty *tp = tpaddr;
|
||||
register int s;
|
||||
|
||||
kd_putfb(tp);
|
||||
|
||||
s = spltty();
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
(*linesw[tp->t_line].l_start)(tp);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put text on the screen using the PROM monitor.
|
||||
* This can take a while, so to avoid missing
|
||||
* interrupts, this is called at splsoftclock.
|
||||
*/
|
||||
static void
|
||||
kd_putfb(tp)
|
||||
struct tty *tp;
|
||||
{
|
||||
char buf[PUT_WSIZE];
|
||||
struct clist *cl = &tp->t_outq;
|
||||
char *p, *end;
|
||||
int len;
|
||||
|
||||
while ((len = q_to_b(cl, buf, PUT_WSIZE-1)) > 0) {
|
||||
/* PROM will barf if high bits are set. */
|
||||
p = buf;
|
||||
end = buf + len;
|
||||
while (p < end)
|
||||
*p++ &= 0x7f;
|
||||
/* Now let the PROM print it. */
|
||||
if (promvec->pv_romvec_vers > 2) {
|
||||
(*promvec->pv_v2devops.v2_write)
|
||||
(*promvec->pv_v2bootargs.v2_fd1, buf, len);
|
||||
} else
|
||||
(*promvec->pv_putstr)(buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Our "interrupt" routine for input. This is called by
|
||||
* the keyboard driver (dev/sun/kbd.c) at spltty.
|
||||
*/
|
||||
void
|
||||
kd_input(c)
|
||||
int c;
|
||||
{
|
||||
struct kd_softc *kd = &kd_softc;
|
||||
struct tty *tp;
|
||||
|
||||
/* XXX: Make sure the device is open. */
|
||||
tp = kd->kd_tty;
|
||||
if (tp == NULL)
|
||||
return;
|
||||
if ((tp->t_state & TS_ISOPEN) == 0)
|
||||
return;
|
||||
|
||||
(*linesw[tp->t_line].l_rint)(c, tp);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* kd console support
|
||||
****************************************************************/
|
||||
|
||||
/* The debugger gets its own key translation state. */
|
||||
static struct kbd_state kdcn_state;
|
||||
|
||||
static void kdcnprobe __P((struct consdev *));
|
||||
static void kdcninit __P((struct consdev *));
|
||||
static int kdcngetc __P((dev_t));
|
||||
static void kdcnputc __P((dev_t, int));
|
||||
static void kdcnpollc __P((dev_t, int));
|
||||
|
||||
struct consdev consdev_kd = {
|
||||
kdcnprobe,
|
||||
kdcninit,
|
||||
kdcngetc,
|
||||
kdcnputc,
|
||||
kdcnpollc,
|
||||
};
|
||||
|
||||
/* We never call this. */
|
||||
static void
|
||||
kdcnprobe(cn)
|
||||
struct consdev *cn;
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
kdcninit(cn)
|
||||
struct consdev *cn;
|
||||
{
|
||||
struct kbd_state *ks = &kdcn_state;
|
||||
|
||||
cn->cn_dev = makedev(KDMAJOR, 0);
|
||||
cn->cn_pri = CN_INTERNAL;
|
||||
|
||||
/* This prepares kbd_translate() */
|
||||
ks->kbd_id = KBD_MIN_TYPE;
|
||||
kbd_xlate_init(ks);
|
||||
|
||||
/* Indicate that it is OK to use the PROM fbwrite */
|
||||
kd_is_console = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
kdcngetc(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
struct kbd_state *ks = &kdcn_state;
|
||||
int code, class, data, keysym;
|
||||
|
||||
for (;;) {
|
||||
code = zs_getc(zs_conschan);
|
||||
keysym = kbd_code_to_keysym(ks, code);
|
||||
class = KEYSYM_CLASS(keysym);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
kdcnputc(dev, c)
|
||||
dev_t dev;
|
||||
int c;
|
||||
{
|
||||
char c0 = (c & 0x7f);
|
||||
|
||||
if (promvec->pv_romvec_vers > 2)
|
||||
(*promvec->pv_v2devops.v2_write)
|
||||
(*promvec->pv_v2bootargs.v2_fd1, &c0, 1);
|
||||
else
|
||||
(*promvec->pv_putchar)(c);
|
||||
}
|
||||
|
||||
static void
|
||||
kdcnpollc(dev, on)
|
||||
dev_t dev;
|
||||
int on;
|
||||
{
|
||||
struct kbd_state *ks = &kdcn_state;
|
||||
|
||||
if (on) {
|
||||
/* Entering debugger. */
|
||||
fb_unblank();
|
||||
/* Clear shift keys too. */
|
||||
ks->kbd_modbits = 0;
|
||||
} else {
|
||||
/* Resuming kernel. */
|
||||
}
|
||||
}
|
||||
|
@ -1,346 +0,0 @@
|
||||
/* $NetBSD: ms.c,v 1.10 1996/09/12 01:36:18 mrg 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/ioctl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <machine/vuid_event.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/kbd.h>
|
||||
#include <machine/conf.h>
|
||||
|
||||
#include <dev/sun/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.
|
||||
* The Sun 4 needs to have the baud rate set explicitly, but we handle
|
||||
* that in ms_open().
|
||||
*/
|
||||
void
|
||||
ms_serial(tp, iopen, iclose)
|
||||
struct tty *tp;
|
||||
void (*iopen) __P((struct tty *));
|
||||
void (*iclose) __P((struct tty *));
|
||||
{
|
||||
|
||||
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;
|
||||
{
|
||||
|
||||
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 */
|
||||
|
||||
if (CPU_ISSUN4) {
|
||||
/* We need to set the baud rate on the mouse. */
|
||||
ms_softc.ms_mouse->t_ispeed =
|
||||
ms_softc.ms_mouse->t_ospeed = 1200;
|
||||
}
|
||||
|
||||
(*ms_softc.ms_open)(ms_softc.ms_mouse);
|
||||
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;
|
||||
{
|
||||
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
|
||||
mspoll(dev, events, p)
|
||||
dev_t dev;
|
||||
int events;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (ev_poll(&ms_softc.ms_events, events, p));
|
||||
}
|
File diff suppressed because it is too large
Load Diff
291
sys/arch/sparc/dev/zs_kgdb.c
Normal file
291
sys/arch/sparc/dev/zs_kgdb.c
Normal file
@ -0,0 +1,291 @@
|
||||
/* $NetBSD: zs_kgdb.c,v 1.1 1997/10/18 00:00:51 gwr Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Gordon W. Ross.
|
||||
*
|
||||
* 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 NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hooks for kgdb when attached via the z8530 driver
|
||||
*
|
||||
* To use this, build a kernel with: option KGDB, and
|
||||
* boot that kernel with "-d". (The kernel will call
|
||||
* zs_kgdb_init, kgdb_connect.) When the console prints
|
||||
* "kgdb waiting..." you run "gdb -k kernel" and do:
|
||||
* (gdb) set remotebaud 19200
|
||||
* (gdb) target remote /dev/ttyb
|
||||
*/
|
||||
|
||||
#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 <sys/kgdb.h>
|
||||
|
||||
#include <dev/ic/z8530reg.h>
|
||||
#include <machine/z8530var.h>
|
||||
#include <sparc/dev/cons.h>
|
||||
|
||||
/* The Sun3 provides a 4.9152 MHz clock to the ZS chips. */
|
||||
#define PCLK (9600 * 512) /* PCLK pin input clock rate */
|
||||
#define ZSHARD_PRI 6 /* Wired on the CPU board... */
|
||||
|
||||
#define ZS_DELAY() (CPU_ISSUN4C ? (0) : delay(2))
|
||||
|
||||
/* The layout of this is hardware-dependent (padding, order). */
|
||||
struct zschan {
|
||||
volatile u_char zc_csr; /* ctrl,status, and indirect access */
|
||||
u_char zc_xxx0;
|
||||
volatile u_char zc_data; /* data */
|
||||
u_char zc_xxx1;
|
||||
};
|
||||
|
||||
static void zs_setparam __P((struct zs_chanstate *, int, int));
|
||||
struct zsops zsops_kgdb;
|
||||
|
||||
static u_char zs_kgdb_regs[16] = {
|
||||
0, /* 0: CMD (reset, etc.) */
|
||||
0, /* 1: ~(ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE) */
|
||||
0, /* 2: 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 | ZSWR9_NO_VECTOR,
|
||||
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_ENA | ZSWR14_BAUD_FROM_PCLK,
|
||||
ZSWR15_BREAK_IE | ZSWR15_DCD_IE,
|
||||
};
|
||||
|
||||
/*
|
||||
* This replaces "zs_reset()" in the sparc driver.
|
||||
*/
|
||||
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) {
|
||||
cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE;
|
||||
}
|
||||
|
||||
/* Initialize the speed, etc. */
|
||||
tconst = BPS_TO_TCONST(cs->cs_brg_clk, 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.
|
||||
* Called after cninit(), so printf() etc. works.
|
||||
*/
|
||||
void
|
||||
zs_kgdb_init()
|
||||
{
|
||||
struct zs_chanstate cs;
|
||||
volatile struct zschan *zc;
|
||||
int channel, zsc_unit;
|
||||
|
||||
/* printf("zs_kgdb_init: kgdb_dev=0x%x\n", kgdb_dev); */
|
||||
if (major(kgdb_dev) != zs_major)
|
||||
return;
|
||||
|
||||
/* Note: (ttya,ttyb) on zsc1, and (ttyc,ttyd) on zsc0 */
|
||||
zsc_unit = (kgdb_dev & 2) ? 0 : 1;
|
||||
channel = kgdb_dev & 1;
|
||||
printf("zs_kgdb_init: attaching tty%c at %d baud\n",
|
||||
'a' + (kgdb_dev & 3), kgdb_rate);
|
||||
|
||||
/* Setup temporary chanstate. */
|
||||
bzero((caddr_t)&cs, sizeof(cs));
|
||||
zc = zs_get_chan_addr(zsc_unit, channel);
|
||||
if (zc == NULL) {
|
||||
printf("zs_kgdb_init: zs not mapped.\n");
|
||||
kgdb_dev = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
cs.cs_channel = channel;
|
||||
cs.cs_brg_clk = PCLK / 16;
|
||||
cs.cs_reg_csr = &zc->zc_csr;
|
||||
cs.cs_reg_data = &zc->zc_data;
|
||||
|
||||
/* 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;
|
||||
{
|
||||
|
||||
if (dev != kgdb_dev)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Yes, this is port in use by kgdb.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
void
|
||||
zskgdb(cs)
|
||||
struct zs_chanstate *cs;
|
||||
{
|
||||
int 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)
|
||||
****************************************************************/
|
||||
|
||||
static void zs_kgdb_rxint __P((struct zs_chanstate *));
|
||||
static void zs_kgdb_txint __P((struct zs_chanstate *));
|
||||
static void zs_kgdb_stint __P((struct zs_chanstate *));
|
||||
static void zs_kgdb_softint __P((struct zs_chanstate *));
|
||||
|
||||
int kgdb_input_lost;
|
||||
|
||||
static void
|
||||
zs_kgdb_rxint(cs)
|
||||
struct zs_chanstate *cs;
|
||||
{
|
||||
register u_char c, rr1;
|
||||
|
||||
/*
|
||||
* First read the status, because reading the received char
|
||||
* destroys the status of this char.
|
||||
*/
|
||||
rr1 = zs_read_reg(cs, 1);
|
||||
c = zs_read_data(cs);
|
||||
|
||||
if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
|
||||
/* Clear the receive error. */
|
||||
zs_write_csr(cs, ZSWR0_RESET_ERRORS);
|
||||
}
|
||||
|
||||
if (c == KGDB_START) {
|
||||
zskgdb(cs);
|
||||
} else {
|
||||
kgdb_input_lost++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
zs_kgdb_txint(cs)
|
||||
register struct zs_chanstate *cs;
|
||||
{
|
||||
register int rr0;
|
||||
|
||||
rr0 = zs_read_csr(cs);
|
||||
zs_write_csr(cs, ZSWR0_RESET_TXINT);
|
||||
}
|
||||
|
||||
static void
|
||||
zs_kgdb_stint(cs)
|
||||
register struct zs_chanstate *cs;
|
||||
{
|
||||
register int rr0;
|
||||
|
||||
rr0 = zs_read_csr(cs);
|
||||
zs_write_csr(cs, ZSWR0_RESET_STATUS);
|
||||
|
||||
/*
|
||||
* Check here for console break, so that we can abort
|
||||
* even when interrupts are locking up the machine.
|
||||
*/
|
||||
if (rr0 & ZSRR0_BREAK) {
|
||||
zskgdb(cs);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
zs_kgdb_softint(cs)
|
||||
struct zs_chanstate *cs;
|
||||
{
|
||||
printf("zs_kgdb_softint?\n");
|
||||
}
|
||||
|
||||
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,188 +0,0 @@
|
||||
/* $NetBSD: zsvar.h,v 1.10 1997/04/14 21:26:28 pk 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.
|
||||
*
|
||||
* @(#)zsvar.h 8.1 (Berkeley) 6/11/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Register layout is machine-dependent...
|
||||
*/
|
||||
|
||||
struct zschan {
|
||||
volatile u_char zc_csr; /* ctrl,status, and indirect access */
|
||||
u_char zc_xxx0;
|
||||
volatile u_char zc_data; /* data */
|
||||
u_char zc_xxx1;
|
||||
};
|
||||
|
||||
struct zsdevice {
|
||||
struct zschan zs_chan[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* 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)
|
||||
|
||||
/* forard decl */
|
||||
struct zs_softc;
|
||||
|
||||
struct zs_chanstate {
|
||||
struct zs_chanstate *cs_next; /* linked list for zshard() */
|
||||
struct zs_softc *cs_sc; /* pointer to softc */
|
||||
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) */
|
||||
char cs_deferred_cc; /* deferred zscnputc() output */
|
||||
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 */
|
||||
u_int cs_ringmask; /* mask, reflecting size of `rbuf' */
|
||||
int *cs_rbuf; /* 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.
|
||||
*
|
||||
* On the SparcStation the 1.6 microsecond recovery time is
|
||||
* handled in hardware. On the older Sun4 machine it isn't, and
|
||||
* software must deal with the problem.
|
||||
*
|
||||
* However, it *is* a problem on some Sun4m's (i.e. the SS20) (XXX: why?).
|
||||
* Thus we leave in the delay.
|
||||
*
|
||||
* XXX: (ABB) Think about this more.
|
||||
*/
|
||||
#if defined(SUN4)
|
||||
|
||||
#define ZS_READ(c, r) zs_read(c, r)
|
||||
#define ZS_WRITE(c, r, v) zs_write(c, r, v)
|
||||
#define ZS_DELAY() (CPU_ISSUN4C ? (0) : delay(1))
|
||||
|
||||
#else /* SUN4 */
|
||||
|
||||
#define ZS_READ(c, r) ((c)->zc_csr = (r), (c)->zc_csr)
|
||||
#define ZS_WRITE(c, r, v) ((c)->zc_csr = (r), (c)->zc_csr = (v))
|
||||
#define ZS_DELAY() (CPU_ISSUN4M ? delay(1) : 0)
|
||||
|
||||
#endif /* SUN4 */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: conf.h,v 1.8 1996/12/31 07:12:43 mrg Exp $ */
|
||||
/* $NetBSD: conf.h,v 1.9 1997/10/18 00:01:05 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
|
||||
@ -60,6 +60,7 @@ cdev_decl(fb);
|
||||
cdev_decl(ms);
|
||||
|
||||
cdev_decl(kbd);
|
||||
cdev_decl(kd);
|
||||
|
||||
cdev_decl(bwtwo);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kbd.h,v 1.6 1996/03/31 22:21:35 pk Exp $ */
|
||||
/* $NetBSD: kbd.h,v 1.7 1997/10/18 00:01:15 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -56,9 +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_LAYOUT 0xfe /* keyboard `get layout' response */
|
||||
#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,19 +81,14 @@
|
||||
#define KBD_CMD_NOBELL 3 /* turn bell off */
|
||||
#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_GLAYOUT 15 /* get DIP switch (type 4 kbd) */
|
||||
#define KBD_CMD_SETLED 14 /* set LED state (type 4 kbd) */
|
||||
#define KBD_CMD_GETLAYOUT 15 /* get DIP switch (type 4 kbd) */
|
||||
|
||||
#define LED_NUM_LOCK 0x1
|
||||
#define LED_COMPOSE 0x2
|
||||
#define LED_SCROLL_LOCK 0x4
|
||||
#define LED_CAPS_LOCK 0x8
|
||||
|
||||
void kbd_serial __P((struct tty *,
|
||||
void (*)(struct tty *), void (*)(struct tty *)));
|
||||
void ms_serial __P((struct tty *,
|
||||
void (*)(struct tty *), void (*)(struct tty *)));
|
||||
void kbd_rint __P((int));
|
||||
void ms_rint __P((int));
|
||||
void kbd_ascii __P((struct tty *));
|
||||
#ifdef _KERNEL
|
||||
int kbd_docmd __P((int, int));
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kbio.h,v 1.4 1995/05/10 16:07:27 pk Exp $ */
|
||||
/* $NetBSD: kbio.h,v 1.5 1997/10/18 00:01:23 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -66,46 +66,53 @@
|
||||
* Keyboard commands and types are defined in kbd.h as they are actually
|
||||
* real hardware commands and type numbers.
|
||||
*/
|
||||
|
||||
struct okiockey { /* Out-dated key translation structure */
|
||||
int kio_tablemask; /* whatever */
|
||||
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 {
|
||||
int kio_tablemask; /* whatever */
|
||||
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
|
||||
|
||||
#if 0 /* XXX - This is wrong. Programs testing this expect 0xA2 */
|
||||
#define HOLE 0x302 /* value for kio_entry to say `really type 3' */
|
||||
#endif
|
||||
|
||||
#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 KIOCLAYOUT _IOR('k', 20, int) /* get keyboard layout */
|
||||
#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 */
|
||||
|
||||
#define TR_NONE 0 /* X compat, unsupported */
|
||||
#define TR_ASCII 1 /* X compat, unsupported */
|
||||
|
85
sys/arch/sparc/include/z8530var.h
Normal file
85
sys/arch/sparc/include/z8530var.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* $NetBSD: z8530var.h,v 1.1 1997/10/18 00:01:30 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.
|
||||
*
|
||||
* @(#)zsvar.h 8.1 (Berkeley) 6/11/93
|
||||
*/
|
||||
|
||||
#include <dev/ic/z8530sc.h>
|
||||
|
||||
struct zsc_softc {
|
||||
struct device zsc_dev; /* required first: base device */
|
||||
struct zs_chanstate *zsc_cs[2]; /* channel A and B soft state */
|
||||
/* Machine-dependent part follows... */
|
||||
struct evcnt zsc_intrcnt; /* count interrupts */
|
||||
struct zs_chanstate zsc_cs_store[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* Functions to read and write individual registers in a channel.
|
||||
* The ZS chip requires a 1.6 uSec. recovery time between accesses.
|
||||
* On the SparcStation the recovery time is handled in hardware.
|
||||
* On the older Sun4 machine it isn't, and software must do it.
|
||||
*
|
||||
* However, it *is* a problem on some Sun4m's (i.e. the SS20) (XXX: why?).
|
||||
* Thus we leave in the delay (done in the functions below).
|
||||
* XXX: (ABB) Think about this more.
|
||||
*
|
||||
* The functions below could be macros instead if we are concerned
|
||||
* about the function call overhead where ZS_DELAY does nothing.
|
||||
*/
|
||||
|
||||
u_char zs_read_reg __P((struct zs_chanstate *cs, u_char reg));
|
||||
u_char zs_read_csr __P((struct zs_chanstate *cs));
|
||||
u_char zs_read_data __P((struct zs_chanstate *cs));
|
||||
|
||||
void zs_write_reg __P((struct zs_chanstate *cs, u_char reg, u_char val));
|
||||
void zs_write_csr __P((struct zs_chanstate *cs, u_char val));
|
||||
void zs_write_data __P((struct zs_chanstate *cs, u_char val));
|
||||
|
||||
/* The sparc has splzs() in psl.h */
|
||||
|
||||
/* We want to call it "zs" instead of "zsc" (sigh). */
|
||||
#ifndef ZSCCF_CHANNEL
|
||||
#define ZSCCF_CHANNEL 0
|
||||
#define ZSCCF_CHANNEL_DEFAULT -1
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: autoconf.c,v 1.79 1997/09/27 18:01:35 pk Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.80 1997/10/18 00:01:42 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
@ -225,9 +225,7 @@ bootstrap()
|
||||
cpuinfo.mmu_nregion,
|
||||
cpuinfo.mmu_nsegment);
|
||||
|
||||
#ifdef KGDB
|
||||
zs_kgdb_init(); /* XXX */
|
||||
#endif
|
||||
/* Moved zs_kgdb_init() to dev/zs.c:consinit(). */
|
||||
#ifdef DDB
|
||||
db_machine_init();
|
||||
ddb_init();
|
||||
@ -444,12 +442,14 @@ bootpath_build()
|
||||
break;
|
||||
|
||||
case 'd': /* kgdb - always on zs XXX */
|
||||
#ifdef KGDB
|
||||
#if defined(KGDB)
|
||||
boothowto |= RB_KDB; /* XXX unused */
|
||||
kgdb_debug_panic = 1;
|
||||
kgdb_connect(1);
|
||||
#elif defined(DDB)
|
||||
Debugger();
|
||||
#else
|
||||
printf("kernel not compiled with KGDB\n");
|
||||
printf("kernel has no debugger\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: conf.c,v 1.50 1997/10/16 23:43:16 christos Exp $ */
|
||||
/* $NetBSD: conf.c,v 1.51 1997/10/18 00:01:55 gwr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -67,7 +67,10 @@
|
||||
#include "cd.h"
|
||||
#include "uk.h"
|
||||
|
||||
#include "zs.h"
|
||||
#include "kbd.h"
|
||||
#include "ms.h"
|
||||
#include "zstty.h"
|
||||
|
||||
#include "fdc.h" /* has NFDC and NFD; see files.sparc */
|
||||
#include "bwtwo.h"
|
||||
#include "cgtwo.h"
|
||||
@ -116,20 +119,20 @@ int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
|
||||
struct cdevsw cdevsw[] =
|
||||
{
|
||||
cdev_cn_init(1,cn), /* 0: virtual console */
|
||||
cdev_notdef(), /* 1 */
|
||||
cdev_tty_init(NKBD,kd), /* 1: Sun keyboard/display */
|
||||
cdev_ctty_init(1,ctty), /* 2: controlling terminal */
|
||||
cdev_mm_init(1,mm), /* 3: /dev/{null,mem,kmem,...} */
|
||||
cdev_notdef(), /* 4 */
|
||||
cdev_notdef(), /* 5 */
|
||||
cdev_notdef(), /* 6 */
|
||||
cdev_notdef(), /* 5: tapemaster tape */
|
||||
cdev_notdef(), /* 6: systech/versatec */
|
||||
cdev_swap_init(1,sw), /* 7: /dev/drum (swap pseudo-device) */
|
||||
cdev_notdef(), /* 8 */
|
||||
cdev_disk_init(NXY,xy), /* 9: SMD disk */
|
||||
cdev_notdef(), /* 10 */
|
||||
cdev_notdef(), /* 11 */
|
||||
cdev_tty_init(NZS,zs), /* 12: zs serial */
|
||||
cdev_gen_init(1,ms), /* 13: /dev/mouse */
|
||||
cdev_notdef(), /* 14 */
|
||||
cdev_notdef(), /* 8: Archive QIC-11 tape */
|
||||
cdev_disk_init(NXY,xy), /* 9: SMD disk on Xylogics 450/451 */
|
||||
cdev_notdef(), /* 10: systech multi-terminal board */
|
||||
cdev_notdef(), /* 11: DES encryption chip */
|
||||
cdev_tty_init(NZSTTY,zs), /* 12: Zilog 8350 serial port */
|
||||
cdev_mouse_init(NMS,ms), /* 13: /dev/mouse */
|
||||
cdev_notdef(), /* 14: cgone */
|
||||
cdev_notdef(), /* 15: sun /dev/winNNN */
|
||||
cdev_log_init(1,log), /* 16: /dev/klog */
|
||||
cdev_disk_init(NSD,sd), /* 17: SCSI disk */
|
||||
@ -143,9 +146,9 @@ struct cdevsw cdevsw[] =
|
||||
cdev_ipf_init(NIPFILTER,ipl), /* 25: ip-filter device */
|
||||
cdev_notdef(), /* 26 */
|
||||
cdev_fb_init(NBWTWO,bwtwo), /* 27: /dev/bwtwo */
|
||||
cdev_notdef(), /* 28 */
|
||||
cdev_gen_init(1,kbd), /* 29: /dev/kbd */
|
||||
cdev_notdef(), /* 30 */
|
||||
cdev_notdef(), /* 28: Systech VPC-2200 versatec/centronics */
|
||||
cdev_mouse_init(NKBD,kbd), /* 29: /dev/kbd */
|
||||
cdev_notdef(), /* 30: Xylogics tape */
|
||||
cdev_fb_init(NCGTWO,cgtwo), /* 31: /dev/cgtwo */
|
||||
cdev_notdef(), /* 32: should be /dev/gpone */
|
||||
cdev_notdef(), /* 33 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user